ImportOS · Docs

Authentication and limits

API keys, scopes, plan-based rate limits, X-RateLimit headers, the problem+json error format and the code table.

API keys

All /v1/* endpoints and /mcp require a key in the header:

Authorization: Bearer rv_live_...
  • The key is created by a company owner in Desk: Settings → API keys. Step by step: quick start.
  • A key is bound to your company (tenant) and works only within it. Other companies' data is not reachable with it.
  • A key is shown once. The database stores only the sha256 of the key and a prefix. API logs show only the prefix rv_live_XXXX, never the key itself.
  • A key can be limited by expiry and revoked at any moment: access stops immediately.
  • Do not embed the key in browser code of a public site and do not commit it to a repository. Keep it in server environment variables.

Scopes (permissions)

A key has a set of permissions. An endpoint without the required permission answers 403 insufficient_scope.

ScopeWhat it allows
read:pricingPOST /v1/landed-cost, GET /v1/market-price, GET /v1/rules/{country}, GET /v1/fx; MCP: calculate_landed_cost, estimate_market_price, get_customs_rules
read:listingsGET /v1/vin/{vin}, GET /v1/listings/search; MCP: decode_vin, search_listings
mcpaccess to POST /mcp. The tool's own permission is required in addition
write:dealsreserved for future endpoints that create and update deals and contacts In development

For an MCP client create a key with mcp, read:pricing and read:listings: tools the key has no permission for are simply not listed in tools/list.

Rate limits

The limit is counted per key per minute and depends on your company's plan:

PlanRequests per minute
trial30
starter60
pro300
business1200

Every response carries these headers:

HeaderMeaning
X-RateLimit-Limitrequests in the window for your key's plan
X-RateLimit-Remaininghow many are left
X-RateLimit-Resetunix time in seconds when the window frees up
X-Request-Idthe request id, also request_id in the error body. Quote it when writing to support

When the limit is exhausted the API answers 429 rate_limited with a Retry-After header (seconds). Wait that long and retry. The SDK can do this on its own.

The order of checks: 401, then 429, then 403. If the Redis that holds the counter is unavailable, the API answers 503 (fail-closed) instead of letting requests through uncounted.

Monthly quotas

Separate monthly API plan quotas (Free 100 / Dev 10,000 / Business 100,000 calls) are for now only counted, not enforced. Reconciling them with the billing plans needs an owner decision Waiting on the owner. API access by ImportOS plan: see the table in For brokers.

Error format: problem+json

All errors have the type application/problem+json (RFC 9457):

{
  "type": "https://importos.app/problems/insufficient_scope",
  "title": "Forbidden",
  "status": 403,
  "detail": "The API key does not have the required scope: read:pricing",
  "instance": "/v1/landed-cost",
  "code": "insufficient_scope",
  "request_id": "..."
}

The type field is the address <API_PROBLEM_BASE_URL>/<code>; on the server it is recommended to set API_PROBLEM_BASE_URL=https://docs.<domain>/problems, so that address leads to this code table.

Rely on code: it is stable, unlike detail. Validation errors add errors[] with a path and message per field, and a 429 also adds retry_after.

codeHTTPWhen
validation_error400Invalid parameters or body (errors[] shows which)
unauthorized401No key, invalid, revoked or expired
insufficient_scope403The key lacks the required scope
origin_not_allowed403A browser Origin outside the allowlist (/mcp protection)
not_found404No such resource
unsupported_country404No rules for this country
method_not_allowed405Method not supported (GET and DELETE on /mcp)
unprocessable_input422The request is valid but cannot be calculated (for example no rules for that date)
rate_limited429Limit exceeded, see Retry-After
internal_error500Internal error
upstream_unavailable502An external provider (FX, VIN decoder) is unavailable
auth_unavailable503The key could not be verified
rate_limiter_unavailable503The rate-limit counter is unavailable

Retry 5xx and 429 with exponential backoff. There is no point in retrying 4xx errors (except 429) unchanged.

CORS and the browser

CORS is allowed only for addresses in API_CORS_ORIGINS (an empty list disables CORS). For /mcp a browser Origin outside the list gets 403: this protects against DNS rebinding. Call the API from your server, not from the user's browser, so the key never reaches the client.

On this page