FCRA Partner API · v1.0.0 · approved partners

Adverse action & revisions

Pre- and post-adverse notices sent for you, the waiting period by jurisdiction, disputes that pause the clock, and report revisions with their own receipts.

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

How it works

When a direct or platform partner’s end user is considering a decision against the consumer because of the report, the API runs the two-step adverse-action process as the consumer reporting agency. You name the records the decision rests on; we send the consumer the pre-adverse notice with the report access code and the summary of rights, wait the period the use location requires, and send the post-adverse notice. A dispute pauses the clock; a correction cancels the action and revises the report. The end user still makes the decision — the API never decides for it.

  1. Read the adverse items: every record the current report furnishes, in plain language, plus the rule the use location adds (GET …/adverse-items).
  2. Start the adverse action with the item ids and, where the rule requires it, your written individualized assessment. The pre-adverse notice goes to the consumer’s e-mail on the order; the order’s adjudication becomes pre_adverse_action. If the mail provider does not accept the notice (failed or skipped), nothing starts: the request answers 502 pre_notice_not_delivered and the action is cancelled with cancelReason: "pre_notice_not_delivered". Fix the address and start again.
  3. The waiting period runs from the moment the pre-adverse notice is delivered: the latest of your waitingDays (default 7 calendar days), the rule’s business days, and a floor of five business days that applies everywhere. A waitingDays below 7 is refused with 422 waiting_period_too_short. The consumer may respond to the end user, dispute with us, or do nothing.
  4. When it has run, the post-adverse notice goes and adjudication becomes post_adverse_action. If you change your mind, cancel it; adjudication clears.

What a decision could rest on — GET /v1/fcra/orders/{order_id}/adverse-items

GET/v1/fcra/orders/{order_id}/adverse-itemsAuth: X-API-Key

Every record the current report furnishes, as items a decision could rest on, and the rule the use location adds.

Request

Path parameters
FieldTypeDescription
order_id
required
string
Example "fo_ee0b34c5b52fd35b"

Response

200 · application/json

FieldTypeDescription
orderId
string
items
array of AdverseItem
rule
AdverseRule or null
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_foundNo such order or adverse action on this account.

The AdverseItem object — a record a decision could rest on

One record the current report furnishes, in plain language, with the record id you name on the adverse action.

Returned or accepted by GET /v1/fcra/orders/{order_id}/adverse-items.

FieldTypeDescription
id
stringThe record id (recordId on the furnished record).
Example "crim:OH-COURT:1234"
type
string
one of "sex_offender", "criminal", "healthcare"
sex_offender or criminal: which search the record came from.
searchId
stringThe search it was furnished by.
text
stringA plain-language line, as the pre-adverse notice will quote it.

Start adverse action — POST /v1/fcra/orders/{order_id}/adverse-actions

POST/v1/fcra/orders/{order_id}/adverse-actionsAuth: X-API-Key

Sends the pre-adverse notice to the consumer now, with the report access code and the summary of rights, and schedules the post-adverse notice after the waiting period.

Request

Path parameters
FieldTypeDescription
order_id
required
string
Example "fo_ee0b34c5b52fd35b"
Body · application/json
FieldTypeDescription
adverseItemIds
required
array of stringThe items the decision rests on, from adverse items.
reasonText
optional
string or nullKept on the adverse action; not sent to the consumer.
waitingDays
optional
integer or nullCalendar days before the post-adverse notice, 1 to 60. Default 7. The use location's rule may lengthen it.
individualizedAssessment
optional · default false
booleanWhether a written individualized assessment was made. Required where the rule says so.
assessmentText
optional
string or nullThe assessment, sent with the pre-adverse notice.
medium
optional
object or nullHow the notices go. {"email": true} today; postal is not yet available.

Response

201 · application/json

The adverse action, pending.

The body is the AdverseAction object. An adverse action on an order: the pre-adverse notice sent, the waiting period, the post-adverse notice scheduled or sent, and what paused or cancelled it.

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; run adverse action in your own flow.
404not_foundNo such order or adverse action on this account.
409order_not_complete
409adverse_action_openOne is already pending or paused on this order.
422consumer_contact_requiredThe order has no consumer e-mail (set it with the consumer route).
422unknown_adverse_itemAn id is not in the current report.
422individualized_assessment_requiredThe use location's rule requires a written assessment.

The AdverseAction object

An adverse action on an order: the pre-adverse notice sent, the waiting period, the post-adverse notice scheduled or sent, and what paused or cancelled it.

