THE COMPLETE CONTRACT
API reference
Every endpoint, parameter and response. Examples use standard HTTP clients and your server’s environment variables.
Read your agency API connection
Read credential scopes, expiry, assigned agency workspace, and live engine configuration. The legacy partner field identifies the agency API account.
any valid agency keyResponse
Returns 200 on success.
partnerobjectrequiredShow nested fields
idstringrequirednamestringrequiredkindstringrequiredAlways agency.
workspace_idstring | nullrequiredkey_idstring | nullrequiredscopesarray[]requiredexpires_atinteger | nullrequiredKey expiration in epoch milliseconds, or null when there is no scheduled expiration. Revocation, agency verification, ownership, and scope checks still apply.
environmentstringrequiredAlways live.
workspacesarray[]requiredShow nested fields
idstringrequiredexternal_idstringrequirednamestringrequiredengine_configuredbooleanrequiredRetries & errors
This read can be retried with exponential backoff. Honor Retry-After when it is returned.
Documented statuses: 200, 400, 401, 403, 404, 409, 429, 502, 503, 504. Error handling guide
/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
}Retrieve your assigned workspace
Requires workspaces:read. API customers cannot create agencies or additional workspaces.
workspaces:readParameters
idpathrequiredResponse
Returns 200 on success.
idstringrequiredexternal_idstringrequirednamestringrequiredcreated_atintegerrequiredUnix epoch milliseconds.
Retries & errors
This read can be retried with exponential backoff. Honor Retry-After when it is returned.
Documented statuses: 200, 400, 401, 403, 404, 409, 429, 502, 503, 504. Error handling guide
/v1/workspaces/{id}curl --request GET 'https://api.crd.systems/v1/workspaces/wsp_example' \
--header "Authorization: Bearer $CRD_API_KEY"{
"id": "wsp_example",
"external_id": "agency_001",
"name": "Example Agency",
"created_at": 1790035200000
}Link or invite an agency creator
Requires creators:write. Provide an existing agency crd_user_id or email, first_name, last_name for a real CRD invitation. Existing creators must belong to the agency and not be staff. Aliases and supported profile URLs update actual CRD identity data; mandate/contact evidence is not fabricated. Invitations send real email and require acceptance/onboarding. Enrollment starts inactive. Retry with identical external_id and payload; changed input conflicts. If roster sync already imported the same CRD user, enrollment reuses its stable API creator ID and may replace the automatic crd:UUID external ID with the supplied ID. A different already-assigned external ID conflicts. No duplicate creator or usage interval is created. New invitation enrollment triggers email; email_sent reports provider acceptance, not inbox delivery or creator acceptance. An identical retry does not resend an invitation. Existing confirmed agency creators can link without invitation. Enrollment never activates protection automatically.
creators:writeRequest body
workspace_idstringrequiredMaximum 200 characters.
external_idstringrequiredMaximum 200 characters.
display_namestringrequiredMaximum 160 characters.
aliasesarray[]Pseudonyms, alternate spellings, and usernames without a required social-network label. Merged into the native CRD search aliases.
Up to 30 items.
profile_urlsarray[]Full canonical HTTPS profile URLs using the same creator-platform rules as the portal. CRD derives the platform and username. Supports the portal platform catalog, X/Twitter aliases and RevealMe (reveal.me). Unknown public HTTPS hosts are stored as website profiles, not newly supported social platforms. No tracking query, fragment, credentials, private host or post URL. These links do not prove account ownership.
Up to 20 items.
crd_user_idstringemailstringMaximum 254 characters.
first_namestringMaximum 100 characters.
last_namestringMaximum 100 characters.
localestringValues: en fr
Response
Returns 201 on success.
idstringrequiredworkspace_idstringrequiredexternal_idstringrequireddisplay_namestringrequiredaliasesarray[]requiredprofile_urlsarray[]requiredFull canonical HTTPS profile URLs using the same creator-platform rules as the portal. CRD derives the platform and username. Supports the portal platform catalog, X/Twitter aliases and RevealMe (reveal.me). Unknown public HTTPS hosts are stored as website profiles, not newly supported social platforms. No tracking query, fragment, credentials, private host or post URL. These links do not prove account ownership.
protection_statusstringrequiredCurrent API dispatch state. For active_creators billing, observed portal activations synchronize this state; valid authorization and paid entitlement remain required.
Values: not_activated active paused
created_atintegerrequiredUnix epoch milliseconds.
enrollment_statusstringrequiredCurrent CRD linkage state, for example invited, pending_onboarding, linked, enrolling, failed, or uncertain.
crd_user_idstring | nullrequiredinvitation_idstring | nullrequiredsimulatedbooleanrequiredAlways false.
scan_schedule_managed_bystringrequiredLegacy response field. The API controls its active-protection setting and on-demand scan eligibility; the existing CRD plan controls recurring scans.
Always api.
crd_subscription_managed_bystringrequiredCRD owns billing and recurring scheduling. Under active_creators billing the protection PUT changes the same billable activation as the portal; legacy agreements retain API-dispatch-only behavior.
Always crd.
email_sentbooleanPresent on a new enrollment response. True means the email provider accepted the invitation email; it does not prove inbox delivery, acceptance, authorization, or activation.
identity_sync_pendingbooleanrequiredTrue when an accepted invitation still needs legal onboarding before its submitted identity data can be applied.
billingobjectShow nested fields
modelstringrequiredValues: legacy active_creators
unit_price_centsinteger | nullrequiredcurrencystringrequiredAlways EUR.
activatedbooleanrequiredoperation_idstringRetries & errors
Reuse the same external_id and complete payload for retries. Changed input under the same external ID conflicts. Use PATCH to update a linked creator’s identity.
Documented statuses: 200, 201, 400, 401, 403, 404, 409, 413, 415, 429, 502, 503, 504. Error handling guide
/v1/creatorscurl --request POST 'https://api.crd.systems/v1/creators' \
--header "Authorization: Bearer $CRD_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"workspace_id": "wsp_example",
"external_id": "creator_001",
"crd_user_id": "33333333-3333-4333-8333-333333333333",
"display_name": "Example Creator",
"aliases": [
"example_creator"
],
"profile_urls": [
"https://onlyfans.com/example_creator"
]
}'{
"id": "crt_example",
"workspace_id": "wsp_example",
"external_id": "creator_001",
"display_name": "Example Creator",
"aliases": [
"example_creator"
],
"profile_urls": [
"https://onlyfans.com/example_creator"
],
"protection_status": "not_activated",
"created_at": 1790035200000,
"enrollment_status": "linked",
"crd_user_id": "33333333-3333-4333-8333-333333333333",
"invitation_id": null,
"simulated": false,
"scan_schedule_managed_by": "api",
"crd_subscription_managed_by": "crd",
"identity_sync_pending": false,
"email_sent": false
}Read your canonical agency roster
Requires creators:read. Reads the existing CRD agency roster, imports missing API mappings without activating billing, and returns stable API creator IDs with current names, aliases, official URLs, authorization, entitlement, and eligibility. Changes made in the CRD app are reflected on reads. The after cursor is a CRD user UUID, not an API creator ID.
creators:readParameters
limitqueryafterqueryCanonical CRD user UUID from next_cursor.
Response
Returns 200 on success.
dataarray[]requiredShow nested fields
idstringrequiredworkspace_idstringrequiredexternal_idstringrequireddisplay_namestringrequiredaliasesarray[]requiredprofile_urlsarray[]requiredFull canonical HTTPS profile URLs using the same creator-platform rules as the portal. CRD derives the platform and username. Supports the portal platform catalog, X/Twitter aliases and RevealMe (reveal.me). Unknown public HTTPS hosts are stored as website profiles, not newly supported social platforms. No tracking query, fragment, credentials, private host or post URL. These links do not prove account ownership.
protection_statusstringrequiredAPI schedule state, separate from enrollment and eligibility. Activation and resumption require an explicit protection PUT after current eligibility checks.
Values: not_activated active paused
created_atintegerrequiredUnix epoch milliseconds.
enrollment_statusstringrequiredCurrent CRD linkage state, for example invited, pending_onboarding, linked, enrolling, failed, or uncertain.
crd_user_idstring | nullrequiredinvitation_idstring | nullrequiredsimulatedbooleanrequiredAlways false.
scan_schedule_managed_bystringrequiredLegacy response field. The API controls its active-protection setting and on-demand scan eligibility; the existing CRD plan controls recurring scans.
Always api.
crd_subscription_managed_bystringrequiredAlways 'crd': the creator's actual CRD subscription and its own automatic scan cadence are managed entirely by CRD, independent of this API's protection_status.
Always crd.
email_sentbooleanPresent on a new enrollment response. True means the email provider accepted the invitation email; it does not prove inbox delivery, acceptance, authorization, or activation.
authorizationobjectrequiredShow nested fields
approvedbooleanrequiredstatusstringexpires_atstring | nullentitlementobjectrequiredShow nested fields
activebooleanrequiredsourcestringeligiblebooleanrequiredidentity_sync_pendingbooleanrequiredTrue when an accepted invitation still needs legal onboarding before its submitted identity data can be applied.
next_cursorstring | nullrequiredLast canonical CRD user UUID for the next roster page, or null.
Retries & errors
This read can be retried with exponential backoff. Honor Retry-After when it is returned.
Documented statuses: 200, 400, 401, 403, 404, 409, 429, 502, 503, 504. Error handling guide
/v1/creatorscurl --request GET 'https://api.crd.systems/v1/creators?limit=25' \
--header "Authorization: Bearer $CRD_API_KEY"{
"data": [
{
"id": "crt_example",
"workspace_id": "wsp_example",
"external_id": "creator_001",
"display_name": "Example Creator",
"aliases": [
"example_creator"
],
"profile_urls": [
"https://onlyfans.com/example_creator"
],
"protection_status": "not_activated",
"created_at": 1790035200000,
"enrollment_status": "linked",
"crd_user_id": "33333333-3333-4333-8333-333333333333",
"invitation_id": null,
"simulated": false,
"scan_schedule_managed_by": "api",
"crd_subscription_managed_by": "crd",
"identity_sync_pending": false,
"authorization": {
"approved": true,
"status": "approved",
"expires_at": null
},
"entitlement": {
"active": true,
"source": "agency_subscription"
},
"eligible": true
}
],
"next_cursor": null
}Read creator linkage and eligibility
Requires creators:read. Refreshes the shared CRD identity so changes made in the agency dashboard are returned by the API. Resolves invitation onboarding and returns actual authorization, entitlement, and eligibility.
creators:readParameters
idpathrequiredResponse
Returns 200 on success.
idstringrequiredworkspace_idstringrequiredexternal_idstringrequireddisplay_namestringrequiredaliasesarray[]requiredprofile_urlsarray[]requiredFull canonical HTTPS profile URLs using the same creator-platform rules as the portal. CRD derives the platform and username. Supports the portal platform catalog, X/Twitter aliases and RevealMe (reveal.me). Unknown public HTTPS hosts are stored as website profiles, not newly supported social platforms. No tracking query, fragment, credentials, private host or post URL. These links do not prove account ownership.
protection_statusstringrequiredAPI schedule state, separate from enrollment and eligibility. Activation and resumption require an explicit protection PUT after current eligibility checks.
Values: not_activated active paused
created_atintegerrequiredUnix epoch milliseconds.
enrollment_statusstringrequiredCurrent CRD linkage state, for example invited, pending_onboarding, linked, enrolling, failed, or uncertain.
crd_user_idstring | nullrequiredinvitation_idstring | nullrequiredsimulatedbooleanrequiredAlways false.
scan_schedule_managed_bystringrequiredLegacy response field. The API controls its active-protection setting and on-demand scan eligibility; the existing CRD plan controls recurring scans.
Always api.
crd_subscription_managed_bystringrequiredAlways 'crd': the creator's actual CRD subscription and its own automatic scan cadence are managed entirely by CRD, independent of this API's protection_status.
Always crd.
email_sentbooleanPresent on a new enrollment response. True means the email provider accepted the invitation email; it does not prove inbox delivery, acceptance, authorization, or activation.
authorizationobjectrequiredShow nested fields
approvedbooleanrequiredstatusstringexpires_atstring | nullentitlementobjectrequiredShow nested fields
activebooleanrequiredsourcestringeligiblebooleanrequiredidentity_sync_pendingbooleanrequiredTrue when an accepted invitation still needs legal onboarding before its submitted identity data can be applied.
Retries & errors
This read can be retried with exponential backoff. Honor Retry-After when it is returned.
Documented statuses: 200, 400, 401, 403, 404, 409, 429, 502, 503, 504. Error handling guide
/v1/creators/{id}curl --request GET 'https://api.crd.systems/v1/creators/crt_example' \
--header "Authorization: Bearer $CRD_API_KEY"{
"id": "crt_example",
"workspace_id": "wsp_example",
"external_id": "creator_001",
"display_name": "Example Creator",
"aliases": [
"example_creator"
],
"profile_urls": [
"https://onlyfans.com/example_creator"
],
"protection_status": "not_activated",
"created_at": 1790035200000,
"enrollment_status": "linked",
"crd_user_id": "33333333-3333-4333-8333-333333333333",
"invitation_id": null,
"simulated": false,
"scan_schedule_managed_by": "api",
"crd_subscription_managed_by": "crd",
"identity_sync_pending": false,
"authorization": {
"approved": true,
"status": "approved",
"expires_at": null
},
"entitlement": {
"active": true,
"source": "agency_subscription"
},
"eligible": true
}Update the shared CRD creator identity
Requires creators:write and a linked current agency creator. Omitted fields are unchanged. display_name updates the CRD name; aliases and supported profile URLs merge into existing CRD identity data. Reads in the API and agency dashboard use the same creator state. This is not removal/replacement of the complete alias or platform collection. Identical retries are safe for these additive/set operations.
creators:writeParameters
idpathrequiredRequest body
display_namestringMaximum 160 characters.
aliasesarray[]Pseudonyms, alternate spellings, and usernames without a required social-network label. Merged into the native CRD search aliases.
Up to 30 items.
profile_urlsarray[]Full canonical HTTPS profile URLs using the same creator-platform rules as the portal. CRD derives the platform and username. Supports the portal platform catalog, X/Twitter aliases and RevealMe (reveal.me). Unknown public HTTPS hosts are stored as website profiles, not newly supported social platforms. No tracking query, fragment, credentials, private host or post URL. These links do not prove account ownership.
Up to 20 items.
Response
Returns 200 on success.
idstringrequiredworkspace_idstringrequiredexternal_idstringrequireddisplay_namestringrequiredaliasesarray[]requiredprofile_urlsarray[]requiredFull canonical HTTPS profile URLs using the same creator-platform rules as the portal. CRD derives the platform and username. Supports the portal platform catalog, X/Twitter aliases and RevealMe (reveal.me). Unknown public HTTPS hosts are stored as website profiles, not newly supported social platforms. No tracking query, fragment, credentials, private host or post URL. These links do not prove account ownership.
protection_statusstringrequiredAPI schedule state, separate from enrollment and eligibility. Activation and resumption require an explicit protection PUT after current eligibility checks.
Values: not_activated active paused
created_atintegerrequiredUnix epoch milliseconds.
enrollment_statusstringrequiredCurrent CRD linkage state, for example invited, pending_onboarding, linked, enrolling, failed, or uncertain.
crd_user_idstring | nullrequiredinvitation_idstring | nullrequiredsimulatedbooleanrequiredAlways false.
scan_schedule_managed_bystringrequiredLegacy response field. The API controls its active-protection setting and on-demand scan eligibility; the existing CRD plan controls recurring scans.
Always api.
crd_subscription_managed_bystringrequiredAlways 'crd': the creator's actual CRD subscription and its own automatic scan cadence are managed entirely by CRD, independent of this API's protection_status.
Always crd.
email_sentbooleanPresent on a new enrollment response. True means the email provider accepted the invitation email; it does not prove inbox delivery, acceptance, authorization, or activation.
authorizationobjectrequiredShow nested fields
approvedbooleanrequiredstatusstringexpires_atstring | nullentitlementobjectrequiredShow nested fields
activebooleanrequiredsourcestringeligiblebooleanrequiredidentity_sync_pendingbooleanrequiredTrue when an accepted invitation still needs legal onboarding before its submitted identity data can be applied.
Retries & errors
Omitted fields stay unchanged. Aliases and platforms merge into the existing CRD identity. Repeating the same update does not add duplicate identity entries.
Documented statuses: 200, 400, 401, 403, 404, 409, 413, 415, 429, 502, 503, 504. Error handling guide
/v1/creators/{id}curl --request PATCH 'https://api.crd.systems/v1/creators/crt_example' \
--header "Authorization: Bearer $CRD_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"display_name": "Example Creator",
"aliases": [
"example_creator_official"
],
"profile_urls": [
"https://mym.fans/fr/example_mym"
]
}'{
"id": "crt_example",
"workspace_id": "wsp_example",
"external_id": "creator_001",
"display_name": "Example Creator",
"aliases": [
"example_creator",
"example_creator_official"
],
"profile_urls": [
"https://onlyfans.com/example_creator",
"https://mym.fans/example_mym"
],
"protection_status": "not_activated",
"created_at": 1790035200000,
"enrollment_status": "linked",
"crd_user_id": "33333333-3333-4333-8333-333333333333",
"invitation_id": null,
"simulated": false,
"scan_schedule_managed_by": "api",
"crd_subscription_managed_by": "crd",
"identity_sync_pending": false,
"authorization": {
"approved": true,
"status": "approved",
"expires_at": null
},
"entitlement": {
"active": true,
"source": "agency_subscription"
},
"eligible": true
}Cancel an invitation or remove incomplete onboarding
Requires creators:write. Pending API invitations are cancelled. Linked creators can be detached only before onboarding completes, matching agency-remove-member. Removes agency membership and pauses API protection; never deletes the user, leaks or legal records. Completed onboarding returns creator_onboarding_completed. Retries after successful detachment are safe.
creators:writeParameters
idpathrequiredResponse
Returns 200 on success.
cancelledbooleanremovedbooleanRetries & errors
Cancels a pending invitation or detaches an accepted creator before onboarding completes. Completed creators return 409 creator_onboarding_completed. User and legal/leak records are retained. Cancelling a pending invitation frees its external ID for a fresh enrollment.
Documented statuses: 200, 400, 401, 403, 404, 409, 429, 502, 503, 504. Error handling guide
/v1/creators/{id}curl --request DELETE 'https://api.crd.systems/v1/creators/crt_example' \
--header "Authorization: Bearer $CRD_API_KEY"{
"cancelled": true
}Activate or pause API protection
Requires protection:write. Read creator.billing.model first. For active_creators, activation or pause changes the agency subscription and recurring protection in both systems. Supply expected_price_cents from the corresponding creator.billing activation or pause quote and a stable UUID Idempotency-Key. First activation returns 202 with checkout_url; the owner must complete checkout. One seven-day trial per agency. Use billing.activation_quote.unit_price_cents or billing.pause_quote.unit_price_cents and confirm its monthly_total_cents. Pricing is EUR 69 each for 1–9 active creators, EUR 59 each for every creator from 10. Changes recalculate the entire roster with proration: increases invoice immediately outside trial; decreases credit the next invoice. Moving from 10 to 9 increases the total from EUR 590 to EUR 621. A paid current invoice is required before credits. Never retry with a new key after an uncertain response. For legacy agreements, this route controls API dispatch only and does not change subscription billing. Current agency KYC, membership, signed agency agreement and creator mandate are enforced. Enrollment alone is free and inactive. Separately negotiated graduated agreements retain their private rates. For pricing_model=graduated, unit_price_cents is the base confirmation rate; always use monthly_total_cents for the total, never multiply quantity by that base. No repeat trial after a prepaid transition.
protection:writeParameters
idpathrequiredIdempotency-KeyheaderRequired UUID for active_creators billing; reuse for the identical request until reconciled.
Request body
statusstringrequiredValues: active paused
expected_price_centsintegerRequired for active_creators billing. Monthly EUR price in cents explicitly approved for this change.
expected_quantityintegerConfirm activation_quote.quantity or pause_quote.quantity to reject a stale roster total.
Maximum: 1000.
Response
Returns 202 on success.
statusstringrequiredValues: checkout payment_pending
checkout_urlstring | nulloperation_idstringrequiredRetries & errors
For active_creators, get owner approval of the current creator.billing.activation_quote.unit_price_cents (or pause_quote.unit_price_cents when pausing) and use a stable UUID Idempotency-Key. Retry the identical key and body after uncertainty. Complete checkout, then read the creator to confirm activation. Legacy agreements retain the API-dispatch-only switch without a price field.
Documented statuses: 200, 202, 400, 401, 403, 404, 409, 413, 415, 429, 502, 503, 504. Error handling guide
/v1/creators/{id}/protectioncurl --request PUT 'https://api.crd.systems/v1/creators/crt_example/protection' \
--header "Authorization: Bearer $CRD_API_KEY" \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: example-request-001' \
--data '{
"status": "active",
"expected_price_cents": 6900
}'{
"status": "checkout",
"operation_id": "77777777-7777-4777-8777-777777777777",
"checkout_url": "https://checkout.stripe.com/example"
}Queue a real CRD scan
Requires scans:write and active API protection. Returns before completion. Idempotency-Key is agency-wide for scan requests. Replays preserve the exact engine request identity; uncertain dispatch is reconciled rather than duplicated. Scans use actual CRD reporting workflows and can have real effects.
scans:writeParameters
idpathrequiredIdempotency-KeyheaderrequiredStable key for one logical operation. Reuse unchanged for retries.
Request body
Send an empty JSON object: {}.
Response
Returns 202 on success.
idstringrequiredcreator_idstringrequiredstatusstringrequiredValues: queued dispatching running uncertain completed failed cancelled
sourcestringrequiredValues: manual scheduled
created_atintegerrequiredUnix epoch milliseconds.
finished_atinteger | nullrequiredUnix epoch milliseconds, or null.
error_codestring | nullrequiredcrd_job_idstring | nullrequiredsimulatedbooleanrequiredAlways false.
Retries & errors
Use one Idempotency-Key per logical scan and preserve it across retries. A matching retry returns 200 with the original scan. Reconcile uncertain state rather than creating replacement work.
Documented statuses: 200, 202, 400, 401, 403, 404, 409, 413, 415, 429, 502, 503, 504. Error handling guide
/v1/creators/{id}/scanscurl --request POST 'https://api.crd.systems/v1/creators/crt_example/scans' \
--header "Authorization: Bearer $CRD_API_KEY" \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: example-request-001' \
--data '{}'{
"id": "scn_example",
"creator_id": "crt_example",
"status": "queued",
"source": "manual",
"created_at": 1790035200000,
"finished_at": null,
"error_code": null,
"crd_job_id": null,
"simulated": false
}Read real scan progress
Requires scans:read. Follow queued/running work through completed, failed, or cancelled. dispatching and uncertain mean provider reconciliation is in progress; do not replace the logical request.
scans:readParameters
idpathrequiredResponse
Returns 200 on success.
idstringrequiredcreator_idstringrequiredstatusstringrequiredValues: queued dispatching running uncertain completed failed cancelled
sourcestringrequiredValues: manual scheduled
created_atintegerrequiredUnix epoch milliseconds.
finished_atinteger | nullrequiredUnix epoch milliseconds, or null.
error_codestring | nullrequiredcrd_job_idstring | nullrequiredsimulatedbooleanrequiredAlways false.
Retries & errors
This read can be retried with exponential backoff. Honor Retry-After when it is returned.
Documented statuses: 200, 400, 401, 403, 404, 409, 429, 502, 503, 504. Error handling guide
/v1/scans/{id}curl --request GET 'https://api.crd.systems/v1/scans/scn_example' \
--header "Authorization: Bearer $CRD_API_KEY"{
"id": "scn_example",
"creator_id": "crt_example",
"status": "completed",
"source": "manual",
"created_at": 1790035200000,
"finished_at": 1790035201000,
"error_code": null,
"crd_job_id": "44444444-4444-4444-8444-444444444444",
"simulated": false
}Read the creator’s native CRD findings
Requires cases:read. Synchronizes existing native CRD leak records for this current agency creator, including manual, scheduled, historical, and API-scan findings. API IDs are stable; status changes are refreshed. Native records without known API-scan provenance have scan_id null and source crd. Use limit up to 100 and after from this creator’s authorized results. Only verified API-scan findings can use the API deindex route.
cases:readParameters
idpathrequiredlimitqueryafterqueryLast case ID in this creator’s authorized collection.
Response
Returns 200 on success.
dataarray[]requiredShow nested fields
idstringrequiredscan_idstring | nullrequiredKnown API scan ID, or null for a native CRD case without API-scan provenance.
creator_idstringrequiredstatusstringrequiredCurrent native CRD finding state observed during synchronization, not a removal confirmation.
urlstringrequiredThe finding URL from the creator’s current native CRD leak record.
simulatedbooleanrequiredAlways false.
created_atintegerrequiredUnix epoch milliseconds.
sourcestringrequiredcrd for native findings without known API-scan provenance; api_scan when a verified API scan mapping exists.
Values: crd api_scan
leak_idstringrequiredThe underlying native CRD leak record ID. Use the API case id in public API paths.
updated_atintegerrequiredNative update time in epoch milliseconds, or the imported creation time until native state is observed.
actionableboolean | nullrequiredNative actionability flag when synchronized; null if not yet observed.
dead_on_arrivalboolean | nullrequiredNative dead-on-arrival flag when synchronized; null if not yet observed.
availablebooleanrequiredWhether the synchronized native record remains available. Removal is observed after complete reconciliation.
api_deindex_supportedbooleanrequiredWhether known API-scan provenance supports the API deindex route. Current authorization and entitlement are checked separately.
escalationobject | nullrequiredLatest observed eligibility for paid escalation. Only CRD-selected leaks qualify. Null means not yet synchronized. Revalidated from current CRD records when quoting and reserving payment.
Show nested fields
eligiblebooleanrequiredreasonstring | nullrequiredsitestringrequiredbase_amount_centsintegerrequiredcurrencystringrequiredAlways eur.
mandate_requiredbooleanrequireddomainstring | nullWebsite hostname without www. Use this exact value to group display rows; this is not escalation billing grouping.
favicon_urlstring | nullGoogle favicon URL, matching the portal. Load with an image fallback; fetching it uses a third-party service.
status_codestringValues: detected reported in_progress manual_review escalation_required removed unknown
next_cursorstring | nullrequiredRetries & errors
This read can be retried with exponential backoff. Honor Retry-After when it is returned.
Documented statuses: 200, 400, 401, 403, 404, 409, 429, 502, 503, 504. Error handling guide
/v1/creators/{id}/casescurl --request GET 'https://api.crd.systems/v1/creators/crt_example/cases?limit=25' \
--header "Authorization: Bearer $CRD_API_KEY"{
"data": [
{
"domain": "example.invalid",
"favicon_url": "https://www.google.com/s2/favicons?domain=example.invalid&sz=64",
"status_code": "detected",
"id": "case_example",
"scan_id": "scn_example",
"creator_id": "crt_example",
"status": "À faire",
"url": "https://example.invalid/illustrative-finding",
"simulated": false,
"created_at": 1790035200000,
"source": "api_scan",
"leak_id": "55555555-5555-4555-8555-555555555555",
"updated_at": 1790035200000,
"actionable": true,
"dead_on_arrival": false,
"available": true,
"api_deindex_supported": true,
"escalation": {
"eligible": false,
"reason": "not_selected_by_crd",
"site": "example.invalid",
"base_amount_cents": 80000,
"currency": "eur",
"mandate_required": false
}
}
],
"next_cursor": null
}Report a leak or impersonation account you already found
Requires cases:write. For a URL the integration already knows about, instead of waiting for the next scan to find it. A known social platform (Instagram, TikTok, X/Twitter, Facebook, Reddit, Telegram) is filed as an impersonation account; anything else is filed as a leak and flows into the same removal process a scan-found leak does. Reporting the same URL again returns the existing record (200) rather than creating a duplicate (201). A reported leak later appears through GET on this same path; a reported impersonation account does not yet have a read endpoint of its own — this response is the only confirmation. Reporting requires current creator authorization and entitlement. The returned id is a native CRD UUID, not a case_ API ID. For a leak, read the cases collection and match the URL to obtain its API ID. Follow impersonation status in the agency portal; no impersonation status endpoint or event stream is exposed.
cases:writeParameters
idpathrequiredRequest body
urlstringrequiredAn https:// URL. No credentials in the URL.
descriptionstringMaximum 2000 characters.
severitystringLeaks only; ignored for an impersonation account. Defaults to Modéré.
Values: Critique Modéré
Response
Returns 201 on success.
idstringrequiredNative CRD leak or impersonation-account UUID. It is not the case_ API ID. Match a reported leak by URL in GET /v1/creators/{id}/cases before subsequent case operations.
typestringrequiredValues: leak impersonation
creator_idstringrequiredRetries & errors
Reporting the same URL again is harmless: it returns the existing record with 200 instead of a duplicate. This id is a native CRD identifier, not the API case id — for a leak, do not use it in a later escalation request. Use the case_… id from GET .../cases instead, matching on url, once synchronization has picked it up.
Documented statuses: 200, 201, 400, 401, 403, 404, 409, 413, 415, 429, 502, 503, 504. Error handling guide
/v1/creators/{id}/casescurl --request POST 'https://api.crd.systems/v1/creators/crt_example/cases' \
--header "Authorization: Bearer $CRD_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"url": "https://example.invalid/reported-leak",
"description": "Reported by the integration"
}'{
"id": "55555555-5555-4555-8555-555555555555",
"type": "leak",
"creator_id": "crt_example"
}Read this creator's whitelisted domains
Requires creators:read. Domains that never become a leak or an impersonation account for this creator — her own scope plus any CRD added globally for every creator. Reading needs only current agency membership, not a valid mandate or entitlement.
creators:readParameters
idpathrequiredResponse
Returns 200 on success.
dataarray[]requiredShow nested fields
idstringrequireddomainstringrequiredscopestringrequiredcreator: only for this creator. global: CRD added it for every creator; it cannot be removed through this API.
Values: creator global
created_atstringrequiredcreatedbooleanPresent only on the add response: true for a newly whitelisted domain, false if it was already there.
Retries & errors
This read can be retried with exponential backoff. Honor Retry-After when it is returned.
Documented statuses: 200, 400, 401, 403, 404, 409, 502, 503. Error handling guide
/v1/creators/{id}/whitelistcurl --request GET 'https://api.crd.systems/v1/creators/crt_example/whitelist' \
--header "Authorization: Bearer $CRD_API_KEY"{
"data": [
{
"id": "wl_example",
"domain": "licensed-reseller.example",
"scope": "creator",
"created_at": "2026-09-01T00:00:00.000Z"
}
]
}Whitelist a domain for this creator
Requires creators:write and current agency membership. Stores a hostname-level exclusion in the existing CRD whitelist; it is not an account-level exemption. Never whitelist a shared social platform to mark one official profile: add that profile to profile_urls instead. Identical repeats return 200 with the existing entry rather than a duplicate (201). Only creator-scoped entries can be removed through the API.
creators:writeParameters
idpathrequiredRequest body
domainstringrequiredA bare domain (site.com) or a full URL — either normalizes to the same hostname.
Maximum 253 characters.
Response
Returns 201 on success.
idstringrequireddomainstringrequiredscopestringrequiredcreator: only for this creator. global: CRD added it for every creator; it cannot be removed through this API.
Values: creator global
created_atstringrequiredcreatedbooleanPresent only on the add response: true for a newly whitelisted domain, false if it was already there.
Retries & errors
Whitelisting the same domain again is harmless: it returns the existing entry with 200 (created: false) instead of a duplicate. Only the hostname is stored, not a path — never whitelist a shared social-platform hostname (instagram.com and similar) to mark one official account; that would also suppress a real impersonator there. Put their own social profiles in profile_urls instead.
Documented statuses: 200, 201, 400, 401, 403, 404, 409, 413, 415, 502, 503. Error handling guide
/v1/creators/{id}/whitelistcurl --request POST 'https://api.crd.systems/v1/creators/crt_example/whitelist' \
--header "Authorization: Bearer $CRD_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"domain": "https://licensed-reseller.example"
}'{
"id": "wl_example",
"domain": "licensed-reseller.example",
"scope": "creator",
"created_at": "2026-09-01T00:00:00.000Z",
"created": true
}Remove a whitelisted domain for this creator
Requires creators:write. Only ever acts on this creator's own entries — a global (CRD-added) entry can never be removed through this API. Removing an entry that is not there, or belongs to a different creator, is refused, not silently accepted.
creators:writeParameters
idpathrequiredidqueryrequiredThe whitelist entry's own ID (from the list or add response), not the creator's ID.
Response
Returns 200 on success.
idstringrequiredRetries & errors
This read can be retried with exponential backoff. Honor Retry-After when it is returned.
Documented statuses: 200, 400, 401, 403, 404, 409, 502, 503. Error handling guide
/v1/creators/{id}/whitelistcurl --request DELETE 'https://api.crd.systems/v1/creators/crt_example/whitelist?id=wl_example' \
--header "Authorization: Bearer $CRD_API_KEY"{
"id": "wl_example"
}Set this creator's profile photo by URL
Requires creators:write. The URL is fetched here (https only, no redirects, a size and time limit, and it must actually be an image) and stored into the same photo storage and profile field the normal sign-up photo picker writes to, so it appears wherever her photo already appears. Write-only for now: GET /v1/creators/{id} does not yet include it.
creators:writeParameters
idpathrequiredRequest body
photo_urlstringrequiredAn https:// URL to an image (JPEG, PNG, WebP, or GIF), up to 8 MB.
Maximum 2048 characters.
Response
Returns 200 on success.
photo_urlstringrequiredThe stored (not the original) address; the original is never hotlinked back.
Retries & errors
This read can be retried with exponential backoff. Honor Retry-After when it is returned.
Documented statuses: 200, 400, 401, 403, 404, 409, 413, 415, 502, 503. Error handling guide
/v1/creators/{id}/photocurl --request POST 'https://api.crd.systems/v1/creators/crt_example/photo' \
--header "Authorization: Bearer $CRD_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"photo_url": "https://cdn.example.com/creator-current-photo.jpg"
}'{
"photo_url": "https://storage.crd.systems/avatars/example/photo.jpg"
}Request CRD's paid legal-escalation service for a leak
Legacy single-case checkout: cases:read plus escalations:write required. CRD must have selected the leak for escalation and the agency must have an active signed escalation mandate. Current creator authorization, entitlement and ownership are required. Arbitrary URLs and impersonation accounts cannot be escalated. Use escalation-quotes to review a price before checkout and group several cases for site discounts. Preserve Idempotency-Key on retries; the same purchase and Stripe session are reused.
cases:readescalations:writeParameters
idpathrequiredIdempotency-KeyheaderrequiredStable key for one logical operation. Reuse unchanged for retries.
Request body
Send an empty JSON object: {}.
Response
Returns 202 on success.
idstringrequiredcase_idstringrequiredFirst API case ID; use case_ids for a grouped purchase.
creator_idstringrequiredFirst creator in the purchase; a quote can span creators in the same workspace.
statusstringrequiredqueued: awaiting dispatch. dispatching/uncertain: dispatch or reconciliation in progress; preserve the same Idempotency-Key. ready: Checkout link is available. paid: CRD recorded the payment. failed: definite rejection; resolve error_code before new work. attention_required: CRD must reconcile the request; do not create a replacement.
Values: queued dispatching uncertain ready paid failed attention_required refunded partially_refunded disputed
payment_linkstring | nullrequiredHosted Stripe Checkout URL when available, otherwise null. An expired or completed checkout may no longer have a URL. CRD computes the amount; API callers cannot set or mark up it.
amount_centsinteger | nullrequiredcurrencystring | nullrequiredsimulatedbooleanrequiredAlways false.
created_atintegerrequiredUnix epoch milliseconds.
updated_atintegerrequiredUnix epoch milliseconds.
error_codestring | nullrequiredcase_idsarray[]requiredquote_idstring | nullrequiredpricingobject | nullrequiredPaid escalation only. URLs group by CRD site/mirror-family rules across the selection. Highest-priced sites first: positions 1–2 at list, 3–4 minus 10%, 5–9 minus 20%, 10–14 minus 30%, 15+ minus 35%. A supported percentage promotion applies after the graduated discount. All monetary fields are EUR cents. leak_ids are native IDs; submit API case_ids in requests.
Show nested fields
currencystringrequiredAlways eur.
site_countintegerrequiredsubtotal_centsintegerrequiredvolume_discount_centsintegerrequiredpromo_discount_centsintegerrequiredtotal_centsintegerrequiredlinesarray[]requiredShow nested fields
sitestringrequiredleak_idsarray[]requiredbase_amount_centsintegerrequireddiscount_percentnumberrequiredMaximum: 100.
amount_centsintegerrequiredworkflowarray[]requiredNative legal work after payment. Payment state paid does not mean work completed. No private notes, documents or recipients are returned.
Show nested fields
idstringrequireduser_idstringrequiredNative CRD creator ID.
website_urlstringrequiredplatformstring | nullrequiredstatusstringrequiredupdated_atstring | nullrequiredpaymentobject | nullLatest independently reconciled Stripe payment state. A refund or dispute does not erase legal work. Null until verified.
Show nested fields
statusstringrequiredValues: pending processing paid cancelled refunded partially_refunded disputed
refunded_amount_centsintegerrequireddispute_statusstring | nullrequiredchecked_atstringrequiredRetries & errors
Preserve the Idempotency-Key for retries — a repeated request returns the same resource, never a second Checkout Session. Leaks only; an impersonation account returns 409 escalation_leaks_only.
Documented statuses: 200, 202, 400, 401, 403, 404, 409, 413, 415, 429, 502, 503, 504. Error handling guide
/v1/cases/{id}/escalation-requestscurl --request POST 'https://api.crd.systems/v1/cases/case_example/escalation-requests' \
--header "Authorization: Bearer $CRD_API_KEY" \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: example-request-001' \
--data '{}'{
"payment": null,
"case_ids": [
"case_example"
],
"quote_id": null,
"workflow": [],
"pricing": null,
"id": "esc_example",
"case_id": "case_example",
"creator_id": "crt_example",
"status": "queued",
"payment_link": null,
"amount_cents": null,
"currency": null,
"simulated": false,
"created_at": 1790035200000,
"updated_at": 1790035200000,
"error_code": null
}Read an escalation request, including its payment link
Read payment state and sanitized native escalation workflow for a purchase belonging to the agency. The same selection is checked for current agency ownership. paid means the real charge was recorded; read workflow for legal-work progress. escalation.status_changed also fires when observed workflow changes. Expired unpaid checkouts become failed with escalation_checkout_expired; request a fresh quote before retrying a purchase.
cases:readParameters
idpathrequiredResponse
Returns 200 on success.
idstringrequiredcase_idstringrequiredFirst API case ID; use case_ids for a grouped purchase.
creator_idstringrequiredFirst creator in the purchase; a quote can span creators in the same workspace.
statusstringrequiredqueued: awaiting dispatch. dispatching/uncertain: dispatch or reconciliation in progress; preserve the same Idempotency-Key. ready: Checkout link is available. paid: CRD recorded the payment. failed: definite rejection; resolve error_code before new work. attention_required: CRD must reconcile the request; do not create a replacement.
Values: queued dispatching uncertain ready paid failed attention_required refunded partially_refunded disputed
payment_linkstring | nullrequiredHosted Stripe Checkout URL when available, otherwise null. An expired or completed checkout may no longer have a URL. CRD computes the amount; API callers cannot set or mark up it.
amount_centsinteger | nullrequiredcurrencystring | nullrequiredsimulatedbooleanrequiredAlways false.
created_atintegerrequiredUnix epoch milliseconds.
updated_atintegerrequiredUnix epoch milliseconds.
error_codestring | nullrequiredcase_idsarray[]requiredquote_idstring | nullrequiredpricingobject | nullrequiredPaid escalation only. URLs group by CRD site/mirror-family rules across the selection. Highest-priced sites first: positions 1–2 at list, 3–4 minus 10%, 5–9 minus 20%, 10–14 minus 30%, 15+ minus 35%. A supported percentage promotion applies after the graduated discount. All monetary fields are EUR cents. leak_ids are native IDs; submit API case_ids in requests.
Show nested fields
currencystringrequiredAlways eur.
site_countintegerrequiredsubtotal_centsintegerrequiredvolume_discount_centsintegerrequiredpromo_discount_centsintegerrequiredtotal_centsintegerrequiredlinesarray[]requiredShow nested fields
sitestringrequiredleak_idsarray[]requiredbase_amount_centsintegerrequireddiscount_percentnumberrequiredMaximum: 100.
amount_centsintegerrequiredworkflowarray[]requiredNative legal work after payment. Payment state paid does not mean work completed. No private notes, documents or recipients are returned.
Show nested fields
idstringrequireduser_idstringrequiredNative CRD creator ID.
website_urlstringrequiredplatformstring | nullrequiredstatusstringrequiredupdated_atstring | nullrequiredpaymentobject | nullLatest independently reconciled Stripe payment state. A refund or dispute does not erase legal work. Null until verified.
Show nested fields
statusstringrequiredValues: pending processing paid cancelled refunded partially_refunded disputed
refunded_amount_centsintegerrequireddispute_statusstring | nullrequiredchecked_atstringrequiredRetries & errors
status becomes paid only once CRD's own systems have recorded the real Stripe charge, never inferred from this read.
Documented statuses: 200, 400, 401, 403, 404, 409, 429, 502, 503, 504. Error handling guide
/v1/escalation-requests/{id}curl --request GET 'https://api.crd.systems/v1/escalation-requests/esc_example' \
--header "Authorization: Bearer $CRD_API_KEY"{
"payment": null,
"case_ids": [
"case_example"
],
"quote_id": null,
"workflow": [],
"pricing": null,
"id": "esc_example",
"case_id": "case_example",
"creator_id": "crt_example",
"status": "ready",
"payment_link": "https://checkout.stripe.com/pay/cs_test_example",
"amount_cents": 80000,
"currency": "eur",
"simulated": false,
"created_at": 1790035200000,
"updated_at": 1790035200000,
"error_code": null
}Read active API protection usage
Requires usage:read. Measures active API protection in UTC creator-months. Agency API access is included in the existing agency plan. Usage is informational, not an invoice or payment confirmation. The legacy billing_basis value active_api_scan_schedule is retained for compatibility; it does not describe a separate recurring scanner.
usage:readParameters
monthqueryUTC calendar month YYYY-MM; defaults to the current month.
Response
Returns 200 on success.
monthstringrequiredperiod_startstringrequiredperiod_endstringrequiredmeasured_throughstringrequiredactive_creator_countintegerrequiredDistinct creators contributing positive active time in the measured period; not current enrollment count.
creator_secondsnumberrequiredcreator_monthsnumberrequiredestimated_subtotal_centsinteger | nullrequiredInteger minor units (cents), or null when unconfigured or not exposed to this credential.
minimum_monthly_centsinteger | nullrequiredInteger minor units (cents), or null when unconfigured or not exposed to this credential.
estimated_total_centsinteger | nullrequiredInteger minor units (cents), or null when unconfigured or not exposed to this credential.
currencystringrequiredValues: EUR USD
estimatebooleanrequiredAlways true.
simulatedbooleanrequiredAlways false.
scopestringrequiredAlways agency.
billing_basisstringrequiredLegacy field value retained for compatibility. Measures active API protection time; recurring scans remain governed by the existing CRD plan.
Always active_api_scan_schedule.
Retries & errors
This read can be retried with exponential backoff. Honor Retry-After when it is returned.
Documented statuses: 200, 400, 401, 403, 404, 409, 429, 502, 503, 504. Error handling guide
/v1/usagecurl --request GET 'https://api.crd.systems/v1/usage?month=2026-09' \
--header "Authorization: Bearer $CRD_API_KEY"{
"month": "2026-09",
"period_start": "2026-09-01T00:00:00.000Z",
"period_end": "2026-10-01T00:00:00.000Z",
"measured_through": "2026-09-16T00:00:00.000Z",
"active_creator_count": 1,
"creator_seconds": 1296000,
"creator_months": 0.5,
"estimated_subtotal_cents": null,
"minimum_monthly_cents": null,
"estimated_total_cents": null,
"currency": "EUR",
"estimate": true,
"simulated": false,
"scope": "agency",
"billing_basis": "active_api_scan_schedule"
}Recover your agency event stream
Requires events:read. Events are in insertion order and share IDs with signed webhook deliveries. Retain the last event ID for later polling even when next_cursor is null. The catalog covers API-linked current agency creators, synchronized native leak records, API protection, API scans, and API-created CRD deindex and legal-escalation requests. Creator, case, and eligibility updates reflect state observed on reads or periodic worker reconciliation, not every intermediate database edit. There are no impersonation-status, invoice-paid, KYC-approved or dedicated mandate-approved events. Webhook receivers are registered in the authenticated agency dashboard, not through a /v1/webhooks route.
events:readParameters
limitqueryafterqueryLast event ID from this authorized stream.
Response
Returns 200 on success.
dataarray[]requiredShow nested fields
idstringrequiredtypestringrequiredValues: protection.activated protection.paused scan.completed scan.failed case.created escalation.status_changed creator.updated case.updated case.deleted impersonation.created impersonation.updated impersonation.deleted
workspace_idstringrequiredcreated_atintegerrequiredUnix epoch milliseconds.
simulatedbooleanrequiredAlways false.
dataobjectrequiredShow nested fields
creator_idstringrequiredscan_idstringcase_idstringcrd_job_idstringstatusstringreasonstringscopestringAlways api_scan_schedule.
escalation_request_idstringcreatorobjectShow nested fields
idstringrequiredworkspace_idstringrequiredexternal_idstringrequireddisplay_namestringrequiredaliasesarray[]requiredprofile_urlsarray[]requiredFull canonical HTTPS profile URLs using the same creator-platform rules as the portal. CRD derives the platform and username. Supports the portal platform catalog, X/Twitter aliases and RevealMe (reveal.me). Unknown public HTTPS hosts are stored as website profiles, not newly supported social platforms. No tracking query, fragment, credentials, private host or post URL. These links do not prove account ownership.
protection_statusstringrequiredAPI schedule state, separate from enrollment and eligibility. Activation and resumption require an explicit protection PUT after current eligibility checks.
Values: not_activated active paused
created_atintegerrequiredUnix epoch milliseconds.
enrollment_statusstringrequiredCurrent CRD linkage state, for example invited, pending_onboarding, linked, enrolling, failed, or uncertain.
crd_user_idstring | nullrequiredinvitation_idstring | nullrequiredsimulatedbooleanrequiredAlways false.
scan_schedule_managed_bystringrequiredLegacy response field. The API controls its active-protection setting and on-demand scan eligibility; the existing CRD plan controls recurring scans.
Always api.
crd_subscription_managed_bystringrequiredAlways 'crd': the creator's actual CRD subscription and its own automatic scan cadence are managed entirely by CRD, independent of this API's protection_status.
Always crd.
email_sentbooleanPresent on a new enrollment response. True means the email provider accepted the invitation email; it does not prove inbox delivery, acceptance, authorization, or activation.
authorizationobjectrequiredentitlementobjectrequiredeligiblebooleanrequiredidentity_sync_pendingbooleanrequiredTrue when an accepted invitation still needs legal onboarding before its submitted identity data can be applied.
caseobjectShow nested fields
idstringrequiredscan_idstring | nullrequiredKnown API scan ID, or null for a native CRD case without API-scan provenance.
creator_idstringrequiredstatusstringrequiredCurrent native CRD finding state observed during synchronization, not a removal confirmation.
urlstringrequiredThe finding URL from the creator’s current native CRD leak record.
simulatedbooleanrequiredAlways false.
created_atintegerrequiredUnix epoch milliseconds.
sourcestringrequiredcrd for native findings without known API-scan provenance; api_scan when a verified API scan mapping exists.
Values: crd api_scan
leak_idstringrequiredThe underlying native CRD leak record ID. Use the API case id in public API paths.
updated_atintegerrequiredNative update time in epoch milliseconds, or the imported creation time until native state is observed.
actionableboolean | nullrequiredNative actionability flag when synchronized; null if not yet observed.
dead_on_arrivalboolean | nullrequiredNative dead-on-arrival flag when synchronized; null if not yet observed.
availablebooleanrequiredWhether the synchronized native record remains available. Removal is observed after complete reconciliation.
api_deindex_supportedbooleanrequiredWhether known API-scan provenance supports the API deindex route. Current authorization and entitlement are checked separately.
escalationobject | nullrequiredLatest observed eligibility for paid escalation. Only CRD-selected leaks qualify. Null means not yet synchronized. Revalidated from current CRD records when quoting and reserving payment.
domainstring | nullWebsite hostname without www. Use this exact value to group display rows; this is not escalation billing grouping.
favicon_urlstring | nullGoogle favicon URL, matching the portal. Load with an image fallback; fetching it uses a third-party service.
status_codestringValues: detected reported in_progress manual_review escalation_required removed unknown
error_codestringPresent on some terminal scan, deindex or escalation events. Refresh the resource for its current error and state.
impersonation_idstringimpersonationobjectShow nested fields
idstringrequiredcreator_idstringrequiredurlstringrequiredusernamestring | nullrequiredplatformstringrequiredtypestringrequiredstatusstringrequiredcreated_atintegerrequiredupdated_atintegerrequiredreported_atinteger | nullrequiredremoved_atinteger | nullrequireddomainstring | nullrequiredWebsite hostname without www. Use this exact value to group display rows; this is not escalation billing grouping.
favicon_urlstring | nullrequiredGoogle favicon URL, matching the portal. Load with an image fallback; fetching it uses a third-party service.
next_cursorstring | nullrequiredLast ID for the next page, or null. Retain the last returned event ID for subsequent polling.
Retries & errors
This read can be retried with exponential backoff. Honor Retry-After when it is returned.
Documented statuses: 200, 400, 401, 403, 404, 409, 429, 502, 503, 504. Error handling guide
/v1/eventscurl --request GET 'https://api.crd.systems/v1/events?limit=25' \
--header "Authorization: Bearer $CRD_API_KEY"{
"data": [
{
"id": "evt_example",
"type": "scan.completed",
"workspace_id": "wsp_example",
"created_at": 1790035200000,
"simulated": false,
"data": {
"creator_id": "crt_example",
"scan_id": "scn_example",
"crd_job_id": "44444444-4444-4444-8444-444444444444"
}
}
],
"next_cursor": null
}Quote selected escalation cases
Requires cases:read and escalations:write. Select 1–100 distinct API case IDs in one workspace. CRD reloads native cases, verifies ownership and its escalation selection, checks the active signed agency escalation mandate, groups sites and applies current graduated pricing. Returns a quote valid for 15 minutes without reserving or charging a payment. Separate quotes are safe; only checkout creates a purchase.
cases:readescalations:writeRequest body
case_idsarray[]requiredUp to 100 items.
promo_codestringOptional active, unrestricted percentage promotion. Fixed-amount, product-limited, customer-first-use, minimum-spend and redemption-limited promotions are not supported.
Maximum 100 characters.
Response
Returns 201 on success.
idstringrequiredcase_idsarray[]requiredexpires_atstringrequiredexpiredbooleanrequiredpricingobjectrequiredPaid escalation only. URLs group by CRD site/mirror-family rules across the selection. Highest-priced sites first: positions 1–2 at list, 3–4 minus 10%, 5–9 minus 20%, 10–14 minus 30%, 15+ minus 35%. A supported percentage promotion applies after the graduated discount. All monetary fields are EUR cents. leak_ids are native IDs; submit API case_ids in requests.
Show nested fields
currencystringrequiredAlways eur.
site_countintegerrequiredsubtotal_centsintegerrequiredvolume_discount_centsintegerrequiredpromo_discount_centsintegerrequiredtotal_centsintegerrequiredlinesarray[]requiredShow nested fields
sitestringrequiredleak_idsarray[]requiredbase_amount_centsintegerrequireddiscount_percentnumberrequiredMaximum: 100.
amount_centsintegerrequiredmandate_statusstringrequiredAlways signed.
Retries & errors
Quoting does not reserve or charge payment. Show the returned total, then create checkout for that quote after manager approval.
Documented statuses: 201, 400, 401, 403, 404, 409, 413, 415, 429, 502, 503, 504. Error handling guide
/v1/escalation-quotescurl --request POST 'https://api.crd.systems/v1/escalation-quotes' \
--header "Authorization: Bearer $CRD_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"case_ids": [
"case_example"
]
}'{
"id": "66666666-6666-4666-8666-666666666666",
"case_ids": [
"case_example"
],
"expires_at": "2026-09-22T00:15:00.000Z",
"expired": false,
"pricing": {
"currency": "eur",
"site_count": 1,
"subtotal_cents": 80000,
"volume_discount_cents": 0,
"promo_discount_cents": 0,
"total_cents": 80000,
"lines": [
{
"site": "example.invalid",
"leak_ids": [
"55555555-5555-4555-8555-555555555555"
],
"base_amount_cents": 80000,
"discount_percent": 0,
"amount_cents": 80000
}
]
},
"mandate_status": "signed"
}Read a saved escalation quote
Requires cases:read. Rechecks current creator membership. An expired quote remains readable but cannot create a new purchase.
cases:readParameters
idpathrequiredResponse
Returns 200 on success.
idstringrequiredcase_idsarray[]requiredexpires_atstringrequiredexpiredbooleanrequiredpricingobjectrequiredPaid escalation only. URLs group by CRD site/mirror-family rules across the selection. Highest-priced sites first: positions 1–2 at list, 3–4 minus 10%, 5–9 minus 20%, 10–14 minus 30%, 15+ minus 35%. A supported percentage promotion applies after the graduated discount. All monetary fields are EUR cents. leak_ids are native IDs; submit API case_ids in requests.
Show nested fields
currencystringrequiredAlways eur.
site_countintegerrequiredsubtotal_centsintegerrequiredvolume_discount_centsintegerrequiredpromo_discount_centsintegerrequiredtotal_centsintegerrequiredlinesarray[]requiredShow nested fields
sitestringrequiredleak_idsarray[]requiredbase_amount_centsintegerrequireddiscount_percentnumberrequiredMaximum: 100.
amount_centsintegerrequiredmandate_statusstringrequiredAlways signed.
Retries & errors
An expired quote stays readable. Requote for a new purchase; recover an existing checkout with its original idempotency key.
Documented statuses: 200, 400, 401, 403, 404, 409, 413, 415, 429, 502, 503, 504. Error handling guide
/v1/escalation-quotes/{id}curl --request GET 'https://api.crd.systems/v1/escalation-quotes/66666666-6666-4666-8666-666666666666' \
--header "Authorization: Bearer $CRD_API_KEY"{
"id": "66666666-6666-4666-8666-666666666666",
"case_ids": [
"case_example"
],
"expires_at": "2026-09-22T00:15:00.000Z",
"expired": false,
"pricing": {
"currency": "eur",
"site_count": 1,
"subtotal_cents": 80000,
"volume_discount_cents": 0,
"promo_discount_cents": 0,
"total_cents": 80000,
"lines": [
{
"site": "example.invalid",
"leak_ids": [
"55555555-5555-4555-8555-555555555555"
],
"base_amount_cents": 80000,
"discount_percent": 0,
"amount_cents": 80000
}
]
},
"mandate_status": "signed"
}Create checkout for an approved quote
Requires cases:read and escalations:write, an unchanged server-issued quote and a stable Idempotency-Key. Returns queued; poll the escalation request for the Stripe link. Eligibility, mandate, ownership and quoted prices are revalidated before reservation. A changed selection or price requires a fresh quote and user review. No price can be supplied by the caller. New keys cannot purchase an already-reserved case again. Retry the original key for uncertain results.
cases:readescalations:writeParameters
idpathrequiredIdempotency-KeyheaderrequiredStable key for one logical operation. Reuse unchanged for retries.
Request body
Send an empty JSON object: {}.
Response
Returns 202 on success.
idstringrequiredcase_idstringrequiredFirst API case ID; use case_ids for a grouped purchase.
creator_idstringrequiredFirst creator in the purchase; a quote can span creators in the same workspace.
statusstringrequiredqueued: awaiting dispatch. dispatching/uncertain: dispatch or reconciliation in progress; preserve the same Idempotency-Key. ready: Checkout link is available. paid: CRD recorded the payment. failed: definite rejection; resolve error_code before new work. attention_required: CRD must reconcile the request; do not create a replacement.
Values: queued dispatching uncertain ready paid failed attention_required refunded partially_refunded disputed
payment_linkstring | nullrequiredHosted Stripe Checkout URL when available, otherwise null. An expired or completed checkout may no longer have a URL. CRD computes the amount; API callers cannot set or mark up it.
amount_centsinteger | nullrequiredcurrencystring | nullrequiredsimulatedbooleanrequiredAlways false.
created_atintegerrequiredUnix epoch milliseconds.
updated_atintegerrequiredUnix epoch milliseconds.
error_codestring | nullrequiredcase_idsarray[]requiredquote_idstring | nullrequiredpricingobject | nullrequiredPaid escalation only. URLs group by CRD site/mirror-family rules across the selection. Highest-priced sites first: positions 1–2 at list, 3–4 minus 10%, 5–9 minus 20%, 10–14 minus 30%, 15+ minus 35%. A supported percentage promotion applies after the graduated discount. All monetary fields are EUR cents. leak_ids are native IDs; submit API case_ids in requests.
Show nested fields
currencystringrequiredAlways eur.
site_countintegerrequiredsubtotal_centsintegerrequiredvolume_discount_centsintegerrequiredpromo_discount_centsintegerrequiredtotal_centsintegerrequiredlinesarray[]requiredShow nested fields
sitestringrequiredleak_idsarray[]requiredbase_amount_centsintegerrequireddiscount_percentnumberrequiredMaximum: 100.
amount_centsintegerrequiredworkflowarray[]requiredNative legal work after payment. Payment state paid does not mean work completed. No private notes, documents or recipients are returned.
Show nested fields
idstringrequireduser_idstringrequiredNative CRD creator ID.
website_urlstringrequiredplatformstring | nullrequiredstatusstringrequiredupdated_atstring | nullrequiredpaymentobject | nullLatest independently reconciled Stripe payment state. A refund or dispute does not erase legal work. Null until verified.
Show nested fields
statusstringrequiredValues: pending processing paid cancelled refunded partially_refunded disputed
refunded_amount_centsintegerrequireddispute_statusstring | nullrequiredchecked_atstringrequiredRetries & errors
Keep the same Idempotency-Key for the entire purchase. Eligibility, mandate, ownership and prices are checked again before reserving it.
Documented statuses: 200, 202, 400, 401, 403, 404, 409, 413, 415, 429, 502, 503, 504. Error handling guide
/v1/escalation-quotes/{id}/checkoutcurl --request POST 'https://api.crd.systems/v1/escalation-quotes/66666666-6666-4666-8666-666666666666/checkout' \
--header "Authorization: Bearer $CRD_API_KEY" \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: example-request-001' \
--data '{}'{
"payment": null,
"case_ids": [
"case_example"
],
"quote_id": "66666666-6666-4666-8666-666666666666",
"workflow": [],
"pricing": null,
"id": "esc_example",
"case_id": "case_example",
"creator_id": "crt_example",
"status": "queued",
"payment_link": null,
"amount_cents": null,
"currency": null,
"simulated": false,
"created_at": 1790035200000,
"updated_at": 1790035200000,
"error_code": null
}Read creator impersonation cases
Requires cases:read. Lists the same native impersonation records as the portal. Poll or use impersonation.created/updated/deleted. IDs are native UUIDs; private descriptions, notes and contacts are excluded.
cases:readParameters
idpathrequiredlimitqueryafterqueryUse this collection’s returned next_cursor unchanged.
Response
Returns 200 on success.
dataarray[]requiredShow nested fields
idstringrequiredcreator_idstringrequiredurlstringrequiredusernamestring | nullrequiredplatformstringrequiredtypestringrequiredstatusstringrequiredcreated_atintegerrequiredupdated_atintegerrequiredreported_atinteger | nullrequiredremoved_atinteger | nullrequireddomainstring | nullrequiredWebsite hostname without www. Use this exact value to group display rows; this is not escalation billing grouping.
favicon_urlstring | nullrequiredGoogle favicon URL, matching the portal. Load with an image fallback; fetching it uses a third-party service.
next_cursorstring | nullrequiredRetries & errors
This read can be retried with exponential backoff. Honor Retry-After when it is returned.
Documented statuses: 200, 400, 401, 403, 404, 409, 429, 502, 503, 504. Error handling guide
/v1/creators/{id}/impersonationscurl --request GET 'https://api.crd.systems/v1/creators/crt_example/impersonations' \
--header "Authorization: Bearer $CRD_API_KEY"{
"data": [
{
"id": "77777777-7777-4777-8777-777777777777",
"creator_id": "crt_example",
"url": "https://instagram.com/example_fake",
"username": "example_fake",
"platform": "instagram",
"type": "impersonation",
"status": "reported",
"created_at": 1790035200000,
"updated_at": 1790035200000,
"reported_at": 1790035200000,
"removed_at": null,
"domain": "instagram.com",
"favicon_url": "https://www.google.com/s2/favicons?domain=instagram.com&sz=64"
}
],
"next_cursor": null
}Read customer-safe creator activity
Requires cases:read. Newest first, with an opaque after cursor. Includes detections, sent notices and recorded removals. leak.status is the CURRENT status timestamped by record_updated, not a fabricated historical transition. Historical intermediate changes are not reconstructed. Notice rows reflect recorded sends, not proof of recipient delivery. No private notes, recipients, email bodies or legal documents.
cases:readParameters
idpathrequiredlimitqueryafterqueryUse this collection’s returned next_cursor unchanged.
Response
Returns 200 on success.
dataarray[]requiredShow nested fields
idstringrequiredcreator_idstringrequiredtypestringrequiredrecord_idstringrequiredurlstringrequiredstatusstring | nullrequiredoccurred_atintegerrequiredtimestamp_basisstringrequireddomainstring | nullrequiredWebsite hostname without www. Use this exact value to group display rows; this is not escalation billing grouping.
favicon_urlstring | nullrequiredGoogle favicon URL, matching the portal. Load with an image fallback; fetching it uses a third-party service.
next_cursorstring | nullrequiredRetries & errors
This read can be retried with exponential backoff. Honor Retry-After when it is returned.
Documented statuses: 200, 400, 401, 403, 404, 409, 429, 502, 503, 504. Error handling guide
/v1/creators/{id}/activitycurl --request GET 'https://api.crd.systems/v1/creators/crt_example/activity' \
--header "Authorization: Bearer $CRD_API_KEY"{
"data": [
{
"id": "leak_detected:55555555-5555-4555-8555-555555555555",
"creator_id": "crt_example",
"type": "leak.detected",
"record_id": "55555555-5555-4555-8555-555555555555",
"url": "https://example.invalid/illustrative-finding",
"status": "detected",
"occurred_at": 1790035200000,
"timestamp_basis": "record_created",
"domain": "example.invalid",
"favicon_url": "https://www.google.com/s2/favicons?domain=example.invalid&sz=64"
}
],
"next_cursor": null
}Read shared subscription and creator capacity
Requires usage:read. Informational snapshot of the existing agency plan, occupied and reserved slots, overflow and protection eligibility. Invitations and creator completion enforce native capacity atomically; a free slot in this response is not a reservation. No new purchase occurs.
usage:readResponse
Returns 200 on success.
planstring | nullrequiredsubscription_statusstring | nullrequiredprotection_eligiblebooleanrequiredtotal_slotsintegerrequiredoccupied_slotsintegerrequiredreserved_slotsintegerrequiredavailable_slotsintegerrequiredoverflow_slotsintegerrequiredapi_includedbooleanrequiredAlways true.
checked_atstringrequiredbilling_modelstringValues: legacy active_creators
unit_price_centsinteger | nullCurrent unit rate for the active creator count. EUR 69 for 1–9, EUR 59 each from 10 on the volume offer. For negotiated graduated pricing this is the base rate, not an average. Use monthly_total_cents and the returned tiers.
currencystringAlways EUR.
pricing_versionstringValues: flat_v1 volume_v2 graduated_39_29_v1
active_countintegermonthly_total_centsinteger | nullRetries & errors
This read can be retried with exponential backoff. Honor Retry-After when it is returned.
Documented statuses: 200, 400, 401, 403, 404, 409, 429, 502, 503, 504. Error handling guide
/v1/capacitycurl --request GET 'https://api.crd.systems/v1/capacity' \
--header "Authorization: Bearer $CRD_API_KEY"{
"plan": "growth",
"subscription_status": "active",
"protection_eligible": true,
"total_slots": 25,
"occupied_slots": 10,
"reserved_slots": 2,
"available_slots": 13,
"overflow_slots": 0,
"api_included": true,
"checked_at": "2026-09-25T00:00:00Z"
}Resend a pending API invitation
Requires creators:write and Idempotency-Key. Reuses the existing CRD invitation email and branding, rotates its link and extends expiry to seven days. Only API-created pending/expired invitations; accepted creators use portal access recovery. One resend per minute, five per 24 hours. A matching retry never sends again; delivery_status uncertain requires review, not a new key. Active invitations do not consume another slot; expired invitations must reserve capacity again.
creators:writeParameters
idpathrequiredIdempotency-KeyheaderrequiredRequest body
Send an empty JSON object: {}.
Response
Returns 200 on success.
invitation_idstringrequiredemail_sentbooleanrequireddelivery_statusstringrequiredreplayedbooleanrequiredRetries & errors
Keep the same Idempotency-Key. A replay never resends; an uncertain delivery requires review.
Documented statuses: 200, 400, 401, 403, 404, 409, 429, 502, 503, 504. Error handling guide
/v1/creators/{id}/resend-invitationcurl --request POST 'https://api.crd.systems/v1/creators/crt_example/resend-invitation' \
--header "Authorization: Bearer $CRD_API_KEY" \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: example-request-001' \
--data '{}'{
"invitation_id": "77777777-7777-4777-8777-777777777777",
"email_sent": true,
"delivery_status": "sent",
"replayed": false
}Download a page of the creator’s leak report
Requires cases:read. CSV with the same cases, domain and normalized statuses as GET cases. At most 100 rows per page. Follow X-Next-Cursor using after until the header is absent. Export all pages to build a complete report; current records are not a frozen snapshot. Deduplicate by id. Cells are quoted and spreadsheet formula prefixes escaped.
cases:readParameters
idpathrequiredlimitqueryafterqueryLast case ID in this creator’s authorized collection.
Response
Returns 200 on success.
Retries & errors
CSV response: read text, then follow X-Next-Cursor for every page. It is not a frozen export.
Documented statuses: 200, 400, 401, 403, 404, 409, 429, 502, 503, 504. Error handling guide
/v1/creators/{id}/reportcurl --request GET 'https://api.crd.systems/v1/creators/crt_example/report?limit=100' \
--header "Authorization: Bearer $CRD_API_KEY""id,creator_id,url,domain,status,status_code,created_at,updated_at\r\n"Quote bulk creator activation
Read a price quote for activating 1–50 eligible, inactive creators. Does not create a billing operation or grant protection. EUR totals include the entire resulting active roster, including the all-creator discount from 10. Requires protection:write and active_creators billing.
protection:writeRequest body
creator_idsarray[]requiredAPI creator IDs belonging to this agency/workspace, all inactive and eligible.
Up to 50 items.
Response
Returns 200 on success.
previous_quantityintegerquantityintegerrequiredunit_price_centsintegerrequiredmonthly_total_centsintegerrequiredselected_countintegerrequiredRetries & errors
This read can be retried with exponential backoff. Honor Retry-After when it is returned.
Documented statuses: 200, 400, 401, 403, 404, 409, 502, 503. Error handling guide
/v1/protection/bulk/quotecurl --request POST 'https://api.crd.systems/v1/protection/bulk/quote' \
--header "Authorization: Bearer $CRD_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"creator_ids": [
"crt_example"
]
}'{
"previous_quantity": 0,
"quantity": 1,
"selected_count": 1,
"unit_price_cents": 6900,
"monthly_total_cents": 6900
}Activate selected creators
Activate 1–50 creators in one durable billing operation after owner approval of the bulk quote. Requires protection:write. Each selected creator must remain eligible and belong to the agency. Send the approved price and quantity and a stable UUID Idempotency-Key; retry the same key and body after uncertainty. A 202 checkout response is pending: complete checkout, then read each creator to confirm active. The entire selection is committed together after confirmed billing; eligibility failure does not partially activate it. One pending billing operation per agency. Individual pause remains available through PUT /v1/creators/{id}/protection; pausing one creator never pauses the others. No bulk pause or enrollment is introduced.
protection:writeParameters
Idempotency-KeyheaderrequiredRequest body
creator_idsarray[]requiredAPI creator IDs belonging to this agency/workspace, all inactive and eligible.
Up to 50 items.
expected_price_centsintegerrequiredexpected_quantityintegerrequiredMaximum: 1000.
Response
Returns 202 on success.
statusstringoperation_idstringcheckout_urlstringRetries & errors
Save the owner-approved quote and a UUID Idempotency-Key. Retry the same key and body. Pending checkout is not active protection; confirm each creator with a fresh read.
Documented statuses: 200, 202, 400, 401, 403, 404, 409, 502, 503. Error handling guide
/v1/protection/bulkcurl --request PUT 'https://api.crd.systems/v1/protection/bulk' \
--header "Authorization: Bearer $CRD_API_KEY" \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: example-request-001' \
--data '{
"creator_ids": [
"crt_example"
],
"expected_price_cents": 6900,
"expected_quantity": 1
}'{
"status": "checkout",
"operation_id": "77777777-7777-4777-8777-777777777777",
"checkout_url": "https://checkout.stripe.com/example"
}