FCRA Partner API · v1.0.0 · approved partners

Hosted consent

Invite the consumer; we collect the disclosure, the authorization and their details, and place the order.

Livehttps://api.offendersearch.appSandboxhttps://sandbox.offendersearch.app

How 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 cra partner collects consent in its own flow and places orders directly; POST /v1/fcra/invitations answers 403 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.

POST /v1/fcra/invitations
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 statusMeaning
pendingSent (or waiting for you to present the link); nothing signed yet.
completedSigned. orderId is the order; consent says who signed, when, and which texts.
expiredThe link ran out. Resend is not possible; invite again.
cancelledYou cancelled it, or the consumer declined (invitation.cancelled with reason: declined).

Invite a consumer to the hosted consent flow — POST /v1/fcra/invitations

POST/v1/fcra/invitationsAuth: X-API-Key

Creates the invitation and e-mails the consumer the link (unless sendEmail is false). applyUrl is returned once, here.

Request

Body · application/json
FieldTypeDescription
endUserId
required
stringThe 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
InviteSubjectWho 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 SearchSpecOne to three searches (sex_offender, criminal, healthcare), each type at most once.
useLocation
optional
UseLocation or nullWhere the job, the housing or the transaction is. Its state picks the state notices the consumer sees.
annualSalary
optional
integer or nullFor 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 nullCarried onto the order.
callbackUrl
optional
string (uri) or nullCarried onto the order; needs a configured webhook endpoint.
metadata
optional
object or nullCarried onto the order.
tags
optional
array of string or nullCarried 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
booleanfalse when you present applyUrl yourself (an embedded flow); we then send nothing.
expiresInDays
optional
integer or null1 to 30. Default 7.

Response

201 · application/json

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.

Errors
StatusCodeWhen
401—No valid X-API-Key (the body is { "detail": "…" }, a string).
403fcra_not_enabledThis account has no active FCRA partner agreement.
403fcra_not_on_trialFCRA orders are not available on a trial account.
403managed_tier_requiredYour agreement names you as the CRA; collect consent in your own flow and place orders directly.
403fcra_purpose_not_allowedThe purpose is not certified for this end user or not in your agreement.
404unknown_end_userNo such end user on this account.
422end_user_suspendedThe end user is suspended.
422webhook_endpoint_requiredcallbackUrl 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.

FieldTypeDescription
firstName
required
stringThe person's first name, prefilled on the consent page. They can correct it.
Example "Jordan"
middleName
optional
string or nullMiddle name, if you know it. null when not.
lastName
required
stringThe person's last name, prefilled on the consent page.
Example "Rivera"
email
required
stringWhere the link goes. The consumer confirms it in the flow.
Example "jordan@example.test"
phone
optional
string or nullA 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.

FieldTypeDescription
id
stringThe 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
stringYour 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
InviteSubjectAs sent, with the name as the consumer confirmed it once completed.
searches
array of SearchSpecThe searches the order will run once consent is in, exactly as requested.
useLocation
object or nullWhere the person will work or live, which picks the state and city forms. null when not given.
useLocation.state
stringTwo-letter state code.
useLocation.city
string or nullCity, when a city ordinance applies. null otherwise.
annualSalary
integer or nullExpected 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 nullYour own reference for this invitation, echoed back unchanged. null when none.
metadata
object or nullUp to 50 string key/value pairs of your own, echoed back unchanged. null when none.
tags
array of stringUp to 20 tags of your own, for filtering in the dashboard.
locale
stringThe language of the consent page and e-mails: en or es.
sendEmail
booleantrue 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 nullWhen the e-mail was handed to the provider. null when sendEmail was false or no provider is configured.
reminderSentAt
string (date-time) or nullThe one reminder, 48 hours in.
completedAt
string (date-time) or nullWhen the person signed. null until then.
cancelledAt
string (date-time) or nullWhen you cancelled it. null unless cancelled.
orderId
string or nullThe order the completed flow placed.
consent
object or nullWhat the consumer signed, once completed.
consent.signerName
string or nullThe typed signature.
consent.signedAt
string (date-time) or nullWhen the authorization was signed. null until the person completes the page.
consent.formsVersion
string or nullThe version of every text they read.
consent.documentId
string or nullThe generated consent document (see consent documents).
consent.copyRequested
booleanWhether they asked for a copy of the report.
sandbox
booleantrue 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

