Skip to content
SendFlow

Self-hosted · 15 networks · one API

Post once. Know exactly where it landed.

SendFlow is the publishing API, and the app on top of it, for fifteen social networks. It refreshes tokens before they expire, retries without double-posting, and hands back a receipt from every network you post to.

Get startedRead the API docs
docker compose up
An example post sent to 6 networks: 5 have published and YouTube is still uploading.
POST/v1/posts5 of 6 published · 1 uploading

Request

{
  "content": "Spring drop is live →",
  "publishNow": true,
  "platforms": [
    { "platform": "twitter",    … },
    { "platform": "linkedin",   … },
    { "platform": "instagram",  … },
    { "platform": "threads",    … },
    { "platform": "youtube",    … },
    { "platform": "telegram",   … }
  ]
}

Idempotency-Key: 7f3c…e19a

  1. Twitter/X@acmePublished0.41 sx.com/acme/status/18…
  2. LinkedInAcme StudioPublished1.18 stoken refreshed first
  3. Instagram@acme.studioPublished2.86 simage 1080×1350
  4. Threads@acmePublished3.02 sretried after a 503, no duplicate
  5. YouTubeAcme StudioUploading
  6. TelegramAcme NewsPublished0.37 st.me/acmenews/412
next · webhook post.published → hooks.acme.dev/socapiX-SocAPI-Signature: sha256=9c1f…

Reliability

The HTTP call is easy. Everything around it is the product.

Tokens that expire at 3 a.m.

Access tokens are refreshed before they expire. If a network revokes access, the account is marked needs_reconnect and a webhook tells you, instead of tomorrow's post failing quietly.

03:00:04 linkedinexpires in 10 min
03:00:05 refresh✓ stored encrypted

09:00:01 post_8Hq2Zt✓ published

Retries that never double-post.

Send the same Idempotency-Key twice and you get the original post back. The worker claims each due post atomically, so more replicas add throughput, not duplicates.

POST /v1/postskey 7f3c…e19a
✕ client timed outrequest had landed

POST /v1/postskey 7f3c…e19a
✓ 200post_8Hq2Zt · original

Failures you actually hear about.

Every post returns a result per network, so a partial failure is visible. Webhooks are signed over timestamp and body, retried with backoff, and kept in a delivery history.

POST hooks.acme.dev/socapi
X-SocAPI-Eventpost.partial_failure
X-SocAPI-Signaturesha256=9c1f…

✓ 200 OK84 ms

Channels

Fifteen networks. One contract.

Every network has its own limits. The composer checks them as you type, against the same spec the API validates with, so a post is fixed before a network can refuse it.

  • Twitter/X280 · text
  • LinkedIn3,000 · text
  • Instagram2,200 · image or video
  • Facebook63,206 · text
  • Threads500 · media optional
  • YouTube5,000 · video upload
  • TikTok2,200 · video
  • Pinterest500 · image
  • Reddit40,000 · text
  • Bluesky300 · text
  • Telegram4,096 · text
  • Discord2,000 · media optional
  • WhatsApp4,096 · text
  • Snapchat250 · finish on phone
  • Google Business1,500 · text
TEST

No credentials for a network yet? It runs against a test stub, and every test account is hatched like this, so a test is never mistaken for a real post.

App and API

Your team uses the app. Your code uses the API.

The app holds no data of its own: every screen runs on the same public API your code calls. Click it in the app today, automate it tomorrow.

New post
To@acmeAcme Studio@acme.studio

Spring drop is live: 40 new pieces, made in small batches. First come, first served → acme.studio/spring

Tue 4 Nov · 09:00Schedule
The same post, as a request
curl -X POST https://social.acme.dev/v1/posts \
  -H "Authorization: Bearer $SOCAPI_KEY" \
  -H "Idempotency-Key: 7f3c…e19a" \
  -d '{
    "content": "Spring drop is live: 40 new…",
    "scheduledFor": "2026-11-04T09:00:00",
    "timezone": "Europe/Berlin",
    "platforms": [
      { "platform": "twitter",   "accountId": "acc_7Kd2p" },
      { "platform": "linkedin",  "accountId": "acc_Q1muv" },
      { "platform": "instagram", "accountId": "acc_m3Rx0" }
    ]
  }'

Self-host

Your infrastructure. Your keys.

There is no hosted tier to sign up for. API keys, provider credentials, the database and uploaded media all stay in your deployment.

  1. Browseryour team
  2. AppNext.js
  3. SendFlowFastAPI · /v1
  4. Postgresencrypted tokens
  5. Workerscheduler + webhooks
  6. 15 networksyour app credentials
One command, production shape
$ docker compose up
# Postgres, migrations, the API, a separate
# publisher worker and the app. Health and
# readiness probes and JSON logs included.
A Render blueprint ships too. Locally it is one script against SQLite.
Ready for agents

Point an agent at the machine-readable docs and it can connect accounts and post, with idempotency keys keeping its retries safe.

Send your first post today.

Start against test accounts on your laptop. Add each network's credentials when you are ready to go live.

Get started
docker compose up