API reference

The Sablefort REST API lets you manage vaults, items, and memberships programmatically. It is the same interface the CLI uses. All requests are authenticated and served over HTTPS.

Base URL

https://api.sablefort.com/v1

Authentication

Every request must include a Bearer token in the Authorization header. Create a token in the admin console under Service accounts, scoped to only the vaults it needs. Requests without a valid token receive 401 Unauthorized.

Authorization: Bearer sk_live_9f2c…
Ciphertext in, ciphertext out. Item contents are returned encrypted. The API never returns plaintext secrets — decryption happens client-side, on your device, under your account. Treat the API as a transport for encrypted material plus metadata.

Conventions

  • Requests and responses use application/json.
  • Timestamps are ISO 8601 in UTC.
  • List endpoints are paginated with ?limit= and ?cursor=; the response includes a next_cursor when more results exist.
  • Errors return a JSON body with error.code and error.message.

List vaults

GET /vaults — returns the vaults the token can access.

curl https://api.sablefort.com/v1/vaults \
  -H "Authorization: Bearer sk_live_9f2c…"

Response:

{
  "data": [
    {
      "id": "vlt_8Ht2",
      "name": "engineering",
      "item_count": 42,
      "created_at": "2026-01-14T09:22:05Z"
    },
    {
      "id": "vlt_0Kp9",
      "name": "on-call",
      "item_count": 9,
      "created_at": "2026-02-02T17:41:11Z"
    }
  ],
  "next_cursor": null
}

List items in a vault

GET /vaults/{vault_id}/items — returns item metadata (titles, types, timestamps). Field contents are not included in the list view.

curl https://api.sablefort.com/v1/vaults/vlt_8Ht2/items \
  -H "Authorization: Bearer sk_live_9f2c…"
{
  "data": [
    {
      "id": "itm_5Rw1",
      "title": "Deploy Key",
      "type": "login",
      "updated_at": "2026-06-30T12:03:44Z"
    }
  ],
  "next_cursor": null
}

Read a single item

GET /vaults/{vault_id}/items/{item_id} — returns the item's fields. Secret field values are delivered as encrypted blobs; your client decrypts them locally.

curl https://api.sablefort.com/v1/vaults/vlt_8Ht2/items/itm_5Rw1 \
  -H "Authorization: Bearer sk_live_9f2c…"
{
  "id": "itm_5Rw1",
  "title": "Deploy Key",
  "type": "login",
  "fields": [
    { "name": "username", "type": "text",     "value": "deploy-bot" },
    { "name": "password", "type": "secret",   "encrypted": true,
      "value": "enc:v2:9c1a…"  }
  ],
  "updated_at": "2026-06-30T12:03:44Z"
}

Non-secret fields such as username may be returned in the clear as metadata; fields marked "type": "secret" arrive with "encrypted": true and an opaque enc: value that only an authorized client can open.

Create an item

POST /vaults/{vault_id}/items — adds an item to a vault. Secret field values must be encrypted by your client before they are sent; the server stores what it receives and never sees plaintext.

curl -X POST https://api.sablefort.com/v1/vaults/vlt_8Ht2/items \
  -H "Authorization: Bearer sk_live_9f2c…" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Staging Deploy Key",
    "type": "login",
    "fields": [
      { "name": "username", "type": "text",   "value": "deploy-staging" },
      { "name": "password", "type": "secret", "value": "enc:v2:4be7…" }
    ]
  }'

Response 201 Created:

{
  "id": "itm_7Yq3",
  "title": "Staging Deploy Key",
  "type": "login",
  "created_at": "2026-07-17T10:12:00Z"
}

Memberships

GET /vaults/{vault_id}/members — lists who can access a vault and at what role.

curl https://api.sablefort.com/v1/vaults/vlt_8Ht2/members \
  -H "Authorization: Bearer sk_live_9f2c…"
{
  "data": [
    { "user_id": "usr_1Aa", "email": "ada@example.com",   "role": "editor" },
    { "user_id": "usr_2Gg", "email": "grace@example.com", "role": "admin"  }
  ]
}

POST /vaults/{vault_id}/members — grants access.

curl -X POST https://api.sablefort.com/v1/vaults/vlt_8Ht2/members \
  -H "Authorization: Bearer sk_live_9f2c…" \
  -H "Content-Type: application/json" \
  -d '{ "email": "lin@example.com", "role": "viewer" }'

Errors

StatusCodeMeaning
400invalid_requestMalformed body or missing field.
401unauthorizedMissing or invalid Bearer token.
403forbiddenToken lacks access to this vault or item.
404not_foundVault or item does not exist.
429rate_limitedToo many requests; retry after the indicated delay.
{
  "error": {
    "code": "forbidden",
    "message": "This token cannot access vault vlt_8Ht2."
  }
}