Bulk upload

Schedule many posts to one channel at once from a CSV file, check every row before anything is scheduled, and undo an import.

Bulk upload turns a spreadsheet into scheduled posts on one channel. You see how every row will be posted (its time, its tags, its image, anything wrong with it) before anything is scheduled, and an import you regret can be undone.

Upload a file

Go to Settings, choose the channel under Platforms, and select Bulk upload.

Choose Download template for a file that already has the right columns, or use your own. Add one row per post, up to 200 rows.

Drop the file into the dialog. Every row is checked and listed with its posting time, tags and image, and is marked ready, with warnings or with errors.

Fix what needs fixing: Edit a row to change its text, time or image link, or remove it. Then choose Import. Rows with errors are skipped and the rest are scheduled.

The columns

ColumnWhat goes in it
textRequiredThe post. Emoji and line breaks are kept. It must fit the network's character limit.
image_urlOptionalA direct link to a JPEG, PNG, GIF or WebP image, up to 10 MB. Separate several links with spaces.
tagsOptionalTags that already exist in the workspace, separated by commas.
posting_timeOptionalYYYY-MM-DD HH:MM in 24-hour time, for example 2026-11-05 17:30.

Column names are matched loosely, so a file with headers like Text, Image URL and Posting Time works too. Files saved as CSV UTF-8 or UTF-16 (Excel's "Unicode Text") are both read, and so are files that use semicolons between columns.

Posting times

Times are read in the channel's posting timezone, which the check step names. A row without a time takes the next free slot in the channel's posting schedule, after everything already booked, in the order the rows appear. Choose Save as drafts instead to leave those rows unscheduled.

A time in the past, a date without a time, and a date that could be read two ways (is 05/11/2026 5 November or 11 May?) are errors rather than guesses. Write dates as YYYY-MM-DD to avoid the last one.

Images

The image is copied into your media library when you import, so the link only has to work while you import. It has to open the image itself: a link to a web page, or a cloud-drive preview, is an error. Right-click the image and choose Copy image address to get a direct link.

Tags

Tags are matched to the workspace's own regardless of capitals. A tag that doesn't exist is left off the post with a warning, and the post is still imported. Create new tags in Settings → Tags first.

On a plan with approvals, posts imported by someone who can't publish wait for approval before they go out, exactly as they would from the composer.

Undo an import

The dialog offers Undo import as soon as the import finishes, and the channel's Bulk upload section lists recent imports with an Undo button. Undoing deletes every post from that import that hasn't gone out yet. Anything already published stays where it is.

From the API, CLI and MCP

The same import is available everywhere:

  • API: POST /api/v1/posts/import with dryRun: true to check rows, then without it to import, and POST /api/v1/posts/imports/{importId}/undo to undo. See the API reference.
  • CLI: orbitwrite import posts.csv -c <channel> --dry-run, then without --dry-run. See the CLI guide.
  • SDK: orbit.imports.check(), orbit.imports.create() and orbit.imports.undo(). See the SDK guide.
  • MCP: the import_posts and undo_post_import tools.