Returned or accepted by POST /v1/fcra/orders/{order_id}/adverse-actions, GET /v1/fcra/orders/{order_id}/adverse-actions, GET /v1/fcra/adverse-actions, GET /v1/fcra/adverse-actions/{aa_id}, POST /v1/fcra/adverse-actions/{aa_id}/pause, POST /v1/fcra/adverse-actions/{aa_id}/resume, POST /v1/fcra/adverse-actions/{aa_id}/cancel.

FieldTypeDescription
id
stringThe adverse action's id (aa_…).
Example "fa_1b2c3d4e5f607182"
orderId
stringThe completed order the decision is based on.
status
string
one of "pending", "paused", "complete", "cancelled"
pending (the clock is running), paused (a dispute, or you), complete (the post-adverse notice was sent), cancelled.
adverseItemIds
array of stringThe record ids from the report that the decision rests on. Every one must be on the report.
reasonText
string or nullYour stated reason, printed on both notices. null when you gave none.
waitingDays
integerThe calendar days actually waited: the later of yours and the rule's.
rule
AdverseRule or nullThe use location's rule, when one applied.
individualizedAssessment
booleantrue when you attached a written individualized assessment. Required where the rule says so.
assessmentText
string or nullThe assessment text, printed with the pre-adverse notice. null when none.
medium
objectHow the notices go out, for example {"email": true}. Mail-only delivery is not offered yet.
preNoticeSentAt
string (date-time) or nullWhen the pre-adverse notice was sent. null until it is.
postNoticeScheduledAt
string (date-time)When the post-adverse notice goes (moves when paused and resumed).
postNoticeSentAt
string (date-time) or nullWhen the final notice was sent. null until the waiting period ends.
pausedAt
string (date-time) or nullWhen you paused it (a dispute, for example). null unless paused.
resumedAt
string (date-time) or nullWhen it was resumed after a pause. null unless resumed.
cancelledAt
string (date-time) or nullWhen you cancelled it. null unless cancelled.
cancelReason
string or nullreport_revised when a dispute changed the report; otherwise what you sent.
disputeId
string or nullThe dispute that paused it.
createdAt
string (date-time)When it was started.
updatedAt
string (date-time)When it last changed.

Adverse actions on an order — GET /v1/fcra/orders/{order_id}/adverse-actions

GET/v1/fcra/orders/{order_id}/adverse-actionsAuth: X-API-Key

Request

Path parameters
FieldTypeDescription
order_id
required
string
Example "fo_ee0b34c5b52fd35b"

Response

200 · application/json

FieldTypeDescription
orderId
string
adverseActions
array of AdverseAction
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_foundNo such order or adverse action on this account.

List adverse actions — GET /v1/fcra/adverse-actions

GET/v1/fcra/adverse-actionsAuth: X-API-Key

Newest first.

Request

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

Response

200 · application/json

FieldTypeDescription
adverseActions
array of AdverseAction
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.

Retrieve an adverse action — GET /v1/fcra/adverse-actions/{aa_id}

GET/v1/fcra/adverse-actions/{aa_id}Auth: X-API-Key

Request

Path parameters
FieldTypeDescription
aa_id
required
string
Example "fa_1b2c3d4e5f607182"

Response

200 · application/json

The body is the AdverseAction object. An adverse action on an order: the pre-adverse notice sent, the waiting period, the post-adverse notice scheduled or sent, and what paused or cancelled it.

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_foundNo such order or adverse action on this account.

Pause the adverse-action clock — POST /v1/fcra/adverse-actions/{aa_id}/pause

POST/v1/fcra/adverse-actions/{aa_id}/pauseAuth: X-API-Key

Stops the clock with the time that is left. A dispute does this on its own.

Request

Path parameters
FieldTypeDescription
aa_id
required
string
Example "fa_1b2c3d4e5f607182"

Response

200 · application/json

The body is the AdverseAction object. An adverse action on an order: the pre-adverse notice sent, the waiting period, the post-adverse notice scheduled or sent, and what paused or cancelled it.

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; run adverse action in your own flow.
404not_foundNo such order or adverse action on this account.
409not_pausableNot pending.

Resume the adverse-action clock — POST /v1/fcra/adverse-actions/{aa_id}/resume

POST/v1/fcra/adverse-actions/{aa_id}/resumeAuth: X-API-Key

Restarts the clock with the time that was left when it paused.

Request

Path parameters
FieldTypeDescription
aa_id
required
string
Example "fa_1b2c3d4e5f607182"

Response

200 · application/json

The body is the AdverseAction object. An adverse action on an order: the pre-adverse notice sent, the waiting period, the post-adverse notice scheduled or sent, and what paused or cancelled it.

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; run adverse action in your own flow.
404not_foundNo such order or adverse action on this account.
409not_paused

