All documentation

API reference

Every endpoint the inference gateway serves, plus the control-plane endpoints behind this dashboard.

Gateway endpoints

Base URL https://sp-cambo.store for Anthropic-compatible clients, or https://sp-cambo.store/v1 for OpenAI-compatible clients. Authenticate with an SP Cambo API key.

Endpoint Surface Description
POST/v1/messages Metered Anthropic MessagesSingle-turn or multi-turn completion. Supports streaming and tool use where the model does.
POST/v1/messages/count_tokens Metered Anthropic MessagesCounts the input tokens a request would use, without generating a completion.
POST/v1/responses Metered OpenAI ResponsesOpenAI-compatible Responses call for clients configured with the Responses wire API.
POST/v1/chat/completions Metered OpenAI Chat CompletionsFor clients and SDKs written against Chat Completions rather than Responses.
GET/v1/modelsOpenAI-shaped listThe aliases this key may call, with the protocols each one supports. Never lists an alias outside the key's scope.
GET/v1/key/statusSP CamboKey state and expiry, allowed aliases, remaining token quota and credit, and the ceilings recorded on the key.

The two GET surfaces are not metered: they read your own key's state and never reach a model, so they cost no quota. They do count against the per-key request ceiling described in rate limits .

/v1/messages/count_tokens is a free local utility. SP Cambo counts the model-visible request locally, returns the estimate, does not reserve Tokens or Credits, and does not call OmniRoute or any background provider.

The gateway also answers GET /health without a credential. It reports whether the gateway itself is up and says nothing about your account.

Not every alias serves every protocol

An alias declares which of the four protocols it supports. Calling one through a protocol it does not support is refused with model_unavailable before any upstream call, so it costs nothing — but it is a configuration error, not an outage, and retrying will not clear it. Each alias's supported protocols are listed in the catalogue and in GET /v1/models.

What SP Cambo changes in your request

Your messages, tool definitions and system prompts are forwarded unchanged. Three things are not:

  • model is replaced with the upstream model the alias currently routes to. That indirection is the point of an alias.
  • the maximum output field for the surface you called is clamped down to your plan's ceiling if you asked for more. Asking for more than your key allows is refused up front instead, with max_output_tokens_exceeded.
  • on a streaming Chat Completions call, stream_options.include_usage is set, because without a usage chunk the request cannot be metered from what the model reports.

Each surface accepts a fixed set of parameters. Anything outside it is rejected with unsupported_parameter and the name of the offending field, rather than being dropped silently — a parameter you believe is in effect but which was quietly discarded is worse than an error.

Example request

Model names

The model field takes an SP Cambo public alias, not a provider model id. Aliases are listed in the catalogue and remain stable across upstream routing changes. An unknown alias, or one outside your key's scope, is rejected before any upstream call is made — so it costs you nothing.

Control-plane endpoints

The account API is served from https://sp-cambo.store/api/v1 and authenticated with your browser session. It is what this dashboard uses. It is not intended as an integration surface for your application code, and it will not accept an inference API key.

Public, no credential:

  • GET /health — liveness of the control plane.
  • GET /status — the service status shown on the status page.
  • GET /catalog/models, GET /catalog/packages — the published catalogue, exactly as the pricing and model pages read it.

With a signed-in session:

  • POST /auth/register/code sends the manual sign-up verification code; POST /auth/register consumes that code and creates the account. POST /auth/login, POST /auth/logout, POST /auth/forgot-password, POST /auth/reset-password handle the remaining account session flows.
  • GET /me, PATCH /me, POST /me/password, GET /me/sessions, DELETE /me/sessions/{id}
  • GET /me/balance, GET /me/entitlements, GET /me/activity, GET /me/usage/summary
  • GET|POST /me/api-keys, POST /me/api-keys/{id}/rotate, PATCH /me/api-keys/{id}/status, GET /me/api-keys/{id}/status
  • GET|POST /orders, GET /orders/{id}, GET|POST /orders/{id}/payment, POST /orders/{id}/payment/verify, POST /promotions/preview

Administration and reseller endpoints exist under /admin and /reseller and are refused unless your account holds the matching permission. Resellers who need to act from their own software use a management key against /reseller-management instead of a browser session; that key carries explicit scopes and cannot reach anything outside them. Those six endpoints are documented in full under the reseller API .

Response envelopes

Successful control-plane responses wrap their payload in data:

200 OK
{
  "data": {
    "...": "endpoint payload"
  }
}

Failures carry a stable machine code alongside the human message:

4xx / 5xx
{
  "message": "Human-readable summary.",
  "code": "insufficient_tokens",
  "errors": {
    "field": ["Only present for validation failures."]
  }
}

Branch on code, never on message — message wording can change at any time. Gateway failures use a different body: they are shaped like the SDK you are calling so your existing error handling keeps working, which means the SP Cambo code sits in a different field. See errors for both shapes and the full code list.

Idempotency and money

Order fulfilment is idempotent: a verified payment credits your account exactly once, however many times verification is re-checked. Asking SP Cambo to re-check a payment is always safe.

All monetary values are transported as integer minor units with an explicit currency and exponent, never as floating-point numbers. Token and credit quantities are integer strings for the same reason. If you consume these values, keep them exact — do not parse them into a float.