Authentication
Every request to /v1 carries a bearer token:
Authorization: Bearer mls_live_3f9ac2e8b71d4c5f9e2a7b6c1d0eThere are three kinds of token. Two of them are API keys, the third is a browser session for the widget.
Key kinds
Section titled “Key kinds”| Prefix | Kind | Can |
|---|---|---|
mls_live_… |
Partner key | Everything for your partner: all workspaces, the webhook, embed sessions |
mls_live_… (workspace-scoped) |
Workspace key | Only that one workspace. Minted for a customer, a mobile app or an MCP client |
mle_… |
Embed session | The widget’s short-lived, workspace-scoped token. Only /v1/embed/* |
Partner keys and workspace keys share the mls_live_ prefix. The scope is decided when the key is created, not by the prefix.
Keys are stored hashed (SHA-256) and shown exactly once, at creation. Store them in a secret manager, never in a browser or a mobile app binary.
Partner keys
Section titled “Partner keys”MissLess issues your partner key when your partner account is set up. Use it from your backend only. To rotate a partner key, ask MissLess for a new one, switch your backend over, then ask for the old one to be revoked.
Workspace keys
Section titled “Workspace keys”You can mint keys that only reach one workspace. They are the recommended credential for end users: give one to a customer’s MCP client or mobile app, and a leak can only touch that customer’s accounts.
curl -X POST https://social.missless.tel/v1/workspaces/ws7k2m9p4q1r8t3/keys \ -H "Authorization: Bearer $MISSLESS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "label": "Claude Code on Nova laptop" }'Response 201, the only time key is returned:
{ "id": "key4d6f8h2j4l6n", "key": "mls_live_8a1d4f7c2e9b6a3d5f0c8e1b4a7d", "prefix": "mls_live_8a1d", "label": "Claude Code on Nova laptop" }List and revoke:
curl https://social.missless.tel/v1/workspaces/ws7k2m9p4q1r8t3/keys \ -H "Authorization: Bearer $MISSLESS_API_KEY"
curl -X DELETE https://social.missless.tel/v1/workspaces/ws7k2m9p4q1r8t3/keys/key4d6f8h2j4l6n \ -H "Authorization: Bearer $MISSLESS_API_KEY"The list returns { id, prefix, label, last_used_at, created } per key. prefix is enough to tell keys apart in a UI.
Rotation is create-switch-delete: mint a new key, move the client over, delete the old one. A deleted key stops working immediately.
Embed sessions
Section titled “Embed sessions”An embed session is minted server-side with POST /embed-sessions using your partner key. It expires (default 3600 seconds) and only works against /v1/embed/*. It is safe to put in the browser because it cannot reach anything outside its workspace or outlive its expiry. See Embed sessions.
Which key for which call
Section titled “Which key for which call”| Call | Partner key | Workspace key | Embed session |
|---|---|---|---|
POST /workspaces, GET /workspaces |
yes | no | no |
GET, PATCH, DELETE /workspaces/:id |
yes | own workspace only | no |
/workspaces/:id/keys |
yes | no | no |
/workspaces/:id/connect-links, /workspaces/:id/accounts |
yes | own workspace only | no |
/accounts/:id, /media, /posts, /conversations |
yes | objects in own workspace only | no |
/webhook, /webhook/test, /events |
yes | no | no |
POST /embed-sessions |
yes | no | no |
/embed/* |
no | no | yes |
/mcp |
yes, with X-MissLess-Workspace |
yes | no |
A workspace key gets forbidden (403) on anything outside its workspace, and not_found (404) for objects that belong to another workspace.
Rate limits
Section titled “Rate limits”- 300 requests per minute per key.
- 60 requests per minute per IP address on unauthenticated endpoints (the connect page and the OAuth callback).
Over the limit you get 429 with a Retry-After header (seconds). Back off for that long, then retry. Instagram has its own publishing limit of 100 posts per account per 24 hours, which surfaces as a network_error. See Rate limits.
Errors
Section titled “Errors”Every error has the same shape:
{ "error": { "code": "validation_error", "message": "caption is required", "field": "caption" } }| Code | HTTP | When |
|---|---|---|
unauthorized |
401 | Missing, malformed, revoked or expired token |
forbidden |
403 | The token is valid but cannot reach this workspace or resource |
not_found |
404 | No such object in your scope |
validation_error |
400 | A field is missing or invalid; field names it |
unsupported |
400 | The network cannot do what you asked, for example text-only on Instagram |
conflict |
409 | The object is in a state that does not allow the action, for example patching a published post |
account_disconnected |
409 | The target account is expired, revoked or in error; reconnect it |
rate_limited |
429 | Over the limit; honour Retry-After |
network_error |
502 | Meta refused or failed the request; details carries Meta’s error |
field is present on validation_error only. details is present on network_error only. Full list with handling advice in Errors.