Create a social post
https://api.norreach.app/v1/social/postsCreates a post (a draft by default) with your own text and media, one version per network — through the app's social calendar, exactly as the composer saves. Nothing goes out: schedule it with POST /social/posts/{id}/schedule. Media: public http(s) addresses, or upload a file first with POST /social/uploads; a file in another workspace's media is refused (422). Each network's character limit and Instagram's need for a picture are checked when scheduling. Posts carry your own text, pictures and videos — there is no operation that writes posts with AI (Nora writes posts in a plan: POST /briefs). Owners, admins and managers.
curl -X POST "https://api.norreach.app/v1/social/posts" \
-H "Authorization: Bearer $NORREACH_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"title": "Winter staffing",
"labels": [
"winter"
],
"variants": [
{
"network": "linkedin",
"content": "Clinics plan their winter staffing now. We place licensed nurses within 48 hours."
},
{
"network": "instagram",
"content": "Winter is coming — so are our nurses.",
"media_urls": [
"https://media.example.com/social-media/6a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d/2f3e4d5c-6b7a-4c8d-9e0f-1a2b3c4d5e6f.jpg"
]
}
]
}'{
"id": "5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b",
"object": "social_post",
"title": "Winter staffing",
"status": "draft",
"scheduled_at": null,
"timezone": null,
"labels": [
"winter"
],
"notes": "",
"networks": [
"linkedin",
"instagram"
],
"variants": [
{
"network": "linkedin",
"network_name": "LinkedIn",
"content": "Clinics plan their winter staffing now. We place licensed nurses within 48 hours.",
"media_urls": [],
"status": "pending",
"published_at": null,
"problem": null
},
{
"network": "instagram",
"network_name": "Instagram",
"content": "Winter is coming — so are our nurses.",
"media_urls": [
"https://media.example.com/social-media/6a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d/2f3e4d5c-6b7a-4c8d-9e0f-1a2b3c4d5e6f.jpg"
],
"status": "pending",
"published_at": null,
"problem": null
}
],
"created_at": "2026-11-05T09:12:33.120Z",
"updated_at": "2026-11-05T09:20:01.000Z"
}Authorizations
Bearer authentication: send Authorization: Bearer <key>, with an API key or an OAuth access token. The key needs the scope social:publish. API keys and scopes
Headers
Any unique string (≤ 255). The same key with the same request returns the first answer for 24 hours.
Body
application/json
The post's name in the calendar (never published).
idea, draft (default) or in_review — scheduling has its own operation.
ideadraftin_reviewInternal notes (never published).
One version per network, with your own text and media.
Show child attributesHide child attributes
linkedin, x, instagram, facebook or tiktok.
linkedinxinstagramfacebooktiktokThe text for this network (each network's own limit is checked when scheduling: X 280, LinkedIn 3000, Instagram 2200, Facebook 5000, TikTok 2200).
Up to 10 pictures or videos. Instagram needs at least one to be scheduled.
Response
201application/json— Create a social post
An id (UUID).
The post's name in the calendar (never published).
idea, draft, in_review, scheduled, publishing, published or failed.
ideadraftin_reviewscheduledpublishingpublishedfailedWhen it goes out (scheduled posts).
The IANA time zone it was scheduled in, for display.
Internal notes (never published).
Show child attributesHide child attributes
linkedin, x, instagram, facebook or tiktok.
linkedinxinstagramfacebooktiktokThe text for this network.
Pictures and videos, in order (public https addresses).
pending (not sent yet), publishing, published or failed.
pendingpublishingpublishedfailedWhen this network's publish failed: a plain sentence (the details are in the app).
RFC 3339 UTC timestamp with milliseconds.
RFC 3339 UTC timestamp with milliseconds.
Errors
Errors are application/problem+json with a stable code.
| Status | Code | Meaning |
|---|---|---|
| 400 | bad_request | The request couldn't be read. |
| 400 | unknown_field | The request has a field this operation doesn't know. |
| 401 | unauthorized | A valid API key is required. |
| 403 | insufficient_scope | This API key doesn't have the scope this operation needs. |
| 403 | feature_not_enabled | The API isn't switched on for this workspace. |
| 403 | role_forbidden | The key's creator's role can't do this. |
| 409 | idempotency_in_progress | A request with this Idempotency-Key is still running. |
| 409 | conflict | That conflicts with the current state. |
| 413 | too_large | The request body is too large. |
| 422 | validation_failed | The request has invalid fields. |
| 422 | idempotency_mismatch | This Idempotency-Key was used with a different request. |
| 429 | rate_limited | Too many requests. Slow down and try again. |
| 500 | server_error | Something went wrong on our side. |
| 503 | unavailable | The API isn't available right now. Try again shortly. |