API Reference
The API behind the research path: 27 federal sources and 3M+ resolved US entities. Authenticate with an API key, query by name or identifier (CIK, EIN, LEI, DUNS, UEI, NPI, CRD), stream events, or ask in natural language.
Authentication
All API requests require an API key passed in the X-API-Key header. Keys use the format pt_live_ followed by your unique key string.
You can generate and manage API keys from your dashboard. Keep your keys secure and never expose them in client-side code.
# Include your API key on each request curl https://api.publictrace.dev/v1/entity/search?q=Acme \ -H "X-API-Key: pt_live_your_key_here"
Base URL
All API endpoints are served from a single base URL. Use HTTPS for all requests.
https://api.publictrace.dev/v1
Response Format
All responses are returned as JSON with a consistent envelope structure. Successful responses include a data field, a meta field with request metadata, and a pagination field for list endpoints.
{ "data": [ ... ], "meta": { "request_id": "req_abc123", "timestamp": "2025-03-15T10:30:00Z", "credits_used": 1, "credits_remaining": 4999 }, "pagination": { "page": 1, "per_page": 25, "total": 142, // null on fuzzy-search endpoints (count too costly) "has_more": true } }
Interactive Reference
This page is the curated, narrative reference. For a complete, always-current machine reference generated directly from the running API, use the interactive OpenAPI surfaces:
X-API-Key to send live, authenticated requests.
/openapi.json for tools that default to the root.
Single fuzzy-name search across the entire dataset. Returns two kinds of results in one relevance-ranked list:
- Verified entities — rows from
entitiesthat resolved to a canonical entity_id, with strong identifiers (CIK / EIN / LEI / UEI / DUNS). - Uncatalogued name clusters — rows from the orphan lake (
orphan_records) that didn't bind to a strong-ID entity. Useful for surfacing data on small businesses, sole-prop sellers, vessels, persons, etc. that never got a federal identifier.
Each result carries a type field ("entity" or "uncatalogued") so the UI can render two card variants. Sort is primary by similarity score; on equal scores, verified entities win.
Parameters
all (default), company, person, vessel, aircraft, other. Has no effect on verified entities (they're always companies).
false. These results carry is_provisional=true; an EIN alone does not establish a verified company identity.
false, returns only verified entities. Default true.
1.
25.
curl "https://api.publictrace.dev/v1/search?q=Pfizer&per_page=5" \ -H "X-API-Key: pt_live_your_key_here"
{ "data": [ { "type": "entity", "entity_id": "ent_2df0fbed55155577", "name": "PFIZER INC", "state": "NY", "identifiers": [ {"type": "cik", "value": "0000078003"}, {"type": "ein", "value": "13-5315170"} ], "record_count": 330, "score": 1.0 }, { "type": "uncatalogued", "name": "PFIZER MANUFACTURING LLC", "name_normalized": "pfizer manufacturing", "record_subject": "company", "record_count": 8, "sources": ["epa_echo", "osha_inspection"], "states": ["PR", "MI"], "score": 0.87 } ], "pagination": { "page": 1, "per_page": 5, "has_more": true }, "meta": { "credits_used": 1, "credits_remaining": 9999 } }
When you only want linked company profiles, pass include_uncatalogued=false — or use /v1/entity/search directly (same shape, entity rows only, no orphan side).
Search linked company profiles — the strong-ID-linked subset of /v1/search. OSHA-only employers are provisional and excluded from default name searches. Set include_provisional=true on either search endpoint to include them; results and entity profiles expose is_provisional. Exact identifier lookups remain available and labeled. A non-provisional profile does not imply that every identifier is verified.
Parameters
22-1024240).
0000200406).
CA).
sec, epa, osha, fda, ftc, irs, sam, ofac, cfpb, hhs_oig, dol_whd.
1.
25.
curl "https://api.publictrace.dev/v1/entity/search?q=Pfizer&source=fda" \ -H "X-API-Key: pt_live_your_key_here"
{ "data": [ { "entity_id": "ent_2df0fbed55155577", "name": "PFIZER INC", "state": "NY", "city": "New York", "sic_code": "2834", "identifiers": [ {"type": "ein", "value": "46-3996345"}, {"type": "lei", "value": "765LHXWGK1KXCLTFYQ30"}, {"type": "duns", "value": "001326495"}, {"type": "cik", "value": "0000078003"} ], "sources": ["fjc_civil", "usaspending_contracts", "sec", "fda", "lda", "doj", …], "record_count": 5920, "subsidiary_count": 468, "source_summary": [ {"source": "fjc_civil", "count": 4984}, {"source": "usaspending_contracts", "count": 314} ], "role": "public_company" } ], "meta": { "request_id": "req_924381e7dc04", "credits_used": 1, "credits_remaining": 19941 }, "pagination": { "page": 1, "per_page": 25, "total": null, "has_more": true } }
Retrieve the full entity profile, including all known identifiers, source coverage, and aggregate statistics across all federal data sources.
curl "https://api.publictrace.dev/v1/entity/ent_321d75" \ -H "X-API-Key: pt_live_your_key_here"
{ "data": { "entity_id": "ent_e36d8ec996d299a5", "name": "AMAZON COM INC", "state": "WA", "city": "SEATTLE", "sic_code": "5961", "naics_code": null, "identifiers": [ {"type": "cik", "value": "0001018724"}, {"type": "ein", "value": "91-1646860"}, {"type": "lei", "value": "ZXTILKJKG63JELOEG630"} ], "alternate_names": ["AMAZON.COM, INC.", "AMAZON.COM SERVICES, INC.", "Amazon"], "sources": ["sec", "sec_13dg", "lda", "fjc_civil", "osha_inspection", "dol_whd", "gleif"], "record_count": null, "subsidiary_count": null, "source_summary": [], "role": null, "record_counts": { "sec": 109, "fjc_civil": 1430, "dol_whd": 24, "osha_inspection": 27 // …one count per source }, "source_records": [ { "source": "sec", "record_type": "filing", "record_date": "2026-04-14", "title": "8-K filing" } // …most-recent records across sources ], "hq": { "address": "410 TERRY AVENUE NORTH", "city": "SEATTLE", "state": "WA", "country": "US", "postal": "98109", "source": "sec_edgar_submissions", "as_of": null }, "sanction_summary": null, "financials": { "revenue_usd": 716924000000, "net_income_usd": 77670000000 // …assets, debt, employees + period_end fields }, "risk_score": { "score": 34, "tier": "medium", "methodology_version": "v3", "computed_at": "2026-05-31T03:56:35Z" }, "created_at": "2026-05-02T00:38:29Z", "updated_at": "2026-05-08T03:58:16Z" }, "meta": { "request_id": "req_5fb9eb7254fb", "credits_used": 1, "credits_remaining": 19940 }, "pagination": null }
Retrieve violations, citations, and enforcement actions for a specific entity. Includes OSHA citations, EPA violations, FDA recalls, FTC enforcement, and SAM.gov exclusions.
Parameters
osha, epa, fda, ftc, sam.
2024-01-01).
curl "https://api.publictrace.dev/v1/entity/ent_321d75/violations?source=osha&min_penalty=10000" \ -H "X-API-Key: pt_live_your_key_here"
{ "data": [ { "record_id": "osha_violation_osha_vio_347970709_01001", "entity_id": "ent_e36d8ec996d299a5", "source": "osha_violation", "violation_type": null, "description": "OSHA Other violation (citation 01001)", "violation_date": "2025-06-13", "penalty_amount": null, "status": null, "url": "https://www.osha.gov/ords/imis/InspectionNr.search?id=347970709", "url_label": "OSHA inspection detail", "data": { "_state": "VA", "viol_type": "O", "activity_nr": "347970709", "citation_id": "01001" // …source-specific fields }, "created_at": "2026-05-11T23:53:53Z" } ], "meta": { "request_id": "req_c8f8d72bbb16", "credits_used": 1, "credits_remaining": 19939 }, "pagination": { "page": 1, "per_page": 25, "total": 25, "has_more": true } }
Retrieve filings and regulatory submissions for an entity. Includes SEC EDGAR filings, IRS 990 forms, and other regulatory documents.
Parameters
sec, irs.
10-K, 10-Q, 8-K, 990).
curl "https://api.publictrace.dev/v1/entity/ent_321d75/filings?source=sec&filing_type=10-K" \ -H "X-API-Key: pt_live_your_key_here"
{ "data": [ { "record_id": "sec_sec_filing_0001104659-26-042880", "entity_id": "ent_e36d8ec996d299a5", "source": "sec", "filing_type": "8-K", "filing_date": "2026-04-14", "period_of_report": "2026-04-14", "description": "Form 8-K - Current report - Item 7.01 Item 9.01", "url": "https://www.sec.gov/Archives/edgar/data/1018724/000110465926042880/", "url_label": "SEC 8-K filing", "data": { "cik": "0001018724", "form_type": "8-K", "accession_no": "0001104659-26-042880" // …items, entities, resources, etc. }, "created_at": "2026-05-05T05:45:11Z" } ], "meta": { "request_id": "req_df403f187456", "credits_used": 1, "credits_remaining": 19938 }, "pagination": { "page": 1, "per_page": 25, "total": 109, "has_more": true } }
Retrieve a unified, chronological timeline of all events for an entity across all sources. Events include filings, violations, recalls, enforcement actions, and exclusions.
Parameters
false.
curl "https://api.publictrace.dev/v1/entity/ent_321d75/timeline?date_from=2024-01-01" \ -H "X-API-Key: pt_live_your_key_here"
{ "data": [ { "event_id": "dol_whd_5090392", "entity_id": "ent_e36d8ec996d299a5", "event_type": "labor_violation", "source": "dol_whd", "event_date": "2026-05-11", "title": "Amazon.com, Inc.", "description": "Labor violation", "url": null, "url_label": null, "metadata": { "city": "Amarillo", "state": "TX", "case_id": "5090392", "naics_code": "455219" // …source-specific fields } } ], "meta": { "request_id": "req_d5e75b557b68", "credits_used": 1, "credits_remaining": 19937 }, "pagination": { "page": 1, "per_page": 25, "total": 1732, "has_more": true } }
Retrieve OpenSanctions-aggregated list memberships for an entity (OFAC SDN, EU FSF, UN SC, US SAM Exclusions, and 100+ other upstream watchlists), kept separate from /violations so foreign sanction listings don't inflate a regulatory penalty count. Costs 1 credit.
Parameters
sanction, debarment, export.control, crime.terror, reg.action, etc.
us_ofac_sdn, eu_fsf_sanctions, un_sc_sanctions, us_sam_exclusions, etc.
2024-01-01).
1.
1-100. Defaults to 25.
curl "https://api.publictrace.dev/v1/entity/ent_321d75/sanctions?topic=sanction" \ -H "X-API-Key: pt_live_your_key_here"
{ "data": [ { "record_id": "rec_9a1f02", "entity_id": "ent_321d75", "source": "sanctions", "title": "ACME LTD — flagged for sanction (us_ofac_sdn)", "record_date": "2023-08-14", "topics": ["sanction"], "datasets": ["us_ofac_sdn"], "countries": ["ru"], "first_seen": "2023-08-14T00:00:00+00:00", "last_seen": "2026-05-01T00:00:00+00:00", "last_change": "2025-02-10T00:00:00+00:00", "url": "https://sanctionssearch.ofac.treas.gov/Details.aspx?id=12345", "url_label": "OFAC SDN entry", "created_at": "2023-08-15T03:21:00+00:00", "data": null } ], "pagination": { "page": 1, "per_page": 25, "total": 1, "has_more": false } }
Retrieve OSHA inspection records for an entity, including inspections that produced no citation. Each row carries inspection-level fields plus an aggregated child-violation count and total penalty computed on read. Costs 1 credit.
Parameters
F (fatality/catastrophe), G (complaint), I (referral), L (planned), M (monitoring), O (other), R (referral), S (selected).
1.
1-100. Defaults to 25.
curl "https://api.publictrace.dev/v1/entity/ent_321d75/inspections?insp_type=L" \ -H "X-API-Key: pt_live_your_key_here"
{ "data": [ { "record_id": "rec_44ab10", "entity_id": "ent_321d75", "source": "osha_inspection", "activity_nr": "317492051", "open_date": "2024-03-11", "close_case_date": "2024-07-02", "site_address": "1200 Industrial Pkwy", "site_city": "Wichita", "site_state": "KS", "site_zip": "67209", "naics_code": "336411", "insp_type": "L", "insp_scope": "C", "owner_type": "A", "safety_hlth": "S", "nr_in_estab": "850", "violation_count": 3, "total_penalty_usd": 28500, "url": "https://www.osha.gov/ords/imis/establishment.inspection_detail?id=317492051", "url_label": "OSHA inspection detail", "data": { "_state": "KS", "activity_nr": "317492051", "naics_code": "336411", "mail_address": "1200 Industrial Pkwy" // …source-specific fields }, "created_at": "2024-08-01T11:05:00+00:00" } ], "pagination": { "page": 1, "per_page": 25, "total": 1, "has_more": false } }
Retrieve the precomputed risk score for an entity. Methodology v3 is anchor-floor: a binding sanction floors the score at 95, a federal debarment/exclusion at 85, and the remaining points stack from per-dimension and per-source signals. Tiers: critical (80-100), high (50-79), medium (20-49), low (0-19). The score is informational, not a compliance clearance. Free (0 credits).
curl "https://api.publictrace.dev/v1/entity/ent_321d75/risk-score" \ -H "X-API-Key: pt_live_your_key_here"
{ "data": { "entity_id": "ent_e36d8ec996d299a5", "name": "AMAZON COM INC", "score": 34, "tier": "medium", "methodology_version": "v3", "computed_at": "2026-05-31T03:56:35Z", "decay_window_years": 10, "breakdown": { "anchor": { "basis": null, // basis is "binding_sanction", "federal_exclusion", or null "floor": 0, "datasets": [], "stack_points": 33.83 }, // per-source blocks are keyed by source name directly: "dol_whd": { "case_count": 24, "raw_points": 5, "most_recent": "2025-04-01", "decay_factor": 0.884, "decayed_points": 4.42, "total_back_wages": 105061.93 }, // …fda, fjc_civil, osha_violation, epa_icis_fec, sec_enforcement, … "by_dimension": { "workplace": { "sources": ["osha_violation", "dol_whd"], "raw_points": 10.0, "decayed_points": 8.94 }, "enforcement": { "sources": ["fjc_civil", "fda"], "raw_points": 38.0, "decayed_points": 24.9 } // …sanctions, environmental }, "penalty_magnitude": { "raw_points": 0, "total_penalties_usd": 0.0 } }, "sources_consulted": ["dol_whd", "epa_icis_fec", "fda", "fjc_civil", "osha_violation", "sec_enforcement"], "disclaimer": "Informational risk indicator from PublicTrace's public-record corpus..." }, "pagination": null }
Find records in the data lake whose name resembles the entity's canonical name or aliases but could not be deterministically attributed to it — surfaced as unverified enrichment context, explicitly NOT linked in the identifier graph. Costs 1 credit.
Parameters
all, company, person, vessel, aircraft, other. Defaults to all (which excludes persons).
1.
1-100. Defaults to 25.
curl "https://api.publictrace.dev/v1/entity/ent_321d75/orphans?subject=company" \ -H "X-API-Key: pt_live_your_key_here"
{ "data": [ { "orphan_id": 8841920, "source": "osha_inspection", "record_type": "inspection", "record_subject": "company", "name": "Boeing Wichita Inc", "state": "KS", "city": "Wichita", "address": "3801 S Oliver St", "country": "US", "record_date": "2022-09-14", "severity": null, "description": "Planned safety inspection", "score": 0.35, "topics": null, "datasets": null, "url": "https://www.osha.gov/ords/imis/establishment.inspection_detail?id=...", "url_label": "OSHA inspection" } ], // total is null on this fuzzy-search endpoint "pagination": { "page": 1, "per_page": 25, "total": null, "has_more": false } }
Submit a "this entity looks wrong" report against an entity. Idempotent per caller: re-flagging the same entity returns the existing row with already_flagged: true. Free (0 credits).
Request Body
profile, tree, subsidiaries, filings, violations, sanctions, orphans, timeline, benchmark, risk, ask. Unrecognized values are dropped.
curl "https://api.publictrace.dev/v1/entity/ent_321d75/flag" \ -H "X-API-Key: pt_live_your_key_here" \ -H "Content-Type: application/json" \ -d '{"section": "violations"}'
{ "data": { "id": 4192, "entity_id": "ent_321d75", "status": "open", "created_at": "2026-05-30T14:22:00+00:00", "already_flagged": false } }
Expand one uncatalogued (orphan) cluster from a /v1/search result into its underlying records. Pass back the exact name_normalized + subject cluster key (an exact match, not fuzzy). Costs 1 credit.
Parameters
name_normalized key from a /v1/search uncatalogued result. 2-160 characters.
record_subject from the uncatalogued result: company, person, vessel, aircraft, or other.
1.
1-100. Defaults to 25.
curl "https://api.publictrace.dev/v1/search/uncatalogued?name_normalized=acme+roofing&subject=company" \ -H "X-API-Key: pt_live_your_key_here"
{ "data": [ { "orphan_id": 2210045, "source": "dol_whd", "record_type": "case", "record_subject": "company", "name": "Acme Roofing LLC", "state": "TX", "city": "Austin", "address": "450 Congress Ave", "country": "US", "record_date": "2023-06-01", "severity": null, "description": "FLSA back-wages case", "score": 1.0, "topics": null, "datasets": null, "url": "https://enforcedata.dol.gov/views/data_summary.php", "url_label": "DOL WHD case" } ], "pagination": { "page": 1, "per_page": 25, "total": null, "has_more": false } }
List triggered alerts for your account. Returns recent alert events for watched entities, ordered by most recent first.
Add ?narrative=true to enrich alert events with AI-generated explanations. Base cost: 1 credit. With narrative: 3 credits.
Parameters
true, each event gets an extra narrative object (AI-generated explanation). Default false. Raises cost to 3 credits.
1.
25.
curl "https://api.publictrace.dev/v1/alerts?since=2025-03-01T00:00:00Z" \ -H "X-API-Key: pt_live_your_key_here"
{ "data": [ { "record_id": "debarment_NK-GvNa8teaWadLgnrdFriAKc", "entity_id": "ent_466ea17d7311f558", "entity_name": "BOEING CO", "event_type": "entity.event.created", "source": "debarment", "title": "orphan-promoted: The Boeing Company", "event_date": "2025-09-11", "detail_url": "/v1/entity/ent_466ea17d7311f558" } ], "meta": { "request_id": "req_3b72ebe4157e", "credits_used": 1, "credits_remaining": 19933 }, "pagination": { "page": 1, "per_page": 25, "total": 39159, "has_more": true } }
Start watching an entity for new events. When a matching event occurs, a webhook will be sent to your configured URL.
Request Body
entity.violation.created, entity.filing.created, entity.event.created, etc. Default: all.
curl -X POST "https://api.publictrace.dev/v1/alerts/watch" \ -H "X-API-Key: pt_live_your_key_here" \ -H "Content-Type: application/json" \ -d '{ "entity_id": "ent_321d75", "event_types": ["entity.violation.created", "entity.filing.created"], "webhook_url": "https://your-app.com/webhooks/publictrace" }'
{ "data": { "id": 221, "customer_id": 17, "entity_id": "ent_321d75", "event_types": ["entity.violation.created", "entity.filing.created"], "webhook_url": "https://your-app.com/webhooks/publictrace", "created_at": "2025-03-15T10:00:00Z" } }
Stop watching an entity. Removes all webhook subscriptions for the specified entity under your account.
curl -X DELETE "https://api.publictrace.dev/v1/alerts/watch/ent_321d75" \ -H "X-API-Key: pt_live_your_key_here"
{ "data": { "deleted": true, "entity_id": "ent_321d75" } }
List the entities on the caller's watchlist, including watches whose entities have had no events yet (unlike /v1/alerts, which only returns entities with recent events). Each row carries the joined entity name/location plus a count of new events since the watch was last marked seen. Free (0 credits).
curl "https://api.publictrace.dev/v1/alerts/watches" \ -H "X-API-Key: pt_live_your_key_here"
{ "data": [ { "entity_id": "ent_321d75", "entity_name": "Acme Manufacturing Inc", "state": "KS", "city": "Wichita", "event_types": ["entity.violation.created"], "created_at": "2026-05-01T09:00:00+00:00", "last_seen_at": "2026-05-29T18:30:00+00:00", "new_events_count": 2, "last_event_at": "2026-05-30T07:12:00+00:00" } ] }
Bulk-update last_seen_at to now for all of the caller's watches, resetting the per-row new-events badge counts. Idempotent, takes no body. Free (0 credits).
curl -X POST "https://api.publictrace.dev/v1/alerts/watches/mark-seen" \ -H "X-API-Key: pt_live_your_key_here"
{ "data": { "updated": 5 } }
Report the status of the caller's webhook signing secret — whether one is on file and its masked prefix. The full secret is never returned here (only at rotation time). Free (0 credits). Note: this endpoint returns a flat object, not the standard data envelope.
curl "https://api.publictrace.dev/v1/alerts/webhook-secret" \ -H "X-API-Key: pt_live_your_key_here"
{ "has_secret": true, "masked": "pt_whsec_ab…", "rotated_at": "2026-05-10T12:00:00+00:00" }
Generate a new webhook signing secret and return the FULL value — this is the only time it is sent over the wire. Rotation is destructive: any endpoint still validating against the old secret starts failing immediately. Takes no body. Free (0 credits). Returns a flat object, not the standard data envelope.
curl -X POST "https://api.publictrace.dev/v1/alerts/webhook-secret/rotate" \ -H "X-API-Key: pt_live_your_key_here"
{ "secret": "pt_whsec_ab12cd34ef56gh78ij90kl", "rotated_at": "2026-05-30T14:30:00+00:00", "warning": "This is the only time the full secret is shown. Save it now. Subsequent reads return only the masked prefix." }
List recent webhook delivery attempts for the caller's watches, with HTTP status, attempt count, and any last error. Free (0 credits). Returns a flat object keyed on deliveries, not the standard data envelope.
Parameters
pending, sent, failed, gave_up.
1-500. Defaults to 50.
curl "https://api.publictrace.dev/v1/alerts/deliveries?status=failed" \ -H "X-API-Key: pt_live_your_key_here"
{ "deliveries": [ { "id": 9013, "watch_id": 221, "record_id": "rec_44ab10", "entity_id": "ent_321d75", "webhook_url": "https://hooks.example.com/publictrace", "source": "osha_violation", "record_type": "violation", "title": "Serious citation issued", "status": "failed", "attempt_n": 3, "http_status": 500, "last_error": "HTTP 500 from endpoint", "requested_at": "2026-05-30T07:12:30+00:00", "completed_at": "2026-05-30T07:12:31+00:00", "next_retry_at": "2026-05-30T07:42:00+00:00" } ] }
Mark a webhook delivery as pending and due now, resetting its attempt counter so it gets the full retry allowance again. The delivery worker picks it up on its next tick. Takes no body. Free (0 credits). Returns a flat object, not the standard data envelope.
curl -X POST "https://api.publictrace.dev/v1/alerts/deliveries/9013/retry" \ -H "X-API-Key: pt_live_your_key_here"
{ "id": 9013, "status": "pending" }
Send a synthetic test.ping event to a webhook URL so you can verify your endpoint accepts the signature scheme. POSTs synchronously and returns the immediate result; not recorded in deliveries. Free (0 credits). Returns a flat object, not the standard data envelope.
Request Body
webhook_url is used; if none exists, the request 400s.
curl "https://api.publictrace.dev/v1/alerts/test-fire" \ -H "X-API-Key: pt_live_your_key_here" \ -H "Content-Type: application/json" \ -d '{"url": "https://hooks.example.com/publictrace"}'
{ "ok": true, "http_status": 200, "url": "https://hooks.example.com/publictrace", "event_id": "evt_test_1748614200" }
Each webhook we POST to your webhook_url is signed with your
account's webhook secret — the pt_whsec_… value shown once when you
rotate it on the Webhooks page. Verify the signature on
each delivery before trusting the payload.
The signature header
We send a header in Stripe's format:
X-PublicTrace-Signature: t=1748900000,v1=3a7f9c2b…e9
"<t>." + raw_body, keyed with your secret.
How to verify
Recompute the HMAC over the timestamp and raw body, then compare it
constant-time against v1. Three things to get right:
t is more than 300 seconds old, and use a timing-safe comparison.
import hmac, hashlib, time
def verify(secret, raw_body, sig_header, max_age=300):
parts = dict(p.split("=", 1) for p in sig_header.split(",") if "=" in p)
try:
ts = int(parts.get("t", ""))
except ValueError:
return False
if not parts.get("v1") or abs(int(time.time()) - ts) > max_age:
return False
msg = f"{ts}.".encode() + raw_body # raw bytes, not re-encoded JSON
expected = hmac.new(secret.encode(), msg, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, parts["v1"])
# Flask: raw_body = request.get_data() (NOT request.json)
const crypto = require("crypto");
function verify(secret, rawBody, sigHeader, maxAge = 300) {
const p = Object.fromEntries(sigHeader.split(",").map(s => s.split("=")));
const ts = parseInt(p.t, 10);
if (!ts || Math.abs(Date.now() / 1000 - ts) > maxAge) return false;
const expected = crypto.createHmac("sha256", secret)
.update(`${ts}.`).update(rawBody).digest("hex"); // rawBody = Buffer
const a = Buffer.from(expected), b = Buffer.from(p.v1 || "");
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
// app.use(express.raw({ type: "application/json" })) -> req.body is the raw Buffer
func verify(secret string, rawBody []byte, sigHeader string, maxAge int64) bool {
var ts int64
var v1 string
for _, part := range strings.Split(sigHeader, ",") {
kv := strings.SplitN(part, "=", 2)
if len(kv) == 2 && kv[0] == "t" { ts, _ = strconv.ParseInt(kv[1], 10, 64) }
if len(kv) == 2 && kv[0] == "v1" { v1 = kv[1] }
}
now := time.Now().Unix()
if ts == 0 || now-ts > maxAge || ts-now > maxAge { return false }
mac := hmac.New(sha256.New, []byte(secret))
mac.Write([]byte(strconv.FormatInt(ts, 10) + "."))
mac.Write(rawBody)
expected := hex.EncodeToString(mac.Sum(nil))
return hmac.Equal([]byte(expected), []byte(v1))
}
Confirm your handler with the Test fire button on the
Webhooks page — it sends a signed test.ping
through the exact same scheme.
Search for up to 100 entities in a single request. Each item in the entities array uses the same parameters as the entity search endpoint. Ideal for repeatable company research and due diligence workflows.
Request Body
name (or its alias q), ein, and/or cik. Other keys are ignored. Billed 1 credit per object.
curl -X POST "https://api.publictrace.dev/v1/bulk/search" \ -H "X-API-Key: pt_live_your_key_here" \ -H "Content-Type: application/json" \ -d '{ "entities": [ { "q": "Tesla" }, { "ein": "00-0000000" } ] }'
// data is an object: matched rows in "results", unmatched/errored in "failed". // input_index maps each row back to its position in the request array. { "data": { "results": [ { "input_index": 0, "entity_id": "ent_ef4a52e0e920296c", "name": "Tesla, Inc.", "match_score": 0.95 } ], "failed": [ { "input_index": 1, "reason": "no_match" } ] }, "meta": { "request_id": "req_25b18e70ed57", "credits_used": 2, "credits_remaining": 19931 } }
Read your team's AI-call history (prompts, responses, token counts, latency) for the /v1/ask and AI-narrative endpoints. Pro tier or above; lower tiers receive a 403. Cursor-paginated on descending id. Free (0 credits).
Parameters
created_at. Defaults to 7 days ago.
created_at. Defaults to now.
id less than this value. Use the next_cursor from the previous page.
1-200. Defaults to 50.
curl "https://api.publictrace.dev/v1/me/audit-log?limit=50" \ -H "X-API-Key: pt_live_your_key_here"
{ "data": [ { "id": 71204, "request_id": "req_a91f02cd", "endpoint": "/v1/ask", "prompt": "How many OSHA violations does Acme have?", "response": "Acme Manufacturing Inc has 8 OSHA violations on record.", "input_tokens": 1820, "output_tokens": 142, "cached": true, "latency_ms": 940, "created_at": "2026-05-30T13:01:00+00:00" } ], "pagination": { "limit": 50, "next_cursor": 71155 } }
Read or update your account's notification preferences (email-digest cadence and webhook delivery toggle). Use GET to retrieve and PUT to update. Free (0 credits).
curl "https://api.publictrace.dev/v1/me/notifications" \ -H "X-API-Key: pt_live_your_key_here"
{ "data": { "email_cadence": "daily", "webhook_enabled": true, "last_email_digest_at": "2026-05-30T06:00:00+00:00", "webhook_configured": true } }
Partial update — only the fields you send are changed; unset fields keep their current value. Flipping a channel from off to on resets its cursor so the first digest/delivery covers only events after the flip.
Request Body
off, daily, or weekly. Any other value returns 422.
curl -X PUT "https://api.publictrace.dev/v1/me/notifications" \ -H "X-API-Key: pt_live_your_key_here" \ -H "Content-Type: application/json" \ -d '{"email_cadence": "weekly", "webhook_enabled": true}'
{ "data": { "email_cadence": "weekly", "webhook_enabled": true, "last_email_digest_at": "2026-05-30T06:00:00+00:00", "webhook_configured": true } }
AI & Analytics
PublicTrace offers AI and analytics endpoints that work across 27 federal sources. AI endpoints (Ask, Summary) use LLM analysis and cost 3 credits per call. Analytics endpoints (Benchmark, Corporate Tree) use SQL and cost 1 credit. SEC Facts costs 1 credit for XBRL data or 3 credits with AI extraction. Responses are cached for 24 hours — cache hits don't consume credits.
Natural Language Queries
Use case: A compliance analyst needs to find all companies in California with OSHA penalties above $100K in the last year. Instead of building a complex query, they type the question in plain English.
AI translates the question into structured API parameters, executes the query, and returns formatted results with source attribution.
Entity Risk Summary
Use case: A procurement team is onboarding a new vendor and needs a quick risk overview before the approval meeting.
AI reads the entity's complete record — violations, filings, sanctions, complaints — across all sources and generates a structured JSON briefing with critical flags, penalty totals, and timeline highlights.
Competitive Benchmark
Use case: A risk analyst wants to know if a company's violation rate is normal for its industry.
Returns SIC-peer percentiles for OSHA, EPA, and DOL counts. Deterministic SQL, no LLM.
Corporate Tree
Use case: Due diligence requires understanding parent/subsidiary relationships before approving a deal.
Walks the ownership graph built from SEC Exhibit 21 subsidiaries, SEC 13D/G beneficial ownership, and GLEIF parent/child relationships. SQL, no LLM.
SEC Fact Extraction
Use case: An analyst wants key financial metrics from a company's latest 10-K without reading the full filing.
Extracts structured facts from SEC XBRL filings. Optional local LLM extraction for complex data — no external API cost.
Translate a natural language question into structured API queries and return results. Costs 3 credits.
Request Body
query (string, required) — Natural language question, 1–1000 characters.
entity_id (string, optional) — Focal PublicTrace entity. Include this when the question is asked from an entity profile so pronouns such as “it” and “this company” resolve correctly.
entity_name (string, optional) — Display name for the focal entity. Send it with entity_id to give the model readable context.
POST /v1/ask X-API-Key: pt_live_xxx Content-Type: application/json { "query": "What are its largest OSHA penalties?", "entity_id": "ent_466ea17d7311f558", "entity_name": "The Boeing Company" }
// The response is wrapped in the standard { data, meta } envelope. // results[] rows are the RAW columns of whatever query the engine ran, // so the keys vary by question; each row carries an enriched _entity block. // match_confidence: "high" | "low" | "none" | "n/a". { "data": { "interpretation": "Companies with OSHA penalties over $100,000 in Texas during 2024", "match_confidence": "n/a", "api_calls_made": [ { "endpoint": "sql", "description": "Database query", "result_count": 12, "error": null } ], "results": [ { "entity_id": "ent_a1b2c3", "name": "Gulf Coast Manufacturing Inc", "violation_count": 3, "total_penalty": 287500, "_entity": { "name": "Gulf Coast Manufacturing Inc", "state": "TX" /* …identifiers, hq */ } } ] }, "meta": { "request_id": "req_…", "credits_used": 3, "credits_remaining": 4997 } }
Generate an AI risk briefing for an entity. Costs 3 credits. Cached for 24 hours.
All numeric fields (violations, sanctions_and_exclusions, filings, etc.) are computed directly from the underlying records and are exact. The model only writes the prose fields (summary, critical_flags, timeline_highlight) from those figures — it never invents a number. total_count / total_penalties_usd count enforcement actions only; mandatory self-reports (OSHA injury logs, EPA TRI releases) are tracked separately under self_reports.
GET /v1/entity/ent_321d75/summary X-API-Key: pt_live_xxx
{
"company_name": "Johnson & Johnson",
"summary": "Appears in 9 federal sources; 62 enforcement records totaling $890,000 in penalties, concentrated in FDA and OSHA.",
"critical_flags": ["Large enforcement penalties ($890,000 total)"],
"sources_found": ["epa_echo", "fda", "irs_990", "osha_violation", "sec"],
"violations": {
"total_count": 62,
"total_penalties_usd": 890000,
"by_source": {
"fda": { "count": 14, "latest_date": "2025-03-15", "severity_breakdown": { "high": 3, "medium": 11 } },
"osha_violation": { "count": 48, "total_penalty": 890000, "latest_date": "2025-01-22" }
}
},
"self_reports": {
"osha_injury_reports": { "count": 31, "latest_date": "2024-12-01" }
},
"filings": {
"sec": { "latest_filing": "2025-04-30", "filing_types": ["8-K", "10-Q", "10-K"] }
},
"sanctions_and_exclusions": {
"ofac": { "sanctioned": false, "programs": [] },
"sam_gov": { "excluded": false },
"hhs_oig": { "excluded": false, "exclusion_types": [] }
},
"timeline_highlight": "Most recent record: FDA enforcement action (fda, 2025-03-15)."
}
Compare an entity's compliance profile against its industry peers. The peer group is the set of entities sharing the entity's NAICS code (falling back to SIC code when NAICS is absent); ranks are computed with SQL window functions. Pure SQL — no AI involved. Costs 1 credit.
Each metric reports the entity's own value, the industry median/average (computed over reporting peers only, so a silent majority of zero-record peers doesn't drag it to 0), a reporter_count (how many peers have any record of that type), a percentile rank (0–100), and a rating. Enforcement findings (violations) are kept separate from mandatory self-reports (self_reports: OSHA injury logs, EPA TRI releases). All figures are peer aggregates — no individual peer is named. Returns 422 NO_INDUSTRY_CODE if the entity has neither a NAICS nor SIC code.
GET /v1/entity/ent_321d75/benchmark X-API-Key: pt_live_xxx
{
"entity_id": "ent_321d75",
"name": "Acme Pharmaceuticals Inc",
"industry": { "naics": "325412", "sic": "2834", "entity_count": 142 },
"violations": {
"entity_count": 29,
"industry_median": 2.0,
"industry_average": 6.0,
"reporter_count": 38,
"percentile": 94.0,
"rating": "well_above_average"
},
"penalties": {
"entity_total_usd": 890000,
"industry_median_usd": 13789.5,
"industry_average_usd": 63373.22,
"reporter_count": 21,
"percentile": 97.0,
"rating": "well_above_average"
},
"complaints": {
"cfpb_count": 0,
"industry_median": 0.0,
"reporter_count": 0,
"percentile": 0.0
},
"self_reports": {
"osha_injury_count": 12,
"osha_industry_median": 223.0,
"osha_reporter_count": 31,
"osha_percentile": 18.0,
"epa_release_count": 0,
"epa_industry_median": 0.0,
"epa_reporter_count": 0,
"epa_percentile": 0.0
}
}
Map parent/subsidiary relationships, drawing primarily on the entity_relationships graph (SEC Exhibit 21, FDIC, Fed NIC, GLEIF, SEC 13D/G), with EPA TRI parent fields, DUNS numbers, and name matching as fallback. SQL-based — no AI involved. Costs 1 credit.
GET /v1/entity/ent_321d75/corporate-tree X-API-Key: pt_live_xxx
{ "data": { "entity_id": "ent_e36d8ec996d299a5", "name": "AMAZON COM INC", "parent": null, // parent is {entity_id, name, source} or null "subsidiaries": [ { "entity_id": "ent_a9e1c60167e16370", "name": "AMAZON TECHNOLOGIES, INC.", "relationship_source": "sec_exhibit21", "confidence": 1.0 }, { "entity_id": "ent_aa3b74350176b73f", "name": "Amazon EU S.à r.l.", "relationship_source": "gleif", "confidence": 1.0 } // relationship_source: sec_exhibit21, fdic, fed_nic, gleif, sec_13dg ], "related_entities": [] // items: {entity_id, name, relationship, source} }, "meta": { "request_id": "req_d72061fe60de", "credits_used": 1, "credits_remaining": 19934 }, "pagination": null }
Every corporate-family edge we hold for an entity — parents, subsidiaries, ultimate parents, beneficial owners, branches, funds — with per-edge source, status, and effective dates. Costs 1 credit.
Parameters
subsidiary, parent, beneficial_owner). Returns all types if omitted.
1.
50, max 100.
GET /v1/entity/ent_321d75/relationships?page=1&per_page=50 X-API-Key: pt_live_xxx
{ "data": [{ "relationship": "subsidiary", "direction": "child", "counterparty": {"entity_id": "ent_1a2b3c", "name": "EXAMPLE SUB LLC"}, "type_raw": "subsidiary_of", "source": "sec_exhibit21", "status": "active", "effective_from": "2019-12-31", "effective_to": null, "last_seen_at": "2026-06-30T00:00:00Z" }], "type_counts": {"subsidiary": 180, "parent": 1, "beneficial_owner": 6}, "pagination": {"page": 1, "per_page": 50, "total": 187, "has_more": true} }
Search person records — executives, directors, and individual reporting owners extracted from SEC filings. Costs 1 credit.
Identity note. Person records are resolved by name within one company's filings. Records are linked across companies only when a strong identifier (an SEC filer CIK, a validated NPI, or a sanctions-list ID) proves they are the same person. Every person object carries a resolution field — "anchored" (strong identifier present) or "name_scoped" (name-resolved, not identity-verified). Name-scoped records can mix filings from different individuals sharing a name at the same company, and never span companies. Treat person data as corporate-governance evidence, not identity verification; per our Terms it may not be used for any FCRA-covered purpose.
Parameters
executive, director, or beneficial_owner.
1 / 25, max 100.
{ "data": [{ "person_id": "per_9f8e7d6c", "canonical_name": "jane q example", "n_roles": 12, "n_entities": 1, "last_year": 2026, "resolution": "name_scoped" }], "pagination": {"page": 1, "per_page": 25, "total": 3, "has_more": false} }
Full person profile: career timeline, name variants, identifiers, and same_name_leads — other person records sharing the identical name, surfaced as explicitly unverified pivots (never merged automatically). See the identity note above; check resolution before treating the record as a verified identity. Costs 1 credit.
{ "data": { "person_id": "per_9f8e7d6c", "canonical_name": "jane q example", "resolution": "anchored", "identifiers": [{"type": "cik", "value": "0001234567"}], "roles": [{"entity_id": "ent_1a2b3c", "role_type": "director", "year_start": 2024}], "same_name_leads": [{"person_id": "per_5b4a3f2e", "entity_name": "OTHER CO INC", "role_types": ["beneficial_owner"]}] } }
Executives, directors, and individual beneficial owners at one company, as reported in its SEC filings (proxy statements, 13D/G cover pages). Optional year parameter restricts to one filing year. Names are as-filed and name-resolved within this company only — see the identity note above. Costs 1 credit.
GET /v1/entity/ent_321d75/roster?year=2026 X-API-Key: pt_live_xxx
Rate Limits
Rate limits are applied per API key. When you exceed your rate limit, requests return a 429 status code. The response includes Retry-After and X-RateLimit-* headers.
| Plan | Rate Limit | Monthly Credits |
|---|---|---|
Free |
1 request/sec | 200/month |
Pro |
5 requests/sec | 2,000/month |
Team |
10 requests/sec | 10,000/month |
Enterprise |
Custom | Custom |
X-RateLimit-Limit: 10 X-RateLimit-Remaining: 7 X-RateLimit-Reset: 1710504000 X-Credits-Remaining: 24847
Error Codes
All errors return a consistent JSON structure with a machine-readable code and a human-readable message.
{ "error": { "code": "rate_limit_exceeded", "message": "Rate limit exceeded. Retry after 1 second.", "status": 429 } }
| Status | Code | Description |
|---|---|---|
| 400 | bad_request |
Invalid request parameters. Check your query string or request body. |
| 401 | unauthorized |
Missing or invalid API key. Ensure your X-API-Key header is set correctly. |
| 403 | forbidden |
Your plan does not include access to this endpoint or feature. |
| 404 | not_found |
The requested entity or resource does not exist. |
| 429 | rate_limit_exceeded |
Too many requests per second. Check the Retry-After header. |
| 429 | credits_exhausted |
Monthly API credit quota reached. Upgrade your plan or wait for renewal. |
| 500 | internal_error |
Unexpected server error. If persistent, contact support. |
| 503 | AI_GENERATION_FAILED |
AI model returned an error. Retry after 30 seconds. Cached AI responses don't consume credits. |
Glossary
Quick reference for the identifiers, filing types, and source authorities that show up across the API. Skim the column that matches what you're working with.
Identifiers
- CIK
- Central Index Key. SEC's per-entity ID for any filer in EDGAR.
10-digit zero-padded. - EIN
- Employer Identification Number. IRS-issued tax ID.
XX-XXXXXXX. - LEI
- Legal Entity Identifier. ISO 17442 / GLEIF-issued global ID for entities engaging in financial transactions. 20 characters.
- DUNS
- Data Universal Numbering System. Dun & Bradstreet 9-digit ID. Replaced by UEI in federal contracting (April 2022) but persists in legacy datasets.
- UEI
- Unique Entity Identifier. SAM.gov's 12-char alphanumeric ID. Per-registration, not per-entity — one company can hold many UEIs.
- NPI
- National Provider Identifier. CMS-issued 10-digit ID for healthcare providers (organisations and individuals).
- CRD / IARD
- FINRA's Central Registration Depository number (broker-dealers) and SEC's Investment Adviser Registration Depository number (RIAs).
- CAGE
- Commercial and Government Entity Code. DLA-issued 5-char ID for federal-contractor sites.
- FDIC Cert
- FDIC Certificate Number. Unique to each insured bank.
- RSSD
- Federal Reserve's primary entity ID for banking institutions tracked in the National Information Center.
- OCC Charter
- Office of the Comptroller of the Currency charter number. National-bank ID.
- SIC / NAICS
- Industry classification codes. SIC is the 4-digit legacy system; NAICS is the 6-digit modern replacement.
Filings & Forms
- 10-K
- Annual report. Audited financials, business overview, risk factors, MD&A. Required for US public companies.
- 10-Q
- Quarterly report. Unaudited financials. Three filings per fiscal year (the fourth quarter is rolled into the 10-K).
- 8-K
- Current report. Material events disclosed within 4 business days — M&A, executive departures, bankruptcy, regulation FD events.
- DEF 14A
- Definitive proxy statement. Annual-meeting agenda + executive compensation + director nominees.
- Form 4
- Insider transaction report. Filed within 2 business days of a Section 16 insider's trade.
- Form D
- Notice of Sale of Securities. Used for Reg-D private placements (start-up funding rounds, hedge-fund offerings).
- Schedule 13D / 13G
- Beneficial-ownership reports. Triggered when a shareholder crosses 5%. 13D is active (intent to influence); 13G is passive.
- Form 990
- Annual return for tax-exempt orgs. Required for 501(c)(3) and most non-profits with gross receipts > $200K.
- Exhibit 21
- List of subsidiaries. Filed as an exhibit to the 10-K. Source of corporate-tree edges.
- S-1 / S-4
- Registration statements. S-1 for IPOs and new offerings; S-4 for M&A consideration shares.
- Form 300A
- OSHA injury & illness annual summary. Establishment-level reporting for high-hazard industries via the ITA portal.
Sources & Concepts
- EDGAR
- SEC's Electronic Data Gathering, Analysis, and Retrieval system. Public-company filings since 1993.
- OFAC SDN
- Office of Foreign Assets Control's Specially Designated Nationals list. US economic-sanctions blocklist.
- OSHA ITA
- Occupational Safety and Health Administration's Injury Tracking Application. Form 300A summaries for covered employers.
- EPA TRI
- Toxic Release Inventory. Annual chemical-release reporting under EPCRA Section 313.
- SAM.gov
- System for Award Management. US federal-contractor registration database, plus the federal exclusions list.
- OpenSanctions
- Aggregated sanctions / PEP / watchlist feed combining 100+ upstream lists (OFAC, EU FSF, UN SC, UK FCDO, …).
- GLEIF
- Global Legal Entity Identifier Foundation. Issues LEIs and publishes the daily GLEIF reference file.
- Entity resolution
- Collapsing name variants ("ACME CORP", "Acme Inc.") into a single canonical record using identifier matches, name similarity, and corporate-tree edges.
- Source record
- One row from one upstream feed — one filing, one violation, one sanction listing. Many source records resolve to one entity.
- Canonical name
- The chosen primary name for an entity. Other observed forms live as aliases.
- Strong identifier
- An ID guaranteed unique per entity (CIK, EIN, LEI, FDIC Cert, RSSD, IARD, OCC Charter). Used to merge with high confidence.
- Weak identifier
- An attribute that isn't strictly per-entity (UEI is per-registration, names & addresses are fuzzy). Needs supporting evidence to drive a merge.