Skip to main content
Bily returns standard HTTP status codes with JSON error bodies, so your application can choose the right recovery step.
{
  "error": "Store not found"
}
An unexpected server error can also include its request ID:
{
  "error": "Internal Server Error",
  "requestId": "2ae61752-6902-4d1b-a54a-b9843fbed75a"
}

Act on each status

StatusMeaningRecommended handling
400Invalid path, query, or request bodyFix the request. Do not retry unchanged.
401Missing or invalid authenticationReplace or rotate the API key.
403The identity or key lacks accessVerify key permissions and scope. Regenerate an older settings-generated key when the error requires a store scope.
404The scoped resource was not foundRefresh customer context or resource IDs.
409The request conflicts with current stateRead the resource and disambiguate or update the request.
429Too many requestsRetry with exponential backoff and jitter.
500Bily could not complete the requestRetry safe reads; investigate before retrying writes.
502A dependent Bily operation was temporarily unavailableRetry safe reads after a short delay.
504The request did not complete before its timeoutRetry safe reads after a short delay or reduce the requested range.

Keep the request ID

Every response includes x-request-id. Record it with the operation and timestamp. You can send a safe correlation value in x-request-id or x-correlation-id. Bily returns the selected value as x-request-id.
const requestId = crypto.randomUUID();
const response = await fetch(
  "https://app.bily.ai/api/customer/v1/context",
  {
    headers: {
      "x-api-key": process.env.BILY_API_KEY!,
      "x-request-id": requestId,
    },
  },
);

if (!response.ok) {
  const bilyRequestId = response.headers.get("x-request-id");
  const body = await response.json().catch(() => null);
  throw new Error(
    `Bily request failed (${response.status}, request ${bilyRequestId}): ${JSON.stringify(body)}`,
  );
}
Keep customer data, credentials, and secrets out of request IDs.

Retry only when safe

Retry idempotent GET requests after transient 429, 500, 502, or 504 responses. Add jitter to capped exponential backoff. Do not automatically retry create, clone, update, toggle, delete, sync, or other mutation requests. First read the affected resource and confirm that the original write did not succeed.