API reference
Schedule posts on your connected accounts from your own tools. Every endpoint is authenticated with an API key generated in Settings → API keys. The API is included in the Pro and Enterprise plans, free trial included.
Base URL — https://hello-socials.com/api/v1
Prefer to publish by asking Claude or ChatGPT? Connect the MCP server
Authentication
Pass your key as a Bearer token. Keys are stored hashed — the plaintext value is shown only once, when you create it. A key carries scopes: read for GET endpoints, write for POST.
Authorization: Bearer hs_live_xxxxxxxxxxxxxxxxxxxx/api/v1/accountsLists your connected accounts. Call it once and store the ids in your tool's configuration: a display name changes when you rename a page, an id never does.
curl https://hello-socials.com/api/v1/accounts \
-H "Authorization: Bearer hs_live_xxx"{
"data": [
{
"id": "cmnj4p2z0000abcd",
"network": "TWITTER",
"username": "hellowesign",
"displayName": "HelloWeSign",
"status": "connected"
},
{
"id": "cmnj53dc0000efgh",
"network": "LINKEDIN_PAGE",
"username": "hellowesign",
"displayName": "HelloWeSign",
"status": "connected"
}
]
}status tells you whether an account needs reconnecting before you send it anything: connected, expiring_soon or expired.
/api/v1/postsCreates a scheduled post: text only, with images, or with one video. X, LinkedIn, Facebook and Threads accept text on its own; Instagram, Pinterest and TikTok require an image or a video. YouTube is not available through the API yet.
curl -X POST https://hello-socials.com/api/v1/posts \
-H "Authorization: Bearer hs_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"content": "Audit trail de signature électronique : retrouver chaque étape d'\''un document.",
"socialAccountIds": ["cmnj53dc0000efgh"],
"scheduledAt": "2026-09-04T09:30:00Z",
"media": [
{ "url": "https://example.com/images/audit-trail.png" }
]
}'Video to TikTok and an Instagram reel in one call:
curl -X POST https://hello-socials.com/api/v1/posts \
-H "Authorization: Bearer hs_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"content": "Nouvelle fonctionnalité #meetarabic",
"socialAccountIds": ["<tiktok-account-id>", "<instagram-account-id>"],
"scheduledAt": "2026-10-20T18:00:00+02:00",
"media": [
{ "url": "https://example.com/videos/demo.mp4", "type": "video", "coverTimestampMs": 2500 }
],
"postType": "reel",
"tiktok": { "privacyLevel": "PUBLIC_TO_EVERYONE", "disableComment": false }
}'Body fields
| content | Required. The post text. |
| socialAccountIds | Required. Array of account ids from GET /accounts. One id is the common case; several send the same text to several accounts at once. |
| scheduledAt | Optional. ISO 8601 with timezone, in the future. |
| media | Optional. Array of { "url": "https://…" } objects, in display order. Or a single video: [{ "url": "https://…", "type": "video", "coverTimestampMs": 2500 }]: the cover is the frame at that moment (1 s by default), sent as an image to Instagram and Facebook and as a timestamp to TikTok; "thumbnailUrl" can provide a custom cover image instead. Required for Instagram, Pinterest and TikTok. |
| captions | Optional. { "<socialAccountId>": "caption" }: a caption for one account instead of content (e.g. a different TikTok caption). Accounts not listed use content. |
| postTypes | Optional. { "<socialAccountId>": "post" | "reel" | "story" }: a format for one Instagram or Facebook account, overriding postType (e.g. two Facebook pages as posts, Instagram as a story). |
| postType | Optional, Instagram and Facebook. "post" (default), "reel" (requires a video) or "story". A single Instagram video is published as a reel either way. |
| draft | Optional. true saves the post as a draft (status DRAFT): nothing is published until you review and schedule it in HelloSocials, Posts › Drafts tab. |
| tiktok | Optional, TikTok accounts only. privacyLevel (PUBLIC_TO_EVERYONE by default, or MUTUAL_FOLLOW_FRIENDS, FOLLOWER_OF_CREATOR, SELF_ONLY), title (90 characters max), disableComment, disableDuet, disableStitch (true by default), autoAddMusic (true by default), isCommercial with isOwnBrand or isPaidPartnership. |
About scheduledAt
An ISO 8601 timestamp with an explicit timezone. A naive timestamp is rejected: it would be read in the server's timezone, and a post meant for 9:30 would go out at another hour. Omit the field to publish as soon as possible — the publisher runs every 5 minutes.
"2026-09-04T09:30:00Z" ✓
"2026-09-04T11:30:00+02:00" ✓
"2026-09-04T09:30:00" ✗ no timezone
"2026-09-04" ✗About media
Pass public https URLs. Each image is downloaded when the post is created, converted to JPEG (1080 px on the longest side) and stored on our side: the post does not depend on your URL any more, even if it goes out days later. Accepted sources: JPEG, PNG, GIF (first frame) and WebP, 20 MB max each. If one image fails, nothing is created and the response says which one. Video: a single item { "url", "type": "video", "thumbnailUrl"? }, MP4 or MOV, 50 MB max, stored as is (no re-encoding); Facebook, Instagram, TikTok, X, LinkedIn and Threads accept it, Pinterest does not.
Images per network
| 4 | |
| 9 | |
| LINKEDIN_PAGE | 9 |
| 10 | |
| THREADS | 10 |
| 10 | |
| 1 | |
| TIKTOK | 35 |
Validation is all-or-nothing
If any target account fails validation, nothing is created and the response lists what went wrong. This avoids a post going out on one network while silently failing on another.
{
"error": "Caption exceeds the character limit for at least one target network",
"details": {
"accounts": [{ "id": "cmnj4p2z0000abcd", "network": "TWITTER", "limit": 280, "length": 412 }]
}
}/api/v1/posts/{id}Returns the state of a post, network by network. Publishing is asynchronous: creation answers PENDING, and the real outcome only exists once the worker has run.
{
"data": {
"id": "cmtlg7ca2000004jp",
"status": "PUBLISHED",
"scheduledAt": "2026-09-04T09:30:00.000Z",
"publishedAt": "2026-09-04T09:30:12.000Z",
"media": [{ "url": "https://…/posts/…/k3J9x.jpg" }],
"results": [
{
"socialAccountId": "cmnj53dc0000efgh",
"network": "LINKEDIN_PAGE",
"status": "PUBLISHED",
"externalId": "urn:li:share:7123456789",
"error": null
}
]
}
}Character limits
X is counted the way X counts: every URL is 23 characters whatever its length, emoji and CJK characters count as 2. Other networks count raw characters.
| 280 | |
| 3000 | |
| LINKEDIN_PAGE | 3000 |
| 63206 | |
| THREADS | 500 |
| 2200 | |
| 500 | |
| TIKTOK | 2200 |
Errors
Errors return a JSON body with an error field, and details when a specific account or field is at fault.
| 400 | Invalid body, unknown account, unsupported network, content too long, too many images, image unreachable or invalid, bad date |
| 401 | Missing, invalid, revoked or expired API key |
| 403 | The key lacks the required scope, or the account has no active Pro or Enterprise subscription |
| 404 | Post not found for this key's owner |