GlobVoice API
A simple REST API with one universal /send endpoint for WhatsApp, Email, SMS, Telegram and Push — plus contacts, templates and campaigns — from your own backend. JSON in, JSON out, authenticated with an API key.
Base URL
https://globvoice.com/api/v1/publicAll requests must be made over HTTPS. All responses are JSON. Successful responses return200/201; errors use the shape described under Errors.
Quickstart
- Open your brand dashboard → API Keys and create a key. Copy it — it is shown only once.
- Send the key in the
X-API-Keyheader on every request. - Make your first call with the universal
/sendendpoint — one call, any channel:
curl -X POST https://globvoice.com/api/v1/send \
-H "X-API-Key: $GLOBVOICE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"channel": "whatsapp",
"to": "919876543210",
"message": "Hello from GlobVoice!"
}'Try it — live API playground
Paste a key from your dashboard, fill in the fields, and run a real request. Your key stays in your browser and is sent only to GlobVoice. Note: this sends real messages.
Request
curl -X POST https://globvoice.com/api/v1/send \
-H "X-API-Key: $GLOBVOICE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"channel": "whatsapp",
"message": "Hello from the GlobVoice playground!"
}'Response
Check delivery status
Authentication
Authenticate by sending your secret key in the X-API-Key request header. Keys are scoped to a single brand and are stored only as a SHA-256 hash — GlobVoice can never show you a key again after creation, so store it securely (e.g. in an environment variable). A key can be revoked at any time from the dashboard.
X-API-Key: gv_live_xxxxxxxxxxxxxxxxxxxxxxxxNever expose your API key in client-side code. All calls should originate from your server.
Rate limits
Each API key is limited to 100 requests per minute. Exceeding the limit returns429 rate_limited. Back off and retry after the current minute window.
{
"error": "rate_limited",
"message": "100 req/min limit exceeded",
"statusCode": 429
}Scopes
When you create a key you can grant it specific scopes. A key with no scopes has full access. Calling an endpoint without its required scope returns 403 insufficient_scope.
| Scope | Grants |
|---|---|
messages:send | Send WhatsApp messages |
messages:read | Read message delivery status |
contacts:read | List and search contacts |
contacts:write | Create and update contacts |
templates:read | List WhatsApp templates |
campaigns:send | Create and send campaigns |
Errors
Errors return a non-2xx status and a consistent JSON body:
{
"error": "insufficient_scope",
"message": "Missing scope: messages:send",
"statusCode": 403
}| Status | Error codes | Meaning |
|---|---|---|
| 400 | validation_error / missing_text / missing_template | The request body failed validation. |
| 401 | missing_api_key / invalid_api_key / revoked_api_key / expired_api_key | Authentication failed — check your X-API-Key header. |
| 403 | insufficient_scope | The key is missing the scope required for this endpoint. |
| 404 | message_not_found | The requested resource does not exist for your brand. |
| 409 | no_sender | No active WhatsApp sender is configured for the brand. |
| 429 | rate_limited | You exceeded 100 requests per minute for this key. |
Endpoint reference
Universal Send — one endpoint, any channel
The simplest way to send. Pick a channel and GlobVoice routes the message through the right provider configured for your brand. Base URL: https://globvoice.com/api/v1.
/sendSend a message on any channel: whatsapp, email, sms, telegram or push. Provide channel + to + message; add the optional fields relevant to the channel. The brand must have that channel configured. Returns a channel-prefixed messageId you can pass to /status.
| Parameter | Type | Description |
|---|---|---|
channelrequired | "whatsapp" | "email" | "sms" | "telegram" | "push" | Which channel to send on. |
to | string | Phone number, email, or Telegram chat ID. Optional for push (broadcasts to the brand's subscribers; pass an endpoint to target one). |
message | string | Message body. Required for all channels except a WhatsApp template-only send. |
subject | string | Email only — subject line. |
templateName | string | WhatsApp only — approved template name. |
templateVars | string[] | WhatsApp only — ordered template variables. |
mediaUrl | string | WhatsApp / Telegram — image URL to send. |
title | string | Push only — notification title. |
url | string | Push only — click-through URL. |
Request
curl -X POST https://globvoice.com/api/v1/send \
-H "X-API-Key: $GLOBVOICE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"channel": "whatsapp",
"to": "919876543210",
"message": "Hello from GlobVoice!"
}'Response
{
"success": true,
"messageId": "wa_a1b2c3d4",
"channel": "whatsapp",
"status": "queued"
}/status/{messageId}Look up the delivery status of any message returned by /send, across every channel. Pass the channel-prefixed messageId (e.g. wa_…, sms_…, email_…). Status is one of: queued, sending, sent, delivered, failed.
| Parameter | Type | Description |
|---|---|---|
messageIdrequired | string (path) | The messageId returned by POST /send. |
Request
curl https://globvoice.com/api/v1/status/sms_8f1c2e3a \
-H "X-API-Key: $GLOBVOICE_API_KEY"Response
{
"success": true,
"messageId": "sms_8f1c2e3a",
"channel": "sms",
"status": "delivered"
}Channel-specific endpoints
For finer control, call the dedicated endpoints below (relative to https://globvoice.com/api/v1/public).
/messages/sendscope: messages:sendSend a WhatsApp message from the brand's active sender. Supports plain text, an approved template, or a raw Meta Cloud API payload for advanced message types.
| Parameter | Type | Description |
|---|---|---|
torequired | string | Recipient phone number in international format, digits only (e.g. 919876543210). |
typerequired | "text" | "template" | "raw" | Message kind. |
text | string | Body text. Required when type=text (max 4096 chars). |
templateName | string | Approved template name. Required when type=template. |
templateParams | object | Map of template variable values, e.g. { "1": "Jane" }. |
rawPayload | object | Raw Meta payload (after messaging_product/to). Required when type=raw. |
idempotencyKey | string | Optional key to safely retry without double-sending. |
Request
curl -X POST https://globvoice.com/api/v1/public/messages/send \
-H "X-API-Key: $GLOBVOICE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "919876543210",
"type": "template",
"templateName": "order_update",
"templateParams": { "1": "Jane", "2": "#A1234" },
"idempotencyKey": "order-A1234"
}'Response
{
"ok": true,
"jobId": "a1b2c3d4-..."
}/messages/{id}/statusscope: messages:readFetch the delivery status and timestamps for a previously sent message.
| Parameter | Type | Description |
|---|---|---|
idrequired | uuid (path) | The message ID. |
Request
curl https://globvoice.com/api/v1/public/messages/MSG_ID/status \
-H "X-API-Key: $GLOBVOICE_API_KEY"Response
{
"message": {
"id": "a1b2c3d4-...",
"status": "delivered",
"recipient": "919876543210",
"sentAt": "2026-06-05T10:00:00.000Z",
"deliveredAt": "2026-06-05T10:00:02.000Z",
"readAt": null,
"failedAt": null,
"errorCode": null,
"errorDetail": null
}
}/contactsscope: contacts:readList contacts for the brand, newest first. Optionally search by phone or name.
| Parameter | Type | Description |
|---|---|---|
limit | number | Max results, 1–500 (default 100). |
search | string | Filter by phone substring or case-insensitive name. |
Request
curl "https://globvoice.com/api/v1/public/contacts?limit=50&search=jane" \
-H "X-API-Key: $GLOBVOICE_API_KEY"Response
{
"contacts": [
{
"id": "c1...",
"phone": "919876543210",
"name": "Jane Doe",
"optedOut": false,
"lastSeenAt": "2026-06-04T09:12:00.000Z",
"createdAt": "2026-05-01T08:00:00.000Z"
}
]
}/contactsscope: contacts:writeCreate a contact, or update it if the phone number already exists for the brand (upsert).
| Parameter | Type | Description |
|---|---|---|
phonerequired | string | Phone number in international format. |
name | string | Display name. |
attributes | object | Custom string attributes, e.g. { "plan": "pro" }. |
Request
curl -X POST https://globvoice.com/api/v1/public/contacts \
-H "X-API-Key: $GLOBVOICE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone": "919876543210",
"name": "Jane Doe",
"attributes": { "plan": "pro" }
}'Response
{
"contact": {
"id": "c1...",
"phone": "919876543210",
"name": "Jane Doe",
"attributes": { "plan": "pro" }
}
}/templatesscope: templates:readList the brand's WhatsApp message templates and their approval status.
Request
curl https://globvoice.com/api/v1/public/templates \
-H "X-API-Key: $GLOBVOICE_API_KEY"Response
{
"templates": [
{
"id": "t1...",
"name": "order_update",
"language": "en",
"category": "UTILITY",
"status": "APPROVED",
"syncedAt": "2026-06-01T00:00:00.000Z"
}
]
}/campaigns/sendscope: campaigns:sendCreate a campaign from an approved template and send it to an audience — specific contacts, a saved segment, or all contacts.
| Parameter | Type | Description |
|---|---|---|
namerequired | string | Campaign name. |
templateNamerequired | string | Approved template to send. |
templateParams | object[] | Per-recipient template variable maps. |
recipientFilterrequired | object | One of: { contactIds: [...] }, { segmentId }, or { all: true }. |
Request
curl -X POST https://globvoice.com/api/v1/public/campaigns/send \
-H "X-API-Key: $GLOBVOICE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "June promo",
"templateName": "promo_june",
"recipientFilter": { "all": true }
}'Response
{
"ok": true,
"campaignId": "cmp_...",
"queued": 1240,
"total": 1300,
"errors": []
}/verify-emailsFree email-list verification (no API key required). Runs syntax, disposable-domain and MX checks. IP rate-limited to 5 requests/hour; max 500 emails per call.
| Parameter | Type | Description |
|---|---|---|
emails | string[] | Array of email addresses (max 500). |
text | string | Alternatively, a raw blob separated by newlines, commas or semicolons. |
Request
curl -X POST https://globvoice.com/api/v1/public/verify-emails \
-H "Content-Type: application/json" \
-d '{ "emails": ["jane@example.com", "bad@@nope"] }'Response
{
"results": [
{ "email": "jane@example.com", "result": "valid", "score": 80 },
{ "email": "bad@@nope", "result": "invalid", "score": 0 }
],
"summary": { "total": 2, "valid": 1, "invalid": 1, "risky": 0 }
}Ready to build?
Create a free account, then generate an API key from your brand dashboard.