CLI

The floggy CLI (v0.4+) drives collections from the terminal and CI. pull / push / diff turn a collection into a directory of JSON files, which is what agent pipelines and CI want to work with.

Collections require the Pro plan. Every command uses your API key's collections:* scopes.

Writes are drafts by default

set and push write drafts. A draft is stored and versioned but not served: default reads skip it, so nothing you write reaches your site until a label points at it. Nothing about a successful set or push makes content live on its own.

Two flags change that:

  • --publish - point the production label at what you just wrote. This is publishing.
  • --label <name> - point that label at it instead (staging, variant-a, ...). The entry stays unpublished.

If you use neither, you publish later with promote or label. If content you pushed is not showing up, this is almost always why.

Commands

floggy collections list                        # list your collections
floggy collections create <collection> --schema f.json
floggy collections show <collection>           # schema + entry count
floggy collections delete <collection>

floggy collections entries <collection>        # list entries [--tag --q --page --per-page]
floggy collections get <collection> <entry>    # full entry [--label --version]
floggy collections set <collection> --file e.json          # upsert one entry, as a DRAFT
floggy collections set <collection> --file e.json --publish       # ... and make it live
floggy collections set <collection> --file e.json --label staging # ... onto another label
floggy collections rm <collection> <entry>

floggy collections versions <collection> <entry>   # version history with labels
floggy collections promote <collection> <entry> <version>   # point production at a version
floggy collections label <collection> <entry> <name> <version> [--meta '{...}']
floggy collections unlabel <collection> <entry> <name>

set matches an existing entry by slug. On a create, --publish publishes in the same API call. On an update, set writes the new version and then moves the label onto it, because a plain update never moves a label by itself.

Directory sync

The workflow that makes collections CI-friendly: keep a directory of one JSON file per entry, and sync it.

pull

floggy collections pull landing-pages ./content/landing-pages

Writes one JSON file per entry into the directory (named by slug or id). This is your local, reviewable copy of the collection's published state.

push

floggy collections push landing-pages ./content/landing-pages            # drafts
floggy collections push landing-pages ./content/landing-pages --publish  # live
floggy collections push landing-pages ./content/landing-pages --label staging

Upserts every file back into the collection, matched by slug. Uses the bulk endpoint under the hood (50 per batch). New slugs are created; existing ones get a new version. This is how an agent pipeline commits a batch of generated content.

Without --publish or --label, every file lands as a draft version and live content does not move.

With --publish, both halves of the batch end up live:

  • New slugs are created with the label applied in the same call, so they are live immediately.
  • Existing slugs get a new version, then the label is moved onto that version in a follow-up pass. This is the part to know: an update alone leaves production pinned to the old version. Before --publish existed, pushing an edit to a published entry wrote the version but left the site serving the old copy, so edits looked like they had silently failed. --publish moves the label, so the edit actually goes live.

If a label move fails for an entry, push says so and that entry stays on its previous published version. The new version is still stored, so re-running with --publish or a manual promote fixes it.

diff

floggy collections diff landing-pages ./content/landing-pages

Shows what push would change: added, modified, and removed entries. Exits 1 when there is drift, 0 when the directory matches the collection, which makes it a drop-in CI check.

Agent pipeline pattern

Review first, publish second:

# 1. agent generates/edits JSON files in ./content/landing-pages
# 2. verify against the live collection
floggy collections diff landing-pages ./content/landing-pages

# 3. push the batch as drafts, nothing goes live
floggy collections push landing-pages ./content/landing-pages

# 4. publish the ones that are ready, by version
floggy collections versions landing-pages black-friday
floggy collections promote landing-pages black-friday 4

Or, when the batch is already trusted (a scheduled regeneration, a reviewed PR merged to main), publish the whole push:

floggy collections push landing-pages ./content/landing-pages --publish

Pick per pipeline. The default stays drafts, so a push never changes live content unless you ask it to.

CI gate

Fail a build when the repo and the collection have drifted:

# in your CI job
- run: floggy collections diff landing-pages ./content/landing-pages
  env:
    FLOGGY_API_KEY: ${{ secrets.FLOGGY_API_KEY }}

diff exits non-zero on drift, so the step fails and the build stops. Swap to push on the main branch to auto-sync after review, and add --publish there if merging to main is your definition of published.

Next