xmark API

chat with your x bookmarks

base URL

https://www.xmark.dev/api/v1
llms.txtllms-full.txtOpenAPI

the xmark API uses REST conventions with JSON request and response bodies. all endpoints require authentication via API key.

responses follow a consistent shape: { data: ... } for success and { error: { code, message, requestId } } for errors.

authentication

all API requests must include your API key in the Authorization header. keys are prefixed with nt_live_ and shown exactly once at creation: store them in a secret manager, never commit them.

header format

http
Authorization: Bearer nt_live_YOUR_API_KEY

verify your key

any valid key can call GET /keys/me to introspect itself, useful for confirming a key works and seeing its scopes.

bash
curl "https://www.xmark.dev/api/v1/keys/me" \
  -H "Authorization: Bearer nt_live_YOUR_API_KEY"

scopes

each API key carries a set of scopes. grant the minimum needed. an admin key can create other keys and manage webhooks, so treat it as a root credential.

scopedescription
readread-only access to owned resources
writecreate and update owned resources
deletedelete owned resources
adminmanage API keys and webhook endpoints

default scopes (if none specified): read, write.

API reference

bookmarks

read, search, and sync the authenticated user's X bookmarks.

paginated list of the caller's bookmarks, newest first

fetch a single bookmark

remove a bookmark. local-only by default (the next sync re-creates anything still bookmarked on X); pass unbookmark=true to also remove it on X

semantic search over the caller's bookmark library (pgvector + OpenAI embeddings)

pull the latest bookmarks from the connected X account, embed new ones, and store them. large libraries sync in chunks: call again while done is false. when X rate-limits the crawl (10 req / 15 min) the response carries retryAfterSeconds: wait that long before the next call, and the sync resumes where it stopped

chat

ask natural-language questions about bookmarks; Claude answers with citations grounded in them.

submit a question. xmark retrieves the most relevant bookmarks via semantic search and has Claude generate an answer with inline citations. returns a single JSON response

conversations

list, read, and delete past chat conversations.

paginated list of the caller's conversations, most recently active first

the conversation's message history, oldest first. assistant messages carry the IDs of the bookmarks retrieved for that answer

permanently delete a conversation and its messages

usage

plan and quota usage for the authenticated user.

the caller's plan, chat-message usage this month, syncs today, bookmark count, and whether an X account is connected. limit and remaining are null on unlimited plans

insights

bookmark analytics: velocity, top authors/topics, early calls, and follow recommendations.

headline stats, weekly bookmark velocity, top authors and topics, 'early calls' (bookmarks saved early that gained traction), and follow recommendations. early calls + recommendations are tier-limited (free: 3, paid: 10)

notifications

the caller's notification inbox.

paginated list of the caller's notifications, newest first

mark a notification read

delete a notification

mark all of the caller's unread notifications read

connections

connect and disconnect the caller's X account (native OAuth).

start native X OAuth: returns an authorization URL to open in an ASWebAuthenticationSession. the backend callback exchanges the code server-side and redirects to the app scheme

disconnect the X account (revoke + clear stored OAuth tokens). reconnect via /connections/x/connect

account

profile, onboarding, settings, and notification preferences.

the authenticated user's profile + onboarding state (used for post-login routing)

mark onboarding complete

delete the account (soft-delete data, cancel any subscription)

the caller's email-notification preference

update the email-notification preference

the caller's profile settings (auto-cleanup window, public-profile toggle, username)

update profile settings

billing

subscription management and Apple receipt verification.

a billing-management URL: a pre-authenticated Stripe customer portal for subscribers, or the web billing page

verify a StoreKit 2 signed transaction server-side and grant the plan

referrals

the 'share your wrapped on X for 2 months free' referral.

the caller's referral / wrapped-share bonus status

post the wrapped summary to the connected X account and grant the one-time bonus

wrapped

the caller's 'xmark wrapped' aggregate stats.

wrapped stats: totals, top authors, top topics, languages

API keys

manage API keys programmatically. key-management endpoints require the admin scope.

list the caller's API keys, newest first

create a new API key: the raw key is returned once

introspect the calling API key (no scope required; JWT principals get 404)

fetch a specific key's metadata

rename a key

revoke a key (204 No Content)

rotate a key: revoke it and mint a replacement with the same name and scopes

webhooks

developer webhook endpoints with signed deliveries. all endpoints require the admin scope.

list the caller's webhook endpoints, newest first

create a webhook endpoint: the signing secret is returned once

fetch a webhook endpoint

update url, events, or active

delete a webhook endpoint (204 No Content)

paginated delivery log, newest first

rotate the signing secret: the new secret is returned once

fire a signed test event and report the delivery outcome

changelog

machine-readable release history - public, no API key required.

release history newest-first: version, date, type (feature/fix/breaking/docs), summary, and migration notes on breaking entries. public - the one-line X-Notice header on every response is the latest entry's summary; this is the structured history behind it

error handling

errors are returned as JSON with code, message, optional field, and requestId. the X-Request-ID response header carries a per-request trace id: include it when contacting support.

json
{
  "error": {
    "code": "SERVER_005",
    "message": "name must be under 100 characters",
    "field": "name",
    "requestId": "req_abc123"
  }
}
authentication
codeHTTPdescription
AUTH_001401missing or invalid authorization header
AUTH_002403API key missing required scope
AUTH_004401invalid or revoked API key
billing
codeHTTPdescription
BILLING_001402no active subscription
BILLING_006402plan usage limit reached (402 on chat quota, 429 on sync rate)
BILLING_007402subscription required for this operation
BILLING_008403current plan does not include this feature
rate limiting
codeHTTPdescription
RATE_001429too many requests - back off and retry
validation & server
codeHTTPdescription
SERVER_001500internal server error
SERVER_002400bad request (malformed body or missing field)
SERVER_003404resource not found
SERVER_004405method not allowed
SERVER_005400validation failed
SERVER_008500database error
SERVER_012409conflict (e.g. concurrent modification)
webhooks
codeHTTPdescription
HOOK_001401invalid webhook signature
HOOK_002500webhook processing failed
HOOK_004408webhook delivery timed out