Cancel adverse action — POST /v1/fcra/adverse-actions/{aa_id}/cancel

POST/v1/fcra/adverse-actions/{aa_id}/cancelAuth: X-API-Key

No post-adverse notice goes; the order's adjudication clears.

Request

Path parameters
FieldTypeDescription
aa_id
required
string
Example "fa_1b2c3d4e5f607182"
Body · application/json
FieldTypeDescription
reason
optional · default "client_cancelled"
stringKept on the adverse action.

Response

200 · application/json

The body is the AdverseAction object. An adverse action on an order: the pre-adverse notice sent, the waiting period, the post-adverse notice scheduled or sent, and what paused or cancelled it.

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; run adverse action in your own flow.
404not_foundNo such order or adverse action on this account.
409not_cancellableAlready complete or cancelled.

The notices sent for an adverse action — GET /v1/fcra/adverse-actions/{aa_id}/notices

GET/v1/fcra/adverse-actions/{aa_id}/noticesAuth: X-API-Key

The pre- and post-adverse notices, and whether the provider took each.

Request

Path parameters
FieldTypeDescription
aa_id
required
string
Example "fa_1b2c3d4e5f607182"

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.
404not_foundNo such order or adverse action on this account.

The waiting period by use location

The federal Act sets no number of days; the practice is five business days, and no adverse action here waits less. Several states and cities set their own minimums and require a written individualized assessment before an employment decision on a criminal record. The engine applies the longest period that applies to the order’s use location and purpose; GET /v1/fcra/adverse-rules lists every rule with its citation. The rules in force today:

Use locationPurposeMinimumWritten assessment
Californiaemployment5 business daysyes
Los Angeles, CAemployment5 business daysyes
San Francisco, CAemployment7 daysyes
New York City, NYemployment5 business daysyes (Article 23-A analysis)
New York City, NYtenant screening5 business daysyes
New York (state)employment5 business daysyes (Article 23-A factors)
Philadelphia, PAemployment10 business daysyes
Illinois; Chicagoemployment5 business daysyes
Seattle, WAemployment2 business days (the five-business-day floor applies)yes
Washington (state); District of Columbia; New Jersey; Minnesotaemployment5 business daysD.C. yes; others no
Everywhere elseany5 business days (default waitingDays 7 calendar days)no

The AdverseRule object — what the use location requires

The adverse-action rule the use location and purpose add: business days to wait and whether a written individualized assessment is required. The engine applies the longest period that applies.

Returned or accepted by GET /v1/fcra/orders/{order_id}/adverse-items, POST /v1/fcra/orders/{order_id}/adverse-actions, GET /v1/fcra/orders/{order_id}/adverse-actions, GET /v1/fcra/adverse-actions, GET /v1/fcra/adverse-actions/{aa_id}, POST /v1/fcra/adverse-actions/{aa_id}/pause, POST /v1/fcra/adverse-actions/{aa_id}/resume, POST /v1/fcra/adverse-actions/{aa_id}/cancel.

FieldTypeDescription
state
stringThe two-letter state the rule belongs to.
city
string or nullThe city the rule is for; null for a state-wide rule.
purpose
stringThe permissible purpose it applies to, usually employment or tenant_screening.
version
stringThe rules version.
waitingBusinessDays
integerBusiness days (Monday–Friday) the consumer gets to respond.
individualizedAssessment
booleanWhether a written individualized assessment must go with the pre-adverse notice.
citation
stringThe statute or ordinance, for your records and the notice.
note
stringWhat the rule requires in plain words.
alsoApplies
array of objectOther rules that apply with a shorter period.
alsoApplies[].citation
stringA city ordinance that also applies at this use location.
alsoApplies[].waitingBusinessDays
integerThe city's waiting period, when longer than the state's.

The adverse-action rules by use location — GET /v1/fcra/adverse-rules

GET/v1/fcra/adverse-rulesAuth: X-API-Key

Every jurisdiction rule the engine applies, with its citation.

Request

Response

200 · application/json

FieldTypeDescription
version
string
defaultWaitingDays
integerCalendar days when no rule applies.
rules
array of object
rules[].state
string
rules[].city
string or null
rules[].purpose
string
rules[].waitingBusinessDays
integer
rules[].individualizedAssessment
boolean
rules[].citation
string
rules[].note
string
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.

Disputes move the clock

