K-Stra developers

Errors, limits & versions

Problem Details

Every error is an RFC 9457 problem, application/problem+json:

{
  "type": "https://www.k-stra.com/errors/insufficient_credits",
  "title": "Insufficient credits",
  "status": 402,
  "detail": "The run was blocked before anything was charged.",
  "error": "insufficient_credits",
  "errorCode": "3f9a1c2b7d",
  "instance": "/api/v1/actions/analysis.people_economy/execute",
  "blockedBy": "organization_balance",
  "credits": 2
}

type is stable per error code. error is the code (the same one the web app uses). errorCode correlates the request in our logs: quote it when you contact support.

detail is a sentence in English written for a person: show it to your user, log it, but do not parse it. Its wording can improve at any time without a new version; error and type are what your code should branch on.

Catalogue

Status error When
400 invalid_input the body is not a JSON object with the action's input
400 validation_error the input does not respect the action's rules; a required field left out is listed in missing and named in detail
400 quote_required a charged execution without quotedCredits
400 not_chargeable /quote called on a free action
401 not_authenticated no valid API key (WWW-Authenticate: Bearer)
402 insufficient_credits balance or a limit does not cover the run; nothing charged; see blockedBy
403 scope_required the key lacks the scope this route needs (run to spend, manage to write analyses, read their sharing and manage webhooks)
403 forbidden the action is not available to this key
404 unknown_action no action with that id in the public API
404 not_found the analysis, version, job, job result or webhook does not exist or is not yours to see
404 unknown_tool MCP only: no tool with that name (tools/list has the current ones)
409 quote_changed the quote no longer matches quotedCredits; nothing charged; quotedCredits carries the new value and declaredCredits the one you sent
429 rate_limited too many requests; wait Retry-After seconds
503 engine_unavailable the geographic engine is restarting; nothing charged; retry in a few seconds
500 internal_error our fault; errorCode identifies the request

Limits

Limit Value
Requests per key (REST and MCP together) 600 per minute
Charged executions per key (REST) 60 per minute
Engine-heavy calls (isochrones, quotes, and charged executions, which quote again before they run) 30 per minute per IP, 2 concurrent isochrones per IP
Continent data is served for oceania (Australia) only; europa stays in the schemas but is refused with 400 validation_error ("Unknown continent") before anything is charged
Isochrone 1 to 10 origins; 1 to 8 bands for analysis.isochrone, 1 to 6 in the analyses; up to 120 minutes or 30 km
Territory up to 1,000,000 address poles for areas and drawn polygons, and also for catchments in real estate; analysis.people_economy on administrative areas has no limit, the whole country included; sector analyses up to 400,000 on any territory; 1 to 12 areas, 1 to 10 polygons with 5,000 vertices in all. Refused with 400 before anything is charged
Store networks (network.coverage) 2 to 500 stores plus up to 100 candidates, catchments up to 60 minutes, at most 50,000,000 address poles across all catchments (refused before charging)
Coverage points (analysis.brand_coverage) up to 500 points (beyond, the first 500 are analysed and the result says so), catchments up to 30 minutes, same 50,000,000-pole ceiling
Request body 8 MB
Active keys per user 20
Webhook endpoints per organization 10
Dataset storage first 50 MB per organization free, then 2 credits a month every 100 MB; unpaid, the datasets are suspended and actions that read them are refused with 400 (see Credits)
Webhook delivery attempts 4 (now, +1 min, +10 min, +1 h); an endpoint is disabled after 20 consecutive failures

Versions and deprecation

The version in the specification (info.version) is the contract version. It grows on additive changes only. Nothing is removed from v1; a deprecated element would keep working and carry the Deprecation and Sunset headers for at least twelve months, with a line in the Changelog.