# Datasource Background Check Partner API > Order and track background checks for the churches you serve. Connect a church once (on a page we host, or with POST /clients), then order checks by applicant name and email; we email the applicant for their details and consent, and send you signed webhooks as checks progress. REST + JSON, API key auth. You never handle SSNs, dates of birth, card numbers or passwords. ## Rules for AI agents - Base URLs: test https://dev.partners.cbgc.io (keys pk_test_...), production https://partners.cbgc.io (keys pk_live_...). Send the key as `X-Api-Key: pk_test_YOUR_KEY` (or `Authorization: Bearer ...`), from a server only. - Address a church as `{clientRef}`: our `clientId` (`cl_…`) or your own `externalClientId`. Address a check as `{checkRef}`: its `id` (`chk_…`) or your `externalIdentifier`. Key your stored checks by `id`. - Order by `level` (1 to 6, from GET /products). Ordering is billable. - The CHMS must collect each applicant's job location and state of employment from the church and send them as `jobLocation` and `stateOfEmployment` (both or neither) on every order; some levels refuse an order without them. Never guess them or use the church's own address. - A `CREATED` check's `stage` is `awaiting_applicant`, then `applicant_ready` (held: someone at the church must review and release it in the Datasource portal at the client's `portalUrl`; we cannot release it from the API) or `in_progress`, then a final status. Show `applicant_ready` to staff as needing action. - `expirationDate` is set only on `CLEAR`/`REVIEW`: `completedAt` plus the church's `checkValidityYears` (PUT /clients/{clientRef}/settings, 1 to 5), else your account default (PUT /settings, default 2). An unexpired result blocks a new order for that applicant unless `forceReorder`. - An `ERROR` check (and its check.updated) has `errorCode` + `errorMessage`: show the message to staff; `missing_job_location` means send jobLocation and stateOfEmployment and order again. Treat unknown codes like `provider_rejected`. - Re-send an applicant's invitation with POST /clients/{clientRef}/checks/{checkRef}/remind (only while awaiting_applicant, at most hourly). An expired invitation ends the check as ERROR `invitation_expired`. - `check.expiring` arrives 30 and 7 days before a CLEAR/REVIEW check's expirationDate. CLEAR/REVIEW checks carry `reportUrl` (portal link; needs the church's sign-in); finished checks carry `charges` (USD). - GET /settings/webhook-deliveries shows the last 30 days of delivery attempts to your webhook endpoint. - Optional `applicantPhone` (batch: `applicants[].phone`), a 10-digit US or Canadian mobile number: the invitation is also texted to it. - Always send your own `externalIdentifier` (≤ 100 characters, unique across all your churches) and reuse it on every retry: a retry never creates a second check. A `409 duplicate_check` on a retry means the first attempt worked: use `order` from the body. - Never set `forceReorder` after a `502`. A 502 whose body is a check (`status` PENDING) resolves on its own within about an hour; a 502 with `code` `upstream_unavailable` created nothing and is safe to retry. - Errors are RFC 9457 problem details with a stable `code`; branch on HTTP status, then `code`. Never on `title` or `detail`. - Verify `X-Partner-Signature` on every webhook: lowercase hex HMAC-SHA256 of the raw body, keyed with the whole `whsec_...` secret, compared in constant time. Answer 2xx within 15 seconds. - Webhooks are at least once and unordered: drop repeats by `eventId`; for each check keep the state with the latest `timestamp`. - Connect a church with POST /connect/sessions (server side), redirect the browser to `connectUrl`, and confirm with the `client.connected` webhook or GET /connect/sessions/{sessionId}. Never treat the return redirect alone as proof. - Register your webhook URL and every connect `returnUrl` with PUT /settings first (https only). - Run a nightly reconciliation per church: GET /clients/{clientRef}/checks?updated_since=...&limit=500, following `nextCursor` until null. - Show prices with their `feesNote` ("Plus pass-through fees."). - Ignore unknown response fields, enum values and webhook events. ## Docs - [Integration guide](https://partners.cbgc.io/docs/guide.md): concepts, every flow end to end, code samples, limits - [Error catalog](https://partners.cbgc.io/docs/errors.md): every `code`, its HTTP status, and whether a retry is safe - [Changelog](https://partners.cbgc.io/docs/changelog.md): dated API changes - [OpenAPI 3.1](https://partners.cbgc.io/openapi/v1.json): machine-readable reference with examples - [Interactive reference](https://partners.cbgc.io/scalar) - [Everything in one file](https://partners.cbgc.io/llms-full.txt): this file, the guide, the error catalog, a section per operation and per webhook with full JSON examples The test environment serves the same documents at https://dev.partners.cbgc.io, plus its test-environment routes.