Operate & monitor
Errors, limits & retries
Use error codes and request IDs to diagnose failures. Preserve operation identity when retrying uncertain writes.
On this page
Read the error response
Service errors return an error object and usually request_id. HTTP ingress failures may include only error.code. Live service responses identify their mode with X-CRD-Mode: live.
Record the HTTP status, error code, and request ID when diagnosing failures. Do not log credentials, signing secrets, or authorization evidence.
{
"error": {
"code": "creator_not_eligible",
"message": "The creator must have a verified mandate and active CRD entitlement."
},
"request_id": "req_example"
}HTTP status codes
| Status | Meaning | Next step |
|---|---|---|
| 400 | Invalid request | Check fields, types, and URL rules. |
| 401 | Unauthorized | Check live key, expiry, and revocation. |
| 403 | Access or verification denied | Check scopes and current agency verification. |
| 404 | Resource unavailable | Check the ID and current agency access. |
| 409 | Conflict or workflow gate | Inspect the specific code before retrying. |
| 413 / 415 | Body or media type rejected | Use JSON below the request size limit. |
| 429 | Rate or scan limit | Honor Retry-After when present and back off. |
| 502 / 503 | Provider unavailable or invalid response | Retry reads with backoff; preserve idempotency on writes. |
Common workflow errors
| Code | How to resolve it |
|---|---|
| agency_verification_unavailable | CRD must configure or restore server-side agency verification. |
| agency_account_required | Complete agency onboarding and KYC approval, then open /agency/api as the current owner. |
| agency_kyc_required | Complete agency KYC and wait for approval. |
| agency_owner_changed | Have the current verified owner open /agency/api and issue new keys and webhook endpoints. |
| agency_key_reissue_required | Issue a replacement key after the verified agency binding. |
| crd_engine_not_configured | CRD must configure the real provider; no synthetic fallback is used. |
| creator_invitation_pending | Wait for invitation acceptance and creator onboarding. |
| creator_not_eligible | Resolve the creator’s actual mandate or entitlement requirement. |
| creator_rebinding_required | Ask CRD to review a creator tied to an earlier agency binding. |
| external_id_conflict | Use the original enrollment payload; this is not an update route. |
| capacity_reached | Ask CRD to adjust the active creator allowance. |
| native_case_managed_by_crd | This native case has no verified API-scan mapping. Use the existing CRD admin workflow; inspect api_deindex_supported before offering this API action. |
| scan_in_progress | Follow the existing pending scan. |
| idempotency_conflict | Retry with the original key and input. |
| scan_limit_reached | Wait for the rolling manual scan allowance. |
Preserve the logical operation
Enrollment uses your stable external ID and identical payload for reconciliation. Scan and deindex writes use the same Idempotency-Key across retries. A fresh key describes new work, not a retry.
An uncertain worker state means the service is reconciling real effects. Do not assume the operation failed or repeat it with a different identity. Read the resource and contact CRD when reconciliation is needed.
Follow each collection’s returned cursor
Use limit from 1 to 100; the default is 25. Follow next_cursor until it is null. Do not infer completion solely from an empty data array: access filtering can leave an empty page that still has a next cursor. Treat cursors as opaque values returned by that collection.
These collections reflect changing live records, not a frozen export. Deduplicate by resource ID while paging. For event polling, keep the previous saved cursor when no newer accessible event is returned, and process repeated events safely.
| Collection | Cursor to send as after | Behavior |
|---|---|---|
| GET /v1/creators | The returned next_cursor, a native CRD user UUID. | Current eligible-to-access agency roster, ordered by native user ID. Do not substitute a crt_… API ID. |
| GET /v1/creators/{id}/cases | The returned next_cursor, an API case ID. | Current native findings for that creator. Keep cursors inside the same creator collection. |
| GET /v1/events | The returned next_cursor while paging, then the last processed event ID for later polling. | Insertion order, filtered by current creator access. Events and webhook deliveries share event IDs. |
Retry the operation, not a new copy of the work
Scan idempotency keys are unique across the agency’s scan operations, not only within one creator. Deindex keys are unique across the agency’s deindex operations. Use a different key for each logical operation and keep scan and deindex operation records separate.
The live scan and deindex routes accept Idempotency-Key values of 1–120 characters. A matching write retry may return 200 instead of the original 201 or 202. HTTP acceptance does not mean the asynchronous work completed.
| Operation | Save before sending | Safe retry approach |
|---|---|---|
| POST creator enrollment | workspace_id, stable external_id, and the original complete JSON payload. | Resend the same payload. Omitted defaults, field order, and array order can affect reconciliation; preserve the original request. Use PATCH for later changes. |
| PATCH creator identity | Creator ID and the desired non-empty subset of fields. | Repeat the same update. Names are set; aliases and URLs merge without removing other entries. |
| PUT protection status | Creator ID and desired active or paused state. | Read eligibility when blocked; repeat the same desired state after the requirement is resolved. |
| POST scan | A unique Idempotency-Key for this logical scan and its creator ID. | Reuse the key and input after a lost response. A matching retry returns the original scan. |
| POST deindex request | A unique Idempotency-Key for this logical case request and provider google. | Reuse the key and input after a lost response. Follow the existing request rather than creating another. |
Default operating limits
These are implementation defaults, not a service-level commitment. Confirm deployment capacity and commercial limits with CRD.
| Control | Default |
|---|---|
| Requests | 120 per agency API account per fixed minute; configurable by CRD. |
| Request body | 16 KiB. |
| Creator aliases / URLs | Up to 30 aliases and 20 profile URLs per request. |
| Agency workspace | One assigned workspace. |
| Total creator enrollment | Up to five times the active creator capacity. |
| Pending scans | One per creator. |
| Manual scans | Five per creator per rolling 24 hours. |
| Webhook attempts | Up to five attempts with exponential backoff. |
Handle rate limits and transient errors
The default request allowance is 120 requests per agency API account per fixed minute, shared by all of that agency’s keys. Creating another key does not create an independent allowance. Manual scans have a separate limit of five per creator over the preceding 24 hours. Scheduled work and webhook delivery are not additional client requests you need to poll continuously.
For 429 rate_limited, pause the agency’s request queue and retry with exponential backoff and jitter. Honor Retry-After if supplied by the deployment; the live API does not guarantee that header. For 429 scan_limit_reached, wait for the creator’s rolling manual-scan allowance instead of immediately retrying.
Retry transient network failures and 502/503/504 reads with backoff. For writes, preserve the same external ID or idempotency key. Do not blindly retry 400 validation failures, 401 invalid credentials, 403 missing permissions, or 409 workflow requirements; correct the reported cause first.
Keep the method, endpoint, HTTP status, error code, and request_id or X-Request-ID if present. Do not log the Authorization header, webhook signing secret, or private authorization evidence.
Request & response example
/v1/mecurl --request GET 'https://api.crd.systems/v1/me' \
--header "Authorization: Bearer $CRD_API_KEY"{
"partner": {
"id": "ptn_example",
"name": "Example Agency",
"kind": "agency"
},
"workspace_id": "wsp_example",
"key_id": "key_example",
"scopes": [
"workspaces:read",
"creators:read",
"creators:write"
],
"expires_at": null,
"environment": "live",
"workspaces": [
{
"id": "wsp_example",
"name": "Example Agency",
"external_id": "agency_001"
}
],
"engine_configured": true
}Illustrative response. Replace example resource IDs with the IDs returned by your API requests. View endpoint details.