Skip to content

Authentication

All API requests require a Bearer token in the Authorization header. Postlark supports two authentication methods.

Section titled “API Key (recommended for MCP, CLI, automation)”
Authorization: Bearer pk_live_xxxxxxxxxxxx

Generate keys in Dashboard → Settings → API Keys. Each key is bound to a specific blog.

The Dashboard uses Supabase JWT tokens for session-based authentication:

Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

When using JWT auth, Postlark auto-selects your first blog. To target a specific blog, include the X-Blog-Id header:

X-Blog-Id: blog-uuid-here

API keys support scoped permissions. Each scope controls access to a specific set of operations.

ScopeDescription
*Full access (all scopes)
posts:readRead posts (list, get)
posts:writeCreate, update, delete, publish, schedule posts
blogs:readRead blog settings
blogs:writeUpdate blog settings, manage API keys
analytics:readRead analytics data
search:readSearch posts
account:readRead profile
account:writeDelete account, manage tokens
packs:readRead post pack balance
packs:writePurchase post packs
domains:readRead custom domain status
domains:writeRegister/remove custom domains
media:readRead uploaded images
media:writeUpload images

Use {resource}:* for all actions on a resource (e.g. posts:* = posts:read + posts:write).

When you create a new key, the default scope is ["*"] (full access). You can restrict scopes when generating a key in the Dashboard or via the API.

Blog API keys do not expire by default. You can revoke a key at any time from Dashboard → Settings → API Keys or via DELETE /blogs/:id/api-keys/:keyId.

Scoped access tokens support optional expiration (30 days, 90 days, 1 year, or no expiration). Create them in Dashboard → Access Tokens or via POST /account/tokens. Expired or revoked tokens return 401 Unauthorized.

JWT session tokens expire according to Supabase Auth settings (default: 1 hour). The Dashboard handles token refresh automatically.

PlanRequests/hour
Free60
Starter300
Creator1,000
Scale10,000
Enterprise10,000+

Every response includes rate limit headers:

X-RateLimit-Limit: 300
X-RateLimit-Remaining: 299
X-RateLimit-Reset: 1711324800

When exceeded, you’ll receive a 429 response with retry_after seconds.

See the full Rate Limits reference for Post Packs and plan details.

All errors follow a consistent JSON format:

{
"error": "not_found",
"message": "Post not found"
}
StatusDescriptionExample
400Invalid input"title is required"
401Missing or invalid token"Invalid API key"
403Plan upgrade required"Post limit exceeded. Free plan allows 10 total posts."
404Resource not found"Post not found"
409Duplicate resource"slug \"my-post\" is already taken"
429Rate limit exceeded"Rate limit exceeded. Limit: 60 requests/hour."
500Server error"Internal server error"
https://api.postlark.ai/v1

Try the interactive API explorer: api.postlark.ai/docs