Cert check · API

The cert check, by API.

The bulk check for a business that checks slabs every day: before a buy, a consignment or vault intake, a loan against a collection or a claim. Send a list of certs; each comes back with what the record shows and the grader’s own lookup.

Certs a call
500
Calls a minute per key
10
Graders
5
Certs kept
None

Who it is for

The people who carry the loss, at the moment they decide.

  1. Marketplaces

    Before a listing goes live or an order ships: the slabs in a seller’s upload, checked as a batch.

  2. Auction houses

    At consignment intake, before the catalogue: every cert in the lot list.

  3. Vaults and tokenized-card platforms

    At vault intake and before a token is minted against a slab: one cert, one record.

  4. Dealers and pawn

    Before a buy: a collection’s cert list, checked while the seller waits.

  5. Lenders

    Before a loan against a collection, and at each top-up: the collateral list, checked as a batch.

  6. Insurers

    At underwriting and when a claim names slabs: what the record shows on each cert.

What each row carries

The bulk page’s four flags, row for row.

  1. 01

    The format

    Whether each number is in the grader’s usual shape. A number out of shape is usually a typing slip.

  2. 02

    The cloned flag

    The same cert more than once in the call, or more than one vault token naming it in the public platform index our watch reads (Collector Crypt).

  3. 03

    The loss register

    Whether a cert has an open report in the Brich House loss register: the status and the reference, nothing about the owner or the loss.

  4. 04

    The grader’s lookup

    A link to the grader’s own record for every cert. We link to it; we never fetch or copy it.

The API runs the bulk page’s own code: the same reads, the same flags and the same words. A call and a run of the same list on /check/bulk answer alike. Nothing is fetched from a grader or any paid source.

The request

One POST, up to 500 certs.

Route
POST https://brich.house/api/v1/cert-check
Headers
Authorization: Bearer <key> and Content-Type: application/json. A key starts bhcert_; keep it on your server, never in a page or an app.
Body
{ "certs": [ { "grader": "PSA", "cert": "12345678" } ] }, 1 to 500 items. grader is PSA, CGC, BGS (Beckett), SGC or TAG. Send cert as a string, so leading zeros and SGC’s hyphen stay as written.

With curl:

curl -X POST https://brich.house/api/v1/cert-check \
  -H "Authorization: Bearer $BRICH_HOUSE_CERT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"certs":[{"grader":"PSA","cert":"12345678"},{"grader":"CGC","cert":"4012345001"},{"grader":"PSA","cert":"012345678"}]}'

The answer

JSON, one row per cert, in the order sent.

as_of
When the watch’s index was last read (ISO 8601), or null when the watch could not be read or no row needed it.
checked_at
When the call was answered.
summary
The counts for the call, as the bulk page’s summary: rows, checked, cloned, repeatedInList, multiToken, registerHits, invalid, and the state of each read (ok, unavailable or not_needed).
results[]
One row per item, in the order sent. line is the item’s position in certs, from 1.
results[].format
ok (the grader’s usual format), unusual, or unreadable (no cert number could be read).
results[].inList, firstLine
How many items in this call carry the same cert, and the first line it appeared on when this row repeats it.
results[].watch
state (found, not_found, not_covered for TAG, unavailable), tokens, listed and the vault names the index gives.
results[].register
state (open, none, unavailable) and, when open, the reference. Never anything about the owner or the loss.
results[].cloned
true when the same cert is in the call more than once, or more than one vault token names it.
results[].lookupUrl
The grader’s own lookup for the cert.
results[].shows
The row in plain words, exactly as the bulk page shows it. Every line ends with the grader’s own lookup and the card in hand deciding.
usage
This key’s month (UTC): rows_this_call, rows_used, monthly_rows, rows_left and resets_at.
note
The line every answer carries: a record check is not a physical authentication.

The answer to the request above, with made-up certs and made-up reads. The third item repeats the first (a leading zero is matched as the register and the watch match it), so both carry the cloned flag; the second is named by two vault tokens.

