Skip to main content

Status codes

StatusMeaningRetry?
202Accepted — { accepted, duplicates }
400Invalid envelope or batch. Nothing was stored.No — fix the request
401Missing or invalid bearer tokenNo — fix the token
429Rate limit exceededYes — back off and retry
503Temporarily unavailable (e.g. a database blip)Yes — honor Retry-After
500Unexpected server errorYes — retry with backoff
Retryable vs. permanent. 400 and 401 won’t change on retry — fix the envelope or the token. 429, 503, and 500 are transient — retry with exponential backoff. On a 503, Pulse sends a Retry-After header (in seconds) and never leaks an internal error.

Validation errors (400)

A single invalid event returns the failing fields:
{
  "error": "invalid event envelope",
  "details": [
    { "path": "confidence", "message": "Number must be less than or equal to 1" }
  ]
}

Batches are all-or-nothing

If any event in an array is invalid, the entire batch is rejected and nothing is stored — the response points at the offending elements by index:
{
  "error": "invalid batch — rejected atomically, nothing was stored",
  "invalid": [
    {
      "index": 1,
      "issues": [
        { "path": "eot", "message": "Required" },
        { "path": "confidence", "message": "Number must be less than or equal to 1" }
      ]
    }
  ]
}
Fix the flagged events and resend the whole batch. The already-valid events were not stored, so there is no risk of duplication.

Rate limiting (429)

Requests are rate-limited per venue. If you exceed the limit, back off and retry. High-frequency sources should batch events (up to 500 per request) rather than send one request each.

Temporary outages (503)

A 503 means Pulse hit a transient infrastructure problem (such as a brief database disconnect). The request was not stored. Retry after the interval in the Retry-After header; because resends are idempotent, retrying is always safe.