Vendor Evidence Drift API
Monitor vendor security, privacy, subprocessor, certification and SLA evidence, and map changes to controls and risk.
Quickstart
Three calls: ask for a key, claim it from your inbox, then use it. No account, no dashboard, no card.
1. Ask for a key
curl -X POST https://vendorevidence-api.com/v1/keys \
-H 'content-type: application/json' \
-d '{"email":"you@example.com"}'
Answers 202 Accepted and emails a one-time claim token to that address. No key is returned by this call. Proving you control the mailbox is what stops anyone who can guess your address from minting a key on your account and spending your allowance. The token is good for 15 minutes; ask again if it lapses.
2. Claim it
curl -X POST https://vendorevidence-api.com/v1/keys/claim \
-H 'content-type: application/json' \
-d '{"token":"PASTE_THE_TOKEN_FROM_THE_EMAIL"}'
This response carries the key, and it is shown once — only a peppered hash is stored, so it cannot be read back later; if you lose it, rotate. Free tier: 150 evidence checks/month.
3. Call the API
curl -X POST https://vendorevidence-api.com/v1/checks \
-H "Authorization: Bearer $KEY" \
-H 'content-type: application/json' \
-d '{"check":{
"vendorId":"vnd-northwind",
"previous":{"capturedAt":"2026-02-01",
"certifications":[{"framework":"soc2_type2","issuedAt":"2025-02-15",
"expiresAt":"2026-02-14",
"scope":["security","availability","confidentiality"]}],
"subprocessors":[{"name":"Cloudmail","country":"US"}],
"slas":[{"metric":"uptime","uptimeBasisPoints":9995}]},
"current":{"capturedAt":"2026-08-01",
"certifications":[{"framework":"soc2_type2","issuedAt":"2026-02-15",
"expiresAt":"2027-02-14",
"scope":["security","confidentiality"]}],
"subprocessors":[{"name":"Cloudmail","country":"US"},
{"name":"Supportly","country":"BR"}],
"slas":[{"metric":"uptime","uptimeBasisPoints":9990}]}}}\'
Or skip the terminal: every endpoint below has a Try it panel that sends the real request from this page. Start at the playground.
Authentication
Authorization: Bearer sp_live_…
x-api-key is also accepted. Keys are scoped to this API — a key issued for another
product returns invalid_api_key, identical to an unknown key, so the API will not
confirm a key is valid elsewhere. Never put a key in browser JavaScript; authenticated
endpoints deliberately do not support CORS.
Playground
Every endpoint below carries a Try it panel, prefilled with a working request. Edit it,
press Send, and read what this API actually answered — status, timing, requestId and body,
unedited. Requests go straight from your browser to https://vendorevidence-api.com; nothing is proxied
through this page and no request is recorded here.
What happens to this key. It is a live credential, and it is treated as one. It is held
in this page's memory for as long as the tab is open and nowhere else — not
localStorage, not sessionStorage, not a cookie, not the URL, not a
query string. It is never logged, and never sent to the server that serves this page. The only
place it goes is the Authorization: Bearer header of requests you send to
https://vendorevidence-api.com. Reloading or closing the tab discards it; Clear discards it now.
Copied curl commands carry $KEY, never the key itself. On a shared machine,
clear it when you are done.
What a call costs. Every panel says so above its Send button, taken from the same contract as the rest of this page. No key required is a public endpoint — no key, no quota, no charge. Free — no quota needs your key but reserves nothing. Billable runs against your real account and reserves the stated quota from your plan before it runs, exactly as it would from your own code. Quota: no fixed cost also runs against your real account, but the contract states no fixed amount: endpoints whose work scales with the payload reserve an amount derived from what you send, so try a small request first.
No key yet? Open the Try it panel on POST /v1/keys, put in your email and
press Send. That call answers 202 and emails you a claim token; paste the token
into the Try it panel on POST /v1/keys/claim and send that. The claim
response is the one that carries the key, and it comes back with a button that loads it
straight into this field.
Endpoints
/v1/keysRequest a free sandbox API key (sends a verification email)
Starts self-serve key issuance. A one-time claim token is emailed to the address you supply; POST it to /v1/keys/claim to receive the key. No key is returned here, and the response is the same whether or not that address already has an account — so this endpoint cannot be used to find out who has one. The email is verified because your account, your usage and your invoice are all keyed to it: issuing on an unverified address would let anyone mint a working key on your account and spend your allowance. Keep using the same address and a paid plan bought with it raises the keys you already hold rather than issuing new ones.
Try itPOST /v1/keysNo key required
Public endpoint. No API key, no quota, nothing billed.
Request body
| Field | Type | Notes | |
|---|---|---|---|
email | string | required | Where the claim token is sent. This becomes your account. Format: email. |
name | string | optional | Optional label for the key, e.g. "staging". Shown in GET /v1/keys. |
Example request
{
"email": "you@example.com",
"name": "staging"
}
curl
curl -X POST https://vendorevidence-api.com/v1/keys \
-H 'content-type: application/json' \
-d '{"email":"you@example.com","name":"staging"}'
Response
| Field | Type | Notes |
|---|---|---|
status | "verification_sent" | |
email | string | Format: email. |
expiresAt | string | After this, request a new one. Format: date-time. |
next | string | The endpoint that turns the emailed token into a key. |
message | string | |
requestId | string |
/v1/keysList your API keys for this API
Every key on YOUR account for this API — label, non-secret prefix, status, when it was created, when it was last used, and what it has consumed this period. Authenticate with any active key on the account; the account is taken from that key, never from a parameter, so this can only ever return your own keys. Keys you hold for other APIs in the portfolio are not listed here. Secrets are not returned and cannot be: only a peppered hash is stored. Free, and consumes no quota.
Try itGET /v1/keysFree — no quota
Needs your API key. The contract gives this endpoint no quota cost and it takes no request body, so nothing is reserved and nothing is billed.
Using the API key from the playground key field — no key set yet. It is sent only in the Authorization: Bearer header, only to https://vendorevidence-api.com.
Your browser will not send an Authorization header to this API from this page: authenticated endpoints do not enable cross-origin access, deliberately, so that a key can never be read out of a web app’s front-end. Press Show as curl and run the request from a terminal instead — your edits are carried into it.
curl
curl -X GET https://vendorevidence-api.com/v1/keys \
-H "Authorization: Bearer $KEY"
Response
| Field | Type | Notes |
|---|---|---|
product | string | |
accountId | string | |
keys | object[] | |
requestId | string |
/v1/checksCompare two evidence snapshots and return drift, controls and risk
Send a previous and a current snapshot of one vendor's published compliance evidence — certifications, subprocessors, policies, SLA commitments, data-residency statements, pen-test and insurance documents. Returns every drift finding with a stable code, a fixed severity, the controls it bears on and a recommended action, plus a risk score whose derivation is printed line by line. Expiry arithmetic is in whole UTC days and expiresAt is the last day covered. Omit "previous" for a first-ever baseline. Send one "check" or up to 50 in "checks" — billed one evidence_check per check. This service compares only what you supply: it never fetches a vendor document, never verifies that a certificate is genuine, and makes no claim about any real vendor's actual posture.
Try itPOST /v1/checksQuota: no fixed cost
Runs against your real account. The contract gives this endpoint no fixed quota cost: nothing is reserved before it runs, and endpoints whose work scales with the payload reserve an amount derived from the body instead — so a large request here can cost more than one unit. Send a small one first.
Using the API key from the playground key field — no key set yet. It is sent only in the Authorization: Bearer header, only to https://vendorevidence-api.com.
Your browser will not send an Authorization header to this API from this page: authenticated endpoints do not enable cross-origin access, deliberately, so that a key can never be read out of a web app’s front-end. Press Show as curl and run the request from a terminal instead — your edits are carried into it.
Request body
| Field | Type | Notes | |
|---|---|---|---|
check | object | optional | |
checks | object[] | optional | At least 1. At most 50. |
Example request
{
"check": {
"vendorId": "vnd-northwind",
"vendorName": "Northwind Software",
"previous": {
"capturedAt": "2026-02-01",
"certifications": [
{
"framework": "soc2_type2",
"auditor": "Prior & Co",
"issuedAt": "2025-02-15",
"expiresAt": "2026-02-14",
"scope": [
"security",
"availability",
"confidentiality"
],
"exceptions": [],
"opinion": "unqualified"
}
],
"subprocessors": [
{
"name": "Cloudmail",
"country": "US",
"purpose": "transactional email",
"processesPersonalData": true
},
{
"name": "Metricly",
"country": "IE",
"purpose": "product analytics",
"processesPersonalData": false
}
],
"policies": [
{
"name": "Information Security Policy",
"version": "4.1",
"effectiveAt": "2025-03-01",
"contentHash": "sha256:9f2c"
}
],
"slas": [
{
"metric": "uptime",
"uptimeBasisPoints": 9995
},
{
"metric": "support_response",
"targetMinutes": 240
}
],
"residency": [
{
"dataCategory": "customer_content",
"countries": [
"IE",
"US"
]
}
],
"attestations": [
{
"kind": "insurance",
"provider": "Meridian",
"issuedAt": "2025-06-01",
"expiresAt": "2026-05-31",
"coverageMinor": 1000000000,
"currency": "USD"
}
]
},
"current": {
"capturedAt": "2026-08-01",
"certifications": [
{
"framework": "soc2_type2",
"auditor": "Nextgen Assurance",
"issuedAt": "2026-03-20",
"expiresAt": "2027-03-19",
"scope": [
"security",
"confidentiality"
],
"exceptions": [
"Access review evidence incomplete for two of twelve months"
],
"opinion": "unqualified"
}
],
"subprocessors": [
{
"name": "Cloudmail",
"country": "US",
"purpose": "transactional email",
"processesPersonalData": true
},
{
"name": "Metricly",
"country": "IE",
"purpose": "product analytics",
"processesPersonalData": false
},
{
"name": "Supportly",
"country": "BR",
"purpose": "customer support tooling",
"processesPersonalData": true
}
],
"policies": [
{
"name": "Information Security Policy",
"version": "4.1",
"effectiveAt": "2025-03-01",
"contentHash": "sha256:44e1"
}
],
"slas": [
{
"metric": "uptime",
"uptimeBasisPoints": 9990
},
{
"metric": "support_response",
"targetMinutes": 480
}
],
"residency": [
{
"dataCategory": "customer_content",
"countries": [
"BR",
"IE",
"US"
]
}
],
"attestations": [
{
"kind": "insurance",
"provider": "Meridian",
"issuedAt": "2026-06-01",
"expiresAt": "2027-05-31",
"coverageMinor": 500000000,
"currency": "USD"
}
]
}
}
}
curl
curl -X POST https://vendorevidence-api.com/v1/checks \
-H "Authorization: Bearer $KEY" \
-H 'content-type: application/json' \
-d '{"check":{"vendorId":"vnd-northwind","vendorName":"Northwind Software","previous":{"capturedAt":"2026-02-01","certifications":[{"framework":"soc2_type2","auditor":"Prior & Co","issuedAt":"2025-02-15","expiresAt":"2026-02-14","scope":["security","availability","confidentiality"],"exceptions":[],"opinion":"unqualified"}],"subprocessors":[{"name":"Cloudmail","country":"US","purpose":"transactional email","processesPersonalData":true},{"name":"Metricly","country":"IE","purpose":"product analytics","processesPersonalData":false}],"policies":[{"name":"Information Security Policy","version":"4.1","effectiveAt":"2025-03-01","contentHash":"sha256:9f2c"}],"slas":[{"metric":"uptime","uptimeBasisPoints":9995},{"metric":"support_response","targetMinutes":240}],"residency":[{"dataCategory":"customer_content","countries":["IE","US"]}],"attestations":[{"kind":"insurance","provider":"Meridian","issuedAt":"2025-06-01","expiresAt":"2026-05-31","coverageMinor":1000000000,"currency":"USD"}]},"current":{"capturedAt":"2026-08-01","certifications":[{"framework":"soc2_type2","auditor":"Nextgen Assurance","issuedAt":"2026-03-20","expiresAt":"2027-03-19","scope":["security","confidentiality"],"exceptions":["Access review evidence incomplete for two of twelve months"],"opinion":"unqualified"}],"subprocessors":[{"name":"Cloudmail","country":"US","purpose":"transactional email","processesPersonalData":true},{"name":"Metricly","country":"IE","purpose":"product analytics","processesPersonalData":false},{"name":"Supportly","country":"BR","purpose":"customer support tooling","processesPersonalData":true}],"policies":[{"name":"Information Security Policy","version":"4.1","effectiveAt":"2025-03-01","contentHash":"sha256:44e1"}],"slas":[{"metric":"uptime","uptimeBasisPoints":9990},{"metric":"support_response","targetMinutes":480}],"residency":[{"dataCategory":"customer_content","countries":["BR","IE","US"]}],"attestations":[{"kind":"insurance","provider":"Meridian","issuedAt":"2026-06-01","expiresAt":"2027-05-31","coverageMinor":500000000,"currency":"USD"}]}}}'
Response
| Field | Type | Notes |
|---|---|---|
count | integer | |
reports | object[] |
/v1/demo/checkPublic demo — compare one pair of snapshots without a key
The real engine, capped at one check and 40 evidence items across both snapshots. Nothing is stored, nothing is metered, no key is needed.
Try itPOST /v1/demo/checkNo key required
Public endpoint. No API key, no quota, nothing billed.
Request body
| Field | Type | Notes | |
|---|---|---|---|
check | object | required |
Example request
{
"check": {
"vendorId": "vnd-northwind",
"vendorName": "Northwind Software",
"previous": {
"capturedAt": "2026-02-01",
"certifications": [
{
"framework": "soc2_type2",
"auditor": "Prior & Co",
"issuedAt": "2025-02-15",
"expiresAt": "2026-02-14",
"scope": [
"security",
"availability",
"confidentiality"
],
"exceptions": [],
"opinion": "unqualified"
}
],
"subprocessors": [
{
"name": "Cloudmail",
"country": "US",
"purpose": "transactional email",
"processesPersonalData": true
},
{
"name": "Metricly",
"country": "IE",
"purpose": "product analytics",
"processesPersonalData": false
}
],
"policies": [
{
"name": "Information Security Policy",
"version": "4.1",
"effectiveAt": "2025-03-01",
"contentHash": "sha256:9f2c"
}
],
"slas": [
{
"metric": "uptime",
"uptimeBasisPoints": 9995
},
{
"metric": "support_response",
"targetMinutes": 240
}
],
"residency": [
{
"dataCategory": "customer_content",
"countries": [
"IE",
"US"
]
}
],
"attestations": [
{
"kind": "insurance",
"provider": "Meridian",
"issuedAt": "2025-06-01",
"expiresAt": "2026-05-31",
"coverageMinor": 1000000000,
"currency": "USD"
}
]
},
"current": {
"capturedAt": "2026-08-01",
"certifications": [
{
"framework": "soc2_type2",
"auditor": "Nextgen Assurance",
"issuedAt": "2026-03-20",
"expiresAt": "2027-03-19",
"scope": [
"security",
"confidentiality"
],
"exceptions": [
"Access review evidence incomplete for two of twelve months"
],
"opinion": "unqualified"
}
],
"subprocessors": [
{
"name": "Cloudmail",
"country": "US",
"purpose": "transactional email",
"processesPersonalData": true
},
{
"name": "Metricly",
"country": "IE",
"purpose": "product analytics",
"processesPersonalData": false
},
{
"name": "Supportly",
"country": "BR",
"purpose": "customer support tooling",
"processesPersonalData": true
}
],
"policies": [
{
"name": "Information Security Policy",
"version": "4.1",
"effectiveAt": "2025-03-01",
"contentHash": "sha256:44e1"
}
],
"slas": [
{
"metric": "uptime",
"uptimeBasisPoints": 9990
},
{
"metric": "support_response",
"targetMinutes": 480
}
],
"residency": [
{
"dataCategory": "customer_content",
"countries": [
"BR",
"IE",
"US"
]
}
],
"attestations": [
{
"kind": "insurance",
"provider": "Meridian",
"issuedAt": "2026-06-01",
"expiresAt": "2027-05-31",
"coverageMinor": 500000000,
"currency": "USD"
}
]
}
}
}
curl
curl -X POST https://vendorevidence-api.com/v1/demo/check \
-H 'content-type: application/json' \
-d '{"check":{"vendorId":"vnd-northwind","vendorName":"Northwind Software","previous":{"capturedAt":"2026-02-01","certifications":[{"framework":"soc2_type2","auditor":"Prior & Co","issuedAt":"2025-02-15","expiresAt":"2026-02-14","scope":["security","availability","confidentiality"],"exceptions":[],"opinion":"unqualified"}],"subprocessors":[{"name":"Cloudmail","country":"US","purpose":"transactional email","processesPersonalData":true},{"name":"Metricly","country":"IE","purpose":"product analytics","processesPersonalData":false}],"policies":[{"name":"Information Security Policy","version":"4.1","effectiveAt":"2025-03-01","contentHash":"sha256:9f2c"}],"slas":[{"metric":"uptime","uptimeBasisPoints":9995},{"metric":"support_response","targetMinutes":240}],"residency":[{"dataCategory":"customer_content","countries":["IE","US"]}],"attestations":[{"kind":"insurance","provider":"Meridian","issuedAt":"2025-06-01","expiresAt":"2026-05-31","coverageMinor":1000000000,"currency":"USD"}]},"current":{"capturedAt":"2026-08-01","certifications":[{"framework":"soc2_type2","auditor":"Nextgen Assurance","issuedAt":"2026-03-20","expiresAt":"2027-03-19","scope":["security","confidentiality"],"exceptions":["Access review evidence incomplete for two of twelve months"],"opinion":"unqualified"}],"subprocessors":[{"name":"Cloudmail","country":"US","purpose":"transactional email","processesPersonalData":true},{"name":"Metricly","country":"IE","purpose":"product analytics","processesPersonalData":false},{"name":"Supportly","country":"BR","purpose":"customer support tooling","processesPersonalData":true}],"policies":[{"name":"Information Security Policy","version":"4.1","effectiveAt":"2025-03-01","contentHash":"sha256:44e1"}],"slas":[{"metric":"uptime","uptimeBasisPoints":9990},{"metric":"support_response","targetMinutes":480}],"residency":[{"dataCategory":"customer_content","countries":["BR","IE","US"]}],"attestations":[{"kind":"insurance","provider":"Meridian","issuedAt":"2026-06-01","expiresAt":"2027-05-31","coverageMinor":500000000,"currency":"USD"}]}}}'
Response
| Field | Type | Notes |
|---|---|---|
report | object |
/v1/drift-typesEvery drift code, severity, control mapping and scoring constant
The catalogue the engine emits from — not a copy of it, the same object. Branch on these codes rather than on the human-readable detail, which is prose and will be reworded. Includes the severity-to-points table and the band boundaries, so a risk score can be reproduced by hand.
Try itGET /v1/drift-typesNo key required
Public endpoint. No API key, no quota, nothing billed.
curl
curl -X GET https://vendorevidence-api.com/v1/drift-types
Response
| Field | Type | Notes |
|---|---|---|
driftTypes | object | Keyed by code: kind, signal, severity, meaning, recommendedAction and control ids. |
bySignal | object | The same codes grouped by evidence family. |
controls | object | The control identifiers findings are mapped to, with framework and name. |
scoring | object | Severity points, band boundaries, the material threshold and the two age windows. |
/v1/checkoutStart a hosted Square checkout for a paid tier
Returns a Square-hosted payment URL for the requested tier. No API key is needed — a prospect has not got one yet. The email Square collects becomes the account, so a key issued later for the same address inherits the paid quota. Enterprise returns a contact route rather than a payment link.
Try itPOST /v1/checkoutNo key required
Public endpoint. No API key, no quota, nothing billed.
Request body
| Field | Type | Notes | |
|---|---|---|---|
tier | string | required | developer | growth | scale | enterprise |
Example request
{
"tier": "developer"
}
curl
curl -X POST https://vendorevidence-api.com/v1/checkout \
-H 'content-type: application/json' \
-d '{"tier":"developer"}'
Response
| Field | Type | Notes |
|---|---|---|
checkoutUrl | string | Square-hosted payment page. Redirect the buyer here. Format: uri. |
tier | string | |
sku | string | |
requestId | string |
/v1/keys/{id}/revokeRevoke one of your API keys
Kills a key immediately: the very next request made with it is refused with 401 invalid_api_key. There is no propagation delay and no cache to wait out. You may revoke the key you are authenticating with — that is the correct move when it has leaked, though you will then need another key, or the email flow, to get back in; rotate does both in one call. A key belonging to another account, or to another API, answers 404 exactly as an unknown id does, so this cannot be used to probe for keys you do not own. Idempotent, and free.
Try itPOST /v1/keys/{id}/revokeFree — no quota
Needs your API key. The contract gives this endpoint no quota cost and it takes no request body, so nothing is reserved and nothing is billed.
Using the API key from the playground key field — no key set yet. It is sent only in the Authorization: Bearer header, only to https://vendorevidence-api.com.
Your browser will not send an Authorization header to this API from this page: authenticated endpoints do not enable cross-origin access, deliberately, so that a key can never be read out of a web app’s front-end. Press Show as curl and run the request from a terminal instead — your edits are carried into it.
The contract declares no request schema for this endpoint, so there is nothing to prefill. See the description above for what it accepts.
curl
curl -X POST https://vendorevidence-api.com/v1/keys/{id}/revoke \
-H "Authorization: Bearer $KEY"
Response
| Field | Type | Notes |
|---|---|---|
id | string | |
status | "revoked" | |
message | string | |
requestId | string |
/v1/keys/{id}/rotateReplace one of your API keys with a new secret
Issues a replacement key and revokes the old one. This is the answer to a leaked or lost key: the new secret is returned once, the old secret stops working immediately, and the label carries over unless you supply a new one. The replacement is issued at your account's current allowance — your paid plan if you have one — not at the old key's. Rotating does not count against the active-key limit, because it replaces rather than adds. Free, and it works while you are out of quota.
Try itPOST /v1/keys/{id}/rotateQuota: no fixed cost
Runs against your real account. The contract gives this endpoint no fixed quota cost: nothing is reserved before it runs, and endpoints whose work scales with the payload reserve an amount derived from the body instead — so a large request here can cost more than one unit. Send a small one first.
Using the API key from the playground key field — no key set yet. It is sent only in the Authorization: Bearer header, only to https://vendorevidence-api.com.
Your browser will not send an Authorization header to this API from this page: authenticated endpoints do not enable cross-origin access, deliberately, so that a key can never be read out of a web app’s front-end. Press Show as curl and run the request from a terminal instead — your edits are carried into it.
Request body
| Field | Type | Notes | |
|---|---|---|---|
name | string | optional | Optional new label. Defaults to the old key's. |
Example request
{
"name": "production (rotated)"
}
curl
curl -X POST https://vendorevidence-api.com/v1/keys/{id}/rotate \
-H "Authorization: Bearer $KEY" \
-H 'content-type: application/json' \
-d '{"name":"production (rotated)"}'
Response
| Field | Type | Notes |
|---|---|---|
apiKey | string | The new secret. Shown once. |
keyId | string | |
replaced | string | The id of the key that was revoked. |
product | string | |
quotaPerPeriod | integer | null | |
plan | string | |
warning | string | |
requestId | string |
/v1/keys/claimExchange an emailed claim token for the API key
Spends the token emailed by POST /v1/keys and returns the key. The key is shown ONCE — only a peppered hash is stored, so it can never be read back; if you lose it, rotate. The key works only on this API, and the allowance it is issued with reflects your account: your paid plan when you have one, the free sandbox allowance when you do not.
Try itPOST /v1/keys/claimNo key required
Public endpoint. No API key, no quota, nothing billed.
Request body
| Field | Type | Notes | |
|---|---|---|---|
token | string | required | The claim token from the verification email. |
Example request
{
"token": "eyJ2IjoxLCJlIjoieW91QGV4YW1wbGUuY29tIn0.ZXhhbXBsZQ"
}
curl
curl -X POST https://vendorevidence-api.com/v1/keys/claim \
-H 'content-type: application/json' \
-d '{"token":"eyJ2IjoxLCJlIjoieW91QGV4YW1wbGUuY29tIn0.ZXhhbXBsZQ"}'
Response
| Field | Type | Notes |
|---|---|---|
apiKey | string | Shown once and never again. Store it now. |
keyId | string | Use this with /v1/keys/{id}/revoke and /v1/keys/{id}/rotate. |
product | string | The key works only on this API. |
quotaPerPeriod | integer | null | |
plan | string | The tier this allowance came from, or "sandbox" on the free tier. |
warning | string | |
usage | string | |
requestId | string |
/v1/usageYour consumption and remaining allowance for this period
Reports what this API key has consumed in the current quota period, the ceiling being enforced against it, and when that ceiling resets. Free, and it consumes no quota, so it still answers once you are getting 429 quota_exceeded — which is the point: compare "used" against "ceiling" and read "period.resetsAt" to tell a period you have simply exhausted from a plan that is no longer active, which shows as a "status" of canceled and a ceiling of 0. "used" counts billing units (see "unit"), not HTTP requests: a single request can consume several. All money is in integer minor units (cents), never a decimal. The period reported here is the quota period — the calendar month in UTC, resetting at 00:00 UTC on the 1st. Your invoice window is anchored to the date you subscribed and is a different window; the amounts here are what this period’s usage has accrued so far, not a bill.
Try itGET /v1/usageFree — no quota
Needs your API key. The contract gives this endpoint no quota cost and it takes no request body, so nothing is reserved and nothing is billed.
Using the API key from the playground key field — no key set yet. It is sent only in the Authorization: Bearer header, only to https://vendorevidence-api.com.
Your browser will not send an Authorization header to this API from this page: authenticated endpoints do not enable cross-origin access, deliberately, so that a key can never be read out of a web app’s front-end. Press Show as curl and run the request from a terminal instead — your edits are carried into it.
curl
curl -X GET https://vendorevidence-api.com/v1/usage \
-H "Authorization: Bearer $KEY"
Response
| Field | Type | Notes |
|---|---|---|
product | string | The API this key is bound to. A key works only on one. |
tier | string | null | The plan tier you are billed on, e.g. "developer". Null on a free sandbox key with no paid plan. |
status | "sandbox" | "active" | "past_due" | "canceled" | State of your plan. "sandbox" means no paid plan; "canceled" explains a ceiling of 0. |
unit | string | The billing unit this API meters. "used", "included", "ceiling" and "remaining" are all counted in these, not in requests. |
period | object | The quota period: the calendar month in UTC. |
included | integer | Units your flat monthly fee already covers, before overage pricing applies. 0 without a paid plan. |
used | integer | Units consumed so far this period. |
ceiling | integer | null | The hard limit enforced against this key: requests are refused beyond it. Null means unlimited. |
remaining | integer | null | ceiling minus used, never below 0. Null when the ceiling is unlimited. |
overageSoFarMinor | integer | What this period’s usage beyond "included" has accrued, in minor units, before your spend cap is applied. 0 without a paid plan. |
spendCapMinor | integer | The most the overage part of one period can ever cost you, in minor units. Your flat base fee is separate and is never capped away. |
requestId | string | Quote this when reporting a problem. |
/Service index — endpoints, auth and error format
Try itGET /No key required
Public endpoint. No API key, no quota, nothing billed.
curl
curl -X GET https://vendorevidence-api.com/
Response
/healthLiveness and deployed version
Try itGET /healthNo key required
Public endpoint. No API key, no quota, nothing billed.
curl
curl -X GET https://vendorevidence-api.com/health
Response
Errors
Every failure returns the same shape. Branch on code — it is a stable enum.
message is for humans and may change.
{
"error": {
"code": "quota_exceeded",
"message": "Quota exceeded for this billing period.",
"requestId": "0f3c8b12-…"
}
}
| Code | HTTP | Meaning |
|---|---|---|
missing_api_key | 401 | No Authorization or x-api-key header |
invalid_api_key | 401 | Unknown, revoked, or issued for a different API |
quota_exceeded | 429 | Allowance used for this period |
rate_limited | 429 | Too many requests |
invalid_request | 400 | Validation failed — details.path names the exact field |
not_found | 404 | No such route or resource |
internal_error | 500 | Our fault, not yours |
requestId appears on every response — success or failure — and in the
x-request-id header. Quote it and we can find the exact request. The playground
shows it above each response.
SDKs
Single files, zero dependencies — no requests, no axios — so they drop
into any environment without a dependency negotiation.
Python
from vendor_evidence_drift import VendorEvidenceDrift
client = VendorEvidenceDrift() # reads VENDOR_EVIDENCE_DRIFT_API_KEY
res = client.check({
"vendorId": "vnd-northwind",
"previous": {
"capturedAt": "2026-02-01",
"certifications": [{"framework": "soc2_type2", "issuedAt": "2025-02-15",
"expiresAt": "2026-02-14",
"scope": ["security", "availability", "confidentiality"]}],
"subprocessors": [{"name": "Cloudmail", "country": "US"}],
"slas": [{"metric": "uptime", "uptimeBasisPoints": 9995}],
},
"current": {
"capturedAt": "2026-08-01",
"certifications": [{"framework": "soc2_type2", "issuedAt": "2026-02-15",
"expiresAt": "2027-02-14",
"scope": ["security", "confidentiality"]}],
"subprocessors": [{"name": "Cloudmail", "country": "US"},
{"name": "Supportly", "country": "BR"}],
"slas": [{"metric": "uptime", "uptimeBasisPoints": 9990}],
},
})
report = res["reports"][0]
# The certification is current and covers less than it did. Branch on the code,
# never on the detail text.
for f in report["findings"]:
if f["material"]:
open_review(f["code"], f["subject"], f["detail"], f["controls"])
print(report["risk"]["score"], report["risk"]["band"])
for line in report["risk"]["derivation"]:
print(line) # the arithmetic, reproducible by hand
for w in report["warnings"]:
print("could not check:", w)
TypeScript
import { VendorEvidenceDrift } from './vendor-evidence-drift.js'
const client = new VendorEvidenceDrift() // reads VENDOR_EVIDENCE_DRIFT_API_KEY
const { reports } = await client.check({
vendorId: 'vnd-northwind',
previous: {
capturedAt: '2026-02-01',
certifications: [{ framework: 'soc2_type2', issuedAt: '2025-02-15',
expiresAt: '2026-02-14',
scope: ['security', 'availability', 'confidentiality'] }],
subprocessors: [{ name: 'Cloudmail', country: 'US' }],
slas: [{ metric: 'uptime', uptimeBasisPoints: 9995 }],
},
current: {
capturedAt: '2026-08-01',
certifications: [{ framework: 'soc2_type2', issuedAt: '2026-02-15',
expiresAt: '2027-02-14',
scope: ['security', 'confidentiality'] }],
subprocessors: [{ name: 'Cloudmail', country: 'US' },
{ name: 'Supportly', country: 'BR' }],
slas: [{ metric: 'uptime', uptimeBasisPoints: 9990 }],
},
})
const report = reports[0]
// The certification is current and covers less than it did. Branch on the
// code, never on the detail text.
for (const f of report.findings) {
if (f.material) openReview(f.code, f.subject, f.detail, f.controls)
}
console.log(report.risk.score, report.risk.band)
report.risk.derivation.forEach((line) => console.log(line))
for (const w of report.warnings) console.log('could not check:', w)
Download
| File | Size | Notes |
|---|---|---|
Python SDK vendor_evidence_drift.py | 9.7 kB | Single file, no dependencies — no requests, no httpx. Python 3.9+. |
TypeScript SDK vendor_evidence_drift.ts | 17.6 kB | Single file, no dependencies — no axios, no node-fetch. Node 18+, Deno, Bun and Workers. |
Postman collection postman_collection.json | 21.1 kB | Every endpoint, generated from the same contract as this page. Import it and set the key variable. |
These are the files from the repo, published here so they are reachable from the site rather than only from a checkout. They are regenerated with this page, so what you download is the version this reference describes.