Developer API
oToK's public API lets you connect any system to your workspace: manage contacts, tags, groups and campaigns, and send WhatsApp templates. On top of that, inbound webhooks fire automations, and the tracking pixel streams activity from your website.
SDKs, full reference and source
The full developer docs are hosted at https://slikkdev.github.io/otok-api/ — including a complete Redoc reference for every endpoint at https://slikkdev.github.io/otok-api/reference/ — and the code is open on GitHub: https://github.com/slikkdev/otok-api. Prefer a ready-made client? Official SDKs are available:
- Node.js — install with npm install @otok/node (Node 18+, TypeScript types, zero dependencies).
- Python — install with pip install otok (Python 3.9+, typed, zero dependencies).
Authentication
Create an API key under Settings → Developers. The key starts with otok_live_ and is shown only once — store it safely. Every request carries an Authorization header:
curl https://app.otok.io/api/v1/contacts \
-H "Authorization: Bearer otok_live_XXXXXXXXXXXX" \
-H "Content-Type: application/json"💡 Base URL: https://app.otok.io/api — and every key is scoped to the workspace it was created in. Full interactive (Swagger) documentation is available at /api/v1/docs.
All endpoints
| Method | Path | Description |
|---|---|---|
| GET | /v1/contacts | List contacts (filter, sort, search, paging) |
| GET | /v1/contacts/:id | Get a contact |
| POST | /v1/contacts | Create or update a contact (upsert by phone/email) |
| PATCH | /v1/contacts/:id | Update a contact |
| GET | /v1/tags · /v1/tags/:id | List tags / get a tag |
| POST | /v1/tags | Create a tag |
| PATCH | /v1/tags/:id | Update a tag |
| GET | /v1/contact-groups · /v1/contact-groups/:id | List contact groups / get a group |
| POST | /v1/contact-groups | Create a contact group |
| PATCH | /v1/contact-groups/:id | Update a contact group |
| GET | /v1/campaigns · /v1/campaigns/:id | List campaigns / get a campaign |
| POST | /v1/campaigns | Create a campaign |
| PATCH | /v1/campaigns/:id | Update a campaign |
| POST | /v1/campaigns/:id/execute | Execute a scheduled campaign |
| GET | /v1/templates · /v1/templates/:id | List message templates / get a template |
| POST | /v1/templates/:id/send | Send a template message to a phone number |
Lists: filtering, sorting and paging
All list endpoints support the same parameters: filter (a JSON object), sort (a field name, prefix with - for descending), limit (default 50), offset and search.
GET /api/v1/contacts?filter={"lifecycle_stage":"customer"}&sort=-created_date&limit=50&offset=0Creating a contact (upsert)
POST /v1/contacts performs an upsert: if a contact exists with the same phone (canonicalized to E.164) — or the same email when no phone is given — it is updated; otherwise a new one is created. Tags and groups are passed by name, and missing ones are created automatically.
curl -X POST https://app.otok.io/api/v1/contacts \
-H "Authorization: Bearer otok_live_XXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '{
"phone": "+972501234567",
"name": "Dana Levi",
"email": "[email protected]",
"tags": ["vip"],
"groups": ["Newsletter"]
}'Sending a WhatsApp template
POST /v1/templates/:id/send sends an approved template to a phone number. The contact and its conversation are created automatically if they don't exist, and the message is recorded in the inbox.
curl -X POST https://app.otok.io/api/v1/templates/TEMPLATE_ID/send \
-H "Authorization: Bearer otok_live_XXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '{ "to": "+972501234567", "body_variables": ["Dana"] }'Inbound webhooks — firing automations
Every automation with a Webhook trigger gets a unique URL. POST JSON to it from any system — a form, a store, a CRM — and the flow runs with the submitted data available as variables.
- The URL is shown in the flow editor on the trigger node.
- You can send a test request and inspect the result in the automation log.
Website tracking pixel
Embed the pixel snippet on your site (code and token under tracking settings) — visitor activity is linked to contacts and becomes available as automation triggers and conditions.