Skip to main content
The API uses standard HTTP status codes and returns a consistent error envelope for all error responses.

Error format

{
  "error": {
    "code": "not_found",
    "message": "The requested contract does not exist or is not accessible",
    "request_id": "req_abc123def456"
  }
}
FieldDescription
codeMachine-readable error code (see table below)
messageHuman-readable description of the error
request_idUnique identifier for this request. Include this when contacting support.

Error codes

HTTP StatusCodeDescription
400validation_failedInvalid query parameters or request format
401unauthorizedMissing or invalid API key
403forbiddenValid key but resource is outside your partner scope
404not_foundResource does not exist or is not accessible
429rate_limitedToo many requests. See Rate Limits
500internal_errorSomething went wrong on our end

Handling errors

const response = await fetch(url, { headers });

if (!response.ok) {
  const body = await response.json();
  const { code, message, request_id } = body.error;

  switch (code) {
    case "rate_limited":
      const retryAfter = response.headers.get("Retry-After");
      // Wait and retry
      break;
    case "unauthorized":
      // Check your API key
      break;
    case "not_found":
      // Resource doesn't exist or isn't in your scope
      break;
    default:
      console.error(`API error [${request_id}]: ${code} - ${message}`);
  }
}

Request IDs

Every response includes an X-Request-ID header. When reporting issues, include this ID so we can trace the exact request in our logs.
curl -v https://prod-api.civicmarketplace.com/v1/contracts/ctr_invalid \
  -H "Authorization: Bearer cmp_live_YOUR_KEY"

# Response headers will include:
# X-Request-ID: req_abc123def456