Publication management

Use publication routes to create a blog publication, manage its identity and settings, and control whether it is available to public readers. A publication has an operational status (active or disabled) and a separate archival state. Only active, unarchived publications are available through public resolution and public read routes.

Authentication

Every route except /publication/resolve requires a bearer token. The caller needs the capability shown in the route table. Publication-specific requests accept publication_id or publication_slug; use the stable ID after creation.

Routes

Route Methods Authorization Required input Optional input and behavior Success result
/publication/list GET, POST Authenticated principal archived, pagination Paginated publications.
/publication/get POST publication.get Publication selector publication.
/publication/create POST publication.create name slug, locale, initial settings groups Created publication and context.
/publication/save POST publication.save Publication selector name, slug, featured_media_id Saved publication.
/publication/archive POST publication.archive Publication selector Archived publication.
/publication/restore POST publication.restore Publication selector Restored publication.
/publication/delete POST publication.delete Publication selector Deleted publication_id.
/publication/update-status POST publication.status Publication selector, status Updated publication.
/publication/resolve POST None publication_slug or slug Public publication identity.
/publication/settings/get POST settings.get Publication selector publication_id and settings.
/publication/settings/save POST settings.save Publication selector and a settings update locale shortcut Updated settings.

Publication object

Management responses return this core shape; they can also include the caller's role, scope, and capabilities.

{
  "publication_id": "PUBLICATION_UUID",
  "slug": "engineering-notes",
  "name": "Engineering Notes",
  "featured_media_id": "MEDIA_UUID",
  "status": "active",
  "archived": 0,
  "archived_at": null,
  "archive_note": null,
  "created_at": "2026-08-19 00:00:00.000000",
  "updated_at": "2026-08-19 00:00:00.000000"
}

Create and update

Create fields

Field Required Type Description
name Yes String Publication name.
slug No String Globally unique slug. Omit or send an empty value to derive it from name.
locale No String Initial settings.identity.locale; letters, numbers, _, and - only.
settings No Object Initial settings groups.
identity, theme, seo, feeds, search, comments, subscriptions, notifications, integrations, metadata No Object Alternative top-level initial settings groups.
curl -sS https://api.blog.service.m7.org/v1/publication/create \
  -H 'Authorization: Bearer ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "name":"Engineering Notes",
    "slug":"engineering-notes",
    "locale":"en-US"
  }'

New publications start active and unarchived. The creating principal becomes its owner. Create rejects caller-supplied owner, status, archival, timestamp, and featured_media_id fields.

Use /publication/save to update the identity:

{
  "publication_id": "PUBLICATION_UUID",
  "name": "Engineering Journal",
  "slug": "",
  "featured_media_id": "MEDIA_UUID"
}

The featured_media_id must reference ready media in the same publication. An empty slug derives a new slug from the submitted name. Fields not sent are retained; status and archival fields are rejected by this route.

Listing and public resolution

/publication/list defaults to unarchived publications. Send archived: 1 to list archived records, along with the standard pagination fields from the service guide.

/publication/resolve is the unauthenticated lookup used before loading public content:

{ "publication_slug": "engineering-notes" }

It returns 404 unless the publication is active and unarchived:

{
  "public_publication": {
    "publication_id": "PUBLICATION_UUID",
    "slug": "engineering-notes",
    "name": "Engineering Notes",
    "created_at": "2026-08-19 00:00:00.000000",
    "updated_at": "2026-08-19 00:00:00.000000"
  }
}

Status and archival lifecycle

Use /publication/update-status to set status to exactly active or disabled. This does not alter archival state.

{ "publication_id": "PUBLICATION_UUID", "status": "disabled" }

Archive and restore accept only a publication selector. Archiving preserves the current status; restoring does the same. A publication must first be archived before it can be permanently deleted. Deletion returns 409 while it still has posts, pages, redirects, domains, authors, tags, categories, or media.

Settings

/publication/settings/get returns all groups. To update settings, send a non-empty settings object or one or more top-level group objects. Updates merge recursively with current settings.

{
  "publication_id": "PUBLICATION_UUID",
  "settings": {
    "identity": { "locale": "en-US" },
    "seo": { "title_suffix": "| Engineering" }
  }
}

The allowed group names are identity, theme, seo, feeds, search, comments, subscriptions, notifications, integrations, and metadata. locale may be sent as a shortcut for identity.locale. Non-empty values under sensitive-looking setting keys are returned as [redacted]; do not use a redacted response as an input value when preserving a secret.