Skip to content

Bulk + Export/Import API ​

Sweep-actions across many Stories, plus full Space backup/restore.

Bulk story actions ​

http
POST /v1/spaces/{slug}/stories/bulk

Body:

json
{
  "action": "publish",
  "uuids": ["abc-...", "def-...", "..."],
  "options": { "publish_at": "2026-06-01T08:00:00Z" }
}

Supported action values:

actionoptionsEffect
publishpublish_at?Publish each story; with publish_at schedules instead of immediate
unpublish—Flip status to draft
archive—Soft-delete (recoverable via restore)
restore—Undo archive
transitionto_stage (required)Workflow transition (RBAC + approval rules still apply)
deleteconfirm: "yes-permanently"Hard delete; requires admin role

Response: 200 { processed, failed: [{ uuid, error }] }. Partial failures are recorded — the rest still process.

Export ​

http
GET /v1/spaces/{slug}/export

Streams a .tar.gz containing:

  • stories.ndjson — one Story per line, all versions
  • blueprints.ndjson — component blueprints
  • locales.ndjson — Locale rows
  • audience-segments.ndjson — segments + rules
  • assets/ — original files (only when ?with_assets=1)
  • manifest.json — schema version + counts

Auth: auth:sanctum + space.scope middleware. Rate-limited throttle:5,60 (5 per hour) — the operation is expensive.

Import ​

http
POST /v1/spaces/{slug}/import
Content-Type: multipart/form-data

Field: bundle (the .tar.gz from export).

Modes (query param ?mode=):

modeBehaviour
dry-run (default)Validate, return diff, write nothing
mergeInsert new, update existing (matched by UUID)
replaceWipe target Space first, then import — destructive

Response includes a per-entity counts dict plus any UUID conflicts.

replace mode

replace deletes everything in the target Space (stories, blueprints, locales, segments) before import. Confirm twice in the admin SPA before clicking the button. CLI: peacock import bundle.tgz --mode replace --i-have-a-backup.

See also ​