Developer API v1
Post to Facebook and Instagram from your own system
Elsy Social exposes a Buffer-style HTTP API. Your CMS, shop, or backend sends a caption and media; we publish to the Pages and Instagram accounts already connected in the workspace.
https://social.elsysolutions.com/api/v1Quick start
- Sign in, connect Facebook on the Channels page, then open Settings.
- Create an API token. Copy it once — we store only a hash.
- List channels, upload media, then create a post.
TOKEN=elsy_live_…
BASE=https://social.elsysolutions.com/api/v1
curl -s "$BASE/me" -H "Authorization: Bearer $TOKEN"
curl -s "$BASE/channels" -H "Authorization: Bearer $TOKEN"
curl -s "$BASE/media" \
-H "Authorization: Bearer $TOKEN" \
-F "file=@photo.jpg"
curl -s "$BASE/posts" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"caption": "New arrival",
"mediaType": "photo",
"mediaUrls": ["https://social.elsysolutions.com/api/media/FILE.jpg"],
"targets": [{ "channelId": "CHANNEL_ID", "network": "facebook" }]
}'Authentication
Every /api/v1 request needs a workspace token in the header. Tokens are created by owners and admins in Settings. A workspace may have up to 10 active tokens.
Authorization: Bearer elsy_live_…
The raw token is shown only at creation. Revoking it in Settings immediately rejects further calls. CORS is open so browser apps can call the API if they hold a token — treat tokens like passwords and keep them on the server when you can.
Errors
Failures return JSON { "error": "message" } with an HTTP status:
401missing or revoked token400validation (no media, unknown channel, bad file type)402video/Reels on the Free plan404post not in this workspace
GET /me
Workspace name, plan, timezone, and how many brands are connected.
curl -s "$BASE/me" -H "Authorization: Bearer $TOKEN"
GET /channels
Pages this workspace can post to. Use id as channelId when creating a post. Instagram is listed only when a professional account is linked to that Page.
{
"channels": [
{
"id": "clx…",
"name": "Elsy Solutions",
"facebookEnabled": true,
"instagramUsername": "elsysolutions",
"instagramEnabled": true
}
]
}Media
POST /media
Multipart upload. Field name file or files. JPEG/PNG up to 8MB. MP4/MOV/WebM up to 100MB on Pro. Returns public HTTPS URLs Meta can fetch at publish time.
curl -s "$BASE/media" \ -H "Authorization: Bearer $TOKEN" \ -F "file=@hero.jpg" \ -F "file=@detail.jpg"
{
"media": [
{ "id": "clm…", "url": "https://social.elsysolutions.com/api/media/….jpg", "kind": "image" }
],
"urls": ["https://social.elsysolutions.com/api/media/….jpg"],
"mediaIds": ["clm…"]
}GET /media
Lists up to 200 files already in the workspace library.
Posts
POST /posts
Create a draft or queue a publish. Leave scheduledAt empty to publish as soon as the worker runs.
| Field | Required | Notes |
|---|---|---|
caption | no | Facebook caption, max 63,000 characters |
captionInstagram | no | If omitted, Facebook caption is reused (max 2,200) |
firstComment | no | Posted after publish |
mediaType | no | photo, carousel, video, reel, story. Inferred from media count if omitted |
mediaUrls | yes | 1–10 HTTPS URLs from POST /media. Alias: imageUrls |
mediaIds | no | Library ids from the upload response |
targets | yes | Array of { channelId, network }. network is facebook or instagram |
scheduledAt | no | ISO-8601 with offset, or local datetime in the workspace timezone |
draft | no | true saves without publishing. Same as status: "draft" |
curl -s "$BASE/posts" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"caption": "Tonight at 6",
"captionInstagram": "Tonight at 6 #colombo",
"mediaType": "photo",
"mediaUrls": ["https://social.elsysolutions.com/api/media/FILE.jpg"],
"targets": [
{ "channelId": "clx…", "network": "facebook" },
{ "channelId": "clx…", "network": "instagram" }
],
"scheduledAt": "2026-08-16T18:00:00+05:30"
}'Status on the returned post is queued or draft. The worker then moves it to publishing, published, or failed. Check targets[].status and targets[].remoteId for per-network results.
GET /posts
Query: status (draft, queued, published, failed), limit (1–100, default 25), offset.
curl -s "$BASE/posts?status=queued&limit=10" -H "Authorization: Bearer $TOKEN"
GET /posts/:id
One post, including target errors.
PATCH /posts/:id
Edit a draft, queued, or failed post. Published posts cannot be changed. Same fields as create.
DELETE /posts/:id
Removes the post and cancels a scheduled job. Cannot delete while publishing.
POST /posts/:id/retry
Re-queues failed targets immediately.
curl -s -X POST "$BASE/posts/POST_ID/retry" -H "Authorization: Bearer $TOKEN"
Formats
- Feed photos: 1 JPEG/PNG, or 2–10 for a carousel.
- Feed video / Reel: one MP4, Pro plan. Reels should be vertical (9:16).
- Story: one photo or video.
Limits
- Free plan: 1 brand, photos only.
- Pro: up to 20 brands, video, Reels, Stories.
- Instagram Graph publish cap is 100 posts per account per 24 hours.
- A Facebook Page can belong to only one Elsy Social workspace.