GET/v1/fcra/invitationsAuth: X-API-Key

Your invitations, newest first.

Request

Query parameters
FieldTypeDescription
status
optional
string
one of "pending", "completed", "expired", "cancelled"
endUserId
optional
string
limit
optional · default 100
integer1 to 500.

Response

200 · application/json

FieldTypeDescription
invitations
array of Invitation
Errors
StatusCodeWhen
401—No valid X-API-Key (the body is { "detail": "…" }, a string).
403fcra_not_enabledThis account has no active FCRA partner agreement.
403fcra_not_on_trialFCRA orders are not available on a trial account.
403managed_tier_requiredYour 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}

GET/v1/fcra/invitations/{invitation_id}Auth: X-API-Key

The invitation and what came of it. Never the link.

Request

Path parameters
FieldTypeDescription
invitation_id
required
string
Example "fi_4c1d2e9a7b3f0c58"

Response

200 · application/json

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.

Errors
StatusCodeWhen
401—No valid X-API-Key (the body is { "detail": "…" }, a string).
403fcra_not_enabledThis account has no active FCRA partner agreement.
403fcra_not_on_trialFCRA orders are not available on a trial account.
403managed_tier_requiredYour agreement names you as the CRA; collect consent in your own flow and place orders directly.
404not_foundNo such invitation on this account.

Cancel an invitation — DELETE /v1/fcra/invitations/{invitation_id}

DELETE/v1/fcra/invitations/{invitation_id}Auth: X-API-Key

Withdraws a pending invitation; the link stops working.

Request

Path parameters
FieldTypeDescription
invitation_id
required
string
Example "fi_4c1d2e9a7b3f0c58"

Response

200 · application/json

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.

Errors
StatusCodeWhen
401—No valid X-API-Key (the body is { "detail": "…" }, a string).
403fcra_not_enabledThis account has no active FCRA partner agreement.
403fcra_not_on_trialFCRA orders are not available on a trial account.
403managed_tier_requiredYour agreement names you as the CRA; collect consent in your own flow and place orders directly.
404not_found
409not_cancellableThe invitation is not pending.

Resend an invitation — POST /v1/fcra/invitations/{invitation_id}/resend

POST/v1/fcra/invitations/{invitation_id}/resendAuth: X-API-Key

A fresh link, e-mailed again; the previous link no longer works.

Request

Path parameters
FieldTypeDescription
invitation_id
required
string
Example "fi_4c1d2e9a7b3f0c58"

Response

200 · application/json

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.

Errors
StatusCodeWhen
401—No valid X-API-Key (the body is { "detail": "…" }, a string).
403fcra_not_enabledThis account has no active FCRA partner agreement.
403fcra_not_on_trialFCRA orders are not available on a trial account.
403managed_tier_requiredYour agreement names you as the CRA; collect consent in your own flow and place orders directly.
404not_found
409not_resendableThe 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.

  1. Summary of rights and the standalone disclosure — each acknowledged.
  2. 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.
  3. 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.
  4. 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}

GET/v1/apply/{token}No API key

Public, by the link token, rate-limited. The forms, who is asking, who prepares the report, the prefilled name.

Request

Path parameters
FieldTypeDescription
token
required
stringFrom the invitation's applyUrl.

Response

200 · application/json

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.

Errors
StatusCodeWhen
404not_foundThe link is not valid (mistyped, replaced by a resend, or no longer an invitation).
429rate_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}.

