REST API
Posts
Endpoints

Endpoints

Use the posts endpoints to create, schedule, update, fetch, list, and delete posts in FeedHive. The response shape is documented on the Post object page.

GET /posts

List all posts owned by the authenticated caller.

Query parameters

FieldTypeDescription
limitnumberPage size. Defaults to 20 and cannot exceed 100.
cursorstringPagination cursor from a previous response.
statusstringOptional comma-separated status filter. Supported values: draft, scheduled, publishing, published, failed.
labelsstringOptional comma-separated label ID filter. Matching uses OR semantics.
socialsstringOptional comma-separated social account ID filter. Matching uses OR semantics.

Example request

curl --request GET \
  --url 'https://api.feedhive.com/posts?limit=20&status=draft,scheduled&labels=lbl_campaign_q4&socials=social_123' \
  --header 'accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY'

Response body

FieldTypeDescription
successbooleanWhether the request succeeded.
data.itemsPost[]Returned posts for this page.
data.totalnumberTotal number of posts owned by the caller.
data.has_morebooleanWhether another page of posts is available.
data.next_cursorstring | nullCursor for the next page, or null when there are no more results.

GET /posts/:id

Fetch a single post by ID.

Path parameters

FieldTypeDescription
idstringPost identifier.

Example request

curl --request GET \
  --url https://api.feedhive.com/posts/post_123 \
  --header 'accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY'

Response body

FieldTypeDescription
successbooleanWhether the request succeeded.
dataPostRequested post.

POST /posts

Create a new post.

Request body

FieldTypeDescription
textstring | nullRoot post text. Required for regular and short publish types; conditionally required for story based on target accounts.
mediastring[]Ordered media IDs to attach.
subpostsSubpostInput[]Optional thread replies.
accountsstring[] | AccountReferenceInput[]Optional social account IDs or account objects to target.
account_customizationsAccountCustomizationInput[]Optional per-account overrides.
labelsstring[]Optional label IDs to attach.
statusdraft | scheduledOptional post status. Defaults to draft.
scheduled_atstringConditional. ISO 8601 future datetime; required when status is scheduled.
notesstring | nullOptional internal notes.
short_link_enabledbooleanOptional short-link setting.
publish_typeregular | short | storyOptional publish mode. Defaults to regular.
titlestring | nullOptional platform-specific title (YouTube, Google Business, Pinterest).
linkstring | nullOptional platform-specific link (Google Business, Pinterest).
terms_and_conditionsstring | nullOptional Google Business offer terms.
coupon_codestring | nullOptional Google Business offer coupon code.
start_datestring | nullOptional Google Business event/offer start datetime.
end_datestring | nullOptional Google Business event/offer end datetime.
ctastring | nullOptional Google Business CTA.
topic_typestring | nullOptional Google Business topic type.
privacy_statusstring | nullOptional YouTube/TikTok privacy status.
allow_commentsboolean | nullOptional TikTok comment toggle.
allow_duetboolean | nullOptional TikTok duet toggle.
allow_stitchboolean | nullOptional TikTok stitch toggle.

SubpostInput

FieldTypeDescription
textstring | nullSubpost text.
mediastring[]Ordered media IDs for the subpost. Do not send duplicates.

AccountReferenceInput

FieldTypeDescription
idstringAccount ID.
board_idstring | nullPinterest board ID.

AccountCustomizationInput

FieldTypeDescription
idstringAccount ID. Must also appear in the accounts array.
textstring | nullOverride text for that account.
mediastring[]Override media IDs.
subpostsSubpostInput[]Override subposts for that account.
titlestring | nullPlatform-specific override title.
linkstring | nullPlatform-specific override link.
terms_and_conditionsstring | nullGoogle Business offer terms override.
coupon_codestring | nullGoogle Business offer coupon code override.
start_datestring | nullGoogle Business event/offer start datetime override.
end_datestring | nullGoogle Business event/offer end datetime override.
ctastring | nullGoogle Business CTA override.

Validation rules

  • publish_type must be one of: regular, short, story.
  • For publish_type = regular:
    • text is required and must be non-empty.
    • media is optional.
  • For publish_type = short:
    • text is required and must be non-empty.
    • media is required.
    • If accounts are present, all accounts must be short-compatible: facebook, instagram, youtube, tiktok.
    • Posts with no accounts are allowed in draft state.
  • For publish_type = story:
    • media is required.
    • If no accounts are present, text is optional.
    • If all accounts are story-compatible (facebook, instagram), text is optional.
    • If any account is not story-compatible, text is required and must be non-empty.
  • Media ID, account ID, and label ID arrays must not contain duplicates.
  • For accounts, you may pass either plain account IDs or { id, board_id } objects.
  • Both snake_case and legacy camelCase are accepted for platform-specific request fields, but snake_case is the official public API format.
  • Every account_customizations[].id value must also be present in accounts.
  • Each account_customizations entry inherits the top-level publish_type and must satisfy that publish type's validation rules.
  • When status is scheduled:
    • accounts must be provided.
    • scheduled_at must be provided.
    • scheduled_at must be a future datetime.
  • scheduled_at is only permitted when status is scheduled.

Public API callers are always treated as non-approvers. If the owner/workspace requires approval, creating with status: "scheduled" stores the post as pending approval while still storing scheduled_at.

Publish type examples

Regular post:

{
  "text": "Launch update for this week",
  "publish_type": "regular"
}

