Overview
Uno SAP connects WhatsApp numbers to your application. The API supports two authentication models: master keys that manage your entire account and all sessions, and session-scoped keys that are tied to a single WhatsApp session for simplified access.
Base URL
https://api.beta.unosap.com/v1Auth
Bearer sk_live_...Content-Type
application/jsonVersion
v1Get your API key from the Sessions page. Each session gets its own key. Store it securely — it's shown only once.
API Keys & Authentication
Uno SAP uses two types of API keys. Both are passed as a Bearer token in the Authorization header.
Master keys have access to all sessions and account-level operations. Use them from your server to create sessions, send messages on behalf of any session, and manage webhooks across your account. Found in Settings.
curl https://api.beta.unosap.com/v1/sessions \
-H "Authorization: Bearer sk_live_master_..."Session-scoped keys are tied to one WhatsApp session. They unlock a simplified API where you never need to specify a session ID in the URL — the key itself determines the session. Available endpoints with a session-scoped key:
/send/webhooks/session/health/messagesGenerate a session-scoped key from the Sessions page, or via POST /v1/sessions/:id/keys.
Authorization header format
Authorization: Bearer sk_live_...Both key types use the same header format. The API detects the key type automatically.
Session Management
These endpoints require a master key. They manage the full lifecycle of your WhatsApp sessions.
/v1/sessionsCreate a new WhatsApp session. Returns a session ID and a session-scoped API key.
curl -X POST https://api.beta.unosap.com/v1/sessions \
-H "Authorization: Bearer sk_live_master_..." \
-H "Content-Type: application/json" \
-d '{"displayName": "Support Line"}'{
"id": "f496492d-...",
"displayName": "Support Line",
"status": "PENDING",
"apiKey": "sk_live_ses_..."
}/v1/sessionsList all WhatsApp sessions for your account.
curl https://api.beta.unosap.com/v1/sessions \
-H "Authorization: Bearer sk_live_master_..."[
{
"id": "f496492d-...",
"displayName": "Support Line",
"phone": "2348012345678",
"status": "CONNECTED",
"healthScore": 100
}
]/v1/sessions/:idGet details for a single session.
curl https://api.beta.unosap.com/v1/sessions/f496492d-... \
-H "Authorization: Bearer sk_live_master_..."/v1/sessions/:id/reconnectTrigger a reconnect for a disconnected session. Returns HTTP 204 on success.
curl -X POST https://api.beta.unosap.com/v1/sessions/f496492d-.../reconnect \
-H "Authorization: Bearer sk_live_master_..."/v1/sessions/:idSoft-delete a session. The session is disconnected and removed from your account. Returns HTTP 204.
curl -X DELETE https://api.beta.unosap.com/v1/sessions/f496492d-... \
-H "Authorization: Bearer sk_live_master_..."/v1/sessions/:id/healthGet the health score and connectivity details for a session.
curl https://api.beta.unosap.com/v1/sessions/f496492d-.../health \
-H "Authorization: Bearer sk_live_master_..."{
"score": 100,
"status": "CONNECTED",
"lastSeen": "2026-05-28T10:30:00Z"
}/v1/sessions/:id/sendSend a WhatsApp message via a specific session using your master key.
curl -X POST https://api.beta.unosap.com/v1/sessions/f496492d-.../send \
-H "Authorization: Bearer sk_live_master_..." \
-H "Content-Type: application/json" \
-d '{"to": "2348012345678", "type": "text", "text": "Hello!"}'/v1/sessions/:id/pairRequest a pairing code instead of scanning a QR code. Pass the phone number in international format.
curl -X POST https://api.beta.unosap.com/v1/sessions/f496492d-.../pair \
-H "Authorization: Bearer sk_live_master_..." \
-H "Content-Type: application/json" \
-d '{"phone": "2348012345678"}'{ "code": "ABCD-1234" }Sending Messages
Messages can be sent using either key type. Use the session-scoped POST /v1/send endpoint for single-session apps, or the master-key POST /v1/sessions/:id/send when managing multiple sessions from one key.
/v1/sendSend a message using a session-scoped key. The session is determined by your API key automatically.
Text
curl -X POST https://api.beta.unosap.com/v1/send \
-H "Authorization: Bearer sk_live_ses_..." \
-H "Content-Type: application/json" \
-d '{"to": "2348012345678", "type": "text", "text": "Hello!"}'Image with caption
curl -X POST https://api.beta.unosap.com/v1/send \
-H "Authorization: Bearer sk_live_ses_..." \
-d '{"to": "2348012345678", "type": "image", "mediaUrl": "https://example.com/photo.jpg", "caption": "Check this"}'Document
curl -X POST https://api.beta.unosap.com/v1/send \
-H "Authorization: Bearer sk_live_ses_..." \
-d '{"to": "2348012345678", "type": "document", "mediaUrl": "https://example.com/file.pdf", "fileName": "report.pdf"}'Interactive buttons
curl -X POST https://api.beta.unosap.com/v1/send \
-H "Authorization: Bearer sk_live_ses_..." \
-d '{"to": "2348012345678", "type": "buttons", "text": "Confirm?", "buttons": [{"id": "yes", "label": "Yes"}, {"id": "no", "label": "No"}]}'List / menu
curl -X POST https://api.beta.unosap.com/v1/send \
-H "Authorization: Bearer sk_live_ses_..." \
-d '{"to": "2348012345678", "type": "list", "text": "Choose", "listButtonText": "Select", "sections": [{"title": "Dept", "rows": [{"id": "a", "title": "Support"}]}]}'Location
curl -X POST https://api.beta.unosap.com/v1/send \
-H "Authorization: Bearer sk_live_ses_..." \
-d '{"to": "2348012345678", "type": "location", "latitude": 6.5244, "longitude": 3.3792, "locationName": "Lagos"}'/v1/sessions/:id/sendSend a message via a specific session using a master key. Same body shape as /send.
curl -X POST https://api.beta.unosap.com/v1/sessions/f496492d-.../send \
-H "Authorization: Bearer sk_live_master_..." \
-H "Content-Type: application/json" \
-d '{"to": "2348012345678", "type": "text", "text": "Hello from master key!"}'Media Upload
Upload files to Uno SAP and receive a hosted URL to use in mediaUrl fields when sending image, video, audio, and document messages.
/v1/media/uploadUpload a file using multipart/form-data. Returns a hosted URL valid for use in message payloads.
curl -X POST https://api.beta.unosap.com/v1/media/upload \
-H "Authorization: Bearer sk_live_..." \
-F "file=@/path/to/photo.jpg"{ "url": "https://media.unosap.com/uploads/abc123/photo.jpg" }File size limits
Images
image/jpeg, image/png, image/webp
Video
video/mp4, video/3gpp
Audio
audio/mpeg, audio/ogg, audio/mp4
Documents
PDF, DOCX, XLSX, and more
Session & Health
These endpoints use a session-scoped key. The session is determined automatically — no ID in the URL.
/v1/sessionGet your session's details, status, and phone number.
curl https://api.beta.unosap.com/v1/session \
-H "Authorization: Bearer sk_live_ses_..."{
"id": "f496492d-...",
"displayName": "Support Line",
"phone": "2348012345678",
"status": "CONNECTED",
"healthScore": 100,
"webhooksEnabled": true
}/v1/healthGet your session's health score and detail.
curl https://api.beta.unosap.com/v1/health \
-H "Authorization: Bearer sk_live_ses_..."Message History
/v1/messages?contactPhone=2348012345678Get outbound messages sent to a phone number. Paginated — 50 per page.
curl "https://api.beta.unosap.com/v1/messages?contactPhone=2348012345678&page=1&limit=50" \
-H "Authorization: Bearer sk_live_ses_..."{
"messages": [{
"id": "msg_abc", "contactPhone": "2348012345678",
"direction": "outbound", "body": "Hello!",
"type": "text", "status": "delivered",
"timestamp": "2026-05-28T10:30:00Z"
}],
"total": 142, "page": 1, "limit": 50
}Webhooks
Receive real-time events at your server. Configure webhook URLs from the API — each session can have multiple webhooks with different event filters. Webhooks can also be managed per-session from the dashboard.
/v1/webhooksCreate a webhook. Secret is auto-generated if not provided.
curl -X POST https://api.beta.unosap.com/v1/webhooks \
-H "Authorization: Bearer sk_live_ses_..." \
-H "Content-Type: application/json" \
-d '{"url": "https://your-server.com/hook", "events": ["message.received"], "secret": "my-secret"}'/v1/webhooksList all your webhooks.
curl https://api.beta.unosap.com/v1/webhooks \
-H "Authorization: Bearer sk_live_ses_..."/v1/webhooks/:webhookIdUpdate a webhook's URL, events, or enable/disable it.
curl -X PATCH https://api.beta.unosap.com/v1/webhooks/wh_abc \
-H "Authorization: Bearer sk_live_ses_..." \
-d '{"enabled": false}'/v1/webhooks/:webhookIdDelete a webhook.
curl -X DELETE https://api.beta.unosap.com/v1/webhooks/wh_abc \
-H "Authorization: Bearer sk_live_ses_..."/v1/webhooks/:webhookId/testSend a test ping event to the webhook URL to verify delivery.
curl -X POST https://api.beta.unosap.com/v1/webhooks/wh_abc/test \
-H "Authorization: Bearer sk_live_ses_..."/v1/webhooks/:webhookId/deliveriesGet recent delivery attempts and their response status for a webhook.
curl https://api.beta.unosap.com/v1/webhooks/wh_abc/deliveries \
-H "Authorization: Bearer sk_live_ses_..."Event payload
POST https://your-server.com/hook
X-Uno-Signature: a1b2c3d4e5f6...
{
"event": "message.received",
"tenantId": "tenant_abc",
"sessionId": "f496492d-...",
"timestamp": 1716894200000,
"data": { "messages": [{ "key": {...}, "message": {...} }] }
}Verify signatures (Node.js)
const crypto = require('crypto');
app.post('/hook', express.raw({ type: 'application/json' }), (req, res) => {
const sig = req.headers['x-uno-signature'];
const expected = crypto
.createHmac('sha256', process.env.WEBHOOK_SECRET)
.update(req.body)
.digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
return res.status(401).end();
}
res.status(200).end();
processEvent(JSON.parse(req.body));
});Event types
message.receivedInbound message from a user.
message.sentYour outbound message was acknowledged.
message.deliveredYour message reached the recipient's device.
message.readThe recipient opened your message.
message.updatedA message was edited.
message.deletedA message was deleted or revoked.
message.reactionA reaction emoji was added/removed.
session.connectedYour session connected.
session.disconnectedYour session disconnected.
session.bannedSession was banned.
session.qr_updatedNew QR code generated.
chats.upsertChat created or updated.
chats.updateChat settings changed.
chats.deleteChat deleted.
groups.upsertGroup created or number added.
groups.updateGroup metadata changed.
group-participants.updateParticipant joined/left/promoted.
call.receivedWhatsApp call detected.
- Respond HTTP 200 within 60 seconds. Process async.
- Always verify signatures using the
X-Uno-Signatureheader with constant-time comparison. - Be idempotent — events may be delivered more than once.
- Don't crash on unknown events — log and continue.