Docs / Errors

Errors

Every error from the API has the same shape:

{
  "error": {
    "type": "invalid_request_error",
    "code": "parameter_invalid",
    "message": "Amounts take at most 2 decimals.",
    "param": "events[2].amount"
  }
}
  • type is the broad kind, code the specific one. Check code in your code.
  • message is for people. It can change, so don't match on it.
  • param is the field at fault, or null. Positions count from 0, so events[2].amount is the third event's amount, whichever body shape you sent. It goes as deep as the problem: events[0].identifiable[1].label. A single event without a list has no position, just amount.

Two ways to fail

One event is rejected

The request still answers 200. That event's result has "status": "rejected" and an error. The other events are recorded as usual. Fix the event and send it again.

curl https://api.bumpbunny.dev/v1/events \
  -H "Authorization: Bearer bump_test_…" \
  -H "Content-Type: application/json" \
  -d '[
    { "identifiable": "usr_123", "amount": 49.99 },
    { "trackable": "orders", "occurred_at": "2030-01-01T09:00:00+01:00" }
  ]'
{
  "object": "list",
  "data": [
    {
      "object": "event",
      "status": "rejected",
      "error": {
        "type": "invalid_request_error",
        "code": "parameter_missing",
        "message": "trackable is missing.",
        "param": "events[0].trackable"
      }
    },
    {
      "object": "event",
      "status": "rejected",
      "error": {
        "type": "invalid_request_error",
        "code": "parameter_invalid",
        "message": "occurred_at is more than 5 minutes in the future.",
        "param": "events[1].occurred_at"
      }
    }
  ]
}

The whole request is refused

Bump answers with an HTTP error status and the error object, and records nothing from the request. This happens when the body can't be read, when it holds more than 100 events, and when the token is missing or wrong.

curl -i https://api.bumpbunny.dev/v1/events \
  -H "Authorization: Bearer bump_test_…" \
  -H "Content-Type: application/json" \
  -d '{"trackable": "orders",}'

Response, headers trimmed:

HTTP/2 400

{
  "error": {
    "type": "invalid_request_error",
    "code": "parameter_invalid",
    "message": "The body isn't valid JSON.",
    "param": null
  }
}

Without a token:

curl -i https://api.bumpbunny.dev/v1/events -d '{"trackable": "orders"}'
HTTP/2 401

{
  "error": {
    "type": "authentication_error",
    "code": "token_missing",
    "message": "No API token. Send it as a Bearer token in the Authorization header.",
    "param": null
  }
}

Codes

Code Type HTTP When
parameter_missing invalid_request_error 200 One event: trackable is missing.
parameter_invalid invalid_request_error 200 One event: a field breaks its rule, or an identifiable's handle is a forgotten one's placeholder. message says which.
parameter_invalid invalid_request_error 400 The body isn't JSON or none of the three shapes, events isn't a list, backfill isn't true or false, more than 100 events, or the trackable in the URL isn't a valid handle. When forgetting: identifiable isn't one handle. When reading totals: more than one handle.
parameter_missing invalid_request_error 400 When forgetting: the body has no identifiable. When reading totals: no handle, or an empty one.
token_missing authentication_error 401 No bearer token in the Authorization header.
token_invalid authentication_error 401 The token doesn't exist or was revoked.
missing_ability permission_error 403 The token can't do this. Every token made in the dashboard can send events; only those made with Can forget identifiables on can forget, and only those made with Can read totals on can read totals.
resource_missing invalid_request_error 404 No such URL, like a typo in the path. When forgetting: no identifiable with that handle in the token's environment. When reading totals: no trackable with that handle in the project.
method_not_allowed invalid_request_error 405 The URL exists but takes another method, like a GET to /events.
rate_limited rate_limit_error 429 More than 600 requests in a minute with this token. Wait the Retry-After seconds.
request_invalid invalid_request_error 4xx Any other request Bump can't process, like a body that's too large.
internal_error api_error 500 Something broke on our side. Events before it in the request are recorded. Retry with the same ids.
not_implemented api_error 501 An endpoint that isn't available yet. None today.

Revoked and unknown tokens

A revoked token gets exactly the answer an unknown one gets: 401 with token_invalid. From the outside you can't tell whether a token ever existed. Revoking works from the next request on.

Finding them later

Rejected events and refused requests show up in Developers > Problems, per environment, kept for 30 days. A problem groups the same error per day, with how often it happened, first and last seen, and the id of the latest rejected event, so a client stuck in a loop is one line with a high count. Resolve a problem once it's fixed. If it happens again, it opens again.

What's recorded:

  • rejected events
  • reused ids: a duplicate whose trackable, count, amount, occurred_at or identifiables differ from the event first sent with that id
  • requests refused as a whole (400, 403, 429) with a valid token
  • reading the totals of a trackable that doesn't exist (404), with the handle asked for
  • calls with a revoked token, in that token's environment, for 30 days after revoking

What isn't: calls with a missing or unknown token, which belong to no project, unknown URLs, forgetting a handle Bump doesn't have, and errors on our side. Problems keep no request bodies, identifiable handles, labels or IP addresses.