Changelog
Changes to the /v1 API and to this documentation, newest first.
/v1 is additive: new endpoints, new fields and new optional parameters
can appear at any time, and a client must ignore fields it does not
recognise. Anything that would break a conforming client cuts /v2 instead
— so nothing on this page below a Breaking label will ever require you
to change working code.
2026-10-14
Section titled “2026-10-14”New — Trust Center access requests can be decided from your own systems.
Approve or reject a pending request with
POST /v1/trust-center/access-requests/{id}/approve
and
POST /v1/trust-center/access-requests/{id}/reject,
and read one with
GET /v1/trust-center/access-requests/{id}.
Deciding needs the new scope trust-center-access:write; a decision already
made answers 409 ACCESS_REQUEST_ALREADY_DECIDED. The visitor’s access link
is always emailed to them and the token is never returned to you. Access
requests gain decidedVia, decidedByApiClientId and decisionReference,
and the trustcenter.access_approved and trustcenter.access_rejected
webhook payloads now carry decidedBy.
Guide.
2026-10-13
Section titled “2026-10-13”New — Trust Center documents carry a protection policy.
GET /v1/trust-center/resources
gains isRestricted (never part of a standard approval — granted only by
name), ndaRequired (the visitor signs the NDA before the file is served,
while the organization’s NDA requirement is on) and downloadAllowed
(false = view-only). isGated keeps its meaning and is true for
restricted documents too.
GET /v1/trust-center/access-requests
gains requestedResourceIds — the restricted documents a visitor asked for
by name, which is a request and not a grant.
New — the Trust Center document access log is pullable.
GET /v1/trust-center/access-events
lists every read of a Trust Center document by a visitor holding access —
who, which document, when, how it was served and whether it was
watermarked — newest first and cursor-paginated. Scope:
trust-center-analytics:read, which is new and mintable from today.
The document fields are a snapshot taken when the file was served, so a
later rename or re-upload does not rewrite history; events recorded before
snapshots existed carry snapshotReconstructed: true. Push delivery is the
new trustcenter.resource_downloaded webhook, whose accessEventId is the
event’s id here; trustcenter.access_rejected is new alongside it.
Changed — webhook deliveries are retried, and each webhook says how.
A failed delivery is no longer dropped: a timeout, a network error, 408,
429 or a 5xx (other than 501/505) is retried — by default up to 6
attempts over about 6 hours, and on a 429 or 503 after the receiver’s
Retry-After. Any other 4xx, 410 Gone, an unfollowable redirect and a
blocked address fail at once. Delivery is therefore at-least-once:
dedupe on X-Vendorica-Delivery, which is identical on every attempt, and
read the new X-Vendorica-Delivery-Attempt header for the attempt number.
The webhooks guide has the full table.
Webhooks gain retryPolicy and failureHandling, readable on every webhook
and settable on POST /v1/webhooks and
PATCH /v1/webhooks/{id}; both
objects are partial on write. 410 Gone now suspends the webhook unless
failureHandling.disableOnGone is false. Deliveries from
GET /v1/webhooks/{id}/deliveries
can be retrying, and carry attemptCount, nextAttemptAt,
lastFailureClass and every attempt in attempts.
Fixed — the published Webhook schema named a trigger string. The
endpoints have returned a triggers array since a webhook could subscribe
to more than one event; the reference now says so. No response changed.
2026-09-07
Section titled “2026-09-07”New — segregation-of-duties findings are pullable.
GET /v1/sod/violations lists every
case where one holder was found with both halves of a duty pair your
organization keeps separate, filterable by status, ruleId,
subjectType and subjectId. Scope: sod:read.
Two things worth knowing before you correlate on it. Read the rung from
evidence.enforcementAtDetection, not from the rule as it stands now — a
rule promoted since is a different statement about the same finding. And
accepted / resolved are terminal: a conflict that recurs is filed as a
new violation rather than reopening the old one, so poll on detectedAt
for new findings and re-read a row to pick up its decision. Push delivery
of the same finding is the sod.violation_detected webhook.
2026-09-07
Section titled “2026-09-07”POST /v1/incidents accepts businessFunctionId. An incident can now
name the critical or important function it affected, so DORA Articles 17–19
are answerable per function rather than only per organisation. Optional, and
absent it behaves exactly as before —
POST /v1/incidents.
2026-09-02
Section titled “2026-09-02”Fixed — createdTo on the audit log now covers the day it names. A bare
date sent to GET /v1/audit-log was compared
against midnight at the start of that day, so createdFrom=2026-09-01 with
createdTo=2026-09-01 matched nothing. It now runs through
2026-09-01T23:59:59.999Z. If you worked around this by sending the next
day as createdTo, that request now returns an extra day — send the day you
mean. A createdTo carrying a time is unchanged and is still used exactly as
given.
2026-09-02
Section titled “2026-09-02”Changed — an idempotent evidence replay redacts sensitive metadata, like
every other read. A digest-matched replay of
POST /v1/controls/{controlId}/evidence
returned the existing row’s summary, description and contentFilename
in full, even where the same row’s
listing redacts them and its
download answers 403.
Evidence flagged isSensitive is readable by its uploader, administrators
and auditors; an API key is none of those, so those three fields now come
back null / "(sensitive)" on a replay for such a caller. The replay
itself is unchanged — still 200 with Idempotent-Replay: true, still safe
to retry — and a caller who may view the row sees no difference.
2026-09-01
Section titled “2026-09-01”New — the policy register answers which version is in force. Each row of
GET /v1/policies now carries
currentVersionNumber / currentVersionPublishedAt for the published
version and latestVersionNumber / latestVersionApprovalStatus for the one
being worked on, plus versionCount. The two are routinely different — an
approved v2 in force under a v3 in review — so neither is derivable from the
other, and answering “is a revision in flight” previously cost a
{id}/versions request per
policy.
2026-09-01
Section titled “2026-09-01”Changed — risk scores follow the organization’s own calculation, and are
no longer integers. inherentScore / residualScore on
GET /v1/risk-scenarios ·
{id} were documented as
integer and are now number. An organization can choose how likelihood
and impact combine — multiply (1–25, the default and what every existing
organization is on), sum (2–10) or average (1–5) — and the last of those
produces halves. Read the score rather than recomputing it from
inherentLikelihood × inherentImpact: that product is only correct for
organizations on the default, and the API does not publish which
calculation is in force.
2026-09-01
Section titled “2026-09-01”New — DORA RoI service type on a contract. A contract now carries
ebaIctServiceType, the ITS type of ICT services as one of the 19
eba_TA:S01–S19 members. It is what the Register of Information files
in B_02.02 c0060 and B_07.01 c0040, and it is the code rather than a
name: the field accepts only members of that closed list, so a label
like "SaaS" is rejected rather than stored and later dropped.
GET /v1/contracts ·
{id}.
2026-09-01
Section titled “2026-09-01”New — The rest of the risk surface. /v1 carried risk registers and
scenarios; it now carries the layers around them. All read-only, all on the
existing risks:read scope:
GET /v1/risk-categories·{id}— the risk taxonomy a scenario’scategoryIdpoints at.GET /v1/risk-indicators·{id}·{id}/trend— key risk indicators and their measurement series.GET /v1/risk-appetite·{id}— appetite statements and their tolerance bands.GET /v1/risk-snapshots·{id}·trend— point-in-time captures of the register.
Two field-level notes worth reading before you build against them: an
indicator’s direction decides which side of a threshold is a breach, and a
trend row’s status is frozen against the thresholds in force when it was
measured, so it can disagree with today’s. Both are documented on the
operations above.
New — GET /v1/users, under a new
users:read scope. A directory — id, email, name, status — so a report can
label the ownerUserId that scenarios, contracts and incidents carry. Grant
the scope when you create a key; existing keys do not acquire it.
2026-08-30
Section titled “2026-08-30”Updated — Rate limits are lower. The per-client budgets are now 300/min reads, 120/min writes and 60/min on the binary upload and download endpoints, down from 1,200 / 300 / 120.
A client that honours Retry-After needs no change. One that paces on a
fixed sleep calculated from the old numbers will start seeing 429 — read
the budget from the RateLimit-* headers instead, which have always carried
it. See rate limits.
The old figures were not sized from observed traffic; they were a comfortable default. If you are doing a bulk migration, ask us to raise the budget on your API client rather than pacing around the default — that override is what it is for.
Docs — A guide to importing vendors and contracts.
Import vendors and contracts covers
POST /v1/vendors/imports end to end — match keys, upsert semantics, LEI
enrichment, and reading the per-row outcome — and is explicit that
contracts have no create endpoint, so a migration plans them through the
in-app importer instead.
Docs — Every documented response carries an example.
All 281 response bodies in the API reference now show a worked
example. Success examples are generated from the schema itself, so they
cannot contradict the field list beside them; error examples come from the
error class the service actually throws, so code and error are the
literal strings you will receive.
402 and 409 deliberately carry no example — each maps to several codes,
and showing one would document a code you may never receive. Their status
descriptions carry the meaning instead.
Docs — These docs were published at developer.vendorica.com.
They went up at docs.vendorica.com first and moved the same day. That
address no longer resolves and never had an audience; it is recorded here
only so a link someone captured in those few hours has an explanation.
2026-08-28
Section titled “2026-08-28”New — Incident reporting.
POST /v1/incidents and GET /v1/incidents, GET /v1/incidents/{id}.
Scopes incidents:write / incidents:read. DORA reporting clocks are
anchored on the incident’s reportedAt, not on when the record was created,
so a backfilled incident keeps its real regulatory deadline.
New — Controls, compliance, policies and Trust Center reads.
| Endpoint | Scope |
|---|---|
GET /v1/controls, /controls/{id}, /controls/{id}/mappings |
controls:read |
GET /v1/compliance/posture, /compliance/frameworks/{code} |
compliance:read |
GET /v1/policies, /policies/{id}, /policies/{id}/versions, /policies/{id}/versions/{versionId} |
policies:read |
GET /v1/trust-center/resources, /access-requests, /subscribers, /visitor-tokens |
trust-center-content:read, trust-center-access:read, trust-center-subscribers:read |
New — The risk write half.
POST /v1/risk-scenarios and PUT /v1/risk-scenarios/{id}, scope
risks:write. Risk registers stay read-only.
How this page is maintained
Section titled “How this page is maintained”Every entry here describes a change that shipped. An entry is written in the same pull request as the change it documents, which is the only way a changelog stays true — one written afterwards is written from memory.
Label each entry with what it does to a client that is already working:
- New — an endpoint, field or parameter that did not exist. Safe.
- Updated — behaviour of something that did exist, in a way a conforming client tolerates. Read it anyway.
- Deprecated — still works, will be removed in a future major version. Always names the replacement and the earliest version it can disappear in.
- Breaking — cannot appear under
/v1. Reserved for a future major. - Fixed — the service now does what this documentation already said.
- Docs — this site changed; the API did not.