VendoVendo Docs
ReferenceHTTP API

Keys

List and revoke the tenant's proxy keys (vendo_sk_*).

/api/keys is the tenant-level CRUD surface for the vendo_sk_* API keys that authenticate against the Vendo proxy. To mint a new key on an existing app, use POST /api/apps/{id}/keys. To mint a brand new app + key in one call, use POST /api/deploy.

GET /api/keys

List every active proxy key for the caller's tenant. Keys span all apps and connections owned by the tenant.

Auth

Session cookie.

Response: 200 OK

{
  "keys": [
    {
      "id": "00000000-0000-0000-0000-000000000000",
      "scope_mode": "app",
      "connection_id": null,
      "app_id": "00000000-0000-0000-0000-000000000001",
      "display_name": "Hermes (support-bot)",
      "prefix": "vendo_sk_a1b2",
      "created_at": "2026-05-01T12:00:00Z",
      "last_used_at": "2026-05-20T09:34:00Z"
    }
  ]
}
FieldTypeNotes
idstringUUID of the keys row
scope_modestring"app" (app-scoped, the deploy default) or "connection" (connection-scoped, issued via POST /api/connections/{id}/keys)
connection_idstring | nullSet only when scope_mode == "connection"
app_idstring | nullSet only when scope_mode == "app"
display_namestring | nullHuman label given at issue time
prefixstringFirst 12 chars of the plaintext key — safe to surface in UI
created_atstringISO 8601 timestamp
last_used_atstring | nullLast time the proxy authenticated this key

The bytea key_hash column is never projected — the full plaintext can only be retrieved at issue time.

Errors

StatusBodyCause
401{ "error": "unauthorized" }No session
404{ "error": "no_tenant" }Signed-in user has no production tenant

DELETE /api/keys/{id}

Revoke a proxy key. The keys.revoked_at column is set and the KV entry is purged so the proxy stops accepting the bearer immediately.

Auth

Session cookie. Caller must own the tenant that owns the key.

Response: 200 OK

{ "revoked_at": "2026-05-20T12:00:00Z" }

Errors

StatusBodyCause
401{ "error": "unauthorized" }No session
404{ "error": "no_tenant" }Signed-in user has no production tenant
404{ "error": "not_found" }Key doesn't exist or isn't owned by this tenant

Revocation is immediate for the proxy (KV delete) but the DB is also updated. If the KV delete fails, the DB row is still marked revoked — resyncAuthorizationKeys reconciles KV on the next sweep, so the bearer will stop working at most a few seconds late.

Where keys are issued

Keys are minted by other endpoints; /api/keys is read+revoke only.

PathIssues a key when
POST /api/deployEvery successful deployment mints one App Key (scope app)
POST /api/apps/{id}/keysAdd an extra App Key to an existing app (rotation, CLI use, etc.)
POST /api/connections/{id}/keysAdd a connection-scoped key for a single provider

The plaintext is returned exactly once at issue. Vendo's session-role reads never expose it again — the canonical column in the keys table is the SHA-256 hash.

On this page