API ReferenceErrors & Status Codes

Errors & Status Codes

All Praevis API errors return a consistent JSON error body alongside the HTTP status code.


Error response format

{
  "error": {
    "code": "INVALID_PARAMS",
    "message": "Missing required field: name",
    "field": "name",
    "request_id": "req-abc123"
  }
}
FieldDescription
codeMachine-readable error code (see table below)
messageHuman-readable description
fieldWhich field caused the error (validation errors only)
request_idInclude this when contacting support

HTTP status codes

HTTPApplication CodeMeaningRetry?
200—Success—
201—Resource created—
204—No content (no-bid or empty result)—
400INVALID_PARAMSMissing or malformed parametersNo — fix the request
400INVALID_JSONRequest body is not valid JSONNo — check encoding
400VALIDATION_ERRORField-level validation failedNo — check field
401UNAUTHORIZEDAPI key missing or invalidNo — check your key
403FORBIDDENValid key but wrong scope (missing partner ID)No — check X-User-Partner-ID
404NOT_FOUNDResource doesn’t existNo
409CONFLICTResource already exists (duplicate name/ID)No — change identifier
422STRATEGY_INVALIDDelegate strategy JSON failed validationNo — fix strategy JSON
429RATE_LIMITEDToo many requestsYes — back off 60s
500INTERNAL_ERRORUnexpected server errorYes — retry with exponential backoff
502BAD_GATEWAYUpstream service errorYes — retry after 5s
503SERVICE_UNAVAILABLEPlanned maintenance or overloadYes — retry after 30s
503AUCTION_TIMEOUTAuction processing exceeded timeoutYes — reduce bid latency

Retry guidance

Retryable errors (5xx + 429)

Use exponential backoff with jitter:

attempt 1: wait 1s
attempt 2: wait 2s
attempt 3: wait 4s
attempt 4: wait 8s
attempt 5: wait 16s (give up after this)

For RATE_LIMITED (429): wait at least 60 seconds. The X-RateLimit-Reset header gives the exact Unix timestamp when the limit resets.

Non-retryable errors (4xx)

Fix the request before retrying. Retrying immediately will return the same error.


Common errors and fixes

UNAUTHORIZED (401)

{ "code": "UNAUTHORIZED", "message": "API key is missing or invalid" }
  • Check X-API-Key header is present and correctly spelled
  • Verify the key is active under Settings → API Keys
  • Production keys start with pk_live_, sandbox keys with pk_sandbox_

FORBIDDEN (403)

{ "code": "FORBIDDEN", "message": "Partner ID required for this endpoint" }
  • Add X-User-Partner-ID: {PARTNER_UUID} header
  • Verify the partner UUID is correct (found in Settings → Partner Info)

INVALID_PARAMS (400)

{ "code": "INVALID_PARAMS", "message": "Missing required field: name", "field": "name" }
  • Check the request body against the endpoint documentation
  • Common missing fields: name, type, mode, endpoint_url (for RTB demand sources)

STRATEGY_INVALID (422)

{
  "code": "STRATEGY_INVALID",
  "message": "Rule condition value must be a string: device.devicetype",
  "field": "rules[0].conditions.device.devicetype"
}
  • All Delegate condition values must be strings: "3" not 3
  • Check the Delegate strategy guide for valid field names and types

RATE_LIMITED (429)

{
  "code": "RATE_LIMITED",
  "message": "Rate limit exceeded",
  "reset_at": 1708171200
}

Rate limit headers:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1708171200

Back off for at least 60 seconds. Contact support if you need a higher rate limit.


Health endpoint

Always available, no auth required:

GET https://api.praevis.com/api/health
{ "status": "ok", "region": "fra", "version": "0.6.30" }

Use this for uptime monitoring. If this returns non-200, check status.praevis.com.


Contacting support

Include the request_id from the error response:

[email protected]
Subject: API Error — request_id: req-abc123

We can look up the full error trace within 24 hours.