Skip to main content

Account Status

Checks whether an API key can make billable API calls right now. If it can't, the response says why and when the block may clear.

Call this endpoint after an unexpected 402, after a 429 whose msg starts with Rate Limited. Monthly quota used., or before a large batch job. It gives a single machine-readable verdict instead of leaving you to work out the account's state from individual error messages. It also works when the key is blocked, because a blocked key is the one that needs this check most.

The verdict uses the same payment and quota checks as the billable endpoints, so for account-wide blocks it matches what a real request would get: an expired key or subscription, depleted credits, a billing limit, the trial daily allowance or the monthly quota.

It does not report the short-term, per-endpoint rate limit. If one endpoint answers 429 with Rate limited. Capacity used., this endpoint can still return api_access: true, because each endpoint has its own allowance. For that case, use the 429's retry_after and the X-RateLimit-* headers described in Rate Limits & Errors.

Request Parameters​

https://api.sapling.ai/api/v1/account/status

HTTP method: GET or POST

key: String
32-character API key. With GET, pass it as a ?key= query parameter. With POST, pass it in the JSON body. With either method you can instead send it as a bearer token in the Authorization header. If both are provided, the key parameter takes precedence.

The endpoint takes no other parameters.

Keys only
  • The public client-side key used by Sapling's website demos gets a 403.
  • OAuth access tokens issued for the MCP server also get a 403. Send an API key instead.

This call is not billed. Each call counts as 2,000 characters against a separate rate-limit bucket, so polling it doesn't use up your main allowance. Check it when something goes wrong rather than before every request.

Sample Code​

curl "https://api.sapling.ai/api/v1/account/status?key=<api-key>"

Response Parameters​

A JSON object. api_access, blocked_reason, message and usage are always present.

api_access: Boolean
true when no account-wide block applies to this key. An individual endpoint can still answer a short-term 429 if its own allowance is used up.

blocked_reason: String or null
null when api_access is true. Otherwise it is one of the values below. These values are stable, so you can safely branch on them in code.

blocked_reasonMeaningWhat a real request returnsClears when
key_expiredThe API key has expired.402You renew the subscription or buy credits.
subscription_expiredThe API subscription is no longer active.402You resubscribe or buy credits.
credits_depletedThe prepaid credit balance is used up.402You buy more credits.
monthly_billing_limitThe account reached the monthly billing limit set on its subscription.402You raise the limit in API settings, or the next billing month starts.
trial_daily_limitA free-trial key used up its daily character allowance.402The next UTC midnight.
monthly_quota_exhaustedThe key used up its monthly character quota.429The next UTC month starts.

message: String or null
Human-readable explanation of the block, the same text a real request's msg would contain. null when not blocked.

retry_after: Integer
Only present when blocked. The number of seconds until the block may clear, matching the Retry-After header a real request would carry:

  • trial_daily_limit: seconds until the next UTC midnight.
  • monthly_quota_exhausted: seconds until the next UTC month starts.
  • Every other reason: 3600. That is only a backoff hint. These blocks don't clear on their own, so resolve them in your API settings.

usage: Object

  • monthly_quota_chars (Integer or null): this key's monthly character quota, or null when it has none.
  • month_start (String (ISO date)): first day of the current UTC month.
  • chars_this_month (Integer): characters used by the account since month_start. This figure is updated periodically, so it can trail your most recent requests slightly.

subscription: Object

  • active (Boolean): whether the account has an API subscription.
  • trial_only (Boolean): whether the account has only free-trial API access.
  • key_expired (Boolean): whether this key has passed its expiry date.

credits: Object
The prepaid credit summary shown in the API dashboard. When credits.enabled is false, the account has no prepaid credits and only currency and alert_threshold_percent are included. Otherwise it also includes:

  • balance_credits, purchased_credits, consumed_credits and consumed_percent
  • low_balance and depleted
  • billing_mode and stops_when_depleted
  • auto_topup

One credit equals one US dollar.

trial: Object
Only present for free-trial accounts.

  • daily_limit_chars (Integer or null): the daily character allowance.
  • chars_used_today (Integer): characters used since the last UTC midnight.
  • resets_at (String): always utc_midnight.
Team-scoped keys

A team-scoped key can be shared by many people, so its response leaves out the personal subscription, credits and trial sections, and usage.month_start and usage.chars_this_month. You still get the verdict fields (api_access, blocked_reason, message, retry_after) and usage.monthly_quota_chars.

Sample Response​

A free-trial key that has used up today's allowance:

{
"api_access": false,
"blocked_reason": "trial_daily_limit",
"message": "Free trial daily API character limit reached. Purchase API credits at https://sapling.ai/api_settings#billing to continue, or wait for the limit to reset at UTC midnight.",
"retry_after": 22140,
"usage": {
"monthly_quota_chars": 250000,
"month_start": "2026-09-01",
"chars_this_month": 131872
},
"subscription": {
"active": false,
"trial_only": true,
"key_expired": false
},
"credits": {
"enabled": false,
"currency": "USD",
"alert_threshold_percent": 80.0
},
"trial": {
"daily_limit_chars": 100000,
"chars_used_today": 100412,
"resets_at": "utc_midnight"
}
}

A key that is ready to use:

{
"api_access": true,
"blocked_reason": null,
"message": null,
"usage": {
"monthly_quota_chars": 25000000,
"month_start": "2026-09-01",
"chars_this_month": 1840533
},
"subscription": {
"active": true,
"trial_only": false,
"key_expired": false
},
"credits": {
"enabled": false,
"currency": "USD",
"alert_threshold_percent": 80.0
}
}

Errors​

StatusWhen
401The key is missing or invalid: {"msg": "Missing API key."} or {"msg": "Invalid API key."}.
403The public demo key or an MCP OAuth access token was sent.
429The status bucket is exhausted. Wait retry_after seconds.

See Rate Limits & Errors for the shared error format.