Introduction
Read/write client identity records and pull real, AI-verified WhatsApp check-in adherence data into your own CRM or backend system. Enterprise plan required.
This documentation aims to provide all the information you need to work with our API.
<aside>As you scroll, you'll see code examples for working with the API in different programming languages in the dark area to the right (or as part of the content on mobile).
You can switch the language used with the tabs at the top right (or from the nav menu at the top left on mobile).</aside>
Authenticating requests
To authenticate requests, include an Authorization header with the value "Bearer {YOUR_API_TOKEN}".
All authenticated endpoints are marked with a requires authentication badge in the documentation below.
Generate a token from Settings → Partner API Tokens (Enterprise plan required). Grant it the abilities it needs: clients:write to create/update client identity records, checkins:read to pull adherence data. The plaintext token is shown once at creation — store it securely.
Adherence
Real, AI-verified check-in adherence data — the core value of this API. Derived entirely from actual WhatsApp check-in behavior run through ZoetiCoach's own verification pipeline. This is deliberately read-only: there is no way to write a check-in through this API.
Get a client's adherence history
requires authentication
Per-day done/partial/missed/frozen/replied/none status for the requested window, plus the client's current streak and total points.
Example request:
curl --request GET \
--get "https://zoeticoach.com/api/partner/v1/clients/client-8821/checkins?days=30" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://zoeticoach.com/api/partner/v1/clients/client-8821/checkins"
);
const params = {
"days": "30",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"external_id": "client-8821",
"days": [
{
"date": "2026-09-28",
"status": "done"
},
{
"date": "2026-09-29",
"status": "partial"
}
],
"current_streak_days": 4,
"total_points": 55,
"week_energy_score": 7
}
Example response (404):
{
"message": "Client not found."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Authentication
Introspect the current API token — its abilities and when it was created. Useful for a partner's SDK to confirm which endpoints a given token can call without having to trigger a 403 first.
Get the current token's abilities
requires authentication
Example request:
curl --request GET \
--get "https://zoeticoach.com/api/partner/v1/me" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://zoeticoach.com/api/partner/v1/me"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"token_name": "Zapier integration",
"abilities": [
"clients:write",
"checkins:read"
],
"created_at": "2026-09-29T10:00:00.000000Z"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Clients
Minimal client-identity endpoints — establishing the external_id mapping a partner needs to later pull adherence data via the Adherence group below. There is no list/enumerate endpoint anywhere in this API by design — every lookup requires you to already know the specific external_id you're asking about.
Create a client
requires authentication
Creates a minimal client-identity record and returns ZoetiCoach's own id alongside your external_id, so you can map the two going forward. Consent is never set via this API — the client starts inert (no WhatsApp check-ins) until they complete ZoetiCoach's own opt-in flow, which this call triggers automatically.
Send an Idempotency-Key header to make a retry of this exact request
safe — a repeat with the same key returns the original response
instead of creating a duplicate client.
Example request:
curl --request POST \
"https://zoeticoach.com/api/partner/v1/clients" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"external_id\": \"client-8821\",
\"name\": \"Priya Nair\",
\"phone\": \"+919800011111\",
\"language\": \"en\"
}"
const url = new URL(
"https://zoeticoach.com/api/partner/v1/clients"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"external_id": "client-8821",
"name": "Priya Nair",
"phone": "+919800011111",
"language": "en"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"id": 42,
"external_id": "client-8821",
"name": "Priya Nair",
"status": "active",
"language": "en"
}
Example response (422):
{
"message": "The external id has already been taken.",
"errors": {
"external_id": [
"The external id has already been taken."
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get a client
requires authentication
Look up a client by the external_id you gave it at creation.
Example request:
curl --request GET \
--get "https://zoeticoach.com/api/partner/v1/clients/client-8821" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://zoeticoach.com/api/partner/v1/clients/client-8821"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"id": 42,
"external_id": "client-8821",
"name": "Priya Nair",
"status": "active",
"language": "en"
}
Example response (404):
{
"message": "Client not found."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update a client
requires authentication
Updates name and/or status only — nothing else about a client is writable through this API.
Example request:
curl --request PATCH \
"https://zoeticoach.com/api/partner/v1/clients/client-8821" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Priya Sharma\",
\"status\": \"paused\"
}"
const url = new URL(
"https://zoeticoach.com/api/partner/v1/clients/client-8821"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Priya Sharma",
"status": "paused"
};
fetch(url, {
method: "PATCH",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"id": 42,
"external_id": "client-8821",
"name": "Priya Nair",
"status": "paused",
"language": "en"
}
Example response (404):
{
"message": "Client not found."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.