Quickstart
You need a partner API key. MissLess issues one when your partner account is set up. It starts with mls_live_ and is shown once. Export it:
export MISSLESS_API_KEY="mls_live_3f9ac2e8b71d4c5f9e2a7b6c1d0e"Every call below goes to https://social.missless.tel/v1, sends Authorization: Bearer $MISSLESS_API_KEY, and uses JSON.
1. Create a workspace
Section titled “1. Create a workspace”One workspace per customer. Pass your own user id as external_id so you can find it again.
curl -X POST https://social.missless.tel/v1/workspaces \ -H "Authorization: Bearer $MISSLESS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "external_id": "user_123", "name": "Salon Nova", "timezone": "Europe/Amsterdam" }'Response 201:
{ "id": "ws7k2m9p4q1r8t3", "external_id": "user_123", "name": "Salon Nova", "timezone": "Europe/Amsterdam", "settings": {}, "status": "active", "accounts_count": 0, "created": "2026-08-25T09:12:04Z", "updated": "2026-08-25T09:12:04Z"}Calling this again with the same external_id returns 200 and the existing workspace. It is safe to run on every login.
2. Create a connect link and send the user through it
Section titled “2. Create a connect link and send the user through it”curl -X POST https://social.missless.tel/v1/workspaces/ws7k2m9p4q1r8t3/connect-links \ -H "Authorization: Bearer $MISSLESS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "networks": ["facebook", "instagram"], "redirect_url": "https://app.example.com/settings/social" }'Response 201:
{ "token": "ct7f3a9c1e5b2d8f4a6c0e", "url": "https://social.missless.tel/connect/ct7f3a9c1e5b2d8f4a6c0e", "expires_at": "2026-08-25T10:12:04Z"}Redirect the user to url. They click Continue with Facebook, approve the Meta consent, and land back on the connect page with their Pages and Instagram accounts listed. Because redirect_url was given, a Back to button returns them to you with ?connected=<n> appended. Each connected account fires an account.connected webhook.
Then list what they connected:
curl https://social.missless.tel/v1/workspaces/ws7k2m9p4q1r8t3/accounts \ -H "Authorization: Bearer $MISSLESS_API_KEY"{ "data": [ { "id": "acig4h2k5m7p9r1", "workspace": "ws7k2m9p4q1r8t3", "network": "instagram", "platform_id": "17841400000000001", "username": "salonnova", "display_name": "Salon Nova", "avatar_url": "https://scontent.example/avatar.jpg", "page_id": "100000000000001", "status": "active", "last_error": null, "scopes": ["instagram_basic", "instagram_content_publish", "instagram_manage_comments", "instagram_manage_messages", "instagram_manage_insights"], "token_expires_at": null, "connected_at": "2026-08-25T09:15:41Z" }, { "id": "acfb8n2c4v6b1m3", "workspace": "ws7k2m9p4q1r8t3", "network": "facebook", "platform_id": "100000000000001", "username": "salonnova", "display_name": "Salon Nova", "avatar_url": "https://scontent.example/page.jpg", "page_id": "100000000000001", "status": "active", "last_error": null, "scopes": ["pages_show_list", "pages_manage_posts", "pages_read_engagement", "pages_messaging"], "token_expires_at": null, "connected_at": "2026-08-25T09:15:41Z" } ], "page": 1, "limit": 50, "total": 2}3. Upload media
Section titled “3. Upload media”Instagram needs at least one media item. Pass a public URL and MissLess fetches it, or upload a file as multipart (see Media).
curl -X POST https://social.missless.tel/v1/media \ -H "Authorization: Bearer $MISSLESS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "workspace": "ws7k2m9p4q1r8t3", "url": "https://cdn.example.com/cuts/friday.jpg", "alt": "Fresh haircut, side view" }'Response 201:
{ "id": "med9x2c4v6b8n1m", "workspace": "ws7k2m9p4q1r8t3", "kind": "image", "mime": "image/jpeg", "size": 482113, "width": 1080, "height": 1350, "alt": "Fresh haircut, side view", "url": "https://social.missless.tel/v1/media/med9x2c4v6b8n1m/file?sig=9b1f2e8d&exp=1756717924", "created": "2026-08-25T09:18:02Z"}4. Create the post
Section titled “4. Create the post”Target both accounts. ?wait=true holds the request for up to 25 seconds and returns the final post, so you do not need webhooks for the first test.
curl -X POST "https://social.missless.tel/v1/posts?wait=true" \ -H "Authorization: Bearer $MISSLESS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "workspace": "ws7k2m9p4q1r8t3", "caption": "Fresh cuts, Friday walk-ins welcome", "media": ["med9x2c4v6b8n1m"], "targets": ["acig4h2k5m7p9r1", "acfb8n2c4v6b1m3"], "external_ref": "acme:post:1234" }'Response 201:
{ "id": "pst5g7j9l2n4q6s", "workspace": "ws7k2m9p4q1r8t3", "external_ref": "acme:post:1234", "caption": "Fresh cuts, Friday walk-ins welcome", "media": [{ "id": "med9x2c4v6b8n1m", "kind": "image", "mime": "image/jpeg", "width": 1080, "height": 1350 }], "targets": [ { "account": "acig4h2k5m7p9r1", "network": "instagram", "username": "salonnova", "status": "published", "platform_post_id": "17900000000000001", "permalink": "https://www.instagram.com/p/C_abc123/", "error": null, "published_at": "2026-08-25T09:20:11Z" }, { "account": "acfb8n2c4v6b1m3", "network": "facebook", "username": "salonnova", "status": "published", "platform_post_id": "100000000000001_200000000000002", "permalink": "https://www.facebook.com/100000000000001/posts/200000000000002", "error": null, "published_at": "2026-08-25T09:20:09Z" } ], "schedule_at": null, "status": "published", "published_at": "2026-08-25T09:20:11Z", "attempts": 1, "last_error": null, "created_by": "api", "created": "2026-08-25T09:19:58Z", "updated": "2026-08-25T09:20:11Z"}Leave out ?wait=true and the response comes back at once with status: "publishing". The outcome then arrives as a webhook, or you poll GET /v1/posts/pst5g7j9l2n4q6s.
5. Receive the outcome as a webhook
Section titled “5. Receive the outcome as a webhook”Register one endpoint per partner. Do this once; every workspace’s events go to it.
curl -X PUT https://social.missless.tel/v1/webhook \ -H "Authorization: Bearer $MISSLESS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://app.example.com/webhooks/missless", "events": ["*"] }'{ "url": "https://app.example.com/webhooks/missless", "events": ["*"], "secret": "7d0b7c8f5a1e4c2b9f6d3a8e1c4b7f0a9d2e5c8b1a4f7d0c"}Store secret. It is shown once. From now on every publish ends with a POST to your URL:
{ "id": "evt1a3c5e7g9i2k", "type": "post.published", "created_at": "2026-08-25T09:20:11Z", "partner": "acme", "workspace": "ws7k2m9p4q1r8t3", "external_id": "user_123", "data": { "id": "pst5g7j9l2n4q6s", "external_ref": "acme:post:1234", "status": "published", "targets": [ { "account": "acig4h2k5m7p9r1", "network": "instagram", "status": "published", "permalink": "https://www.instagram.com/p/C_abc123/" }, { "account": "acfb8n2c4v6b1m3", "network": "facebook", "status": "published", "permalink": "https://www.facebook.com/100000000000001/posts/200000000000002" } ] }}The headers X-MissLess-Signature and X-MissLess-Timestamp let you verify it came from MissLess. See Verify signatures. Use X-MissLess-Delivery to de-duplicate retries.
What next
Section titled “What next”- Posts: per-network captions, options, drafts.
- Scheduling:
schedule_atand the status lifecycle. - Conversations: DMs and comments as an inbox.
- Next.js partner integration: the same flow as a typed integration in your app.