API
Public Teak API for creating, querying, and syncing cards
Teak provides a public API at https://api.teakvault.com/v1.
Base URLs
- Production:
https://api.teakvault.com/v1 - Local development:
http://api.teak.localhost:1355/v1 - OpenAPI:
https://api.teakvault.com/openapi.json
MCP Endpoint
Teak also exposes a remote MCP server:
- Production:
https://api.teakvault.com/mcp - Local development:
http://api.teak.localhost:1355/mcp
See the dedicated MCP docs for tool contracts and JSON-RPC examples.
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.
Headers
X-Request-Idis returned on every gateway response.Idempotency-Keyis supported onPOST /v1/cardsandPOST /v1/cards/bulk.- Rate-limited responses may include
RateLimit-Limit,RateLimit-Remaining,RateLimit-Reset, andRetry-After.
Endpoints
Service Health
GET /healthz{
"status": "ok",
"service": "teak-api",
"version": "v1"
}API Info
GET /v1Response includes the current v1 route list plus MCP connection details.
Canonical Card Listing
GET /v1/cards?q=design&limit=25&cursor=opaque&include=content,metadataSupported query parameters:
qlimitcursorsort=newest|oldesttypetagfavorited=true|falsecreatedAftercreatedBeforeinclude=content,metadata,processing
The include parameter is a comma-separated list of field groups to add to each item. Omitting it returns the base fields only.
include value | Extra fields added |
|---|---|
content | content, notes, aiSummary |
metadata | fileUrl, linkPreviewImageUrl, screenshotUrl, thumbnailUrl |
processing | processingStatus, metadataStatus, aiTranscript |
Response:
{
"items": [
{
"id": "card_1",
"appUrl": "https://app.teakvault.com/?card=card_1",
"createdAt": 1,
"isFavorited": true,
"metadataTitle": "Example",
"tags": ["design"],
"type": "link",
"updatedAt": 2,
"url": "https://example.com"
}
],
"pageInfo": {
"hasMore": false,
"nextCursor": null
}
}Create Card
POST /v1/cards
Content-Type: application/json
Idempotency-Key: save-link-123Supported request body fields:
content— text or URL to save (required ifurlis not set)url— URL to save (required ifcontentis not set)notes— optional freeform notes attached to the card (string or null)tags— optional array of tag stringssource— optional string identifying the client or integration (e.g."raycast_quick_save")
{
"content": "https://teakvault.com",
"tags": ["design"]
}{
"status": "created",
"cardId": "card_1",
"appUrl": "https://app.teakvault.com/?card=card_1"
}Bulk Card Operations
POST /v1/cards/bulk
Content-Type: application/json
Idempotency-Key: bulk-ops-001{
"operation": "favorite",
"items": [{ "cardId": "card_1", "isFavorited": true }]
}Supported operations:
createupdatefavoritedelete
Response:
{
"operation": "favorite",
"results": [{ "index": 0, "status": "success", "cardId": "card_1" }],
"summary": { "total": 1, "succeeded": 1, "failed": 0 }
}Incremental Sync
GET /v1/cards/changes?since=1710000000000&limit=50{
"items": [],
"deletedIds": ["card_2"],
"pageInfo": {
"hasMore": false,
"nextCursor": null
}
}Legacy Search Endpoints
These remain stable for existing consumers:
GET /v1/cards/search?q=design&limit=50
GET /v1/cards/favorites?q=design&limit=50Supported filters on both legacy endpoints:
qlimittypetagsortfavoritedcreatedAftercreatedBefore
Legacy response shape remains:
{
"items": [],
"total": 0
}Get Card
GET /v1/cards/:cardIdReturns the full card object.
Update Card
PATCH /v1/cards/:cardId
Content-Type: application/jsonAllowed fields:
contenturlnotestags
Example:
{
"notes": "Updated note",
"tags": ["reference"]
}Delete Card
DELETE /v1/cards/:cardIdResponse: 204 No Content
Favorite State
PATCH /v1/cards/:cardId/favorite
Content-Type: application/json{
"isFavorited": true
}Tags
GET /v1/tags{
"items": [{ "name": "design", "count": 3 }]
}Errors
Errors preserve the stable { code, error } shape. Some responses may also include requestId, details, or retryAt.
{
"code": "INVALID_INPUT",
"error": "Body must include `content` or `url`"
}Idempotency Key Errors
When using Idempotency-Key on POST /v1/cards or POST /v1/cards/bulk, two 409 Conflict scenarios may occur:
| Situation | code | error |
|---|---|---|
| A request with the same key is still in flight | CONFLICT | Idempotency-Key is already being processed |
| The key was already used with a different request body | CONFLICT | Idempotency-Key was already used with a different request |
If the key was previously used with an identical request body, the original response is replayed without re-processing the operation.