Numeral’s exemption certificate management (ECM) surface covers two related
objects:
certificate_request — an outstanding ask for an exemption certificate
from one of your customers. Trigger one, read its state, cancel it.
exemption_certificate — the submitted certificate itself, with
per-jurisdiction validity, expiration, and a short-lived download URL.
Both surfaces are live-only. Using a sk_test_* key returns
TESTMODE_NOT_SUPPORTED.
Certificate Requests
The certificate_request object represents an outstanding ask for an
exemption certificate from one of your customers. A request is opened when
you (or an integration acting on your behalf) trigger one for a customer; it
closes when the customer submits a valid certificate, the request is
canceled, or it expires.
Lifecycle
┌─────────────────┐
│ pending │ ← initial state
│ (awaiting │
│ customer) │
└────────┬────────┘
│
┌─────────────────┼──────────────────┐
│ │ │
customer cancel request
submits cert via DELETE expires or is
│ │ rejected
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│fulfilled │ │ canceled │ │ invalid │
│(terminal)│ │(terminal)│ │(terminal)│
└──────────┘ └──────────┘ └──────────┘
| Status | Meaning |
|---|
pending | The request is open and the customer has not yet responded. |
fulfilled | The customer submitted a certificate. certificate_id is populated. |
canceled | The request was canceled before fulfillment. |
invalid | The request expired or could not be fulfilled. |
pending and fulfilled are the only non-terminal-on-creation outcomes
clients typically observe.
When to read certificate requests
- Render a customer-facing dashboard of outstanding requests.
- Reconcile your CRM / sales system with which buyers still owe a cert.
- Stop a campaign when your sales team no longer needs the exemption (call
DELETE /tax/certificate-requests/{id}).
Triggering a certificate request
POST /tax/customers/{customer_id}/certificate-requests opens a new request
for an existing customer. Full reference documentation for the trigger
endpoint ships in an upcoming release.
Reading a fulfilled request’s certificate
Once status flips to fulfilled, the certificate_id field is populated
with the cert_* id of the submitted certificate. Fetch it via
GET /tax/certificates/{certificate_id}
to read its status, jurisdictions, and download URL.
Example
curl https://api.numeralhq.com/tax/certificate-requests?status=pending&limit=5 \
-H "Authorization: Bearer sk_live_xxx" \
-H "X-API-Version: 2026-03-01"
{
"object": "list",
"certificate_requests": [
{
"id": "cert_req_b2f1e4a3-9c0d-4e7a-8b1f-2d5a6e7b8c9d",
"object": "tax.certificate_request",
"status": "pending",
"customer": {
"id": "cust_6126acaf-7379-411a-8ada-00005bac0715",
"reference_customer_id": "20506"
},
"certificate_id": null,
"certificate_type_id": "US-CA-CDTFA-230",
"jurisdictions": ["US-CA"],
"created_at": "2026-06-10T18:24:09.123Z",
"updated_at": "2026-06-10T18:24:09.123Z",
"expires_at": "2026-07-10T18:24:09.123Z",
"livemode": true
}
],
"has_more": false
}
Exemption Certificates
The exemption_certificate object represents a tax exemption certificate
submitted by one of your customers. Use the certificate endpoints to render
exemption state in your own UI, sync validity / expiration into your system
of record, and offer a download link to the original document.
Public status vocabulary
The status field uses a deliberately narrow public vocabulary — Numeral’s
review pipeline runs many internal states that are not surfaced.
| Status | Meaning |
|---|
processing | Numeral’s review pipeline is still working on the certificate. |
needs_info | Additional information is required before approval. |
active | The certificate is valid and in effect. |
expiring | The certificate will expire soon. |
expired | The certificate has lapsed. May be renewable depending on jurisdiction. |
invalid | The certificate was rejected, revoked, or could not be validated. |
expiring and expired are kept distinct from invalid so you can
differentiate a lapsed but renewable certificate from a revoked or rejected
one.
A top-level status reflects the certificate as a whole. Each entry in
jurisdictions[] carries its own status — a certificate may be active
in one jurisdiction and expired in another.
Per-jurisdiction validity
Multi-state certificates expose one entry per covered jurisdiction:
{
"jurisdictions": [
{
"jurisdiction_id": "US-CA",
"status": "active",
"effective_date": "2026-01-01",
"expiration_date": "2027-01-01"
},
{
"jurisdiction_id": "US-TX",
"status": "expiring",
"effective_date": "2026-01-01",
"expiration_date": "2026-07-15"
}
]
}
Treat the per-jurisdiction status as authoritative when calculating whether
a buyer is exempt in a specific state — the top-level status is a summary
view.
Downloading the document
GET /tax/certificates/{certificate_id} returns a pre-signed download_url
that expires one hour after issuance. Re-fetch the certificate to mint a
fresh URL. download_url is null until the certificate is fully ingested
(a processing certificate may have no document attached yet).
Treat download_url as confidential. Anyone with the URL can read the
certificate until it expires.
Example
curl https://api.numeralhq.com/tax/certificates/cert_a8f3d2c1-... \
-H "Authorization: Bearer sk_live_xxx" \
-H "X-API-Version: 2026-03-01"
{
"id": "cert_a8f3d2c1-1b9a-4c5e-8d7e-6f4a3b2c1d0e",
"object": "tax.exemption_certificate",
"status": "active",
"certificate_type": {
"id": "12",
"name": "California Resale Certificate (CDTFA-230)",
"certificate_identifier": "US-CA-CDTFA-230"
},
"customer": {
"id": "cust_6126acaf-7379-411a-8ada-00005bac0715",
"reference_customer_id": "20506"
},
"jurisdictions": [
{
"jurisdiction_id": "US-CA",
"status": "active",
"effective_date": "2026-01-01",
"expiration_date": "2027-01-01"
}
],
"effective_date": "2026-01-01",
"expiration_date": "2027-01-01",
"created_at": "2026-01-02T10:15:23.456Z",
"updated_at": "2026-01-05T11:00:00.000Z",
"livemode": true,
"download_url": "https://signed.example.com/...?X-Amz-Expires=3600&..."
}