{
  "info": {
    "name": "TrustVerify Public API",
    "description": "Requests for the TrustVerify public API. Set apiKey to a test key (tv_test_sk_…) to get sandbox demo data only. Docs: https://trustverify.co.uk/docs",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
    "version": "1.1.0"
  },
  "item": [
    {
      "name": "KYC",
      "item": [
        {
          "name": "Run a full KYC verification via API key",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{API_KEY}}",
                "type": "text"
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "https://api.trustverify.co.uk/api/v1/kyc/verify",
              "protocol": "https",
              "host": [
                "api",
                "trustverify",
                "co",
                "uk"
              ],
              "path": [
                "api",
                "v1",
                "kyc",
                "verify"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"documentImage\": \"/9j/4AAQ…\",\n  \"documentImageFront\": \"/9j/4AAQ…\",\n  \"documentImageBack\": \"string\",\n  \"selfieImage\": \"/9j/4AAQ…\",\n  \"documentType\": \"passport\",\n  \"checks\": {\n    \"amlScreening\": false\n  },\n  \"generateReport\": false,\n  \"metadata\": {\n    \"firstName\": \"Jane\",\n    \"lastName\": \"Smith\",\n    \"dateOfBirth\": \"1990-05-20\",\n    \"country\": \"GB\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Accepts base64-encoded document and selfie images. Runs face matching, optional document corroboration and AML screening, and returns a synchronous result. Liveness is covered by the guided selfie step; the liveness signal reports what was returned for this check."
          },
          "response": []
        }
      ],
      "description": "Identity checks: ID document, selfie and liveness."
    },
    {
      "name": "KYB",
      "item": [
        {
          "name": "Verify a business against the Companies House register (API key)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{API_KEY}}",
                "type": "text"
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "https://api.trustverify.co.uk/api/v1/kyb/verify",
              "protocol": "https",
              "host": [
                "api",
                "trustverify",
                "co",
                "uk"
              ],
              "path": [
                "api",
                "v1",
                "kyb",
                "verify"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"companyNumber\": \"00445790\",\n  \"companyName\": \"TESCO PLC\",\n  \"lei\": \"2138002P5RNKC5W2JZ46\",\n  \"jurisdiction\": \"GB\",\n  \"checks\": {\n    \"sanctionsScreening\": false,\n    \"leiLookup\": false\n  },\n  \"generateReport\": false,\n  \"metadata\": {}\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Either companyNumber or companyName is required. The company is verified against the live Companies House register: a companyNumber resolves directly; a companyName must clear a similarity threshold against the registered name — below it, ranked \"did you mean\" candidates are returned instead of a guess. Registry-verified companies (registered name + active officers) are then screened against sanctions and PEP lists with material-hit scoring, and an LEI register lookup runs when lei is supplied or checks.leiLookup is true. Statuses: passed (registry-verified, active, screens clear) · review (verified but flagged, or screening unavailable) · failed (not on the register) · unverified (registry unavailable, ambiguous name, or unsupported jurisdiction — never a pass). Test-mode keys receive deterministic sandbox fixtures labelled environment:\"sandbox\"."
          },
          "response": []
        }
      ],
      "description": "UK company checks against Companies House."
    },
    {
      "name": "AML",
      "item": [
        {
          "name": "Screen an individual or business for AML/sanctions (API key)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{API_KEY}}",
                "type": "text"
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "https://api.trustverify.co.uk/api/v1/aml/screen",
              "protocol": "https",
              "host": [
                "api",
                "trustverify",
                "co",
                "uk"
              ],
              "path": [
                "api",
                "v1",
                "aml",
                "screen"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"type\": \"individual\",\n  \"name\": \"Jane Smith\",\n  \"dateOfBirth\": \"string\",\n  \"country\": \"string\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Screens the subject against sanctions and PEP list. A 200 means the screen ran: `riskLevel` and `hits` describe what was found, and `pepStatus` / `adverseMedia` are derived from the matched entities' topics. If sanctions and PEP list does not return a result the endpoint responds 503 — it never reports an unscreened subject as clear, because a clear that was never performed is not evidence and cannot support a CDD record."
          },
          "response": []
        },
        {
          "name": "Enrol a subject in ongoing AML monitoring",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{API_KEY}}",
                "type": "text"
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "https://api.trustverify.co.uk/api/v1/aml/monitor",
              "protocol": "https",
              "host": [
                "api",
                "trustverify",
                "co",
                "uk"
              ],
              "path": [
                "api",
                "v1",
                "aml",
                "monitor"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"entityId\": \"cust_88213\",\n  \"name\": \"Ivan Petrov\",\n  \"entityType\": \"individual\",\n  \"dateOfBirth\": \"1971-04-02\",\n  \"country\": \"RU\",\n  \"metadata\": {\n    \"bookingRef\": \"B-4412\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Screens the subject immediately and, if that screen succeeds, enrols them for daily re-screening. New matches are delivered as the `aml.hit` webhook event to endpoints registered with POST /api/v1/webhooks — exactly once per new match, keyed on the sanctions and PEP list entity id, so a changed caption or score does not re-alert. The enrolment screen is the baseline the daily diff runs against: if it cannot be completed the endpoint returns 503 and NO monitor is created, because a monitor with an unknown baseline would report every pre-existing listing as a new match. Metered per ACTIVE subject against the plan limit, not per screen — daily re-screens do not consume the monthly API quota. Requires the aml_monitoring feature (Growth and above). There is no per-monitor webhookUrl: supplying one is a 400."
          },
          "response": []
        },
        {
          "name": "List monitored subjects",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{API_KEY}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "https://api.trustverify.co.uk/api/v1/aml/monitor?status=&entityId=&limit=50&offset=0",
              "protocol": "https",
              "host": [
                "api",
                "trustverify",
                "co",
                "uk"
              ],
              "path": [
                "api",
                "v1",
                "aml",
                "monitor"
              ],
              "query": [
                {
                  "key": "status",
                  "value": "",
                  "disabled": true
                },
                {
                  "key": "entityId",
                  "value": "",
                  "disabled": true
                },
                {
                  "key": "limit",
                  "value": "50",
                  "disabled": true
                },
                {
                  "key": "offset",
                  "value": "0",
                  "disabled": true
                }
              ]
            },
            "description": "Returns this account's monitors, newest first. `lastScreenedAt` and `consecutiveFailures` let you verify monitoring is actually running rather than taking it on trust."
          },
          "response": []
        },
        {
          "name": "Read one monitored subject and its match history",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{API_KEY}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "https://api.trustverify.co.uk/api/v1/aml/monitor/:monitorId",
              "protocol": "https",
              "host": [
                "api",
                "trustverify",
                "co",
                "uk"
              ],
              "path": [
                "api",
                "v1",
                "aml",
                "monitor",
                ":monitorId"
              ],
              "variable": [
                {
                  "key": "monitorId",
                  "value": "",
                  "description": ""
                }
              ]
            },
            "description": "Read one monitored subject and its match history"
          },
          "response": []
        },
        {
          "name": "Cancel monitoring for a subject",
          "request": {
            "method": "DELETE",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{API_KEY}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "https://api.trustverify.co.uk/api/v1/aml/monitor/:monitorId",
              "protocol": "https",
              "host": [
                "api",
                "trustverify",
                "co",
                "uk"
              ],
              "path": [
                "api",
                "v1",
                "aml",
                "monitor",
                ":monitorId"
              ],
              "variable": [
                {
                  "key": "monitorId",
                  "value": "",
                  "description": ""
                }
              ]
            },
            "description": "Stops re-screening and frees the subject slot immediately. Returns 200 rather than 204 because the record is kept as evidence of what was monitored and when — it moves to status \"cancelled\" rather than being deleted. Idempotent. The cancelled record, and the sanctions matches recorded against it, are retained for the statutory period (5 years from cancellation under MLR 2017 reg. 40) and are then permanently deleted; after that the monitor id returns 404."
          },
          "response": []
        }
      ],
      "description": "Sanctions and PEP screening, and ongoing monitoring."
    },
    {
      "name": "Checks",
      "item": [
        {
          "name": "Retrieve a check result by ID (API key)",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{API_KEY}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "https://api.trustverify.co.uk/api/v1/checks/:checkId",
              "protocol": "https",
              "host": [
                "api",
                "trustverify",
                "co",
                "uk"
              ],
              "path": [
                "api",
                "v1",
                "checks",
                ":checkId"
              ],
              "variable": [
                {
                  "key": "checkId",
                  "value": "",
                  "description": ""
                }
              ]
            },
            "description": "Retrieve a check result by ID (API key)"
          },
          "response": []
        }
      ],
      "description": "Read check results."
    },
    {
      "name": "Workflows",
      "item": [
        {
          "name": "Trigger a workflow by ID (API key)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{API_KEY}}",
                "type": "text"
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "https://api.trustverify.co.uk/api/v1/workflows/run",
              "protocol": "https",
              "host": [
                "api",
                "trustverify",
                "co",
                "uk"
              ],
              "path": [
                "api",
                "v1",
                "workflows",
                "run"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"workflowId\": 12,\n  \"inputs\": {},\n  \"webhookUrl\": \"string\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Trigger a workflow by ID (API key)"
          },
          "response": []
        }
      ],
      "description": "Run a saved workflow."
    },
    {
      "name": "Webhooks",
      "item": [
        {
          "name": "List registered webhook endpoints (API key)",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{API_KEY}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "https://api.trustverify.co.uk/api/v1/webhooks",
              "protocol": "https",
              "host": [
                "api",
                "trustverify",
                "co",
                "uk"
              ],
              "path": [
                "api",
                "v1",
                "webhooks"
              ]
            },
            "description": "Lists the endpoints on this account. Any key, test or live, can list. The signing secret is never returned here: it is shown once, in the response that creates the endpoint."
          },
          "response": []
        },
        {
          "name": "Register a webhook endpoint (API key)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{API_KEY}}",
                "type": "text"
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "https://api.trustverify.co.uk/api/v1/webhooks",
              "protocol": "https",
              "host": [
                "api",
                "trustverify",
                "co",
                "uk"
              ],
              "path": [
                "api",
                "v1",
                "webhooks"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"Production listener\",\n  \"url\": \"https://your-server.com/webhooks/tv\",\n  \"events\": [\n    \"aml.hit\"\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Registers an endpoint. Needs a live key. The 201 response is the only one that carries the whsec_… signing secret: store it then. No later response returns it."
          },
          "response": []
        },
        {
          "name": "Update a webhook endpoint (API key)",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{API_KEY}}",
                "type": "text"
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "https://api.trustverify.co.uk/api/v1/webhooks/:id",
              "protocol": "https",
              "host": [
                "api",
                "trustverify",
                "co",
                "uk"
              ],
              "path": [
                "api",
                "v1",
                "webhooks",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "",
                  "description": ""
                }
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"Production listener\",\n  \"url\": \"https://your-server.com/webhooks/tv\",\n  \"events\": [\n    \"aml.hit\"\n  ],\n  \"isActive\": true\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Partial update of an owned endpoint — send only the fields to change. A changed url is re-screened against SSRF rules before being saved. Needs a live key. The response does not include the signing secret."
          },
          "response": []
        },
        {
          "name": "Delete a webhook endpoint (API key)",
          "request": {
            "method": "DELETE",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{API_KEY}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "https://api.trustverify.co.uk/api/v1/webhooks/:id",
              "protocol": "https",
              "host": [
                "api",
                "trustverify",
                "co",
                "uk"
              ],
              "path": [
                "api",
                "v1",
                "webhooks",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "",
                  "description": ""
                }
              ]
            },
            "description": "Deletes an owned endpoint. Needs a live key."
          },
          "response": []
        }
      ],
      "description": "Register endpoints that receive signed events."
    },
    {
      "name": "Authentication",
      "item": [
        {
          "name": "Exchange an API key for a short-lived Bearer access token",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "https://api.trustverify.co.uk/api/v1/token",
              "protocol": "https",
              "host": [
                "api",
                "trustverify",
                "co",
                "uk"
              ],
              "path": [
                "api",
                "v1",
                "token"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"grantType\": \"client_credentials\",\n  \"clientId\": \"my-integration\",\n  \"clientSecret\": \"string\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "client_credentials grant: clientSecret is your tv_*_sk_… API key. The returned JWT authenticates against every /api/v1 endpoint via Authorization: Bearer for one hour."
          },
          "response": []
        },
        {
          "name": "Validate the presented API key and return plan/usage info",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{API_KEY}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "https://api.trustverify.co.uk/api/v1/validate-key",
              "protocol": "https",
              "host": [
                "api",
                "trustverify",
                "co",
                "uk"
              ],
              "path": [
                "api",
                "v1",
                "validate-key"
              ]
            },
            "description": "Validate the presented API key and return plan/usage info"
          },
          "response": []
        }
      ],
      "description": "Validate keys and exchange them for short-lived tokens."
    },
    {
      "name": "Reports",
      "item": [
        {
          "name": "Report availability metadata / PDF download for a check",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{API_KEY}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "https://api.trustverify.co.uk/api/v1/reports/:reportType/:checkId",
              "protocol": "https",
              "host": [
                "api",
                "trustverify",
                "co",
                "uk"
              ],
              "path": [
                "api",
                "v1",
                "reports",
                ":reportType",
                ":checkId"
              ],
              "variable": [
                {
                  "key": "reportType",
                  "value": "",
                  "description": ""
                },
                {
                  "key": "checkId",
                  "value": "",
                  "description": ""
                }
              ]
            },
            "description": "GET /api/v1/reports/RPT-001/{checkId} returns JSON availability metadata; GET /api/v1/reports/RPT-001/{checkId}.pdf streams the PDF report rendered from the stored check data. 404 when the check does not exist for your account.\n\n**Report types this API produces:** `RPT-001` Individual Identity Verification (KYC) — for `kyc` checks; `RPT-002` Business Verification (KYB) — for `kyb` checks; `RPT-003` AML Screening — for `aml_screen` checks. `RPT-016` is the ZIP evidence bundle and is requested via POST /api/v1/reports/rpt-016, not here.\n\nOther advertised report codes (RPT-004 … RPT-015) have no renderer on this API and return **501**; a code that is not a TrustVerify report type returns **400**; a valid code requested for a check of the wrong subject (for example RPT-002 for a `kyc` check) returns **409** with the correct type in `suggestedType`. No document is ever produced outside this set — a TrustVerify-branded PDF always means the named report was really rendered from the named check."
          },
          "response": []
        },
        {
          "name": "Register a regulatory evidence bundle (RPT-016) for a check",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{API_KEY}}",
                "type": "text"
              },
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "url": {
              "raw": "https://api.trustverify.co.uk/api/v1/reports/rpt-016",
              "protocol": "https",
              "host": [
                "api",
                "trustverify",
                "co",
                "uk"
              ],
              "path": [
                "api",
                "v1",
                "reports",
                "rpt-016"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"checkId\": \"string\",\n  \"includeTypes\": [\n    \"RPT-001\"\n  ],\n  \"regulatorRef\": \"FCA-2026-1234\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Registers a ZIP evidence bundle for an existing check. `includeTypes` may only name report types this API produces for that check type (see GET /api/v1/reports/{reportType}/{checkId}); anything else is rejected with **400** and `unavailableTypes`, so a registered bundle can never promise a document the archive will not contain. Omit `includeTypes` to get the report for the check's own type (a `kyc` check → `[\"RPT-001\"]`)."
          },
          "response": []
        },
        {
          "name": "Evidence bundle readiness metadata / ZIP download",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{API_KEY}}",
                "type": "text"
              }
            ],
            "url": {
              "raw": "https://api.trustverify.co.uk/api/v1/bundles/:bundleId",
              "protocol": "https",
              "host": [
                "api",
                "trustverify",
                "co",
                "uk"
              ],
              "path": [
                "api",
                "v1",
                "bundles",
                ":bundleId"
              ],
              "variable": [
                {
                  "key": "bundleId",
                  "value": "",
                  "description": ""
                }
              ]
            },
            "description": "GET /api/v1/bundles/{bundleId} returns JSON readiness metadata; GET /api/v1/bundles/{bundleId}.zip streams the ZIP. 404 when the bundle was never registered for your account.\n\n**Archive layout**\n\n```\n{bundleId}.zip\n├── report.pdf                       # bundle cover sheet (RPT-016)\n├── reports/RPT-001-{checkId}.pdf    # one PDF per included report type\n├── evidence.json                    # machine-readable check record + what is included\n└── manifest.json                    # sha256 + byte length of every other entry (not signed)\n```\n\n`manifest.json.files[]` covers every entry in the archive except `manifest.json` itself. Bundles are **not signed**: `signature` and `signatureAlgorithm` are null and `integrity` is `sha256_hashes_only`. Re-hashing each file against the manifest shows whether anything changed since you downloaded it; it does not prove who produced the archive. `manifest.json.unavailableReports[]` and `evidence.json.unavailableReports[]` list any requested type that was not produced, with the reason — a placeholder document is never substituted."
          },
          "response": []
        }
      ],
      "description": "Compliance reports and evidence bundles."
    }
  ],
  "variable": [
    {
      "key": "BASE_URL",
      "value": "https://api.trustverify.co.uk",
      "type": "string"
    },
    {
      "key": "API_KEY",
      "value": "tv_test_sk_replace_me",
      "type": "string"
    }
  ],
  "event": [
    {
      "listen": "prerequest",
      "script": {
        "type": "text/javascript",
        "exec": [
          "// TrustVerify Public API. Set API_KEY to your secret key.",
          "// A test key (tv_test_sk_…) only returns sandbox demo data and never runs real or paid checks.",
          "// X-TrustVerify-API-Key: {{API_KEY}} is an accepted alternative to the Authorization header."
        ]
      }
    }
  ]
}