FieldTypeDescription
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
stringThe end user's name.
branding
BrandingThe partner's branding (display name, logo, colour, support contact) to render the page in.
agency
AgencyThe consumer reporting agency named on every disclosure, report and notice.
permissiblePurpose
stringWhy the report is being requested, shown to the person.
searches
array of stringThe search types that will run, for example ["sex_offender", "criminal"].
useLocation
object or nullWhere the person will work or live, when given. null otherwise.
useLocation.state
stringTwo-letter state code.
useLocation.city
string or nullCity, when one applies. null otherwise.
forms
array of ApplyFormIn reading order.
requiredAcknowledgements
array of stringThe form ids that must be acknowledged true.
offersCopy
booleantrue when the page must offer the person a free copy of their report.
prefill
objectWhat the inviter already knew about the person, to prefill the form. Every value may be null.
prefill.firstName
string or nullFirst name, or null.
prefill.middleName
string or nullMiddle name, or null.
prefill.lastName
string or nullLast name, or null.
prefill.email
string or nullE-mail the invitation went to, or null.
prefill.phone
string or nullPhone, or null.
locale
stringen or es: the language the page should render in.
identityNote
stringSays 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}.

FieldTypeDescription
id
stringAcknowledge 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
stringRecorded in the consent document.
title
stringThe form's title as shown to the person.
text
stringThe full text, as shown.
url
string or nullA link to the full published text (the summary of rights).
state
string or nullFor a state notice.
offersCopy
booleanWhether this notice offers a copy of the report.
requiresAcknowledgement
booleantrue when the person must tick that they read it before they can sign.
requiresSignature
booleanThe 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}.

FieldTypeDescription
legalName
stringThe consumer reporting agency's legal name as it appears on consent forms and notices.
Example "OffenderSearch LLC"
email
stringConsumer questions and disputes.
url
stringThe consumer page.

Hosted consent, sign and authorize — POST /v1/apply/{token}/complete

POST/v1/apply/{token}/completeNo API key

Records the acknowledgements and the typed signature, stores the consent document, places the order.

Request

Path parameters
FieldTypeDescription
token
required
string
Body · application/json
FieldTypeDescription
acknowledgements
required
objectForm id → true, for every id in requiredAcknowledgements.
signerName
required
stringThe typed signature; must match the name entered.
subject
required
ApplySubjectThe person's name, date of birth, aliases and address history as they entered them.
contact
required
ApplyContactThe person's e-mail and optional phone.
copyRequested
optional · default false
booleantrue when the person ticked the box asking for a copy of the report.

Response

201 · application/json

The body is the ApplyResult object. What the consumer is told after signing. Nothing about the order.

Errors
StatusCodeWhen
404not_found
409invitation_completedAlready signed.
409invitation_expired
409invitation_cancelled
422acknowledgement_requiredA required form was not acknowledged.
422signature_mismatchThe typed name does not match the name entered.
422—A field failed validation, including any Social Security number sent.
429rate_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.

FieldTypeDescription
firstName
required
stringThe person's legal first name.
middleName
optional
string or nullMiddle name. null when none, in which case noMiddleName must be true.
noMiddleName
optional · default false
booleantrue when the person confirms they have no middle name.
lastName
required
stringThe person's legal last name.
dob
required
string (date)Full date of birth.
aliases
optional
array of ApplyAlias or nullUp to 5.
addresses
required
array of ApplyAddressCurrent 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.

FieldTypeDescription
state
required
stringTwo-letter state code. The only required part: a state alone adds the statewide sources.
city
optional
string or nullCity, used to find the county. null when unknown.
line1
optional
string or nullStreet address. Stored with the consent record; not used to pick sources. null when not given.
postalCode
optional
string or nullZIP code, used to find the county when there is no city. null when unknown.
county
optional
string or nullCounty name, when the person knows it. Overrides the city/ZIP lookup. null otherwise.
from
optional
string or nullYYYY, YYYY-MM or YYYY-MM-DD.
to
optional
string or nullWhen 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.

FieldTypeDescription
firstName
required
stringFirst name the person has also used.
lastName
required
stringLast 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.