Short post:

{
  "text": "Quick update",
  "media": ["med_short_video"],
  "accounts": ["social_fb"],
  "publish_type": "short"
}

Story post:

{
  "media": ["med_story_image"],
  "accounts": ["social_ig"],
  "publish_type": "story"
}

Story post with no accounts yet:

{
  "media": ["med_story_image"],
  "publish_type": "story"
}

Story post targeting a non-story-compatible account (text required):

{
  "text": "Cross-posting this story asset",
  "media": ["med_story_image"],
  "accounts": ["social_linkedin"],
  "publish_type": "story"
}

Example request

curl --request POST \
  --url https://api.feedhive.com/posts \
  --header 'accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "text": "Launch update for this week",
    "media": ["med_hero_image"],
    "subposts": [
      {
        "text": "Thread follow-up with the main rollout checklist.",
        "media": []
      }
    ],
    "accounts": [
      "social_123",
      { "id": "social_456", "board_id": null }
    ],
    "account_customizations": [
      {
        "id": "social_456",
        "text": "A LinkedIn-specific version of the launch update.",
        "media": [],
        "subposts": [],
        "title": "Launch week teaser",
        "link": "https://feedhive.com/launch",
        "terms_and_conditions": "Valid while supplies last.",
        "coupon_code": "LAUNCH20",
        "start_date": "2026-04-15T00:00:00.000Z",
        "end_date": "2026-04-22T00:00:00.000Z",
        "cta": "learn_more"
      }
    ],
    "labels": ["lbl_campaign_q4"],
    "status": "scheduled",
    "scheduled_at": "2026-04-15T13:00:00.000Z",
    "notes": "Use the updated CTA once legal signs off.",
    "short_link_enabled": true,
    "title": "Launch week teaser",
    "link": "https://feedhive.com/launch",
    "terms_and_conditions": "Valid while supplies last.",
    "coupon_code": "LAUNCH20",
    "start_date": "2026-04-15T00:00:00.000Z",
    "end_date": "2026-04-22T00:00:00.000Z",
    "cta": "learn_more",
    "topic_type": "offer",
    "privacy_status": "private",
    "allow_comments": true,
    "allow_duet": false,
    "allow_stitch": true
  }'

Response body

FieldTypeDescription
successbooleanWhether the request succeeded.
dataPostCreated post.

PATCH /posts/:id

Update an existing post. Fields use replace semantics, so any field you send fully overwrites the current value.

Path parameters

FieldTypeDescription
idstringPost identifier.

Request body

FieldTypeDescription
textstring | nullReplacement root text.
mediastring[]Replacement media IDs.
subpostsSubpostInput[]Replacement subposts.
accountsstring[] | AccountReferenceInput[]Replacement social account IDs or account objects.
account_customizationsAccountCustomizationInput[]Replacement per-account overrides.
labelsstring[]Replacement label IDs.
statusdraft | scheduledReplacement status.
publish_typeregular | short | storyReplacement publish mode.
scheduled_atstring | nullReplacement scheduled datetime. Send null to clear it.
notesstring | nullReplacement notes value.
short_link_enabledbooleanReplacement short-link setting.
titlestring | nullNew platform-specific title.
linkstring | nullNew platform-specific link.
terms_and_conditionsstring | nullNew Google Business offer terms.
coupon_codestring | nullNew Google Business coupon code.
start_datestring | nullNew Google Business event/offer start datetime.
end_datestring | nullNew Google Business event/offer end datetime.
ctastring | nullNew Google Business CTA.
topic_typestring | nullNew Google Business topic type.
privacy_statusstring | nullNew YouTube/TikTok privacy status.
allow_commentsboolean | nullNew TikTok comment toggle.
allow_duetboolean | nullNew TikTok duet toggle.
allow_stitchboolean | nullNew TikTok stitch toggle.

The same validation rules as POST /posts apply.

When updating to status: "scheduled", Public API callers are always treated as non-approvers. If the owner/workspace requires approval, the post is stored as pending approval, with scheduled_at preserved.

Example request

curl --request PATCH \
  --url https://api.feedhive.com/posts/post_123 \
  --header 'accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "text": "Launch update for this week - revised",
    "labels": ["lbl_campaign_q4", "lbl_product_launch"],
    "scheduled_at": "2026-04-16T13:00:00.000Z",
    "notes": "Approved for the final review pass.",
    "short_link_enabled": false,
    "title": "Launch week teaser - revised",
    "link": "https://feedhive.com/launch-revised",
    "terms_and_conditions": "Valid while supplies last.",
    "coupon_code": "LAUNCH20",
    "start_date": "2026-04-16T00:00:00.000Z",
    "end_date": "2026-04-23T00:00:00.000Z",
    "cta": "learn_more",
    "topic_type": "offer",
    "privacy_status": "private",
    "allow_comments": true,
    "allow_duet": false,
    "allow_stitch": true
  }'

Response body

FieldTypeDescription
successbooleanWhether the request succeeded.
dataPostUpdated post.

DELETE /posts/:id

Soft-delete a post. Deleted posts no longer appear in list results, but the underlying record is retained internally.

Path parameters

FieldTypeDescription
idstringPost identifier.

Example request

curl --request DELETE \
  --url https://api.feedhive.com/posts/post_123 \
  --header 'accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY'

Response body

FieldTypeDescription
successbooleanWhether the request succeeded.
dataPostDeleted post.