From 9bea6b79cfb82d9ff03576ad00917cfd8b203ce2 Mon Sep 17 00:00:00 2001 From: liyb Date: Sat, 24 Oct 2026 09:37:11 +0800 Subject: [PATCH 1/3] docs: remove daily free API allowance; data APIs are billed per call SandBase no longer offers free data APIs, and apiserver no longer returns the 'daily free API limit exceeded' 429. Drop the allowance section and error entries from the rate-limit guide, admin rate limits, both error references and llms-full.txt. --- admin/rate-limits.md | 2 -- api-reference/errors.md | 4 +--- for-agents/errors.md | 7 +++---- guides/rate-limiting.md | 15 --------------- public/llms-full.txt | 1 - 5 files changed, 4 insertions(+), 25 deletions(-) diff --git a/admin/rate-limits.md b/admin/rate-limits.md index bd4145bf..264a7692 100644 --- a/admin/rate-limits.md +++ b/admin/rate-limits.md @@ -27,8 +27,6 @@ When a limit is exceeded, the API aborts the request with HTTP 429. On the `/v1/ Protocol-compatible endpoints such as `POST /v1/messages` and the Gemini endpoints return the same `429` in their own error envelope. -API operations that are currently free to call also share a daily call allowance per organization that resets at 00:00 UTC. When it is used up, those calls return `429` with `"daily free API limit exceeded"`; retrying before the reset does not help. - ::: warning Platform-generated rate-limit responses do not currently add `Retry-After` or remaining-quota headers. A compatible provider response can include provider rate-limit headers. Honor `Retry-After` when present; otherwise use bounded diff --git a/api-reference/errors.md b/api-reference/errors.md index 9e77ae65..5576ece2 100644 --- a/api-reference/errors.md +++ b/api-reference/errors.md @@ -48,7 +48,7 @@ Use the [OpenAPI specification](/openapi.yaml) for the exact status codes and sc | `404` | Model or resource is unavailable to the caller | Verify the current model ID or resource ID. | | `409` | Resource state conflict | Read the latest state before deciding whether a retry is safe. | | `422` | Semantically invalid resource input | Correct the documented field values. | -| `429` | Organization request limit, video concurrency limit, or daily free API allowance | Retry with bounded backoff and jitter when the operation is safe to repeat. | +| `429` | Organization request limit or video concurrency limit | Retry with bounded backoff and jitter when the operation is safe to repeat. | | `500`, `502`, `503`, `504` | SandBase or upstream failure | Retry only when the operation is safe to repeat. | Not every endpoint documents every status in this table. The operation's OpenAPI response map is authoritative. @@ -72,8 +72,6 @@ A revoked key cannot be re-enabled. Create a replacement, update the consuming a `organization rate limit exceeded` (`429`) means your organization reached its assigned requests-per-minute limit, which all of its API keys share. Protocol-compatible endpoints return it in their own envelope. SandBase does not publish one universal numeric limit because the limit is assigned per organization. -`daily free API limit exceeded` (`429`) means your organization used its daily allowance for API operations that are currently free. It resets at 00:00 UTC, so do not retry before then. - If a response includes `Retry-After`, respect it. Otherwise use bounded exponential backoff with jitter. See [Rate limits](/guides/rate-limiting) for request-smoothing patterns. Task submissions have two additional checks. `organization concurrency limit exceeded` (`429`) means your organization already has as many tasks in progress as its account level allows; it clears when a running task finishes. It applies to every model type on `POST /v1/run` and `/v1/api/*`, and to video submissions on other endpoints. `insufficient credit for estimated video cost` (`402`) means the estimated cost is more than your balance plus credit line; top up before retrying. See [Concurrency limits](/guides/concurrency-limits). diff --git a/for-agents/errors.md b/for-agents/errors.md index f6312dea..60771365 100644 --- a/for-agents/errors.md +++ b/for-agents/errors.md @@ -47,7 +47,7 @@ Anthropic-compatible envelope: | `403` | The credential lacks permission, or a compatibility surface maps a spending failure to 403 | Inspect the documented envelope and use an authorized key. | | `404` | Model or resource not found | Verify the current model name or resource ID. | | `409` | Resource state conflict | Read the latest resource state before deciding whether a retry is safe. | -| `429` | Organization request limit, video concurrency limit, or daily free API allowance | Retry with bounded exponential backoff and jitter. | +| `429` | Organization request limit or video concurrency limit | Retry with bounded exponential backoff and jitter. | | `500`, `502`, `503`, `504` | SandBase or upstream transient failure | Retry only when the operation is safe to repeat. | ## Authentication and rate-limit messages @@ -61,9 +61,8 @@ Documented authentication messages include: A scoped key used outside its scope returns `403` with a nested body instead: `{"error":{"code":"insufficient_scope","message":"API key is not authorized for this endpoint","request_id":"..."}}`. Agents platform resources return the same `code` in their own envelope. -Documented rate-limit messages are `organization rate limit exceeded` (the organization's assigned requests-per-minute -limit, shared by all of its API keys) and `daily free API limit exceeded` (the organization's daily allowance for -currently free API operations, reset at 00:00 UTC). A `429` response does not currently include `Retry-After` or +The documented rate-limit message is `organization rate limit exceeded` (the organization's assigned requests-per-minute +limit, shared by all of its API keys). A `429` response does not currently include `Retry-After` or `X-RateLimit-*` headers, and there is no published universal RPM or concurrency default. ## Model and resource lookup diff --git a/guides/rate-limiting.md b/guides/rate-limiting.md index 7ba9b6fc..df85e998 100644 --- a/guides/rate-limiting.md +++ b/guides/rate-limiting.md @@ -90,21 +90,6 @@ async def run_one(client, prompt): Concurrency is not the same as requests per minute. Tune both against observed latency and the capacity assigned to your application. -## Daily allowance for free APIs - -API operations that are currently free to call share a daily call allowance per organization. The count resets at -00:00 UTC. When the allowance is used up, further calls to free operations return: - -```http -HTTP/1.1 429 Too Many Requests -Content-Type: application/json - -{"error":"daily free API limit exceeded"} -``` - -Retrying within the same UTC day does not help. Resume after the reset, or contact SandBase support if your workload -needs a higher allowance. Paid API operations are not counted. - ::: tip Video tasks Video submissions are also limited by how many tasks your organization can run at once, based on its account level. That `429` says `organization concurrency limit exceeded` and clears when a running task finishes, not on a timer. See diff --git a/public/llms-full.txt b/public/llms-full.txt index 4647bd45..d3c9617c 100644 --- a/public/llms-full.txt +++ b/public/llms-full.txt @@ -322,7 +322,6 @@ Error bodies are protocol-specific. Core middleware may return {"error":"message | API key has expired | 401 | Key is past expiration | | insufficient_scope | 403 | Scoped key not authorized; nested {"error":{"code":"insufficient_scope","message":...}} body | | organization rate limit exceeded | 429 | Organization RPM limit exceeded (shared by all keys); back off with jitter | -| daily free API limit exceeded | 429 | Daily allowance for free API operations used up; resets 00:00 UTC | | API key spending limit exceeded | 402 or protocol-specific 403 | Key spending limit reached | | HTTP 400 | Invalid or unsupported input; fix the request using the endpoint and model schema | | HTTP 404 | Model or resource not found; verify current IDs before retrying | From 677640d3d422491e097deabd2a97f4e0d7a7a083 Mon Sep 17 00:00:00 2001 From: liyb Date: Sat, 24 Oct 2026 17:36:04 +0800 Subject: [PATCH 2/3] docs: document the 100 daily free data API calls per organization --- for-agents/full.md | 2 ++ for-agents/index.md | 1 + guides/billing.md | 18 ++++++++++++++++++ guides/rate-limiting.md | 5 +++++ public/llms-full.txt | 2 ++ public/llms.txt | 2 ++ 6 files changed, 30 insertions(+) diff --git a/for-agents/full.md b/for-agents/full.md index 9b073a02..060c9db1 100644 --- a/for-agents/full.md +++ b/for-agents/full.md @@ -515,6 +515,8 @@ Body `{"name", "kind": "mcp_bearer", "server_url", "token"}`; `Idempotency-Key` - Read the selected model's current pricing formula and units from its `model_card`. - Token-priced models can include input, output, cache, or reasoning components when declared. - Media and other models can use per-request, duration, resolution, or other model-specific units. +- Data APIs (search, social, scraping, e-commerce, finance) include 100 free calls per organization per UTC day, shared across eligible data APIs and reset at 00:00 UTC. Later calls are billed per call; they are not rejected. Organizations with a zero balance can still use the free calls. +- MCP: `sandbase_inspect` shows `pricing.free_quota` on eligible tools; `sandbase_account` returns `free_api_quota` (`daily_limit`, `used_today`, `remaining`, `resets_at`); settled `sandbase_run` and `sandbase_run_get` results include `free_quota_status` (`free`, `overage`, or `degraded`). - When a billable operation returns a task ID (including an `x-task-id` response header), use `GET /v1/tasks/{task_id}/cost` for settlement and usage. - For asynchronous `POST /v1/run` responses, query the generation result with `GET /v1/run/{id}`; a run ID is not a task ID and must not be sent to the cost endpoint. diff --git a/for-agents/index.md b/for-agents/index.md index 385837aa..8356cb5a 100644 --- a/for-agents/index.md +++ b/for-agents/index.md @@ -77,6 +77,7 @@ Pay per use. Pricing is model-specific and may change independently of this page - **Model pricing**: read the selected model's current formula and units from `model_card` - **Token pricing**: can include input, output, cache, or reasoning components when declared by that model - **Media and other operations**: can use per-request, duration, resolution, or other model-specific units +- **Data APIs** (search, social, scraping, e-commerce, finance): each organization gets 100 free calls per UTC day, shared across eligible data APIs; after that, calls are billed per call, not blocked. In MCP, eligible tools show `pricing.free_quota` in `sandbase_inspect`, and `sandbase_account` returns `free_api_quota` (`daily_limit`, `used_today`, `remaining`, `resets_at`). See [Daily free API calls](/guides/billing#daily-free-api-calls). Discover the current model ID with `GET /v1/models`, then inspect `GET /v1/models/{id_or_name}` before sending a request. Do not assume that pricing or cache discounts are shared across providers. diff --git a/guides/billing.md b/guides/billing.md index 3a6d9bd9..64073ff1 100644 --- a/guides/billing.md +++ b/guides/billing.md @@ -9,6 +9,24 @@ SandBase uses pay-as-you-go billing. Model availability, price formulas, cache m charges can change independently, so integrations should read live metadata instead of relying on copied price tables. +## Daily free API calls + +Every organization gets 100 free data API calls (search, social, scraping, e-commerce, finance) per UTC day. The +allowance is shared by all eligible data APIs and all of the organization's keys, and resets at 00:00 UTC. LLMs and +media models are not eligible. + +- Calls within the allowance are not charged, and an organization with a zero balance can still use them. +- After the 100th call, eligible calls keep working and are billed per call at the price the tool shows. They are not + rejected or rate-limited because the allowance is used up. +- Unused calls do not carry over to the next day. + +In the [SandBase MCP tools](/setup/), `sandbase_inspect` marks eligible tools with `pricing.free_quota` +(`daily_limit`, `scope`, `resets`). `sandbase_account` returns today's allowance as `free_api_quota` with +`daily_limit`, `used_today`, `remaining`, and `resets_at`; `used_today` and `remaining` are omitted when the count is +temporarily unavailable. After a run settles, `sandbase_run` and `sandbase_run_get` report `free_quota_status`: +`free` (covered by the allowance), `overage` (billed after the allowance was used up), or `degraded` (not charged +because the allowance count was unavailable). + ## Manage billing in the Console Use **Console → Billing** to view your balance, add credits, and manage the billing settings available to your diff --git a/guides/rate-limiting.md b/guides/rate-limiting.md index df85e998..f8744225 100644 --- a/guides/rate-limiting.md +++ b/guides/rate-limiting.md @@ -90,6 +90,11 @@ async def run_one(client, prompt): Concurrency is not the same as requests per minute. Tune both against observed latency and the capacity assigned to your application. +::: info Daily free API calls +The organization's 100 free data API calls per UTC day are a billing allowance, not a rate limit. Calls beyond it are +billed per call rather than rejected. See [Daily free API calls](/guides/billing#daily-free-api-calls). +::: + ::: tip Video tasks Video submissions are also limited by how many tasks your organization can run at once, based on its account level. That `429` says `organization concurrency limit exceeded` and clears when a running task finishes, not on a timer. See diff --git a/public/llms-full.txt b/public/llms-full.txt index d3c9617c..b4793f56 100644 --- a/public/llms-full.txt +++ b/public/llms-full.txt @@ -339,6 +339,8 @@ Do not retry unchanged 400, 401, 402, 403, or 404 requests. Check idempotency be - Read each model's current pricing formula and units from its model_card - Token-priced models can include input, output, cache, or reasoning components when declared - Media and other models can use per-request, duration, resolution, or other model-specific units +- Data APIs (search, social, scraping, e-commerce, finance): 100 free calls per organization per UTC day, shared across eligible data APIs, reset 00:00 UTC; later calls are billed per call, not rejected; zero-balance organizations can still use the free calls +- MCP: sandbase_inspect shows pricing.free_quota on eligible tools; sandbase_account returns free_api_quota {daily_limit, used_today, remaining, resets_at}; settled sandbase_run / sandbase_run_get results include free_quota_status (free, overage, degraded) - Check cost: GET /v1/tasks/{task_id}/cost - API key spending controls: https://www.sandbase.ai/console/keys - Usage and cost: https://www.sandbase.ai/console/activities?tab=usage diff --git a/public/llms.txt b/public/llms.txt index 50e2894f..2dcbf728 100644 --- a/public/llms.txt +++ b/public/llms.txt @@ -66,6 +66,8 @@ Agents platform resources accept `Authorization: Bearer` or `X-API-Key` and retu Pricing formulas and billing units differ by model. Use GET /v1/models for discovery and GET /v1/models/{id_or_name} for the current model card, capabilities, input schema, and detailed pricing. Use GET /v1/tasks/{id}/cost for recorded task cost. +Data APIs (search, social, scraping, e-commerce, finance) include 100 free calls per organization per UTC day, shared across eligible +data APIs; later calls are billed per call. MCP sandbase_account reports the remaining allowance as free_api_quota. ## Docs From ea6def606d1bd2582d9213fa0e815135866a782f Mon Sep 17 00:00:00 2001 From: liyb Date: Sat, 24 Oct 2026 20:26:54 +0800 Subject: [PATCH 3/3] docs(billing): say which data APIs are outside the daily free calls Per the B-303 review: pricier or formula-priced data APIs (some batch, crawl, Xiaohongshu PGY, Douyin Xingtu kol-* routes) are billed from the first call; pricing.free_quota on sandbase_inspect is the check. Mirrored in llms-full.txt and for-agents/full.md. --- for-agents/full.md | 1 + guides/billing.md | 5 ++++- public/llms-full.txt | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/for-agents/full.md b/for-agents/full.md index 060c9db1..13cd3b2b 100644 --- a/for-agents/full.md +++ b/for-agents/full.md @@ -516,6 +516,7 @@ Body `{"name", "kind": "mcp_bearer", "server_url", "token"}`; `Idempotency-Key` - Token-priced models can include input, output, cache, or reasoning components when declared. - Media and other models can use per-request, duration, resolution, or other model-specific units. - Data APIs (search, social, scraping, e-commerce, finance) include 100 free calls per organization per UTC day, shared across eligible data APIs and reset at 00:00 UTC. Later calls are billed per call; they are not rejected. Organizations with a zero balance can still use the free calls. +- Not eligible: LLMs, media models, and pricier or formula-priced data APIs (for example some batch endpoints, crawl, Xiaohongshu PGY, and the Douyin Xingtu `kol-*` routes), which are billed from the first call. `pricing.free_quota` on `sandbase_inspect` is the check. - MCP: `sandbase_inspect` shows `pricing.free_quota` on eligible tools; `sandbase_account` returns `free_api_quota` (`daily_limit`, `used_today`, `remaining`, `resets_at`); settled `sandbase_run` and `sandbase_run_get` results include `free_quota_status` (`free`, `overage`, or `degraded`). - When a billable operation returns a task ID (including an `x-task-id` response header), use `GET /v1/tasks/{task_id}/cost` for settlement and usage. - For asynchronous `POST /v1/run` responses, query the generation result with `GET /v1/run/{id}`; a run ID is not a task ID and must not be sent to the cost endpoint. diff --git a/guides/billing.md b/guides/billing.md index 64073ff1..4e92952c 100644 --- a/guides/billing.md +++ b/guides/billing.md @@ -13,7 +13,10 @@ tables. Every organization gets 100 free data API calls (search, social, scraping, e-commerce, finance) per UTC day. The allowance is shared by all eligible data APIs and all of the organization's keys, and resets at 00:00 UTC. LLMs and -media models are not eligible. +media models are not eligible. Some data APIs are not eligible either: pricier or formula-priced ones, such as some +batch endpoints, crawl endpoints, Xiaohongshu PGY, and the Douyin Xingtu `kol-*` routes, are billed from the first call. +To check a tool, run `sandbase_inspect`: eligible tools carry `pricing.free_quota`, and tools without it are always +billed. - Calls within the allowance are not charged, and an organization with a zero balance can still use them. - After the 100th call, eligible calls keep working and are billed per call at the price the tool shows. They are not diff --git a/public/llms-full.txt b/public/llms-full.txt index b4793f56..25ae2da1 100644 --- a/public/llms-full.txt +++ b/public/llms-full.txt @@ -340,6 +340,7 @@ Do not retry unchanged 400, 401, 402, 403, or 404 requests. Check idempotency be - Token-priced models can include input, output, cache, or reasoning components when declared - Media and other models can use per-request, duration, resolution, or other model-specific units - Data APIs (search, social, scraping, e-commerce, finance): 100 free calls per organization per UTC day, shared across eligible data APIs, reset 00:00 UTC; later calls are billed per call, not rejected; zero-balance organizations can still use the free calls +- Not eligible: LLMs, media models, and pricier or formula-priced data APIs (e.g. some batch endpoints, crawl, Xiaohongshu PGY, Douyin Xingtu kol-* routes), which are billed from the first call; pricing.free_quota on sandbase_inspect is the check - MCP: sandbase_inspect shows pricing.free_quota on eligible tools; sandbase_account returns free_api_quota {daily_limit, used_today, remaining, resets_at}; settled sandbase_run / sandbase_run_get results include free_quota_status (free, overage, degraded) - Check cost: GET /v1/tasks/{task_id}/cost - API key spending controls: https://www.sandbase.ai/console/keys