GunSpec

Fehlerbehandlung

Jeder Fehler ist ein JSON-Umschlag mit einem stabilen code, einem genaueren reason und einer request_id. Verzweige auf code und reason, nie auf message, dessen Wortlaut sich ändern kann. Diese Seite wird aus der OpenAPI-Spezifikation der API und ihrer Reason-Registry erzeugt.

Jede Nicht-2xx-Antwort hat diese Form, und success ist immer false.

Fehlerantwort
json
{  "success": false,  "error": {    "code": "FORBIDDEN",    "reason": "PLAN_REQUIRED",    "message": "This endpoint requires 'studio' tier or above. Your tier: 'builder'",    "details": {      "requiredTier": "studio",      "currentTier": "builder"    }  }}
  • codestringerforderlich

    Machine-readable error code, e.g. NOT_FOUND, RATE_LIMITED, SUBSCRIPTION_REQUIRED. Branch on this, never on message.

  • reasonenumerforderlich

    Which situation, within code. Stable and machine-readable: branch on this, never on message. Each error response lists the reasons it can carry, and the error reference says what to do about each.

  • messagestringerforderlich

    Human-readable account of what went wrong. The wording may change; treat it as text for a log or a person, not as a value to match on.

  • detailsobjectoptional

    Structured context for the reason: the invalid fields for INVALID_PARAMETER, requiredTier for PLAN_REQUIRED.

  • limitintegeroptional

    On DAILY_CAP_EXCEEDED, MCP_DAILY_CAP_EXCEEDED and MONTHLY_CAP_EXCEEDED only: the limit that was reached. The daily limits are per key; the monthly one is the plan's allowance for the whole account.

  • resetsAtstringoptional

    On DAILY_CAP_EXCEEDED, MCP_DAILY_CAP_EXCEEDED and MONTHLY_CAP_EXCEEDED only: when the limit returns to zero, ISO 8601. The next midnight UTC for the daily limits (the same instant as X-Daily-Reset), midnight UTC on the first of next month for the monthly one (X-Monthly-Reset). Nothing sent before then will be served.

  • retryAfterintegeroptional

    On DAILY_CAP_EXCEEDED, MCP_DAILY_CAP_EXCEEDED and MONTHLY_CAP_EXCEEDED only: whole seconds until resetsAt, the same figure as the Retry-After header.

  • request_idstringoptional

    Quote this to support: it finds the request in our logs.

Die HTTP-Status, die ein Fehler tragen kann, die Situationen dahinter und wie viele Endpunkte ihn deklarieren.

DiagrammWas bei welchem Status zu tun ist
100%
Was bei welchem Status zu tun istEine 2xx ist Ihre Antwort, eine 304 heißt, Ihre vorhandene Kopie ist aktuell. Eine 400 ist eine zu korrigierende Anfrage, und error.reason nennt den Parameter. Eine 401 heißt: gültigen Schlüssel senden. Eine 403 heißt, der Schlüssel ist in Ordnung und etwas anderes nicht, und der Grund sagt, ob es Tarif, Berechtigung oder Seitentiefe ist. Eine 404 nach einem Resolve heißt neu auflösen, nicht wiederholen. Nur zwei Status lohnen eine Wiederholung: eine 429 nach der in Retry-After genannten Wartezeit und eine 5xx mit Backoff.
StatusBeschreibungGründeEndpunkte
400Validation error159
401Missing or invalid API key134
403The credential is valid and the caller is not permitted. Three causes, none of which reissuing a key changes: the plan is below the endpoint's tier, the account is suspended, or the key is not attached to the thing being acted on, meaning a user account for /v1/me or a shop for /v1/vendor. Distinct from 401, which means the credential is missing, malformed or expired and a new one can work.134
404Resource not found71
413The request body is larger than this endpoint accepts, which is 1 MB for a JSON body. Refused from Content-Length before the body is read, so nothing was stored and the request can be split and resent. error.maxBytes carries the limit.8
429A limit was reached. RATE_LIMITED is the per-minute limit: wait Retry-After seconds (a minute) and retry. DAILY_CAP_EXCEEDED is the plan's daily limit, per key: nothing will be served until the counters return to zero at midnight UTC. MONTHLY_CAP_EXCEEDED is the plan's monthly allowance, for the whole account: nothing will be served until midnight UTC on the first of next month, or until the plan changes. For both, Retry-After is the seconds until then and error.resetsAt says when as an instant. Calls made after a refusal are refused too and do not spend the month, and a free key that keeps calling is paused, so stop at the first one and resume at the reset.160
500Internal server error160

code ist die Familie und ändert sich nie. Schlägt eine Anfrage ohne genauere Situation fehl, ist der Grund der Standard der Familie, hier gelistet.

