PostZen
Posts

Bulk upload posts from CSV

POST
/v1/posts/bulk-upload

Validates and creates up to 500 posts from a CSV file. This endpoint requires a read-write API key. Each data row targets every connected account for the selected platforms on one profile. Set dryRun=true to validate without billing checks, media ingestion, or writes. A mixed success/failure response uses HTTP 207; all-success and all-failure responses use HTTP 200.

CSV columnPurpose
post_contentRequired base post text.
platformsRequired comma-separated platforms: instagram, facebook, threads, tiktok, linkedin, x, youtube, pinterest, bluesky, or telegram; twitter aliases x.
profilesRequired single profile id or unique profile name.
schedule_timeRequired column. Use YYYY-MM-DD HH:mm[:ss] in tz, or ISO 8601 with an explicit offset. May be empty for draft, publish-now, or queue rows.
tzIANA timezone; defaults to UTC.
media_urlsComma-separated HTTP(S) URLs, up to 10 per row and 50 distinct URLs per upload.
is_draft, publish_now, use_queueMutually exclusive boolean mode flags. With none set, the row is scheduled.
title, tags, hashtags, mentions, visibilityGeneral title, comma-separated tags, appended hashtags/mentions, and YouTube visibility.
custom_content_<platform>Platform-specific content override; custom_content_twitter targets X.
youtube_title, youtube_descriptionYouTube title and description override.
facebook_first_comment, linkedin_first_commentFirst comments.
instagram_content_type, instagram_collaborators, instagram_first_commentInstagram post type, collaborators, and first comment.
tiktok_privacy, tiktok_allow_comments, tiktok_allow_duet, tiktok_allow_stitch, tiktok_brand_partner, tiktok_organic_brand, tiktok_draft, tiktok_descriptionTikTok publishing options.
telegram_parse_mode, telegram_disable_web_page_preview, telegram_disable_notification, telegram_protect_contentTelegram publishing options.
pinterest_title, pinterest_link, pinterest_board_idPinterest pin options.

Authorization

bearerAuth
AuthorizationBearer <token>

PostZen API key.

In: header

Query Parameters

dryRun?boolean

Validate every row without ingesting media, charging billing, or creating posts.

Header Parameters

x-request-id?string

Optional upload idempotency key. Each row derives the stable key bulk-api:{x-request-id}:{1-based row index}.

Request Body

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/v1/posts/bulk-upload" \  -F file="string"
{  "total": 0,  "valid": 0,  "invalid": 0,  "results": [    {      "rowIndex": 1,      "ok": true,      "createdPostId": "string"    }  ],  "warnings": [    "string"  ]}
{  "total": 0,  "valid": 0,  "invalid": 0,  "results": [    {      "rowIndex": 1,      "ok": true,      "createdPostId": "string"    }  ],  "warnings": [    "string"  ]}
{  "error": "JSON body is required"}
{  "error": "Unauthorized"}
{  "error": "Add a payment method before connecting more than 2 social accounts.",  "code": "paymentRequired",  "reason": "freeTierExceeded",  "documentationUrl": "https://docs.postzen.dev/api-reference/connect/create-connect-url",  "dashboardUrl": "https://app.postzen.dev/settings?tab=billing",  "details": {    "freeTierAccountLimit": 2,    "currentAccountCount": 2,    "hasPaymentMethod": false  }}
{  "error": "API key requires read_write permission"}
{  "error": "rate_limited",  "retryAfter": 30}