Get quotas, warm-up and timelock state
GEThttps://api.wapito.com/v1/channel/limits
Send a channel token on every request: Authorization: Bearer wpt_YOUR_TOKEN
Returns everything that can throttle this channel right now: plan quotas with their current usage and reset times, the warm-up ladder a freshly linked number is climbing, the hourly cold-send guard, the WhatsApp reachout timelock and the engine capping counters. Read it before a bulk run so you size the batch to the remaining allowance instead of discovering the limit through 429 responses.
Responses
200
Every limit that currently applies.
| Field | Type | Required | Description |
|---|---|---|---|
api_requests | object | Required | One metered counter and the cap that applies to it. A `null` cap means unlimited on this plan. |
cap | integer | null | Required | Cap for the window, or `null` when unlimited. |
resets_at | string | null | Required | ISO 8601 timestamp the window rolls over.date-time |
used | integer | Required | Units consumed in the current window. |
capping | object | Optional | Engine-side capping counters (WhatsApp new-recipient cap). |
remaining | integer | null | Required | New recipients still allowed in the current window. |
reset_at | string | null | Required | ISO 8601 timestamp the cap resets.date-time |
totalQuota | integer | null | Required | Size of the window, or `null` when `unlimited`. |
unlimited | boolean | Required | True when WhatsApp reports no cap for this account. |
usedQuota | integer | Required | New recipients already messaged in the current window, under the engine’s own name. |
cold_send | object | Required | Guard on first messages to recipients who never wrote to you. |
resets_at | string | null | Required | ISO 8601 timestamp the hourly window resets.date-time |
used | integer | Required | Cold sends already made this hour. |
window_cap | integer | Required | Cold sends allowed in the current hour. |
media_max_bytes | integer | Required | Largest upload accepted by `POST /media` and the media send endpoints. |
number_checks | object | Required | One metered counter and the cap that applies to it. A `null` cap means unlimited on this plan. |
cap | integer | null | Required | Cap for the window, or `null` when unlimited. |
resets_at | string | null | Required | ISO 8601 timestamp the window rolls over.date-time |
used | integer | Required | Units consumed in the current window. |
plan | string | Required | Billing plan in force.one of sandbox, premium |
rate_limit_per_minute | integer | Required | Requests per minute allowed across the whole API. |
sent | object | Required | One metered counter and the cap that applies to it. A `null` cap means unlimited on this plan. |
cap | integer | null | Required | Cap for the window, or `null` when unlimited. |
resets_at | string | null | Required | ISO 8601 timestamp the window rolls over.date-time |
used | integer | Required | Units consumed in the current window. |
timelock | object | Optional | WhatsApp reachout timelock reported by the engine. |
active | boolean | Required | True while outbound first contact is blocked. |
reason | string | null | Required | Reason string the engine supplied. |
until | string | null | Required | ISO 8601 timestamp the lock lifts.date-time |
warmup | object | Required | Warm-up ladder state for a freshly linked number. |
cap | integer | null | Required | Sends allowed today by the ladder, or `null` once the ladder is complete. |
day | integer | Required | Days since the number connected, starting at 0. |
ladder_complete | boolean | Required | True once the plan cap replaces the ladder. |
webhooks_max | integer | Required | Maximum number of webhook subscriptions. |
{
"api_requests": {
"cap": null,
"resets_at": "2026-10-01T00:00:00.000Z",
"used": 19422
},
"capping": {
"remaining": 238,
"reset_at": "2026-09-16T00:00:00.000Z",
"totalQuota": 250,
"unlimited": false,
"usedQuota": 12
},
"cold_send": {
"resets_at": "2026-09-15T09:00:00.000Z",
"used": 4,
"window_cap": 60
},
"media_max_bytes": 67108864,
"number_checks": {
"cap": 2000,
"resets_at": "2026-09-16T00:00:00.000Z",
"used": 38
},
"plan": "premium",
"rate_limit_per_minute": 300,
"sent": {
"cap": null,
"resets_at": "2026-09-16T00:00:00.000Z",
"used": 412
},
"timelock": {
"active": false,
"reason": null,
"until": null
},
"warmup": {
"cap": null,
"day": 11,
"ladder_complete": true
},
"webhooks_max": 5
}401
The channel token is missing, malformed, revoked or belongs to a deleted channel.
Show 2 example bodies
token_revoked — the token was rotated in the dashboard
{
"error": {
"code": "token_revoked",
"message": "This channel token has been revoked.",
"request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
}
}unauthorized — no or unusable Bearer token
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid channel token.",
"request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
}
}403
The token is valid but the channel may not perform this action right now.
Show 2 example bodies
channel_locked — billing lapsed or the channel was locked by an operator
{
"error": {
"code": "channel_locked",
"details": {
"reason": "plan_required"
},
"message": "This channel is locked.",
"request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
}
}forbidden — the channel does not own the target object
{
"error": {
"code": "forbidden",
"message": "You are not allowed to perform this action.",
"request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
}
}409
The channel is in the wrong state for this action, or the account type does not support it.
Show 3 example bodies
business_account_required — labels need WhatsApp Business
{
"error": {
"code": "business_account_required",
"message": "This action requires a WhatsApp Business account.",
"request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
}
}channel_not_connected — link the number first
{
"error": {
"code": "channel_not_connected",
"details": {
"status": "qr"
},
"message": "The channel is not connected.",
"request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
}
}channel_not_in_qr_state — no QR available while the session boots
{
"error": {
"code": "channel_not_in_qr_state",
"details": {
"status": "created"
},
"message": "The channel is not waiting for a QR scan.",
"request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
}
}429
A rate limit, a plan quota or one of the anti-ban guards stopped the request. Every one of these is safe to retry later; read `Retry-After` when present.
Show 5 example bodies
cold_send_limit — too many first messages to new recipients this hour
{
"error": {
"code": "cold_send_limit",
"details": {
"resets_at": "2026-09-15T09:00:00.000Z",
"window_cap": 20
},
"message": "The hourly limit for messages to new recipients is reached.",
"request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
}
}quota_exceeded — plan quota for the day or month
{
"error": {
"code": "quota_exceeded",
"details": {
"quota": "sent",
"resets_at": "2026-09-16T00:00:00.000Z",
"used": 150
},
"message": "The plan quota for this resource is exhausted.",
"request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
}
}rate_limited — per-minute API rate limit
{
"error": {
"code": "rate_limited",
"details": {
"retry_after": 12
},
"message": "Too many requests.",
"request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
}
}send_rate_limited — the send queue did not drain within 20 s
{
"error": {
"code": "send_rate_limited",
"details": {
"retry_after": 5
},
"message": "The send queue for this channel is saturated.",
"request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
}
}warmup_limit — the warm-up ladder cap for today
{
"error": {
"code": "warmup_limit",
"details": {
"cap": 200,
"day": 2
},
"message": "The warm-up limit for this channel is reached.",
"request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
}
}500
Something went wrong inside Wapito. Quote `request_id` when reporting it.
Show the example body
internal_error — unexpected failure
{
"error": {
"code": "internal_error",
"message": "Something went wrong on our side.",
"request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
}
}502
The engine answered with an error Wapito could not translate into a more specific code.
Show the example body
engine_error — unexpected engine failure
{
"error": {
"code": "engine_error",
"details": {
"engine": "gows",
"status": 500
},
"message": "The WhatsApp engine returned an error.",
"request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
}
}503
The engine session is not reachable. Retry with backoff.
Show the example body
engine_unavailable — engine down or restarting
{
"error": {
"code": "engine_unavailable",
"details": {
"engine": "gows"
},
"message": "The WhatsApp engine is unavailable.",
"request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
}
}504
The engine did not answer before the upstream timeout.
Show the example body
engine_timeout — no answer within the deadline
{
"error": {
"code": "engine_timeout",
"details": {
"timeout_ms": 20000
},
"message": "The WhatsApp engine did not respond in time.",
"request_id": "req_01JRQ8F4X9N2K7YB3C5V6W8H0T"
}
}Errors
Code examples
import requests
url = "https://api.wapito.com/v1/channel/limits"
headers = {"Authorization": "Bearer wpt_YOUR_TOKEN"}
response = requests.get(url, headers=headers)
print(response.json())Used in
Related
Try it on your own number
Create a channel, link a WhatsApp number by QR or pairing code, and call the API in a couple of minutes. The Sandbox plan is free and needs no card.