Developer guide
Connect GetPulseRelay to your own systems. Use the REST API (a set of web addresses your code can call) to manage contacts and send messages, webhooks to hear about events as they happen, and the browser extension to bring the inbox into your CRM.
API keys
An API key is a secret that lets your code act on behalf of your workspace.
- 1Go to Developers → API keys and create a key. Name it after the system that will use it, so you can tell keys apart later.
- 2Copy the key straight away. We only keep a scrambled version, so we can't show it to you again.
- 3Send it as a Bearer token in the Authorization header of every request.
- 4You can revoke a key at any time. It stops working from the very next request.
REST endpoints
| Method | Path | What it does |
|---|---|---|
| GET | /api/public/v1/contacts | Lists your contacts, newest first. Use ?limit= to get up to 200 at a time, and ?search= to find a name or number. |
| POST | /api/public/v1/contacts | Creates a contact, or updates the existing one with the same phone number. |
| POST | /api/public/v1/messages | Sends an approved WhatsApp template. |
| GET | /api/public/status | Shows whether the service is up. |
curl -X POST https://getpulserelay.com/api/public/v1/messages \
-H "Authorization: Bearer $PULSERELAY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-1042-shipped" \
-d '{
"to": "+919876543210",
"template_name": "order_shipped",
"language": "en",
"variables": ["Navin", "TRK12345"]
}'- Phone numbers should include the country code, e.g. +919876543210. If we can't read a number, the request is rejected.
- variables fills the template's {{1}}, {{2}}… placeholders, in order.
- Contacts who replied STOP are unsubscribed. Sending to them returns a 422 response and nothing is sent.
- Messages count towards your plan's monthly allowance and your number's daily WhatsApp limit.
- Send an Idempotency-Key header so it's safe to retry: if we've already handled that key, we return the original response instead of sending again.
- Each key has a per-minute request limit. If you go over it, you'll get a 429 response with a Retry-After header telling you how many seconds to wait.
Outgoing webhooks
A webhook is a web address on your server that we call whenever something happens. Add yours under Developers → Webhooks and choose the events you want: message.received, message.status, message.sent, message.failed, campaign.finished, contact.created, contact.opted_out and contact.opted_in.
- Each delivery is a JSON POST with an X-PulseRelay-Event header naming the event.
- It's signed so you can check it really came from us: the X-PulseRelay-Signature header is sha256= followed by an HMAC-SHA256 of the raw body, using your webhook secret.
- Compare signatures in constant time, and reject anything that doesn't match.
- We wait up to 10 seconds for a reply and don't follow redirects. Reply quickly with a 2xx status and do any slow work afterwards.
- If your server is down, times out, or answers 408, 429 or 5xx, we try again after about 30 seconds, 2 minutes, 10 minutes, 30 minutes, 2 hours and 6 hours. Other 4xx answers are not retried.
- Every attempt carries the same X-PulseRelay-Delivery id (also the id field of the body): store it and ignore repeats. X-PulseRelay-Attempt counts the tries.
- Messages you sent through the API carry your reference and metadata in message.sent, message.status and message.failed.
- You can see recent deliveries and your server's responses on the Developers page, which helps with debugging.
const header = request.headers.get("X-PulseRelay-Signature") ?? "";
const received = header.replace(/^sha256=/, "");
const expected = crypto
.createHmac("sha256", process.env.PULSERELAY_WEBHOOK_SECRET)
.update(rawBody)
.digest("hex");
if (
received.length !== expected.length ||
!crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected))
) {
return new Response("Invalid signature", { status: 401 });
}Meta webhook
This is the address Meta uses to tell us about new messages, delivery updates and template decisions. Each workspace gets its own, and it's set up automatically when you click Connect with Meta. We check Meta's signature on every update. You only need to set it up yourself if you connected WhatsApp manually in Settings.
Browser extension
- A Chrome and Edge extension that shows your GetPulseRelay inbox in a side panel next to your CRM.
- It spots a phone number on the page and opens the matching chat.
- Send saved replies and approved templates without leaving your CRM.
- Download it from the Developers page and load it into your browser, or install it from the store listing.
Still stuck? Open a support ticket.
