Get started
Authentication
Workspace API keys: their format, scope, revocation and use.
Every request to /api/v1 authenticates with a workspace API key. There is no other credential for this API: no shared or platform-wide token, and no sign-in session.
Sending the key
Send the key in the Authorization header, as a bearer token:
GET /api/v1/status HTTP/1.1
Host: www.vestiarion.xyz
Authorization: Bearer vxk_example2_NotARealKey_ExampleOnly_NotARealKey_ExampleThe API reads the key from this header only.
The key format
A key looks like vxk_<prefix>_<secret>:
vxk_marks it as a Vestiarion key.<prefix>is eight characters,atozand2to7. It identifies the key, and Settings shows it in the list of keys, asvxk_<prefix>_…, so you can tell keys apart.<secret>is 32 random bytes, base64url-encoded: 43 characters.
Vestiarion stores the prefix and a SHA-256 hash of the secret, never the key itself. That is why a key is shown once, right after it is created, and cannot be shown again. If you lose one, create another and revoke the lost one.
One key, one workspace
A key belongs to the workspace it was created in, and reaches that workspace's data and no other: it reads it and, with write access, adds to it. To read two workspaces, use two keys. Asking for another workspace's counterparty by its id answers 404, as if it did not exist.
Creating a key
An owner or an admin creates keys on the workspace's Settings page, /o/<slug>/settings, under API keys. A key's name is 1 to 60 characters. A workspace holds at most 20 active keys; revoke one to make room for another. A key works for as long as the person who created it is a member of the workspace (see Revoking a key). Every other member of the workspace sees the list of keys, without the controls to create or revoke one. The Quickstart walks through it.
Tick Can also add records to give the key write access, and leave it clear for a key that only reads. A key's access is set when it is created: to change it, create a new key and revoke the old one.
Scopes
A key is read-only, or it reads and writes:
- Read only, the scope
read: everyGETendpoint. Every key has it. - Read and write, the scopes
readandwrite: also Add a counterparty, Add an invoice, Add a milestone and Create a payee link. The list of keys shows Read and write beside such a key.
A key whose scopes do not cover a route answers 403 forbidden, as a read-only key does on a write.
A write also needs the person who created the key to be able to add records now, which owners and admins can. If an owner moves them to approver or viewer, the key keeps reading, and each write answers 403 forbidden: "This key's issuer can no longer add records in this workspace."
Write access adds records, and nothing more. A key never verifies work, approves, rejects or pays:
- The agent decides an invoice added with one as it decides one typed into the console, with every guardrail.
- A milestone added with one waits for GitHub, or a person, to verify it.
- An address added with one, or entered by a payee through a link made with one, waits for a person in the workspace to confirm it, and the agent pays nothing to it until then.
Add invoices from your own system and Pay for merged pull requests walk through it.
Last used
Settings shows when each key was last used. The time is recorded after the response is sent, at most once a minute per key, so it can trail your latest request by up to a minute. A key that shows "never", or a date long past, is a candidate to revoke.
Revoking a key
An owner or an admin revokes a key from the same list. Revoking takes effect at once and cannot be undone: from then on the key answers exactly like a key that never existed. It leaves the list for Revoked keys, folded below it, which shows the day each key was revoked.
A key is also revoked when the person who created it stops being a member of the workspace: when they leave it, when an owner or an admin removes them, or when they delete their account. Every active key they created in that workspace, read-only or read-and-write, is revoked in the same step that ends their membership, so no key reads or adds records for someone who has left. Keys that other members created keep working, and so do the person's keys in workspaces they still belong to. Before anyone is removed, or leaves, the confirmation names the keys that will stop working. A workspace's last owner cannot leave it, so their keys stay.
Creating and revoking a key each add an entry to the workspace's ledger, api_key_created or api_key_revoked. The entry names the key by its id, and api_key_created lists its scopes; the key itself is never written to the ledger. api_key_revoked also says why, in reason:
person: an owner or an admin revoked it in Settings.byis who revoked it.member_left: the person who created it left the workspace.byis that person.member_removed: an owner or an admin removed the person who created it.byis who removed them, andmemberis the person removed.account_deleted: the person who created it deleted their account.byis that person.
A key revoked because its creator left, or was removed, gets its own entry right after the member's member_left or member_removed.
To rotate a key without downtime, create the new key, deploy it, check that its Last used time moves, and then revoke the old one.
When authentication fails
A missing key, a malformed one, an unknown one and a revoked one all get the same answer:
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{"error":{"code":"unauthorized","message":"A valid API key is required."}}The answer does not say which of the four it was, so it cannot be used to find out whether a key exists.
If Vestiarion cannot look the key up at all, because of a database error, it answers 500 internal rather than 401. A 500 says nothing about your key, so do not discard the key on one: retry later. Errors lists every code.
Keeping a key safe
A key reads the whole workspace: its invoices, counterparties, treasury and ledger. A read-and-write key can also add counterparties, invoices, milestones and payee links, so give write access only to a system that adds records.
- Never put a key in a URL. URLs end up in server logs, browser history and proxies. The API does not read a key from a query string anyway.
- Never put a key in client-side code, such as a web page, a browser extension or a mobile app. Anyone who has the code can read the key. Call the API from your server, and pass on only what the client needs.
- Keep it in a secret store or an environment variable, such as
VESTIARION_API_KEY, not in source control. - Use one key per integration, named after it, so you can revoke one without stopping the others.
- Create a long-lived integration's key as someone who will stay. A key stops working when the person who created it leaves the workspace. Before someone who created keys leaves, have a member who stays create replacements, and switch your integrations to them.
The Try it panel on each read operation's reference page keeps the key you paste in the page's memory only. An operation that adds records has no panel. It is not stored in the browser, and it is sent only in the Authorization header of the request you make, to this site's /api/v1.