API

Public Teak API for creating, searching, editing, deleting, and favoriting cards

Teak provides a public API at https://api.teakvault.com/v1.

Base URLs

  • Production: https://api.teakvault.com/v1
  • Local development: http://localhost:8787/v1

Authentication

All API requests require your Teak API key in the Authorization header:

Authorization: Bearer teakapi_xxx_xxx

Generate API keys in Teak Settings: https://app.teakvault.com/settings.

Endpoints

Service Health

GET /healthz

Response:

{
  "status": "ok",
  "service": "teak-api",
  "version": "v1"
}

API Info

GET /v1

Response:

{
  "version": "v1",
  "endpoints": [
    "POST /v1/cards",
    "GET /v1/cards/search",
    "GET /v1/cards/favorites",
    "PATCH /v1/cards/:cardId",
    "DELETE /v1/cards/:cardId",
    "PATCH /v1/cards/:cardId/favorite"
  ],
  "auth": "Authorization: Bearer <api_key>"
}

Create Card

POST /v1/cards
Content-Type: application/json
{
  "content": "https://teakvault.com"
}

Response:

{
  "status": "created",
  "cardId": "j57fnzw9zy6m3qbjxm4j5f8j2d7st9q8"
}

status can be created or duplicate.

Search Cards

GET /v1/cards/search?q=design&limit=50

Response:

{
  "items": [],
  "total": 0
}

Favorite Cards (List)

GET /v1/cards/favorites?q=design&limit=50

Response shape matches search:

{
  "items": [],
  "total": 0
}

Edit Card

PATCH /v1/cards/:cardId
Content-Type: application/json

Request fields (any subset):

  • content: string
  • url: string
  • notes: string | null
  • tags: string[]

Examples:

{
  "notes": null,
  "tags": []
}
  • notes: null clears notes
  • tags: [] clears tags

Response: 200 with updated card object.

Delete Card

DELETE /v1/cards/:cardId

Response: 204 No Content

Set Favorite State

PATCH /v1/cards/:cardId/favorite
Content-Type: application/json
{
  "isFavorited": true
}

Response: 200 with updated card object.

Gateway Behavior

  • Default upstream timeout is 10_000ms.
  • Successful upstream responses are validated as JSON payloads.
  • When upstream response status/body are valid, the gateway passes through status and response body.

Limits

  • limit is clamped to 1..100
  • Missing/empty q on search endpoints returns latest cards

Error Behavior

Common error codes:

  • UNAUTHORIZED / INVALID_API_KEY
  • RATE_LIMITED
  • BAD_REQUEST / INVALID_INPUT
  • NOT_FOUND
  • INTERNAL_ERROR
  • UPSTREAM_TIMEOUT
  • UPSTREAM_UNAVAILABLE
  • UPSTREAM_INVALID_RESPONSE
  • CONFIG_ERROR

Errors are returned as JSON:

{
  "code": "INVALID_INPUT",
  "error": "Field `content` must be a non-empty string"
}