{
  "as_of": "2026-10-27T11:00:00.000Z",
  "checked_at": "2026-10-27T14:05:09.000Z",
  "summary": {
    "rows": 3,
    "checked": 3,
    "cloned": 3,
    "repeatedInList": 2,
    "multiToken": 1,
    "registerHits": 0,
    "invalid": 0,
    "over": 0,
    "watch": "ok",
    "register": "ok",
    "indexAsOf": "2026-10-27T11:00:00.000Z"
  },
  "results": [
    {
      "line": 1,
      "grader": "PSA",
      "cert": "12345678",
      "format": "ok",
      "note": null,
      "inList": 2,
      "firstLine": null,
      "watch": {
        "state": "not_found",
        "tokens": 0,
        "listed": 0,
        "vaults": []
      },
      "register": {
        "state": "none"
      },
      "lookupUrl": "https://www.psacard.com/cert/12345678",
      "cloned": true,
      "shows": "The same cert appears 2 times in this list. PSA’s own lookup and the card in hand decide."
    },
    {
      "line": 2,
      "grader": "CGC",
      "cert": "4012345001",
      "format": "ok",
      "note": null,
      "inList": 1,
      "firstLine": null,
      "watch": {
        "state": "found",
        "tokens": 2,
        "listed": 1,
        "vaults": [
          "Vault A",
          "Vault B"
        ]
      },
      "register": {
        "state": "none"
      },
      "lookupUrl": "https://www.cgccards.com/certlookup/4012345001/",
      "cloned": true,
      "shows": "The record shows 2 vault tokens naming this cert in the Collector Crypt index as of 27 Oct 2026 (1 still listed). One slab should carry one record; this is a reason to look, not a finding. CGC’s own lookup and the card in hand decide."
    },
    {
      "line": 3,
      "grader": "PSA",
      "cert": "012345678",
      "format": "ok",
      "note": null,
      "inList": 2,
      "firstLine": 1,
      "watch": {
        "state": "not_found",
        "tokens": 0,
        "listed": 0,
        "vaults": []
      },
      "register": {
        "state": "none"
      },
      "lookupUrl": "https://www.psacard.com/cert/012345678",
      "cloned": true,
      "shows": "The same cert is already on line 1 of this list (2 times in all). PSA’s own lookup and the card in hand decide."
    }
  ],
  "usage": {
    "month": "2026-10",
    "rows_this_call": 3,
    "rows_used": 1203,
    "monthly_rows": 5000,
    "rows_left": 3797,
    "resets_at": "2026-11-01T00:00:00.000Z"
  },
  "note": "A record check is not a physical authentication. It shows what the records we read hold on each number; the grader's own lookup and the card in hand decide. Brich House has no affiliation with any grader."
}

The limits

Per call, per minute, per month.

A call
Up to 500 certs and 128 KB of body.
A minute
10 calls per key, as a bucket that refills evenly over the minute. The bucket lives on the server instance that answered, so it is a fuse against a tight loop; the monthly count is the record.
A month
Each key has a monthly row allowance (5,000 unless agreed otherwise), counted in rows sent, by calendar month in UTC. A call that does not fit in what is left is refused whole with 429, before anything is checked; every answer says how many rows are left. Calls sent at the same instant are each checked against the count before them.
Status codes
Errors answer with error, message and docs.
  • 200The answer.
  • 400bad_request or invalid_json: not JSON, not { certs: [...] }, no certs, or an item without a grader the check reads (PSA, CGC, BGS, SGC, TAG) or a cert. The message names the item.
  • 401unauthorized: no key, a key not recognised, or a revoked key.
  • 413too_large or too_many_rows: a body over 128 KB, or more than 500 certs.
  • 429rate_limited: past 10 calls a minute (Retry-After, in seconds). allowance_used: the call does not fit in what is left of the month; nothing is checked, and the message says how many rows are left and when the month resets.
  • 503unavailable: the key store could not be read just now. Try again in a few minutes.
  • 500internal_error: our side. Write to hello@brich.house.

How to use the answer

The record shows. The grader’s lookup and the card in hand decide.

  1. 01

    A record check is not a physical authentication.

    Each row says what the records we read hold on that number. It is not a grading, an appraisal or an opinion on any card.

  2. 02

    A flag is a reason to look, not a finding.

    A re-listed token or a typing slip can raise the cloned flag. Open the grader’s own lookup and match the card, the label and the images to the slab in hand.

  3. 03

    An open loss-register report means stop and call.

    The row carries the reference. Do not complete the purchase; contact Brich House with the reference, and a person takes it from there.

  4. 04

    Things, never people.

    The answer is about the slab and its record. Nothing in it is about a seller, an owner or anyone behind a cert, and nothing should be read that way.

  5. 05

    Show your users the words as given.

    If you show a row to your own staff or customers, show the shows line as it is, with the grader’s lookup beside it.

Request a key

Tell us what you check, and we reply.

Keys are issued by hand for now, each with a monthly row allowance set for the business. The key is shown once to us and sent to you; we keep only a hash of it.

The name your customers know.

example.com is enough.

Buys, consignment or vault intake, loans against collections, claims: the moment and a rough count.

Anything that helps us reply well: the graders you see most, your systems, a timeline.

What you type here is read by Brich House and answered from hello@brich.house. It is never published, never sold and never used for anything else. Privacy

Questions

Is there an API to check PSA certs in bulk?
Yes, for businesses: POST up to 500 PSA, CGC, Beckett, SGC or TAG certs a call to /api/v1/cert-check with a key, and each comes back with the format, the cloned flag, the loss register and a link to the grader’s own lookup. It is the same check as the free bulk page.
Does the API read the grader’s own record?
No. Each row links to the grader’s own lookup; we never fetch or copy a grader’s record, and Brich House has no affiliation with any grader. The record check narrows the list; the grader’s lookup and the card in hand decide.
Are the certs we send kept?
No. The certs live only in the request. Each key’s usage is kept as counts: rows and calls a day. Nothing about anyone behind a cert is read, kept or returned.
How do we get a key?
Request one with the form on this page. Brich House reads every request and issues keys by hand for now, with a monthly row allowance set for the business.