No waiting period runs while a dispute on the order is open. A dispute opened while an adverse action is pending pauses it with the time that was left, and the consumer receives a receipt; an adverse action started while a dispute is open starts paused. Resuming is refused with 409 dispute_open until every dispute on the order is resolved. When the last open dispute is resolved verified, the action resumes. A dispute resolved modified, deleted or unable_to_verify changes what the report furnishes: the report is revised and the adverse action is cancelled with cancelReason: "report_revised", because the notice the consumer received no longer matches the report. Start a new one on the revised report if the decision still stands.

Record your decision — POST /v1/fcra/orders/{order_id}/adjudication

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

Sets adjudication on a complete order (engaged or cleared). Adverse action sets pre_adverse_action and post_adverse_action itself.

Request

Path parameters
FieldTypeDescription
order_id
required
string
Example "fo_ee0b34c5b52fd35b"
Body · application/json
FieldTypeDescription
decision
required
string
one of "engaged", "cleared"
engaged (hired, housed, proceeded) or cleared (no action on the report).

Response

200 · application/json

The order.

The body is the Order object. An FCRA order: its status, its end user and purpose, every search it carries, and the consumer portal access code.

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_foundNo such order or adverse action on this account.
409order_not_complete
409adverse_action_openCancel the open adverse action first.

Report revisions

Revision 1 is the report at completion. Each dispute that changes it writes the next revision: a rebuilt report without the removed records (and with corrections attached), a re-rendered PDF, new hashes, and a receipt that signs the revision number. Every earlier revision stays fetchable — GET …/report?revision=N, GET /v1/fcra/receipts/{id}?revision=N — so whoever holds an older PDF can still verify it against the receipt that was issued for it. order.revised tells you when it happens.

Every revision of an order's report — GET /v1/fcra/orders/{order_id}/revisions

GET/v1/fcra/orders/{order_id}/revisionsAuth: X-API-Key

Revision 1 at completion, then one per dispute that changed the report. Fetch any revision's report with ?revision= and its receipt likewise.

Request

Path parameters
FieldTypeDescription
order_id
required
string
Example "fo_ee0b34c5b52fd35b"

Response

200 · application/json

FieldTypeDescription
orderId
string
revision
integerThe current revision.
revisions
array of ReportRevision
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_foundNo such order or adverse action on this account.

The ReportRevision object

One revision of an order's report: revision 1 at completion, a new one each time a dispute changes what the report furnishes. Each has its own hashes and its own receipt.

Returned or accepted by GET /v1/fcra/orders/{order_id}/revisions.

FieldTypeDescription
revision
integerThe revision number: 1 is the report as first completed, each later revision adds one.
reportSha256
stringSHA-256 of the revision's JSON report, which the receipt signs.
pdfSha256
string or nullSHA-256 of the revision's PDF. null when no PDF was produced.
disputeId
string or nullThe dispute that caused it; null for revision 1.
createdAt
string (date-time)When the revision was produced.

Consumer contact and notices

Orders from the hosted consent flow carry the consumer’s e-mail and whether they asked for a copy. For an order placed through the API, set them with PATCH …/consumer before the order completes (the copy of the report goes out on completion) or before starting adverse action (the notices need an address). Every consumer e-mail — the copy, the two adverse notices, the dispute receipt and resolution — is recorded and listed under GET …/notices with whether the provider took it.

Where the consumer's notices go — PATCH /v1/fcra/orders/{order_id}/consumer

PATCH/v1/fcra/orders/{order_id}/consumerAuth: X-API-Key

For an API order: the consumer's e-mail for notices and the copy of the report.

Request

Path parameters
FieldTypeDescription
order_id
required
string
Example "fo_ee0b34c5b52fd35b"
Body · application/json
FieldTypeDescription
email
optional
string or nullWhere the consumer's notices and copy go. null clears it.
phone
optional
string or nullThe consumer's phone. null clears it.
copyRequested
optional
boolean or nullSend the portal link and access code when the order completes.
locale
optional
string or null
one of "en", "es"
en or es for the consumer's notices. null keeps the default.

Response

200 · application/json

FieldTypeDescription
orderId
string
consumer
object
consumer.email
string or null
consumer.phone
string or null
consumer.copyRequested
boolean
consumer.locale
string
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_foundNo such order or adverse action on this account.

Every consumer e-mail for an order — GET /v1/fcra/orders/{order_id}/notices

GET/v1/fcra/orders/{order_id}/noticesAuth: X-API-Key

The copy of the report, the adverse-action notices and the dispute receipts sent for this order.

Request

Path parameters
FieldTypeDescription
order_id
required
string
Example "fo_ee0b34c5b52fd35b"

Response

200 · application/json

FieldTypeDescription
orderId
string
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.
404not_foundNo such order or adverse action on this account.

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