Errors

Every non-2xx response from /api/v1 uses the same JSON envelope:

json
{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit exceeded"
  }
}

Treat error.code as the stable machine-readable value. error.message is human-readable context and may contain validation details.

Error reference

StatusCodeMeaningRetry?
400invalid_requestThe body, parameter, cursor, or required header is invalid.Fix the request.
401unauthorizedThe API key is missing, malformed, expired, or revoked.Use a valid key.
403forbiddenThe key lacks a scope, or its owner's role lacks permission.Change access.
403plan_requiredThe team does not currently have Public API access.Activate Pro access.
404not_foundThe file does not exist or belongs to another team.No.
413payload_too_largeThe direct upload exceeds 100 MiB.Upload through the app.
415unsupported_media_typeThe normalized content type is not accepted.Change the file or type.
429rate_limitedThe key's request budget is exhausted.Wait for Retry-After.
507quota_exceededThe team's storage quota is full.Free storage or increase quota.
500internal_errorAn unexpected server error occurred.Retry with backoff.

JavaScript error helper

js
async function apiFetch(path, options = {}) {
  const response = await fetch(`${process.env.NEW_ARCHIVE_URL}${path}`, {
    ...options,
    headers: {
      Authorization: `Bearer ${process.env.NEW_ARCHIVE_API_KEY}`,
      ...options.headers,
    },
  })

  const body = await response.json()
  if (!response.ok) {
    const error = new Error(body.error?.message ?? `HTTP ${response.status}`)
    error.code = body.error?.code
    error.status = response.status
    error.retryAfter = Number(response.headers.get("retry-after") ?? 0)
    throw error
  }
  return body
}

Retry rate limits

Respect Retry-After when present. Add a fallback and cap retries so a broken integration cannot loop forever.

Validation errors

Validation failures identify the field in message. They are safe to log, but do not log the request's Authorization header.

json
{
  "error": {
    "code": "invalid_request",
    "message": "limit: Too big: expected number to be <=100"
  }
}