CodeStatusStandardgrund
400INVALID_REQUEST
401AUTH_REQUIRED
403ACTION_NOT_ALLOWED
403PAGINATION_DEPTH_EXCEEDED
403PLAN_REQUIRED
404RESOURCE_NOT_FOUND
409CONFLICT
413PAYLOAD_TOO_LARGE
429DAILY_CAP_EXCEEDED
429MCP_DAILY_CAP_EXCEEDED
429MONTHLY_CAP_EXCEEDED
429RATE_LIMITED
429REPORT_RATE_LIMITED
429RATE_LIMITED
500INTERNAL_ERROR
503DEPENDENCY_UNAVAILABLE

Jeder reason, den die API senden kann, nach Status: was passiert ist und was als Nächstes zu tun ist. Ein Grund ist Teil des veröffentlichten Vertrags: neue kommen hinzu, keiner wird umbenannt.

400Ungültige Anfrage3
  • A path, query or body field failed validation. details names each field and what was wrong with it.

    Was tunCorrect the named fields and send the request again.

  • The request body is not valid JSON.

    Was tunSend a JSON body with Content-Type: application/json.

  • The request is well-formed but asks for something the endpoint refuses; the message says what.

    Was tunChange the request as the message describes.

401Unauthorized: das Credential11Mehr lesen
  • This endpoint needs a credential and none was sent.

    Was tunSend an API key in X-API-Key, or sign in.

  • No API key was sent.

    Was tunSend your key in the X-API-Key header.

  • The API key is not one we issued, or it has been deleted.

    Was tunCheck the key for a typo, or create a new one in your account.

  • The key was switched off by the account that owns it.

    Was tunRe-enable it in your account, or use another key.

  • The key has passed its expiry date.

    Was tunCreate a new key in your account.

  • This endpoint needs a signed-in session.

    Was tunSign in, then retry.

  • The session is no longer valid.

    Was tunSign in again.

  • The credential verified, but the account behind it no longer exists.

    Was tunSign in again, or contact support.

  • A proxy or marketplace credential was presented and does not verify.

    Was tunThrough a marketplace such as RapidAPI, contact the API provider: the proxy is misconfigured.

  • An inbound webhook delivery is unsigned, or its signature does not match the secret it was sent under.

    Was tunSet the same webhook secret on the sender and in the console; a sender's test delivery signed with another secret fails here.

403Forbidden: die Berechtigung16Mehr lesen
  • The credential is valid and its plan is below what this endpoint needs. details.requiredTier names the plan.

    Was tunUpgrade the plan. A new key on the same plan will get the same answer.

  • The account behind this credential has been suspended.

    Was tunContact support. Rotating the key will not help.

  • This key is paused: it kept making requests long after its daily or monthly limit refused them. Only this key is paused, never the account.

    Was tunStop sending requests and wait for the time in Retry-After, or upgrade your plan, which lifts the pause at once. Signing in and changing plan are unaffected. A new key does not help: the pause follows the key you were given, and creating more is limited by your plan.

  • The key is valid but no user account owns it, so account endpoints (/v1/me) have nothing to act on.

    Was tunUse a key created from your account.

  • The key is a platform token issued for the hosted MCP server alone, and this request did not come through it.

    Was tunCall the MCP server at the documented URL with this key, or use a key of your own for direct API requests.

  • The key is valid but no shop names it, so seller endpoints (/v1/vendor) have no shop to act for.

    Was tunName the key in Profile > Seller on the shop it should act for, then check GET /v1/vendor/shops.

  • The shop exists and has not been approved yet.

    Was tunWait for approval. Nothing needs to be sent again.

  • The resource exists and belongs to another account or shop.

    Was tunUse an id your account owns.

  • The download belongs to a product this account has not bought.

    Was tunBuy the product, then retry.

  • The plan's allowance for this kind of item is used up.

    Was tunRemove one, or upgrade for a larger allowance.

  • The plan does not page this deep into a list.

    Was tunNarrow the list with filters, or upgrade for deeper paging.

  • Staff-only endpoint.

    Was tunSign in with a staff account.

  • This is an impersonation session, which may look but never change anything.

    Was tunMake the change from your own account.

  • A browser request carried a GunSpec origin without the signature our own apps send.

    Was tunCall the API with an API key.

  • This client, user agent or address is blocked.

    Was tunContact support if you think this is a mistake.

  • The action is not permitted on this resource; the message says why.

    Was tunDo not retry unchanged.

404Nicht gefunden2
  • The path is right and no record has that id.

    Was tunCheck the id. The list and search endpoints return valid ones.

  • No endpoint answers this method and path.

    Was tunCheck the path and method against the API reference.

409Konflikt1
  • The request conflicts with existing data, such as a slug already in use.

    Was tunChange the conflicting value and retry.

413Body zu groß1
  • The request body is larger than this endpoint accepts. maxBytes carries the limit.

    Was tunSplit the request into smaller ones.

