How to fetch KYC, KYB and AML screening reports by API, check they exist, download the PDF and assemble an evidence bundle for audit.
A verification result in your database is useful to your code. It is much less useful to the person who asks, eight months later, why a seller was approved. That person wants a document: what was checked, when, against what, and what came back. If producing that document means a developer digging through logs, it will not get done well.
This post explains how to pull verification reports through the TrustVerify API, how to check a report is available before you fetch it, what the error responses tell you, and how to put several reports together into an evidence bundle.
Most marketplaces start by storing the decision: approve, review or reject. That is enough to run onboarding. It is not enough when someone needs to understand a decision after the fact. Common reasons include:
In each case, a report generated from the stored check is better than a screenshot or a summary written later. It is consistent, it is dated, and it shows the same thing every time someone opens it.
TrustVerify's report endpoint produces these main report types, each tied to a kind of check:
| Report | What it covers | Check type |
|---|---|---|
| RPT-001 | Individual identity verification (KYC) | kyc |
| RPT-002 | Business verification (KYB) | kyb |
| RPT-003 | AML screening | aml_screen |
There is also RPT-016, which is an evidence bundle rather than a single report. It is requested a different way, covered below. The reports and evidence bundles guide has the full picture.
The endpoint is the same for metadata and for the document itself:
GET /api/v1/reports/{reportType}/{checkId}
GET /api/v1/reports/{reportType}/{checkId}.pdf
Without the .pdf suffix, you get JSON describing the report: the report type and title, the check ID, a status of available, a download URL, when it was generated and a retainedUntil date. With the suffix, you get the PDF itself, rendered from the stored check data.
A sensible pattern is to call the metadata version first. It confirms the report exists for that check on your account and tells you how long it will be retained, which is worth storing alongside your own record. Then fetch the PDF when you actually need the document, rather than downloading every report the moment a check finishes.
The report metadata reference lists the response fields.
You can also ask for a report link at the time of the check. The KYC and KYB requests accept a generateReport flag; when it is true, the response includes a reportUrl for the RPT-001 or RPT-002 PDF. That saves a call if you know you will want the document for every check.
The report endpoint is strict, and its errors are informative:
404. The check does not exist for your account. Either the ID is wrong or it belongs to a different account or environment.
400 UNKNOWN_REPORT_TYPE. The report code is not a TrustVerify report type at all. Usually a typo.
409. The report type is valid but does not match the check. Asking for RPT-002, the business report, for a kyc check returns 409, and the response includes the correct type in suggestedType. Your code can read that and retry with the right code, though it is better to map check types to report types once and avoid the mismatch.
501. Other report codes that appear in some materials, RPT-004 to RPT-015, have no renderer on this API and return 501. Do not build features that depend on them.
The important point for audit is the reverse of the errors: no report is produced outside this set. A TrustVerify PDF for a check means that report was rendered from that check.
None of these errors is worth retrying unchanged. As with any 4xx other than 429, fix the request instead. Our errors reference has the general rules.
Sometimes one PDF is not enough. An auditor may want the report, the underlying data and a way to show nothing was altered. That is what the RPT-016 evidence bundle is for.
You register a bundle with:
POST /api/v1/reports/rpt-016
and fetch it from:
GET /api/v1/bundles/{bundleId}
GET /api/v1/bundles/{bundleId}.zip
The ZIP contains three files:
report.pdf, the human-readable reportevidence.json, the structured data behind itmanifest.json, listing the files with their SHA-256 hashesThe hashes let anyone recompute a file's hash and compare it with the manifest, which shows the file has not changed since the bundle was produced. Be precise when describing this to auditors: the hashes show a file has not changed, but they do not prove who produced the bundle. The RPT-016 reference sets out the request body.
You have two broad choices: fetch reports on demand from the API, or copy them into your own storage.
Fetching on demand keeps one source of truth and avoids extra copies of personal data. The limit is retention. Reports and check data are not kept forever. By default, TrustVerify deletes due diligence check records after five years, and the retainedUntil field tells you the date for each report.
Copying reports into your own storage gives you control but also gives you responsibility. That copy is personal data held by you, so it needs its own retention period, access controls and deletion process. Keeping a PDF indefinitely because it was easy to save is hard to justify under UK GDPR. The ICO's storage limitation guidance explains the principle.
A middle path many teams use: store the check ID, report type, retainedUntil and your own decision notes, and fetch the PDF only when a case needs it.
Reports contain personal data: names, dates of birth, document details and screening results. Treat the endpoint like any other sensitive one.
These sound obvious, but report downloads tend to be built late and quickly, often for one urgent request, and then stay in place for years.
Reports are most useful when reviewers can reach them without asking an engineer. A simple integration:
That last step matters most. A report shows what the check found. Your notes show what you decided and why. Together they answer the question someone will eventually ask. Our review queues page shows how cases flow through review.
.pdf for the document.suggestedType; 501 means that report code is not produced.For what the checks themselves cover, see our KYC software for UK businesses and the guide to choosing KYC software in the UK.
See how reports and bundles fit into your audit trail. Read the reports guide.
KYC, KYB, AML screening and fraud prevention in one place, with published pricing.
Developer
Using the TrustVerify Sandbox: Test Keys and Your First Check
A developer guide to the TrustVerify sandbox: test and live keys, deterministic synthetic results, magic test values and what the sandbox does not cover.
Developer
KYC Webhooks and Decision Handling for Marketplaces
A practical guide to consuming KYC and fraud webhooks on a marketplace: signatures, retries, idempotency and mapping decisions to seller states.
Developer
Rate Limits, Retries and Idempotency for Verification APIs
How verification API rate limits work, which errors to retry, how to back off properly and how to keep retries from creating duplicate checks.