Posts

Create post draft

Creates a LinkedIn post draft assigned to a profile. Never publishes by itself.

POST/api/public/posts
cURLPOST /api/public/posts
curl -X POST https://postiv.ai/api/public/posts \
  -H "Authorization: Bearer pk_postiv_..." \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Launch lessons",
    "content": "Three things we learned from launch week...",
    "integrationId": 123,
    "humanize": true
  }'
200Response
{
  "success": true,
  "post": {
    "id": "post1...",
    "status": "draft",
    "content": "Most founders think..."
  },
  "humanized": false
}

Authorization

Requires an organization API key with the posts:write scope, sent as Authorization: Bearer or x-api-key.

Body parameters

typestring

Only 'document' is accepted; omit to default.

One of:document
titlestring

Max 240 chars.

contentstringdefault: ""

Max 100000 chars.

integrationIdintrequired

Alias: integration_id. Required: a draft always belongs to a profile.

templateIduuid

Alias: template_id, from search_templates.

planItemIduuid

Alias: plan_item_id, from get_content_plan_item.

humanizebooleandefault: false

REST-only opt-in: runs the humanizer pass over content before saving. (The MCP create_post tool always runs both the humanizer and hook-lint pass unconditionally, with no opt-out.)

Response

The created post.

postobject

Full post object: same shape as GET /api/public/posts/:id.

humanizedboolean

Whether the humanizer changed the content.

Errors

400missing_integration_id: integrationId omitted
400content_too_long_to_humanize: content over 20000 chars with humanize on
402subscription_required (from checkSubscriptionAccess inside createPostDraft)
404linkedin_profile_not_found / post_template_not_found

Good to know

  • Markdown emphasis (bold, *italic*) is always converted to Unicode glyphs before saving: LinkedIn renders everything else as literal characters. planItemId links the draft back to Bob's plan and marks that item drafted.