Hosted consent
Invite the consumer; we collect the disclosure, the authorization and their details, and place the order.
Livehttps://api.offendersearch.appSandboxhttps://sandbox.offendersearch.appHow it works
For partners we act as the consumer reporting agency for — direct (you are the end user) and platform (you order for your own clients) — the consent step can be ours to run. You invite the consumer; we e-mail them a link in your branding; they read a summary of their rights and the standalone disclosure, the notices their state adds, give their name, date of birth, other names and address history, and sign the authorization by typing their name. Completing the flow places the order with source: "invitation" and stores the signed consent as a PDF with the order’s evidence.
- Your branding is on the page and the e-mails: your name, logo and colour. The consumer reporting agency’s legal name is on the disclosure, the authorization and the footer, because the consumer must know who prepares the report and who to dispute with.
- No Social Security number is asked for anywhere, and one sent is refused. Identity verification is coming soon; until then the order is matched on the name, the full date of birth and the addresses the consumer gives.
- The link lives seven days by default (1 to 30), with one reminder after 48 hours. A resend issues a fresh link and the previous one stops working.
- A
crapartner collects consent in its own flow and places orders directly;POST /v1/fcra/invitationsanswers403 managed_tier_required.
Invite a consumer
POST /v1/fcra/invitations takes the end user and purpose, what you know of the consumer (name and e-mail), the searches, and where the job or housing is — its state picks the state notices the consumer sees. The response carries applyUrl once; it never appears on a read. Set sendEmail: false to present the link yourself inside your own product; we then send nothing. liveScope (relevant, all, or matches once enabled for your account — see Orders) is carried onto the order the consumer’s signature places; asking for matches before it is enabled is refused 422 live_scope_not_enabled.
curl -X POST "https://api.offendersearch.app/v1/fcra/invitations" \
-H "X-API-Key: $OFFENDERSEARCH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"endUserId": "eu_0b44acbeefeaa7d7",
"permissiblePurpose": "employment",
"subject": { "firstName": "Jordan", "lastName": "Rivera", "email": "jordan@example.test" },
"searches": [{ "type": "sex_offender" }, { "type": "criminal" }],
"useLocation": { "state": "CA", "city": "Fresno" },
"clientReference": "req-2026-1187",
"expiresInDays": 7
}'| Invitation status | Meaning |
|---|---|
pending | Sent (or waiting for you to present the link); nothing signed yet. |
completed | Signed. orderId is the order; consent says who signed, when, and which texts. |
expired | The link ran out. Resend is not possible; invite again. |
cancelled | You cancelled it, or the consumer declined (invitation.cancelled with reason: declined). |
Invite a consumer to the hosted consent flow — POST /v1/fcra/invitations
Creates the invitation and e-mails the consumer the link (unless sendEmail is false). applyUrl is returned once, here.
Request
| Field | Type | Description |
|---|---|---|
| endUserId required | string | The end user the report is for. Example "eu_0b44acbeefeaa7d7" |
| permissiblePurpose required | string one of "employment", "tenant_screening", "consumer_written_instructions", "legitimate_business_need" | employment, tenant_screening, consumer_written_instructions or legitimate_business_need. Sets which forms and state notices apply. |
| subject required | InviteSubject | Who to invite: a name and the e-mail the invitation goes to. The person completes the rest (date of birth, addresses) on the consent page. |
| searches required | array of SearchSpec | One to three searches (sex_offender, criminal, healthcare), each type at most once. |
| useLocation optional | UseLocation or null | Where the job, the housing or the transaction is. Its state picks the state notices the consumer sees. |
| annualSalary optional | integer or null | For employment: the salary exemption to the federal seven-year rule applies at 75,000 and above. |
| liveScope optional · default "relevant" | string one of "relevant", "all", "matches" | relevant (default) searches the places in the person's address history and where they will work or live; all searches every live source we have. matches: our stored copies are searched for the subject and a subject with no possible record is answered from them, with no live calls. Each possible record is then confirmed live at the agency that keeps it before it can be reported; a source we hold no copy of is searched live. Available when enabled for your account. |
| clientReference optional | string or null | Carried onto the order. |
| callbackUrl optional | string (uri) or null | Carried onto the order; needs a configured webhook endpoint. |
| metadata optional | object or null | Carried onto the order. |
| tags optional | array of string or null | Carried onto the order. |
| locale optional · default "en" | string one of "en", "es" | The language of the flow and the e-mails. |
| sendEmail optional · default true | boolean | false when you present applyUrl yourself (an embedded flow); we then send nothing. |
| expiresInDays optional | integer or null | 1 to 30. Default 7. |
Response
The invitation with its one-time applyUrl.
The body is the Invitation object. An invitation to the hosted consent flow and what came of it. applyUrl is present on the create and resend responses only.
| Status | Code | When |
|---|---|---|
| 401 | — | No valid X-API-Key (the body is { "detail": "…" }, a string). |
| 403 | fcra_not_enabled | This account has no active FCRA partner agreement. |
| 403 | fcra_not_on_trial | FCRA orders are not available on a trial account. |
| 403 | managed_tier_required | Your agreement names you as the CRA; collect consent in your own flow and place orders directly. |
| 403 | fcra_purpose_not_allowed | The purpose is not certified for this end user or not in your agreement. |
| 404 | unknown_end_user | No such end user on this account. |
| 422 | end_user_suspended | The end user is suspended. |
| 422 | webhook_endpoint_required | callbackUrl without a configured webhook endpoint. |
| 422 | — | A field failed validation (the standard validation body). |
The InviteSubject object — who you are inviting
What you know about the consumer. They confirm their name and give their date of birth, other names and address history in the flow. No Social Security number is asked for, here or there.
Returned or accepted by POST /v1/fcra/invitations, GET /v1/fcra/invitations, GET /v1/fcra/invitations/{invitation_id}, DELETE /v1/fcra/invitations/{invitation_id}, POST /v1/fcra/invitations/{invitation_id}/resend.
| Field | Type | Description |
|---|---|---|
| firstName required | string | The person's first name, prefilled on the consent page. They can correct it. Example "Jordan" |
| middleName optional | string or null | Middle name, if you know it. null when not. |
| lastName required | string | The person's last name, prefilled on the consent page. Example "Rivera" |
| email required | string | Where the link goes. The consumer confirms it in the flow. Example "jordan@example.test" |
| phone optional | string or null | A phone number for the person, if you have one. null when not. |
The Invitation object
An invitation to the hosted consent flow and what came of it. applyUrl is present on the create and resend responses only.
Returned or accepted by POST /v1/fcra/invitations, GET /v1/fcra/invitations, GET /v1/fcra/invitations/{invitation_id}, DELETE /v1/fcra/invitations/{invitation_id}, POST /v1/fcra/invitations/{invitation_id}/resend.
| Field | Type | Description |
|---|---|---|
| id | string | The invitation's id (inv_…).Example "fi_4c1d2e9a7b3f0c58" |
| status | string one of "pending", "completed", "expired", "cancelled" | pending until the consumer signs (completed), the link runs out (expired) or you or the consumer withdraw it (cancelled). |
| endUserId | string | Your id for the end user the report is for. |
| permissiblePurpose | string one of "employment", "tenant_screening", "consumer_written_instructions", "legitimate_business_need" | The permissible purpose the invitation was created with. |
| subject | InviteSubject | As sent, with the name as the consumer confirmed it once completed. |
| searches | array of SearchSpec | The searches the order will run once consent is in, exactly as requested. |
| useLocation | object or null | Where the person will work or live, which picks the state and city forms. null when not given. |
| useLocation.state | string | Two-letter state code. |
| useLocation.city | string or null | City, when a city ordinance applies. null otherwise. |
| annualSalary | integer or null | Expected annual salary in whole dollars, used by salary-threshold state rules. null when not given. |
| liveScope | string one of "relevant", "all", "matches" | relevant, all or matches, as requested. |
| clientReference | string or null | Your own reference for this invitation, echoed back unchanged. null when none. |
| metadata | object or null | Up to 50 string key/value pairs of your own, echoed back unchanged. null when none. |
| tags | array of string | Up to 20 tags of your own, for filtering in the dashboard. |
| locale | string | The language of the consent page and e-mails: en or es. |
| sendEmail | boolean | true when we e-mailed the invitation; false when you chose to deliver the link yourself. |
| expiresAt | string (date-time) | When the link stops working. |
| sentAt | string (date-time) or null | When the e-mail was handed to the provider. null when sendEmail was false or no provider is configured. |
| reminderSentAt | string (date-time) or null | The one reminder, 48 hours in. |
| completedAt | string (date-time) or null | When the person signed. null until then. |
| cancelledAt | string (date-time) or null | When you cancelled it. null unless cancelled. |
| orderId | string or null | The order the completed flow placed. |
| consent | object or null | What the consumer signed, once completed. |
| consent.signerName | string or null | The typed signature. |
| consent.signedAt | string (date-time) or null | When the authorization was signed. null until the person completes the page. |
| consent.formsVersion | string or null | The version of every text they read. |
| consent.documentId | string or null | The generated consent document (see consent documents). |
| consent.copyRequested | boolean | Whether they asked for a copy of the report. |
| sandbox | boolean | true on the sandbox server; false in production. |
| createdAt | string (date-time) | When the invitation was created. |
| updatedAt | string (date-time) | When it last changed. |
| applyUrl | string (uri) | The consumer's link. Returned once on create and resend; never on a read. Example "https://offendersearch.app/apply/9f3c…" |
List invitations — GET /v1/fcra/invitations
Your invitations, newest first.
Request
| Field | Type | Description |
|---|---|---|
| status optional | string one of "pending", "completed", "expired", "cancelled" | |
| endUserId optional | string | |
| limit optional · default 100 | integer | 1 to 500. |
Response
| Field | Type | Description |
|---|---|---|
| invitations | array of Invitation |
| Status | Code | When |
|---|---|---|
| 401 | — | No valid X-API-Key (the body is { "detail": "…" }, a string). |
| 403 | fcra_not_enabled | This account has no active FCRA partner agreement. |
| 403 | fcra_not_on_trial | FCRA orders are not available on a trial account. |
| 403 | managed_tier_required | Your agreement names you as the CRA; collect consent in your own flow and place orders directly. |
Retrieve an invitation — GET /v1/fcra/invitations/{invitation_id}
The invitation and what came of it. Never the link.
Request
| Field | Type | Description |
|---|---|---|
| invitation_id required | string | Example "fi_4c1d2e9a7b3f0c58" |
Response
The body is the Invitation object. An invitation to the hosted consent flow and what came of it. applyUrl is present on the create and resend responses only.
| Status | Code | When |
|---|---|---|
| 401 | — | No valid X-API-Key (the body is { "detail": "…" }, a string). |
| 403 | fcra_not_enabled | This account has no active FCRA partner agreement. |
| 403 | fcra_not_on_trial | FCRA orders are not available on a trial account. |
| 403 | managed_tier_required | Your agreement names you as the CRA; collect consent in your own flow and place orders directly. |
| 404 | not_found | No such invitation on this account. |
Cancel an invitation — DELETE /v1/fcra/invitations/{invitation_id}
Withdraws a pending invitation; the link stops working.
Request
| Field | Type | Description |
|---|---|---|
| invitation_id required | string | Example "fi_4c1d2e9a7b3f0c58" |
Response
The invitation, cancelled.
The body is the Invitation object. An invitation to the hosted consent flow and what came of it. applyUrl is present on the create and resend responses only.
| Status | Code | When |
|---|---|---|
| 401 | — | No valid X-API-Key (the body is { "detail": "…" }, a string). |
| 403 | fcra_not_enabled | This account has no active FCRA partner agreement. |
| 403 | fcra_not_on_trial | FCRA orders are not available on a trial account. |
| 403 | managed_tier_required | Your agreement names you as the CRA; collect consent in your own flow and place orders directly. |
| 404 | not_found | |
| 409 | not_cancellable | The invitation is not pending. |
Resend an invitation — POST /v1/fcra/invitations/{invitation_id}/resend
A fresh link, e-mailed again; the previous link no longer works.
Request
| Field | Type | Description |
|---|---|---|
| invitation_id required | string | Example "fi_4c1d2e9a7b3f0c58" |
Response
The invitation with a new one-time applyUrl.
The body is the Invitation object. An invitation to the hosted consent flow and what came of it. applyUrl is present on the create and resend responses only.
| Status | Code | When |
|---|---|---|
| 401 | — | No valid X-API-Key (the body is { "detail": "…" }, a string). |
| 403 | fcra_not_enabled | This account has no active FCRA partner agreement. |
| 403 | fcra_not_on_trial | FCRA orders are not available on a trial account. |
| 403 | managed_tier_required | Your agreement names you as the CRA; collect consent in your own flow and place orders directly. |
| 404 | not_found | |
| 409 | not_resendable | The invitation is not pending. |
What the consumer sees
The apply page is at the link. It is public, rate-limited, and shows exactly what GET /v1/apply/{token} returns: who is asking, who prepares the report, every form in reading order, and the prefilled name. The page is ours to host; a platform that wants the flow inside its own product calls the same three routes from its own pages.
- Summary of rights and the standalone disclosure — each acknowledged.
- State notices for the use location (California, New York, Washington, Minnesota, Oklahoma, Maine, Massachusetts, New Jersey today) and the offer of a free copy of the report.
- Their details: legal name, date of birth, other names used, where they have lived in the last seven years (a ZIP is enough to place the county), and how to reach them.
- The authorization, signed by typing their full name. The signature must match the name entered.
Hosted consent, what the consumer sees — GET /v1/apply/{token}
Public, by the link token, rate-limited. The forms, who is asking, who prepares the report, the prefilled name.
Request
| Field | Type | Description |
|---|---|---|
| token required | string | From the invitation's applyUrl. |
Response
The body is the ApplyView object. Everything the apply page renders: who is asking, who prepares the report, the forms, and the prefilled name. Never an order id or an access code.
| Status | Code | When |
|---|---|---|
| 404 | not_found | The link is not valid (mistyped, replaced by a resend, or no longer an invitation). |
| 429 | rate_limited |
The ApplyView object — the hosted flow as the consumer sees it
Everything the apply page renders: who is asking, who prepares the report, the forms, and the prefilled name. Never an order id or an access code.
Returned or accepted by GET /v1/apply/{token}.
| Field | Type | Description |
|---|---|---|
| status | string one of "pending", "completed", "expired", "cancelled" | pending while open, then completed, expired or cancelled. Only a pending invitation can be completed. |
| expiresAt | string (date-time) | When the link stops working. |
| requestedBy | string | The end user's name. |
| branding | Branding | The partner's branding (display name, logo, colour, support contact) to render the page in. |
| agency | Agency | The consumer reporting agency named on every disclosure, report and notice. |
| permissiblePurpose | string | Why the report is being requested, shown to the person. |
| searches | array of string | The search types that will run, for example ["sex_offender", "criminal"]. |
| useLocation | object or null | Where the person will work or live, when given. null otherwise. |
| useLocation.state | string | Two-letter state code. |
| useLocation.city | string or null | City, when one applies. null otherwise. |
| forms | array of ApplyForm | In reading order. |
| requiredAcknowledgements | array of string | The form ids that must be acknowledged true. |
| offersCopy | boolean | true when the page must offer the person a free copy of their report. |
| prefill | object | What the inviter already knew about the person, to prefill the form. Every value may be null. |
| prefill.firstName | string or null | First name, or null. |
| prefill.middleName | string or null | Middle name, or null. |
| prefill.lastName | string or null | Last name, or null. |
| prefill.email | string or null | E-mail the invitation went to, or null. |
| prefill.phone | string or null | Phone, or null. |
| locale | string | en or es: the language the page should render in. |
| identityNote | string | Says that identity verification is coming soon and that no Social Security number is asked for. |
The ApplyForm object — one text the consumer reads
A form in the hosted flow: the summary of rights, the standalone disclosure, a state notice, or the authorization.
Returned or accepted by GET /v1/apply/{token}.
| Field | Type | Description |
|---|---|---|
| id | string | Acknowledge it under this id. Example "disclosure" |
| kind | string one of "rights", "disclosure", "state_notice", "authorization" | rights (the CFPB summary of rights), disclosure, state_notice or authorization. |
| version | string | Recorded in the consent document. |
| title | string | The form's title as shown to the person. |
| text | string | The full text, as shown. |
| url | string or null | A link to the full published text (the summary of rights). |
| state | string or null | For a state notice. |
| offersCopy | boolean | Whether this notice offers a copy of the report. |
| requiresAcknowledgement | boolean | true when the person must tick that they read it before they can sign. |
| requiresSignature | boolean | The authorization: a typed signature is required. |
The Agency object — the consumer reporting agency
Who prepares the report: the legal name and contact that appear on the disclosure, the report and every notice, whatever the branding.
Returned or accepted by GET /v1/consumer/portal/report, GET /v1/fcra/branding, PUT /v1/fcra/branding, GET /v1/apply/{token}.
| Field | Type | Description |
|---|---|---|
| legalName | string | The consumer reporting agency's legal name as it appears on consent forms and notices. Example "OffenderSearch LLC" |
| string | Consumer questions and disputes. | |
| url | string | The consumer page. |
Hosted consent, sign and authorize — POST /v1/apply/{token}/complete
Records the acknowledgements and the typed signature, stores the consent document, places the order.
Request
| Field | Type | Description |
|---|---|---|
| token required | string |
| Field | Type | Description |
|---|---|---|
| acknowledgements required | object | Form id → true, for every id in requiredAcknowledgements. |
| signerName required | string | The typed signature; must match the name entered. |
| subject required | ApplySubject | The person's name, date of birth, aliases and address history as they entered them. |
| contact required | ApplyContact | The person's e-mail and optional phone. |
| copyRequested optional · default false | boolean | true when the person ticked the box asking for a copy of the report. |
Response
The body is the ApplyResult object. What the consumer is told after signing. Nothing about the order.
| Status | Code | When |
|---|---|---|
| 404 | not_found | |
| 409 | invitation_completed | Already signed. |
| 409 | invitation_expired | |
| 409 | invitation_cancelled | |
| 422 | acknowledgement_required | A required form was not acknowledged. |
| 422 | signature_mismatch | The typed name does not match the name entered. |
| 422 | — | A field failed validation, including any Social Security number sent. |
| 429 | rate_limited |
The ApplySubject object
The consumer's identity details. No Social Security number field exists; one sent is refused.
Returned or accepted by POST /v1/apply/{token}/complete.
| Field | Type | Description |
|---|---|---|
| firstName required | string | The person's legal first name. |
| middleName optional | string or null | Middle name. null when none, in which case noMiddleName must be true. |
| noMiddleName optional · default false | boolean | true when the person confirms they have no middle name. |
| lastName required | string | The person's legal last name. |
| dob required | string (date) | Full date of birth. |
| aliases optional | array of ApplyAlias or null | Up to 5. |
| addresses required | array of ApplyAddress | Current address first, up to 20. |
The ApplyAddress object
One address the consumer has lived at. Everything they type is a declared address.
Returned or accepted by POST /v1/apply/{token}/complete.
| Field | Type | Description |
|---|---|---|
| state required | string | Two-letter state code. The only required part: a state alone adds the statewide sources. |
| city optional | string or null | City, used to find the county. null when unknown. |
| line1 optional | string or null | Street address. Stored with the consent record; not used to pick sources. null when not given. |
| postalCode optional | string or null | ZIP code, used to find the county when there is no city. null when unknown. |
| county optional | string or null | County name, when the person knows it. Overrides the city/ZIP lookup. null otherwise. |
| from optional | string or null | YYYY, YYYY-MM or YYYY-MM-DD. |
| to optional | string or null | When the person stopped living there (YYYY-MM or YYYY). null for a current address. |
The ApplyAlias object
Another name the consumer has used.
Returned or accepted by POST /v1/apply/{token}/complete.
| Field | Type | Description |
|---|---|---|
| firstName required | string | First name the person has also used. |
| lastName required | string | Last name the person has also used (a maiden name, for example). |
The ApplyContact object
Where the consumer's notices go.
Returned or accepted by POST /v1/apply/{token}/complete.
| Field | Type | Description |
|---|---|---|
| email required | string | Where the person's copy and any notices go. |
| phone optional | string or null | A phone number, if the person gives one. null otherwise. |
The ApplyResult object
What the consumer is told after signing. Nothing about the order.
Returned or accepted by POST /v1/apply/{token}/complete.
| Field | Type | Description |
|---|---|---|
| status | string one of "completed" | Always completed. |
| completedAt | string (date-time) | When the person signed. |
| copyRequested | boolean | Whether the person asked for a copy of the report. |
| whatHappensNext | string | Plain language. |
Hosted consent, decline — POST /v1/apply/{token}/decline
The consumer declines; the invitation is cancelled and you receive invitation.cancelled with reason: declined.
Request
| Field | Type | Description |
|---|---|---|
| token required | string |
| Field | Type | Description |
|---|---|---|
| reason optional | string or null | Optional, kept on the invitation. |
Response
| Field | Type | Description |
|---|---|---|
| status | string one of "declined" |
| Status | Code | When |
|---|---|---|
| 404 | not_found | |
| 409 | — | invitation_completed | invitation_expired | invitation_cancelled. |
Consent documents
The hosted flow generates a PDF of everything the consumer read and signed — each text with its version, each acknowledgement, the typed signature, the time, the IP address and browser — and stores it with the order. For an order you place through the API you can attach the consent you collected yourself. Every document is listed with its SHA-256 and downloadable byte for byte.
Consent documents behind an order — GET /v1/fcra/orders/{order_id}/consent-documents
The signed consent behind an order: generated by the hosted flow or uploaded by you.
Request
| Field | Type | Description |
|---|---|---|
| order_id required | string | Example "fo_ee0b34c5b52fd35b" |
Response
| Field | Type | Description |
|---|---|---|
| orderId | string | |
| documents | array of ConsentDocument |
| Status | Code | When |
|---|---|---|
| 401 | — | No valid X-API-Key (the body is { "detail": "…" }, a string). |
| 403 | fcra_not_enabled | This account has no active FCRA partner agreement. |
| 403 | fcra_not_on_trial | FCRA orders are not available on a trial account. |
| 404 | not_found | No such order on this account. |
The ConsentDocument object
A signed disclosure and authorization behind an order: generated by the hosted flow, or uploaded by you for an API order. Kept with the order's evidence.
Returned or accepted by GET /v1/fcra/orders/{order_id}/consent-documents, POST /v1/fcra/orders/{order_id}/consent-documents.
| Field | Type | Description |
|---|---|---|
| id | string | The document's id (cdoc_…).Example "fcd_7a2b9c4d1e0f3a65" |
| kind | string one of "generated", "uploaded" | generated by the hosted flow or uploaded by you. |
| contentType | string | application/pdf, image/png or image/jpeg. |
| sha256 | string | The hash of the exact bytes you can download. |
| size | integer | Bytes. |
| signerName | string or null | The name typed or written as the signature. null when the upload did not include one. |
| signedAt | string or null | The signing date or date-time you supplied, or the hosted page recorded. null when unknown. |
| forms | array of object | The texts the consumer read, with versions (generated documents). |
| forms[].id | string | The form's id, for example disclosure or authorization. |
| forms[].version | string | The version of the form text the person saw. |
| forms[].title | string | The form's title as shown to the person. |
| invitationId | string or null | The invitation this consent came from. null for a document you uploaded. |
| createdAt | string (date-time) | When the document was stored. |
Attach your signed consent to an order — POST /v1/fcra/orders/{order_id}/consent-documents
For an order you placed through the API: store the disclosure and authorization you collected, with the order's evidence.
Request
| Field | Type | Description |
|---|---|---|
| order_id required | string |
| Field | Type | Description |
|---|---|---|
| contentType required | string one of "application/pdf", "image/png", "image/jpeg" | The file's type: application/pdf, image/png or image/jpeg. |
| data required | string | The file, base64. |
| signerName optional | string or null | The name on the signature, if legible. null when not. |
| signedAt optional | string or null | The date the person signed (YYYY-MM-DD or a date-time). null when unknown. |
Response
The stored document.
The body is the ConsentDocument object. A signed disclosure and authorization behind an order: generated by the hosted flow, or uploaded by you for an API order. Kept with the order's evidence.
| Status | Code | When |
|---|---|---|
| 401 | — | No valid X-API-Key (the body is { "detail": "…" }, a string). |
| 403 | fcra_not_enabled | This account has no active FCRA partner agreement. |
| 403 | fcra_not_on_trial | FCRA orders are not available on a trial account. |
| 404 | not_found | |
| 422 | validation | Not base64, empty, over 5 MB, or not the type it claims. |
Download a consent document — GET /v1/fcra/orders/{order_id}/consent-documents/{doc_id}
The exact bytes, with X-Document-SHA256.
Request
| Field | Type | Description |
|---|---|---|
| order_id required | string | |
| doc_id required | string |
Response
The document (PDF, PNG or JPEG).
| Field | Type | Description |
|---|
| Status | Code | When |
|---|---|---|
| 401 | — | No valid X-API-Key (the body is { "detail": "…" }, a string). |
| 403 | fcra_not_enabled | This account has no active FCRA partner agreement. |
| 403 | fcra_not_on_trial | FCRA orders are not available on a trial account. |
| 404 | not_found |
Notices
Every e-mail we send a consumer is recorded before it is sent — the kind, the recipient, the subject, the template version — and updated with the provider’s answer. GET /v1/fcra/invitations/{id}/notices lists them. With no mail provider configured a notice is recorded as skipped, the flow continues, and the dashboard shows the message as not sent.
What was e-mailed for an invitation — GET /v1/fcra/invitations/{invitation_id}/notices
Every message we sent for the invitation and whether the provider took it.
Request
| Field | Type | Description |
|---|---|---|
| invitation_id required | string | Example "fi_4c1d2e9a7b3f0c58" |
Response
| Field | Type | Description |
|---|---|---|
| notices | array of Notice |
| Status | Code | When |
|---|---|---|
| 401 | — | No valid X-API-Key (the body is { "detail": "…" }, a string). |
| 403 | fcra_not_enabled | This account has no active FCRA partner agreement. |
| 403 | fcra_not_on_trial | FCRA orders are not available on a trial account. |
| 403 | managed_tier_required | Your agreement names you as the CRA; collect consent in your own flow and place orders directly. |
| 404 | not_found |
The Notice object — a message we sent the consumer
One consumer-facing e-mail: what kind, to whom, and whether the provider took it. Bodies are not stored; the template version says what was said.
Returned or accepted by GET /v1/fcra/invitations/{invitation_id}/notices, GET /v1/fcra/adverse-actions/{aa_id}/notices, GET /v1/fcra/orders/{order_id}/notices.
| Field | Type | Description |
|---|---|---|
| id | string | The notice's id (ntc_…). |
| kind | string one of "invitation", "invitation_reminder", "report_copy", "pre_adverse", "post_adverse", "dispute_received", "dispute_resolved" | What was sent: invitation, invitation_reminder, report_copy, pre_adverse, post_adverse, dispute_received or dispute_resolved. |
| to | string | The e-mail address it went to. |
| subject | string | The e-mail's subject line. |
| status | string one of "queued", "sent", "failed", "skipped" | sent (the provider accepted it), failed (it did not; see error), skipped (no mail provider is configured), queued. |
| sentAt | string (date-time) or null | When the mail provider accepted it. null while pending or when it could not be sent. |
| error | string or null | Why it could not be sent, when it could not. null otherwise. |
| templateVersion | string | The version of the notice text that was sent, for your records. |
| createdAt | string (date-time) | When the notice was queued. |
Test FCRA orders on the sandbox server
With a test key (os_test_…) every account is a sandbox FCRA partner on the sandbox server, with the same last-name rules. Register an end user, then place orders against it; nothing is billed. An order finishes right after the 202: read it once with GET /v1/fcra/orders/{orderId}.
- Base URL
https://sandbox.offendersearch.appNothttps://api.offendersearch.app, which takes live keys only.- Test key
- In the dashboard, Developers → API keys → Create test key. Test keys begin
os_test_; send yours in theX-API-Keyheader.
curl -X POST "https://sandbox.offendersearch.app/v1/fcra/end-users" \
-H "X-API-Key: $OFFENDERSEARCH_TEST_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Sample Staffing LLC",
"permissiblePurposes": [
"employment"
],
"certification": {
"text": "End user certifies it will use reports only for employment purposes.",
"version": "v1",
"certifiedAt": "2026-10-01T12:00:00Z"
}
}'curl -X POST "https://sandbox.offendersearch.app/v1/fcra/orders" \
-H "X-API-Key: $OFFENDERSEARCH_TEST_KEY" \
-H "Content-Type: application/json" \
-d '{
"endUserId": "{endUserId}",
"permissiblePurpose": "employment",
"consent": {
"obtainedAt": "2026-10-01T12:00:00Z",
"method": "esign"
},
"subject": {
"firstName": "Pat",
"lastName": "Records",
"dob": "1980-01-01"
},
"searches": [
{
"type": "sex_offender"
},
{
"type": "criminal"
}
]
}'Try it here
Pick a scenario, edit the request, and run it against the sandbox from this page. The explorer accepts os_test_ keys only and never reaches the live host, so nothing here is billed; the “production” code it copies is for your own backend with a live key.
Copy this request as code
Sandbox code uses your test key. Production code calls the live host and is billed per call; run it from your backend with an os_live_… key.
curl -X POST https://sandbox.offendersearch.app/v1/fcra/end-users \
-H "X-API-Key: $OFFENDERSEARCH_TEST_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Sample Staffing LLC", "permissiblePurposes": [ "employment" ], "certification": { "text": "End user certifies it will use reports only for employment purposes.", "version": "v1", "certifiedAt": "2026-10-01T12:00:00Z" } }'Every test name: FCRA API sandbox ordersPostman collectionFCRA API sandbox