API
Teak provides a public API at https://api.teakvault.com/v1.
Base URLs
Section titled “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
Section titled “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
Section titled “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
Section titled “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
Section titled “Endpoints”Service Health
Section titled “Service Health”GET /healthz{ "status": "ok", "service": "teak-api", "version": "v1"}API Info
Section titled “API Info”GET /v1Response includes the current v1 route list plus MCP connection details.
Canonical Card Listing
Section titled “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
Section titled “Create Card”POST /v1/cardsContent-Type: application/jsonIdempotency-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
Section titled “Bulk Card Operations”POST /v1/cards/bulkContent-Type: application/jsonIdempotency-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
Section titled “Incremental Sync”GET /v1/cards/changes?since=1710000000000&limit=50{ "items": [], "deletedIds": ["card_2"], "pageInfo": { "hasMore": false, "nextCursor": null }}Legacy Search Endpoints
Section titled “Legacy Search Endpoints”These remain stable for existing consumers:
GET /v1/cards/search?q=design&limit=50GET /v1/cards/favorites?q=design&limit=50Supported filters on both legacy endpoints:
qlimittypetagsortfavoritedcreatedAftercreatedBefore
Legacy response shape remains:
{ "items": [], "total": 0}Get Card
Section titled “Get Card”GET /v1/cards/:cardIdReturns the full card object.
Update Card
Section titled “Update Card”PATCH /v1/cards/:cardIdContent-Type: application/jsonAllowed fields:
contenturlnotestags
Example:
{ "notes": "Updated note", "tags": ["reference"]}Delete Card
Section titled “Delete Card”DELETE /v1/cards/:cardIdResponse: 204 No Content
Favorite State
Section titled “Favorite State”PATCH /v1/cards/:cardId/favoriteContent-Type: application/json{ "isFavorited": true}GET /v1/tags{ "items": [{ "name": "design", "count": 3 }]}Errors
Section titled “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
Section titled “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.