Get started
Authentication
Every request carries a workspace API key. The key decides which workspace you talk to and what you can do in it.
The Authorization header#
Send the key as a Bearer token on every request:
Authorization: Bearer sk_live_...Keys look like sk_live_ followed by 43 characters. heysteff stores only a hash: if you lose the secret it cannot be recovered; create another key or rotate the one you have.
Create a key#
- Sign in at app.heysteff.com.
- Go to Settings → Developers → API Keys and click New API key.
- Pick the minimum scopes your integration needs and, optionally, the IPs allowed to use it.
- Copy the secret into your secrets manager or an environment variable.
Scopes#
Every operation requires a scope. A key without it gets 403 forbidden. Give each integration only what it uses: a store that sends shipping updates does not need refunds:write.
| Scope | Allows | Endpoints |
|---|---|---|
messages:write | Send messages (text, files, templates, buttons, lists, locations and reactions) and mark them as read. | POST /v1/messagesPOST /v1/messages/{id}/read |
conversations:read | Read conversations and their messages. | GET /v1/conversationsGET /v1/conversations/{id}GET /v1/conversations/{id}/messagesGET /v1/messages/{id} |
conversations:write | Hand a conversation to a person, pause or resume the bot, and resolve it. | POST /v1/conversations/{id}/escalatePOST /v1/conversations/{id}/botPOST /v1/conversations/{id}/resolve |
contacts:read | Read contacts and lists. | GET /v1/contactsGET /v1/contact-lists |
contacts:write | Create contacts and add them to lists. | POST /v1/contactsPOST /v1/contact-lists/{id}/members |
campaigns:read | Read a campaign status. | GET /v1/campaigns/{id} |
campaigns:write | Create and trigger campaigns. | POST /v1/campaigns |
events:read | Read the event stream. | GET /v1/events |
events:write | Ingest events from your system. | POST /v1/events |
conversions:write | Report conversions for attribution. | POST /v1/conversions |
charges:write | Charge with a payment link. | POST /v1/charges |
refunds:write | Refund payments. | POST /v1/refunds |
sales:read | Read the sales funnel. | GET /v1/sales/funnel |
reviews:read | Read reviews. | GET /v1/reviews |
reviews:write | Request reviews. | POST /v1/reviews |
automations:trigger | Trigger flows. | POST /v1/automation-flows/{id}/trigger |
owner:write | Sleep mode of a personal workspace. | GET /v1/owner/sleepPOST /v1/owner/sleep |
webhooks:read | Read webhooks and their delivery log. | GET /v1/webhooksGET /v1/webhooks/{id}/deliveries |
webhooks:write | Create, edit and delete webhooks and retry a delivery. | POST /v1/webhooksPATCH /v1/webhooks/{id}DELETE /v1/webhooks/{id}POST /v1/webhook-deliveries/{id}/retry |
numbers:read | See your heysteff WhatsApp numbers and the plan quota. | GET /v1/numbersGET /v1/numbers/{id}GET /v1/whatsapp-numbers/{id}GET /v1/whatsapp-numbers/{id}/business-profile |
numbers:write | Reserve a number (with its connect link), release a reservation and request the display name. | POST /v1/numbersDELETE /v1/numbers/{id}POST /v1/numbers/{id}/display-namePATCH /v1/whatsapp-numbers/{id}/business-profile |
flows:read | See your WhatsApp Flows, their Flow JSON, the preview and customers' answers. | GET /v1/whatsapp-flowsGET /v1/whatsapp-flows/{id}GET /v1/whatsapp-flows/{id}/jsonGET /v1/whatsapp-flows/{id}/previewGET /v1/whatsapp-flows/responses |
flows:write | Create, change, publish, deprecate and delete WhatsApp Flows, upload their Flow JSON and sync them with Meta. | POST /v1/whatsapp-flowsPOST /v1/whatsapp-flows/syncPATCH /v1/whatsapp-flows/{id}DELETE /v1/whatsapp-flows/{id}PUT /v1/whatsapp-flows/{id}/jsonPOST /v1/whatsapp-flows/{id}/publishPOST /v1/whatsapp-flows/{id}/deprecate |
calls:read | See the WhatsApp call log and a number's call settings. | GET /v1/callsGET /v1/whatsapp-numbers/{id}/calling |
calls:write | Turn a number's calls on or off and change its hours. | PATCH /v1/whatsapp-numbers/{id}/calling |
inbox:embed | Create, see, change and revoke embedded inbox tokens. | POST /v1/inbox-embedsGET /v1/inbox-embedsPATCH/DELETE /v1/inbox-embeds/{id} |
logs:read | Read the unified logs: API calls, webhook deliveries and failed messages (GET /v1/logs). | |
templates:write | Create WhatsApp templates (they go to Meta for review) and delete them. | POST /v1/templatesDELETE /v1/templates/{name} |
customers:read | See your customers and the channels they connected. | GET /v1/customersGET /v1/customers/{id}GET /v1/customers/{id}/channels |
customers:write | Create, change and delete customers, and generate their setup links. | POST /v1/customersPATCH /v1/customers/{id}DELETE /v1/customers/{id}POST /v1/customers/{id}/setup-links |
agent:read | See the AI agent (on or off, model, trial quota, saved keys by their last 4 only) and its custom tools. | GET /v1/agentGET /v1/agent/toolsGET /v1/agent/tools/{id} |
agent:write | Configure the agent, save or delete your provider key and manage custom tools. | PATCH /v1/agentPUT /v1/agent/keysDELETE /v1/agent/keys/{provider}POST /v1/agent/toolsPATCH /v1/agent/tools/{id}DELETE /v1/agent/tools/{id} |
insights:read | Read the findings from your conversations. | GET /v1/insights |
Rotate a key without downtime#
From the key list, Rotate creates a new secret and keeps the old one working for a grace period (24 hours by default). Deploy the new secret in that time; when the grace period ends, the old one stops working on its own.
IP allowlist#
You can restrict a key to a list of IPs or CIDR ranges (for example 203.0.113.0/24). A request from any other IP gets 403 even with a valid key.
Revoke#
Revoke kills the key immediately. Do it as soon as you suspect a leak, then create a new one for the integration.
Authentication errors#
| Status | Code | What happened |
|---|---|---|
| 401 | unauthorized | Missing header, or the key is invalid, expired or revoked. |
| 403 | forbidden | The key lacks the operation scope or the IP is not allowed. |
| 403 | workspace_disabled | The workspace is disabled. |
| 429 | rate_limited | You went over the key rate limit. |
Best practices#
- One key per integration, named after where it runs.
- Keep it in environment variables or a secrets manager, never in code.
- Never call the API from a browser or a mobile app: always go through your server.
- Rotate production keys on a schedule.