429Langsamer6Mehr lesen
  • Too many requests this minute for the plan.

    Was tunWait for Retry-After seconds, then retry.

  • The plan's daily request allowance is used up. It resets at midnight UTC.

    Was tunWait for the reset, or upgrade for a larger allowance.

  • The plan's monthly request allowance is used up. It resets at midnight UTC on the first of the month. Calls a limit refused do not count towards it.

    Was tunWait for the reset in Retry-After, error.resetsAt or X-Monthly-Reset, or choose a larger plan, which raises the allowance at once.

  • The plan's daily allowance for calls through the MCP server is used up. It resets at midnight UTC; direct API requests still count against the plan's own allowance.

    Was tunWait for the reset, call the API directly, or upgrade for a larger MCP allowance.

  • Too many sequential pages in a short time.

    Was tunSlow the walk down, or use a larger per_page.

  • A data report for this section was already filed in the last 24 hours.

    Was tunWait a day, or add to the report already filed.

500Unsere Seite1
  • Something failed on our side. It has been logged against request_id.

    Was tunRetry with backoff. Quote request_id if it persists.

503Vorübergehend nicht verfügbar2
  • A service this endpoint depends on is temporarily unavailable.

    Was tunRetry after a short wait.

  • The API is paused for maintenance.

    Was tunWait for Retry-After seconds, then retry.

Jede Antwort trägt einen X-Request-Id-Header, jeder Fehlerkörper wiederholt ihn als request_id. Nenne ihn dem Support: er findet die Anfrage in unseren Logs.

Retry-After sind die Sekunden bis zur nächsten erlaubten Anfrage. Beim Minutenlimit sind es 60. Bei der Tagesgrenze sind es die Sekunden, bis die Zähler um Mitternacht UTC auf null zurückgehen, nie mehr als ein Tag. Beim Monatskontingent sind es die Sekunden bis Mitternacht UTC am 1., nie mehr als ein Monat. Davor wird nichts ausgeliefert. Ein 503 während Wartung trägt ihn ebenfalls. Eine Tages- oder Monatsablehnung sagt es auch im Body: error.limit, error.resetsAt (ein ISO-8601-Zeitpunkt, derselbe wie X-Daily-Reset oder X-Monthly-Reset) und error.retryAfter. Was übrig ist, wird auf jeder Antwort gesendet: der Tag, je Schlüssel, als X-Daily-Limit, X-Daily-Remaining und X-Daily-Reset (bei MCP-Verkehr zusätzlich X-Daily-MCP-*), und der Monat, für das ganze Konto, als X-Monthly-Limit, X-Monthly-Remaining und X-Monthly-Reset bei einem Aufruf mit Schlüssel. Jeder Remaining-Wert ist das, was nach dem Aufruf übrig ist, der ihn geliefert hat: eine Antwort mit 0 war die letzte, die ausgeliefert wurde. Nur ausgelieferte Aufrufe verbrauchen den Monat: ein abgelehnter Aufruf und ein 304 nicht. Richten Sie Ihr Tempo nach den Headern und gleichen Sie mit GET /v1/me/usage ab. Es gibt kein X-RateLimit-Remaining; der Edge-Limiter meldet, ob eine Anfrage erlaubt war, nicht wie viel von der Minute übrig ist. Halten Sie bei der ersten Ablehnung an: die SDKs warten einen Reset nur ab, wenn er wenige Sekunden entfernt ist, und ein kostenloser Schlüssel, der weiter anfragt, wird mit KEY_ON_HOLD pausiert. Im Tarif bleiben zeigt, wie ein Skript rechtzeitig anhält.

Was die API mit einem Aufruf macht, der nicht in der Referenz steht. Das sind Zusagen, bei jedem Lauf gegen die Produktion geprueft, kein Verhalten, das heute zufaellig gilt.

  • Eine Methode, die ein Pfad nicht beantwortet, ergibt 404 mit error.reason ROUTE_NOT_FOUND und nennt Methode und Pfad. Kein 405: ein Pfad ist hier je Methode definiert, POST /v1/firearms ist also kein Firearms-Endpunkt, der ein Verb ablehnt, sondern kein Endpunkt.
  • HEAD wird ueberall dort beantwortet, wo GET beantwortet wird, mit gleichem Status, gleichen Headern und ohne Body. Das schliesst das ETag ein, ein HEAD mit If-None-Match antwortet also 304 und ist der guenstigste Weg zu fragen, ob sich ein Datensatz geaendert hat. Er wird nicht aus dem geteilten Cache bedient und kostet daher eine Anfrage aus dem Kontingent. Siehe Caching.
  • Ein Query-Parameter, den die Operation nicht dokumentiert, wird ignoriert statt abgelehnt. Ein falsch geschriebener Filter liefert deshalb ungefilterte Daten statt eines Fehlers: pruefe den Namen an der Operation, wenn ein Ergebnis zu breit aussieht.