Publishing
Publishing delivers a finished article to its destination — the built-in Terradium CMS or your own webhook. Articles can publish automatically when they finish, or stay as drafts until you publish them by hand.
How publishing works
When an article is published, Terradium delivers it to the project's target. Delivery runs on a background sweep (about once a minute), so a just-published article may show Publishing… briefly before it goes live. A project's publish state is derived from what's actually been delivered, so it always reflects reality.
Auto-publish vs draft
This is set per project under project settings → Publishing → After generation:
- Save as draft (default) — finished articles wait as drafts for your review.
- Publish automatically — finished articles are delivered on their own, after a review window and once your site is ready to be cited.
The review window
Auto-published articles don't go out the instant they finish. They wait for the project's review window — 24 hours by default — so you have a chance to read one before it's live. Set it to 0 to never auto-publish, or up to 7 days.
Publishing an article yourself is always immediate; the window only applies to auto-publish.
The GEO readiness gate
Auto-publish also waits until your site passes its GEO readiness checks. There's no point publishing an article to a page AI engines can't read: if your blog renders its content only in the browser, returns errors, blocks AI crawlers, or has no brand entity set, an auto-published article is held rather than delivered.
Held articles show as on hold in the publish queue with the reason. They are not failures and are never dropped — fix the site, and the next readiness check releases the backlog automatically. This is also why your first articles usually need publishing by hand: until something is live, there's no page for the readiness check to inspect.
You can always publish a held article yourself — the gate only applies to auto-publish.
Rebuild your site on publish
If your site is statically built, publishing an article in Terradium doesn't help until your site rebuilds. Connect the repository that builds it and Terradium will trigger a build every time an article goes live.
Under project settings → Publishing → Rebuild your site on publish:
- Connect GitHub — installs the Terradium GitHub App and lets you choose which repository (or repositories) it can see. Grant it one repo; it does not need access to anything else. Start from this button rather than installing from GitHub directly, so the installation is linked to this project.
- Pick the repository and workflow. The default workflow file is
terradium-publish.ymlonmain; point us at an existing build workflow instead if you already have one. It must have aworkflow_dispatch:trigger. - Trigger a test build to confirm the wiring without waiting for an article.
What Terradium does and doesn't do
Terradium fires a workflow_dispatch and nothing else. Your articles are never
committed into your repository — the content stays in Terradium and your build
pulls it from the public content API at build time. The
repo only ever needs the one workflow file.
The app's permissions are correspondingly narrow: trigger workflows, and write the single workflow file. No pull requests, no source access, no PAT, and nothing tied to a Terradium employee's GitHub account.
A starting workflow
yamlname: Terradium publish on: workflow_dispatch: inputs: reason: description: "What triggered this build" required: false default: manual project_id: required: false push: branches: [main] concurrency: # A burst of publishes should produce one deploy, not a queue of them. group: terradium-publish cancel-in-progress: true jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: 20, cache: npm } - run: npm ci - name: Build env: TERRADIUM_API_KEY: ${{ secrets.TERRADIUM_API_KEY }} run: npm run build - name: Deploy run: echo "Add your deploy step here"
Store your project API key as a repository secret (TERRADIUM_API_KEY) —
never commit it. Fetch posts once with ?include=body rather than one request
per slug: the content API is rate-limited per IP and CI runners share addresses.
When a build fails
A failed trigger never affects the article — it is already published to the Terradium CMS and served by the content API. The failure is recorded against the connection and shown on this settings card, and Terradium retries a few times to ride out a transient GitHub outage.
The most common cause is a workflow file that doesn't exist on that branch, or
one without a workflow_dispatch: trigger. The error message says which.
Publish targets
Also in project settings, choose where published articles go:
- Terradium CMS — a built-in content store served read-only by the public content API. Best if you want to pull posts into your own frontend by API key.
- Webhook — Terradium
POSTs the finished article as a signed JSON payload to your URL, so you can ingest it into your own system. Verification details are in the API reference.
Manual publish
When auto-publish is off, you publish on demand:
- From an article, click Publish (or Retry publish if a delivery failed).
- From the Publish screen's Drafts tab, publish a single article or use Publish all to send every draft for the selected project.
The publishing queue
The Publish screen has three tabs:
- Drafts — finished articles not yet published.
- Published — live articles, with their slug, a copy URL action, and an Unpublish button.
- Queue — in-flight and failed deliveries, with retry counts and any error. Failed rows can be Retried; pending rows can be Cancelled.
Publish states
An article shows one of these states:
- Draft — finished but not published.
- Publishing — queued or mid-delivery.
- Published — live (served by the API or delivered to your webhook).
- Failed — a delivery error you can retry.
- Unpublished — previously live, now taken down.
Unpublishing
You can take a published article down at any time — from the article's publishing card or the Published tab — with Unpublish. It stops being served by the public API; you can publish it again later.