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.

Fields of the 200 response
FieldTypeRequiredDescription
api_requestsobjectRequiredOne metered counter and the cap that applies to it. A `null` cap means unlimited on this plan.
capinteger | nullRequiredCap for the window, or `null` when unlimited.
resets_atstring | nullRequiredISO 8601 timestamp the window rolls over.date-time
usedintegerRequiredUnits consumed in the current window.
cappingobjectOptionalEngine-side capping counters (WhatsApp new-recipient cap).
remaininginteger | nullRequiredNew recipients still allowed in the current window.
reset_atstring | nullRequiredISO 8601 timestamp the cap resets.date-time
totalQuotainteger | nullRequiredSize of the window, or `null` when `unlimited`.
unlimitedbooleanRequiredTrue when WhatsApp reports no cap for this account.
usedQuotaintegerRequiredNew recipients already messaged in the current window, under the engine’s own name.
cold_sendobjectRequiredGuard on first messages to recipients who never wrote to you.
resets_atstring | nullRequiredISO 8601 timestamp the hourly window resets.date-time
usedintegerRequiredCold sends already made this hour.
window_capintegerRequiredCold sends allowed in the current hour.
media_max_bytesintegerRequiredLargest upload accepted by `POST /media` and the media send endpoints.
number_checksobjectRequiredOne metered counter and the cap that applies to it. A `null` cap means unlimited on this plan.
capinteger | nullRequiredCap for the window, or `null` when unlimited.
resets_atstring | nullRequiredISO 8601 timestamp the window rolls over.date-time
usedintegerRequiredUnits consumed in the current window.
planstringRequiredBilling plan in force.one of sandbox, premium
rate_limit_per_minuteintegerRequiredRequests per minute allowed across the whole API.
sentobjectRequiredOne metered counter and the cap that applies to it. A `null` cap means unlimited on this plan.
capinteger | nullRequiredCap for the window, or `null` when unlimited.
resets_atstring | nullRequiredISO 8601 timestamp the window rolls over.date-time
usedintegerRequiredUnits consumed in the current window.
timelockobjectOptionalWhatsApp reachout timelock reported by the engine.
activebooleanRequiredTrue while outbound first contact is blocked.
reasonstring | nullRequiredReason string the engine supplied.
untilstring | nullRequiredISO 8601 timestamp the lock lifts.date-time
warmupobjectRequiredWarm-up ladder state for a freshly linked number.
capinteger | nullRequiredSends allowed today by the ladder, or `null` once the ladder is complete.
dayintegerRequiredDays since the number connected, starting at 0.
ladder_completebooleanRequiredTrue once the plan cap replaces the ladder.
webhooks_maxintegerRequiredMaximum 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.