# Verification API and MCP

Run an exclusion check and get back a sealed, publicly linkable
verification record: the same record the site produces, created from your
vendor-onboarding system instead of a browser. The canonical HTML version
is https://federal.contractors/docs. The machine-readable spec is https://federal.contractors/openapi.json and the
step-by-step agent guide is https://federal.contractors/agent-setup.md.

Every account receives a one-time allowance of 50 API-created
verification records without charge. Additional record credits are
purchased upfront: $50 for 100 credits ($0.50 per record).
Scheduled monitoring records are included in monitoring service and do not
consume this balance.

Every successful API verification call seals a permanent record. Each record is readable
by anyone who has its link and preserves the query, the entity identity it
resolved, candidate information, and dated source facts. Newly issued audit
packets omit automatic login name and email. Revoking an API key or deleting
the account does not remove or rewrite records already issued.

## Authentication

Send your API key as a bearer token: `Authorization: Bearer fc_...`. Keys
are created at https://federal.contractors/keys and shown once. Only a hash is stored.
API keys are private credentials. Use server-side code or a trusted desktop
client for integrations, and never embed a key in public browser code.
The API and MCP endpoint do not provide cross-origin browser access.

## POST /v1/verify

Body is `{ "query": string }`, a UEI (12 characters), CAGE code, or legal
name (3 to 200 characters). Runs the exclusion check against the latest
successfully loaded, dated SAM.gov Exclusions extract, seals a verification
record, and returns the record reference plus the full evidence payload.

```sh
curl -X POST https://federal.contractors/v1/verify \
  -H "Authorization: Bearer fc_your_key" \
  -H "Content-Type: application/json" \
  -d '{"query": "RZK2AJC7QGA3"}'
```

The response contains:

- `record`: `{ id, formatVersion, sha256, url, scitt }`. New records
  report format version 2. `record.scitt` carries the issuer-asserted
  issuance time, SPKI-derived key id, and `timestamp` metadata with the
  authority, policy OID, and independent timestamp time. `record.url` is
  permanent and public by unguessable id.
- `query`, `matchType` (`"uei"`, `"cage"`, or `"name"`), `checkedAt`
  (UTC timestamp), and `identityStatus`.
- `matchingMethod`, `matchingVersion`, and `normalizationVersion`: the
  exact matching contract used.
- `resultStatus`: `matched_uei`, `potential_match`, or
  `no_active_exclusion_record_matched`.
- `total`, `matches`, and `truncated`: the full candidate count, up to
  200 returned candidate rows, and whether that returned list is
  incomplete. Each candidate carries its identity state, match basis, and
  field-level agreements or contradictions.
- `source`: the SAM.gov Exclusions extract snapshot the check ran against,
  including its artifact name, as-of and retrieval times, source-freshness
  classification at check time (retrieval age within
  36 hours; source-date lag within 1 day), record
  and invalid-row counts, byte count, and SHA-256 digest.
- `credits`: `{ included, purchased, used, remaining }`.

## POST /v1/verify/batch

Body is `{ "queries": string[] }` (1 to 100 items). Each successfully
created record consumes one credit. The response is
`{ "results": [...], "credits": ... }`, with an `ok` flag on each item.
Successful items carry the query, match type, result status, candidate
total, truncation and matching versions, and record reference. Failed items
carry their own error, including credit exhaustion. Full evidence remains
at each successful record URL.

## GET /v1/records/{id}

Fetches an existing sealed record by id (`vr_...`). Free and keyless; the
unguessable id is the capability. It returns the format version,
canonicalization method, sealed results, source provenance, separate check,
issuer, independent timestamp, and source times, SHA-256 seal, and Signed
Statement metadata when present. Operational account-ownership fields and
canonical-byte storage columns are not exposed. Any identity already sealed
inside a historical packet remains part of its immutable payload. The
permanent page links to bare statement and offline bundle downloads. Use
this route to re-fetch evidence without spending a credit.

## Manual sealing versus API sealing

Manual sealing from the browser (the exclusion check page) stores the exact
completed check referenced by a one-time attestation through
`POST /api/records` with `{ "attestation": string }`; client-supplied
evidence is never accepted and the source query is never rerun. Manual
sealing carries daily allowances of 20 records per IP address
without an account and 100 records per day signed in, and never
consumes API credits. API sealing (`POST /v1/verify`,
`POST /v1/verify/batch`, or the MCP tools below) authenticates an API key
and consumes one prepaid record credit per record created.

## MCP server

The API also speaks Model Context Protocol, so Claude, Cursor, or any
MCP-compatible assistant can run checks directly. Point a streamable HTTP
MCP client at `https://federal.contractors/mcp` with your API key as a bearer header. Three
tools: `verify_entity` with `{ "query": string }` runs one check and seals
a record (one credit), `verify_batch` with `{ "queries": string[] }` checks
up to 100 entities (one credit per record), and `get_record` with
`{ "id": string }` fetches an existing sealed record for no charge.

## Credits and errors

The single-check response includes the resulting credit balance. The batch
response reports a top-level balance after its last successful item, or
`null` when no item succeeds. Existing record retrieval and seal validation
consume no credits. Non-2xx HTTP responses use
`{ "error": { "code": <http status>, "message": "..." } }`.
Per-item batch failures are reported inside a successful HTTP batch response.

- `400`: malformed body. Fix the request, do not retry as-is.
- `401`: missing or invalid key.
- `402`: no record credits remain in the account balance. Check the balance
  on https://federal.contractors/keys. Wait for any pending purchase to be confirmed before
  deciding whether to purchase more credits.
- `429`: request rate limit. The response carries a `Retry-After` header;
  honor it before retrying.

## Interpreting results

- `resultStatus: "no_active_exclusion_record_matched"` means no active
  exclusion record matched under the recorded method, as of the extract
  named in `source`. It is not a present-tense status and not a verdict.
- `resultStatus: "matched_uei"` means at least one active exclusion record
  matched the searched UEI exactly.
- `resultStatus: "potential_match"` means a person must review the
  candidate basis and field agreements or contradictions.
- `matchType` describes how the input was classified. It is not the
  outcome.
- `truncated: true` means the returned candidate list is incomplete. Do
  not present it as a complete candidate review.

## Reading the assurance layers

Recomputing the SHA-256 seal checks whether the canonical payload matches
the printed checksum. The checksum alone does not authenticate
federal.contractors as issuer or establish independent time. New
production records add an RFC 9943 SCITT PS256 issuer signature over the
exact format 2 bytes and a DigiCert RFC 3161 timestamp over the RFC 9921
signature imprint. The timestamp proves that issuer signature existed no
later than the Timestamp Authority's time. Neither mechanism proves check
execution time, source truth, matching correctness, identity, or a legal
outcome. No independent Transparency Service receipt is attached. The
record is evidence of diligence, not a verdict.

## Keyless endpoints

`GET https://federal.contractors/health` (liveness) and `GET https://federal.contractors/v1/stats` (public
registry stats) need no key. Every successful `/v1/verify` call consumes a
real credit and seals a real record, so test with one call, not a loop.

## Methodology

Sources, freshness rules, sealing, signatures, timestamps, and limits are
described in the methodology reference at https://federal.contractors/methodology.md. The
record is evidence of diligence, not a verdict. federal.contractors is not
affiliated with the U.S. government.
