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