FieldTypeDescription
email
required
stringWhere the person's copy and any notices go.
phone
optional
string or nullA 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.

FieldTypeDescription
status
string
one of "completed"
Always completed.
completedAt
string (date-time)When the person signed.
copyRequested
booleanWhether the person asked for a copy of the report.
whatHappensNext
stringPlain language.

Hosted consent, decline — POST /v1/apply/{token}/decline

POST/v1/apply/{token}/declineNo API key

The consumer declines; the invitation is cancelled and you receive invitation.cancelled with reason: declined.

Request

Path parameters
FieldTypeDescription
token
required
string
Body · application/json
FieldTypeDescription
reason
optional
string or nullOptional, kept on the invitation.

Response

200 · application/json

FieldTypeDescription
status
string
one of "declined"
Errors
StatusCodeWhen
404not_found
409—invitation_completed | invitation_expired | invitation_cancelled.

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.

FieldTypeDescription
id
stringThe document's id (cdoc_…).
Example "fcd_7a2b9c4d1e0f3a65"
kind
string
one of "generated", "uploaded"
generated by the hosted flow or uploaded by you.
contentType
stringapplication/pdf, image/png or image/jpeg.
sha256
stringThe hash of the exact bytes you can download.
size
integerBytes.
signerName
string or nullThe name typed or written as the signature. null when the upload did not include one.
signedAt
string or nullThe signing date or date-time you supplied, or the hosted page recorded. null when unknown.
forms
array of objectThe texts the consumer read, with versions (generated documents).
forms[].id
stringThe form's id, for example disclosure or authorization.
forms[].version
stringThe version of the form text the person saw.
forms[].title
stringThe form's title as shown to the person.
invitationId
string or nullThe 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

POST/v1/fcra/orders/{order_id}/consent-documentsAuth: X-API-Key

For an order you placed through the API: store the disclosure and authorization you collected, with the order's evidence.

Request

Path parameters
FieldTypeDescription
order_id
required
string
Body · application/json
FieldTypeDescription
contentType
required
string
one of "application/pdf", "image/png", "image/jpeg"
The file's type: application/pdf, image/png or image/jpeg.
data
required
stringThe file, base64.
signerName
optional
string or nullThe name on the signature, if legible. null when not.
signedAt
optional
string or nullThe date the person signed (YYYY-MM-DD or a date-time). null when unknown.

Response

201 · application/json

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.

Errors
StatusCodeWhen
401—No valid X-API-Key (the body is { "detail": "…" }, a string).
403fcra_not_enabledThis account has no active FCRA partner agreement.
403fcra_not_on_trialFCRA orders are not available on a trial account.
404not_found
422validationNot base64, empty, over 5 MB, or not the type it claims.

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

GET/v1/fcra/invitations/{invitation_id}/noticesAuth: X-API-Key

Every message we sent for the invitation and whether the provider took it.

Request

Path parameters
FieldTypeDescription
invitation_id
required
string
Example "fi_4c1d2e9a7b3f0c58"

Response

200 · application/json

FieldTypeDescription
notices
array of Notice
Errors
StatusCodeWhen
401—No valid X-API-Key (the body is { "detail": "…" }, a string).
403fcra_not_enabledThis account has no active FCRA partner agreement.
403fcra_not_on_trialFCRA orders are not available on a trial account.
403managed_tier_requiredYour agreement names you as the CRA; collect consent in your own flow and place orders directly.
404not_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.

FieldTypeDescription
id
stringThe 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
stringThe e-mail address it went to.
subject
stringThe 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 nullWhen the mail provider accepted it. null while pending or when it could not be sent.
error
string or nullWhy it could not be sent, when it could not. null otherwise.
templateVersion
stringThe 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.app Not https://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 the X-API-Key header.
1. POST /v1/fcra/end-users
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"
      }
    }'
2. POST /v1/fcra/orders
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.

Create a test key under Dashboard → API keys. Live keys are refused here.
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" } }'

Product overview