The API (application programming interface) is a secure way for your other systems to talk to SupplierVault without anyone copying and pasting. Power BI can pull your supplier list every morning, Excel can refresh a spend sheet, your finance system can add invoices as they arrive, and a workflow tool can react when a supplier changes. You don't need the API to use SupplierVault: it's only for connecting other software.
Which plan includes it
API access is included in the Enterprise plan. It is also available during the free trial, because the trial includes everything, so you can test a connection before you choose a plan. On Essentials and Professional the "API keys" panel shows "API access is included in the Enterprise plan. Contact us to upgrade." If your plan ends or the free month runs out, existing keys stop working until a plan is active again: nothing is deleted.
Create a key
Only an admin can create or revoke keys.
- Click the account button (top right, with your initial and organisation name) and open the Organisation tab.
- Scroll to API keys. In "What will use it, e.g. Power BI", type a name you'll recognise later (up to 80 characters).
- Choose the scope: Read only for reporting tools, or Read and write if the system needs to add suppliers or invoices.
- Click Create key. The key appears once: "Copy this key now. It won't be shown again." Click Copy key and paste it straight into your password manager or the other system's secure settings.
The list shows each key's name, the first few characters, "Read and write" or "Read only", when it was created, and "last used <date>" or "not used yet". Click Revoke (then "Click again to revoke") to stop a key working immediately. You can have up to 20 active keys per organisation.
Read only or read and write?
| Scope | Can do | Use it for |
|---|---|---|
| Read only | Download suppliers, tasks, invoices, purchase requests, sourcing events, savings, people, activity, obligations and signatures | Power BI, Excel, dashboards, data warehouses |
| Read and write | Everything above, plus add suppliers, add invoices and update an invoice's status | Finance systems, workflow tools, intake forms |
Both kinds follow your organisation's data only. A key belongs to one organisation; it can't see any other.
Making a request
Every request goes to this base address:
Send the key in a header called X-API-Key (or as Authorization: Bearer sv_…). Keys start with sv_. Everything comes back as JSON. A simple test is to ask for the base address itself: it replies with the API name, version, your key's name and scope, and the list of resources.
What you can read
| Request | Returns |
|---|---|
GET /suppliers | Every supplier, with all the fields on its record (contract, risk, finance set-up, governance and so on), plus id, area and updated_at |
GET /suppliers/{id} | One supplier, or 404 "Not found" |
GET /tasks | Tasks, as you see them on the Tasks page |
GET /invoices | The invoice register |
GET /requests | Purchase requests |
GET /sourcing | Sourcing events |
GET /savings | The savings register |
GET /people | Stakeholders |
GET /activity | The activity (audit) trail, newest first |
GET /obligations | One row per contract obligation, with supplierId, supplier, area, owner, due date and status |
GET /signatures | Electronic signatures: signer name, role and email, document name, the document's SHA-256 fingerprint, and when it was signed |
Any of these (except obligations and signatures) can also be fetched one at a time with /{resource}/{id}.
Filters and paging
| Parameter | What it does |
|---|---|
limit | How many records per page, 1 to 500. Default 100. |
cursor | Ask for the next page. Use the next_cursor value from the previous reply. When next_cursor is null there are no more pages. |
updated_since | Only records changed since a date or time, e.g. 2026-10-01. Handy for nightly refreshes. |
area | Only one area, by its exact name, e.g. Facilities |
stage | Filter suppliers by stage, e.g. active |
status | Filter tasks or invoices by status, e.g. on-hold |
supplier_id | Only the tasks or invoices for one supplier |
Every list comes back as {"data": [ … ], "next_cursor": "…"}. Records are ordered by id, except activity, which is newest first. Signatures don't take updated_since or the filters. Obligations are gathered supplier by supplier, so one page can hold a few more or fewer rows than your limit.
What you can add or change (read-and-write keys)
Add a supplier: POST /suppliers
| Field | Rules |
|---|---|
name | Required, up to 200 characters |
category | The area, up to 80 characters. Defaults to "Other" |
legalName | Defaults to the name |
regNo, vatNo | Company and VAT numbers, up to 20 characters each |
currency | Three letters, default GBP |
notes | Up to 2,000 characters |
The supplier is created at the Intake stage, as tier T3 Approved supplier, with a 90-day notice period, and the activity trail records "Supplier <name> added at the intake stage (via API key "<key name>")". From there your team onboards it in the normal way. Your plan's supplier limit still applies.
Add an invoice: POST /invoices
| Field | Rules |
|---|---|
supplierId | Required. The supplier's id from GET /suppliers |
number | Required, up to 80 characters. Must be new for that supplier |
amount | Required, not zero. Enter it excluding VAT, as in the app |
currency | Three letters |
date | YYYY-MM-DD, default today |
period | Billing month, e.g. 2026-10 |
po | Purchase order number, up to 40 characters |
note | Up to 500 characters |
The same fraud protection applies as in the app. If the supplier's bank details are verified (penny test passed, call-back done and no bank change waiting), the invoice is saved as Received. If not, it's saved On hold with the note "Held: bank details unverified".
Update an invoice: PATCH /invoices/{id}
Send status (one of received, matched, on-hold, disputed, paid), an optional note, and paidOn (YYYY-MM-DD, used with paid; default today). Moving an invoice to paid, matched or received is refused while the supplier's bank details aren't verified.
Errors
Errors come back as {"error": {"code": "…", "message": "…"}}.
| Status | Code | What it means |
|---|---|---|
| 400 | bad_request | Something is missing or in the wrong format, e.g. "updated_since must be a date, e.g. 2026-10-01" or "Nothing to change" |
| 401 | unauthorised | No key sent ("Send your API key in the X-API-Key header.") or the key is wrong or revoked |
| 403 | plan | Your plan doesn't include the API, or the plan has ended ("changes are paused") |
| 403 | read_only | A read-only key tried to change something: "Create a read-and-write key to make changes." |
| 404 | not_found | Unknown address or record. Try /api/v1/suppliers |
| 405 | not_allowed | "That change isn't available through the API." |
| 409 | duplicate | "Invoice <number> already exists for this supplier" |
| 409 | bank_unverified | "This supplier's bank details aren't verified, so the invoice stays on hold." |
| 500 | server_error | "Something went wrong. Try again." This can also happen if adding a supplier would take you over your plan's supplier limit. |
Connect Power BI or Excel
- Create a Read only key named after the report, e.g. "Power BI".
- In Power BI or Excel choose Get data › From web, then Advanced.
- Enter the address, for example
…/api/v1/suppliers?limit=500. - Under HTTP request header parameters, add
X-API-Keywith your key as the value. - When the result opens, expand the
datalist into a table, then expand the columns you want. - Repeat for
/invoices,/tasksor any other resource, and relate the tables on the supplier id.
next_cursor to fetch further pages, or filter by area or updated_since.Good to know
- Keys work only for the organisation that created them, and only an admin can see the keys panel.
- A key doesn't follow "access by area": it sees every area in the organisation. Give keys only to systems that should see everything.
- Full bank account numbers are never stored in SupplierVault, so the API can't return them.
- The full technical reference is on the developers page.