SocialMate Local API
Diagnostics & accounts
Health, version, status, and the accounts / chats / contacts read endpoints.
Liveness and identity probes, plus the read endpoints for accounts, chats, and contacts.
All are GETs available on Free with a read-scoped key —
except /health, which needs no key at all.
Diagnostics
/healthThe one unauthenticated route — a cheap liveness check. Not wrapped in the data envelope.
{ "status": "ok", "app": "SocialMate", "version": "2.0.0", "timestamp": "…", "uptimeSec": 3601 }
/v1/versionBuild identity — handy when filing an issue.
curl http://localhost:3456/v1/version \
-H "x-api-key: YOUR_KEY"
{ "data": { "app": "SocialMate", "version": "2.0.0", "electron": "…", "node": "…", "gitCommit": "…" } }
/v1/statusA deep health snapshot: DB connectivity, tunnel URL, per-account connection state, queue counters, and how many webhook endpoints are auto-disabled.
curl http://localhost:3456/v1/status \
-H "x-api-key: YOUR_KEY"
{
"data": {
"ok": true,
"database": { "ok": true },
"tunnel": { "url": "https://your-name.trycloudflare.com" },
"adapters": [ { "accountId": "a1b2c3", "state": "connected" } ],
"queue": { "pending": 4, "processing": 1, "failed": 0 },
"webhooks": { "brokenEndpoints": 0 },
"timestamp": "…"
}
}
/v1/capabilitiesThe integration handshake — the first call any integration should make
(it powers the n8n node's "Test connection"). One round-trip returns the license tier (so you
can grey out Pro-only operations instead of surfacing a raw 402), the enabled
feature flags, the tunnel mode/URL, the key's account scope, and the account list.
curl http://localhost:3456/v1/capabilities \
-H "x-api-key: YOUR_KEY"
{
"data": {
"app": "SocialMate", "version": "2.0.0", "tier": "pro",
"features": { "apiWriteEnabled": true, "localMessageCache": true, "scheduledMessages": true },
"tunnel": { "mode": "named", "url": "https://api.example.com" },
"keyScope": null,
"accounts": [ { "id": "a1b2c3", "phone": "15551234567", "name": "Sales", "status": "connected" } ]
}
}
/v1/network/statusA lighter probe than /v1/status when you only need the public address and
port — e.g. to print the current quick-tunnel URL (which rotates) in a setup script.
{ "data": { "tunnelUrl": "https://your-name.trycloudflare.com", "apiPort": 3456, "app": "SocialMate", "version": "2.0.0" } }
Accounts
/v1/accountsEvery linked account with its live risk and warming snapshot.
{
"data": [
{
"id": "a1b2c3", "phone": "15551234567", "name": "Sales line", "status": "connected",
"riskLevel": "safe", "riskScore": 23, "warmingDay": 1, "messagesToday": 41, "dailyLimit": 500
}
]
}
/v1/accounts/{id}One account's detail. 404 if the id is unknown.
curl http://localhost:3456/v1/accounts/ACCOUNT_ID \
-H "x-api-key: YOUR_KEY"
{ "data": { "id": "a1b2c3", "phone": "15551234567", "name": "Sales", "status": "connected", "dailyLimit": 500, "state": "connected" } }
Chats
/v1/accounts/{id}/chatsAll chats for the account (individual and group). No query params. Group-only? See Groups.
curl http://localhost:3456/v1/accounts/ACCOUNT_ID/chats \
-H "x-api-key: YOUR_KEY"
{ "data": [ { "id": "[email protected]", "name": "Acme", "type": "individual", "lastMessagePreview": "See you then!", "lastMessageAt": 1718800000000, "unreadCount": 0 } ] }
Contacts
/v1/accounts/{id}/contactsBounded, searchable contact list. Query params: search, limit
(max 500, default 100), offset. Always returns the paginated envelope
({ data, pagination }). Pass limit/offset to page;
omit them to get the full list in one page (pagination.total still reports the count).
curl "http://localhost:3456/v1/accounts/ACCOUNT_ID/contacts?search=jane&limit=50" \
-H "x-api-key: YOUR_KEY"
{ "data": [ { "id": "155512300001", "name": "Jane", "phone": "155512300001" } ], "pagination": { "limit": 50, "offset": 0, "total": 1 } }
/v1/accounts/{id}/contacts/{contactId}A single contact. 404 if not found on this account.
curl http://localhost:3456/v1/accounts/ACCOUNT_ID/contacts/155512300001 \
-H "x-api-key: YOUR_KEY"
{ "data": { "id": "155512300001", "name": "Jane", "phone": "155512300001", "jid": "[email protected]" } }
/v1/accounts/{id}/contacts/{contactId}Agent Memory. Save what your AI agent learned about a contact — a
customName, notes, email, company or
tags. The custom name then shows in the Live feed, message history and
GET /ai-context, and a WhatsApp sync can never overwrite it.
Create-if-missing: a contactId the WhatsApp contact list never
carried (a plain phone number in international format, or a senderId from a webhook)
is created. A provided field is saved, null clears it, an omitted field is left
unchanged; a group id returns 400. SocialMate stores what your agent learned — it
never generates it.
curl -X PATCH http://localhost:3456/v1/accounts/ACCOUNT_ID/contacts/155512300001 \
-H "x-api-key: YOUR_KEY" -H "Content-Type: application/json" \
-d '{ "customName": "Jane (VIP)", "company": "Acme", "tags": ["vip","lead"] }'
{ "data": { "success": true, "created": false,
"contact": { "id": "155512300001", "displayName": "Jane (VIP) . 155512300001",
"customName": "Jane (VIP)", "company": "Acme", "tags": ["vip","lead"] } } }
Message history is Pro. Reading and searching past messages
(GET /v1/accounts/{id}/messages) and backfill sync require Pro — see
Messages reference.