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_xxxGenerate API keys in Teak Settings: https://app.teakvault.com/settings.
Endpoints
Service Health
GET /healthzResponse:
{
"status": "ok",
"service": "teak-api",
"version": "v1"
}API Info
GET /v1Response:
{
"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=50Response:
{
"items": [],
"total": 0
}Favorite Cards (List)
GET /v1/cards/favorites?q=design&limit=50Response shape matches search:
{
"items": [],
"total": 0
}Edit Card
PATCH /v1/cards/:cardId
Content-Type: application/jsonRequest fields (any subset):
content: stringurl: stringnotes: string | nulltags: string[]
Examples:
{
"notes": null,
"tags": []
}notes: nullclears notestags: []clears tags
Response: 200 with updated card object.
Delete Card
DELETE /v1/cards/:cardIdResponse: 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
limitis clamped to1..100- Missing/empty
qon search endpoints returns latest cards
Error Behavior
Common error codes:
UNAUTHORIZED/INVALID_API_KEYRATE_LIMITEDBAD_REQUEST/INVALID_INPUTNOT_FOUNDINTERNAL_ERRORUPSTREAM_TIMEOUTUPSTREAM_UNAVAILABLEUPSTREAM_INVALID_RESPONSECONFIG_ERROR
Errors are returned as JSON:
{
"code": "INVALID_INPUT",
"error": "Field `content` must be a non-empty string"
}