API and Zapier
Connect SocioRelay to the rest of your business. Send drafts into your app from a shop, a form, a spreadsheet or your own system, and hear when posts are approved, published or fail.
Included in Growth, Pro and Agency, and in the free trial. Create a key in your account: API and webhooks.
Ideas
- A new product in your shop becomes a draft post, waiting for your approval.
- A row added to a Google Sheet becomes a scheduled post.
- When a post is published, add it to a Slack channel or your CRM.
- When a post fails or a client asks for changes, alert the team.
Zapier and Make
Our own Zapier and Make apps are on their way. Until they're listed, use Webhooks by Zapier or Make's HTTP module with the calls below: "POST a draft" as an action, and a webhook (or "GET events") as a trigger.
Authentication
Send your key in the Authorization header. Every call is over HTTPS; the base address is https://sociorelay.com/api/public/v1.
curl https://sociorelay.com/api/public/v1/me \
-H "Authorization: Bearer sr_live_..."
Businesses
GET /businesses lists the businesses (apps) you can post to. Agencies have one per client. With one business, you can leave out business_id everywhere.
Send a draft
POST /drafts with JSON. Your app collects it within a few minutes and adds it to Scheduled posts, following that business's approval setting (by default it waits for approval; with two-stage approval it goes to a manager, then the client).
| Field | Required | Meaning |
|---|---|---|
text | Yes | The post. The app makes each platform's version. |
business_id | With more than one business | From GET /businesses. |
platforms | No | Any of linkedin, facebook, instagram, x, threads, bluesky, tiktok, youtube, pinterest, google. Default: the business's usual platforms. |
image_url | No | An https:// image (PNG or JPG). Only send images you have the rights to use. |
schedule_at | No | When to publish, for example 2026-11-02T09:30:00Z. Default: the next free slot. |
ref | No | Your own id. Sending the same ref again returns the first draft, so retries never post twice. |
curl -X POST https://sociorelay.com/api/public/v1/drafts \
-H "Authorization: Bearer sr_live_..." -H "Content-Type: application/json" \
-d '{"text": "New in: our winter menu, from Monday.", "platforms": ["facebook", "instagram"], "ref": "menu-2026-11"}' The answer (201) is the draft: {"id": 812, "status": "waiting", ...}. Statuses: waiting (not collected yet), in_app, approved, scheduled, published, failed, rejected, cancelled.
GET /drafts/{id} shows one draft; GET /drafts?status=&business_id=&limit= lists them; DELETE /drafts/{id} cancels one the app hasn't collected yet.
Events
draft.created: A draft was sent through the API
post.in_app: A draft reached the app (waiting for approval or scheduled)
post.approved: A post was approved (by the team or the client)
post.changes_requested: A client asked for changes to a post
post.scheduled: A post was scheduled
post.published: A post was published on a platform
post.failed: A post failed to publish
blog.published: A blog article went live
alert: An alert from the app (login expiring, platform not connected, post late)
GET /events?type=post.published&after_id=&limit= lists events, newest first (kept 30 days). Use it for polling triggers.
Webhooks
Add one in your account, or with POST /webhooks {"url": "https://...", "events": ["post.published"]} (answer includes a secret, shown once). DELETE /webhooks/{id} removes it. We POST each event as JSON:
{"id": 5531, "type": "post.published", "created_at": "2026-11-02T09:30:12Z",
"business": {"id": 41, "name": "Corner Cafe"},
"data": {"post_id": 207, "platform": "instagram", "url": "https://www.instagram.com/p/...", "draft_id": 812}} Every request has a SocioRelay-Signature header: t=<unix time>,v1=<signature>, where the signature is the hex HMAC-SHA256 of <t>.<raw body> with your secret. Check it, and reject times more than 5 minutes old:
// PHP
parse_str(str_replace(",", "&", $_SERVER["HTTP_SOCIORELAY_SIGNATURE"]), $sig);
$body = file_get_contents("php://input");
$ok = hash_equals(hash_hmac("sha256", $sig["t"] . "." . $body, $secret), $sig["v1"]) && abs(time() - (int)$sig["t"]) < 300; # Python
import hmac, hashlib, time
t, v1 = [p.split("=", 1)[1] for p in request.headers["SocioRelay-Signature"].split(",")]
ok = hmac.compare_digest(hmac.new(secret.encode(), f"{t}.".encode() + request.body, hashlib.sha256).hexdigest(), v1) and abs(time.time() - int(t)) < 300 Answer with any 2xx within 15 seconds. We retry failures after 1 and 5 minutes, then 30 minutes, 2, 6 and 24 hours. Answering 410 Gone switches the webhook off; so do 50 failures in a row.
Limits and errors
Up to 120 requests a minute per key (then 429 with Retry-After). Errors are JSON: {"error": {"type": "invalid_request", "message": "..."}} with 400, 401 (key), 402 (plan), 404, 409, 422 (a field is wrong) or 500.
Content sent through the API is your content: the terms of service (section 7 on AI and automatic posting, section 9 on the API) apply. Questions: info@sociorelay.com.