Publish your first post in five minutes.
Four calls: authenticate, create a profile, connect an account, publish. Every example below is copy-pasteable — replace the host and key with your own.
1 Authenticate
Every request carries your API key as a bearer token. Keys are created in the dashboard under API keys and shown exactly once.
# Store it once in your shell export SOCAPI_KEY="sk_live_..." export SOCAPI_URL="http://localhost:8000" # Confirm it works — this returns your organization curl "$SOCAPI_URL/v1/me" -H "Authorization: Bearer $SOCAPI_KEY"
{"success": false, "error": "...", "requestId": "..."} — quote the
requestId if you need to trace a request in the logs.
2 Create a profile
A profile groups the accounts one brand publishes through. Most integrations need only one to start.
curl -X POST "$SOCAPI_URL/v1/profiles" \ -H "Authorization: Bearer $SOCAPI_KEY" \ -H "Content-Type: application/json" \ -d '{"name": "My Brand"}' # => { "success": true, "profile": { "_id": "prof_CMqLDdWut7M", ... } }
3 Connect an account
Starting a connection returns an authUrl. If the platform has provider
credentials configured, that URL is the real OAuth screen — send your user to it.
If not, it points back at this API's development stub.
curl "$SOCAPI_URL/v1/connect/twitter?profileId=prof_CMqLDdWut7M" \ -H "Authorization: Bearer $SOCAPI_KEY" # => { "success": true, "authUrl": "https://twitter.com/i/oauth2/authorize?...", ... }
metadata.mode == "development" and the dashboard labels them, so a
test is never mistaken for a real post.
Connecting is easier from the dashboard — it handles both the OAuth redirect and the stub for you.
4 Publish
One request fans out to every target. platforms is required, and each
account must match its declared platform.
curl -X POST "$SOCAPI_URL/v1/posts" \ -H "Authorization: Bearer $SOCAPI_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "content": "Hello from SendFlow", "publishNow": true, "platforms": [ { "platform": "twitter", "accountId": "acc_7Kd2p" }, { "platform": "linkedin", "accountId": "acc_Q1muv" } ] }'
partial_failure — accepted by one platform and rejected by another.
The results array carries the outcome and reason for each target.
5 Schedule, draft and edit
Send scheduledFor instead of publishNow to schedule.
Omit both to save a draft.
| Goal | Request |
|---|---|
| Publish now | "publishNow": true |
| Schedule | "scheduledFor": "2026-09-01T09:00:00Z" |
| Save a draft | omit both |
| Edit a draft | PATCH /v1/posts/{id} |
| Cancel a scheduled post | DELETE /v1/posts/{id} |
| Retry a failure | POST /v1/posts/{id}/publish |
draft, scheduled and failed posts can be
edited or deleted. Anything that reached a platform is part of the delivery record
and is refused with a 422.
6 Get told what happened
Rather than polling, subscribe to events. Deliveries are signed, retried with backoff, and kept in a delivery log you can inspect in the dashboard.
curl -X POST "$SOCAPI_URL/v1/webhooks" \ -H "Authorization: Bearer $SOCAPI_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://your-app.example/hooks/socapi", "events": ["post.published", "post.failed", "account.needs_reconnect"] }'
Verify every delivery before trusting it:
expected = "sha256=" + hmac.new( secret.encode(), f"{timestamp}.".encode() + raw_body, hashlib.sha256, ).hexdigest() assert hmac.compare_digest(expected, received_signature)