Authentication
The Wabot API uses short-lived JWT access tokens. You get one by sending your Client ID and Client Secret to the authenticate endpoint.
Find your credentials
Section titled “Find your credentials”Open Developer → Developer Credentials in Wabot. Every account gets a Client ID and Client Secret automatically when it is created.
Get an access token
Section titled “Get an access token”POST /v1/authenticate
| Header | Value |
|---|---|
clientid |
Your Client ID |
clientsecret |
Your Client Secret |
The header names are lowercase, with no dash or underscore.
curl -X POST https://api.wabot.shop/v1/authenticate \ -H "clientid: $WABOT_CLIENT_ID" \ -H "clientsecret: $WABOT_CLIENT_SECRET"const res = await fetch('https://api.wabot.shop/v1/authenticate', { method: 'POST', headers: { clientid: process.env.WABOT_CLIENT_ID, clientsecret: process.env.WABOT_CLIENT_SECRET, },});const { token, refreshToken } = await res.json();import os, requests
res = requests.post( "https://api.wabot.shop/v1/authenticate", headers={ "clientid": os.environ["WABOT_CLIENT_ID"], "clientsecret": os.environ["WABOT_CLIENT_SECRET"], },)token = res.json()["token"]refresh_token = res.json()["refreshToken"]$ch = curl_init('https://api.wabot.shop/v1/authenticate');curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'clientid: ' . getenv('WABOT_CLIENT_ID'), 'clientsecret: ' . getenv('WABOT_CLIENT_SECRET'), ],]);$data = json_decode(curl_exec($ch), true);$token = $data['token'];Response 200
{ "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…", "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…"}| Token | Lifetime |
|---|---|
token |
1 hour |
refreshToken |
7 days. Only the most recent one is valid; logging in again replaces it |
Errors
| Status | Body |
|---|---|
| 401 | {"error": "Missing credentials"} |
| 401 | {"error": "Invalid credentials"} |
Use the token
Section titled “Use the token”Send the token in the Authorization header as is, with no Bearer prefix:
curl https://api.wabot.shop/v2/contacts -H "Authorization: $TOKEN"Refresh the token
Section titled “Refresh the token”When the access token expires, you get 401 {"message": "jwt expired"}. Exchange the refresh token for a new pair:
POST /v1/refreshToken
curl -X POST https://api.wabot.shop/v1/refreshToken \ -H "Content-Type: application/json" \ -d '{"refreshToken": "'"$REFRESH_TOKEN"'"}'The response has the same shape as /v1/authenticate. The refresh token rotates, so store the new one each time.
| Status | Body |
|---|---|
| 401 | {"message": "Refresh token required"} |
| 403 | {"message": "Invalid refresh token"} or {"message": "Refresh token not recognized"} |
Log out
Section titled “Log out”DELETE /v1/logout/{refreshToken}
This revokes the refresh token. Access tokens already issued stay valid until they expire.
Grants
Section titled “Grants”Each Client ID has a list of grants, which are the API areas it may call. A new account gets all the standard grants:
| Grant | Endpoints |
|---|---|
/send-message |
Sending template and session messages |
/templates |
Listing, creating, updating and syncing templates |
/contacts |
Creating, listing and finding contacts |
/conversations |
Reading conversations and messages |
/account |
Account details and connected numbers |
/campaigns |
Triggering API campaigns |
/workflows |
Listing and creating workflows |
/flow |
WhatsApp Flows |
If a grant is missing you get:
{ "message": "Unauthorized to make this request", "required_grant": "/conversations" }Contact support to add a grant to your client.
Recommended token handling
Section titled “Recommended token handling”- Keep the Client ID and Client Secret in server-side environment variables.
- Cache the access token in memory and reuse it for up to 1 hour. Don’t authenticate before every request, because that counts towards your rate limit.
- If a request returns
401 jwt expired, refresh the token once and retry the request. - Store the rotated refresh token every time you refresh.
