Guide 06 · Developer docs

The APIs: REST, GraphQL and custom endpoints

Every Core dna site answers three kinds of API request under /cdna-api: REST for everything, GraphQL for reads that span several entity types, and web events for endpoints you define yourself as jobs. Which fits which task, one worked request for each, and what is true of all three. Jobs were called hooks until the module was renamed Orchestration; the API's routes still use the old name.

L1–L3
Unit 02 · Writing content

Making a revision live, rolling back and publishing

Choosing which revision is live, going back to an older one, and deciding when visitors see the record at all. The request for each, the routes the types with their own rules use, and how to pin a patch so it does not undo a rollback.

Who this is for. The integrations engineer who publishes content, and whoever has to put a page back the way it was. Read Versioned content and the live revision first if the three separate switches are new to you.

Live in the same request

Put "activeRevision": true inside the patchRevision or revisions object, and the revision the request makes becomes the live one. Leave it out and the revision is saved for later. The patch example does this.

Rolling back, or forward

At the top level of an edit, activeRevision takes the id of a revision the record already has, and makes it live. No revision is made and published does not change. It works in either direction, so the same request undoes a rollback.

Make an earlier revision live again
PUT /cdna-api/pages/page/1885?properties={id,activeRevision{id},lastRevision{id},navSection:activeRevision.areaText(navSection)} HTTP/1.1
Host: hub.coredna.com
Authorization: Bearer YOUR_ACCESS_TOKEN
Accept: application/json
Content-Type: application/json

{
  "activeRevision": 3277
}
Response 200 OK
{
  "result": "success",
  "data": {
    "id": 1885,
    "activeRevision": {
      "id": 3277
    },
    "lastRevision": {
      "id": 3425
    },
    "navSection": "API sandbox"
  },
  "message": "The Page has been saved successfully."
}
Real response from this documentation site, on its API sandbox page

The page shows revision 3277 again, and 3425, the newer one, is still there. A patch must name originRevision, or it copies the newest revision, 3425, not the live one, so an edit to a single section would bring the rolled-back text back with it:

A patch without originRevision, just after a rollback
PUT /cdna-api/pages/page/1885?properties={id,activeRevision{id},lastRevision{id},navSection:activeRevision.areaText(navSection)} HTTP/1.1
Host: hub.coredna.com
Authorization: Bearer YOUR_ACCESS_TOKEN
Accept: application/json
Content-Type: application/json

{
  "patchRevision": {
    "activeRevision": true,
    "patchAreaCollectionElement(pageSections, 1)": {
      "areaContent(body)": "<p>Mixed: inserted, edited</p>"
    }
  }
}
Response 200 OKRollback undone
{
  "result": "success",
  "data": {
    "id": 1885,
    "activeRevision": {
      "id": 3426
    },
    "lastRevision": {
      "id": 3426
    },
    "navSection": "API sandbox, patched"
  },
  "message": "The Page has been saved successfully."
}
Real response from this documentation site, on its API sandbox page

Read the live revision's id before every patch and send it as originRevision: with "originRevision": 3277, the patch copies the live revision and changes only the section asked for.

Types with routes of their own

RecordMake a revision liveDelete a revision
Pages, books, units, book pages, blog posts, FAQ pages and questions, product descriptions{"activeRevision": <id>} on the record's edit routeNot through the API
Custom entity recordsThe same, or PUT /cdna-api/custom-entities/activate-revision/{record}/{revision}DELETE /cdna-api/custom-entities/record-revision/{record}/{revision}
FormsPUT /cdna-api/forms/activate-form-revision/{form} with {"revision_id": <id>}Not through the API
Files and imagesPUT /cdna-api/files/revisions/{filename}/{revision}DELETE on the same path; the live revision answers 409

A form's activation route wants revision_id, with an underscore. Each route is on its reference page.

Publishing and scheduling

published is a date and time, not a flag:

  • true publishes now.
  • A datetime in the future schedules it: the record is published from that moment. It reads back in UTC.
  • null or false unpublishes.

To take a record down at a time, set unpublishAt. When it passes, the record is unpublished and both published and unpublishAt are cleared, so a later manual republish stays up. There is also a publishAt field, but the scheduled publishing does not read it: schedule go-live with a future published.

Schedule a page to go live
PUT /cdna-api/pages/page/1885?properties={id,published,publishAt,unpublishAt} HTTP/1.1
Host: hub.coredna.com
Authorization: Bearer YOUR_ACCESS_TOKEN
Accept: application/json
Content-Type: application/json

{
  "published": "2027-01-01T09:00:00+11:00"
}
Response 200 OK
{
  "result": "success",
  "data": {
    "id": 1885,
    "published": "2026-12-31T22:00:00+00:00",
    "publishAt": null,
    "unpublishAt": null
  },
  "message": "The Page has been saved successfully."
}
Real response from this documentation site, on its API sandbox page

Three things to know about scheduled changes:

  • The clock crossing a date saves nothing. A background worker notices the change afterwards and sends the events a save would have sent, so search indexing, cache clearing and jobs that listen for publishing happen when it runs, shortly after the time, not to the second.
  • Publishing needs the publish permission. A user without it who sends published at all is refused.
  • Admins see unpublished records. Check what visitors see signed out, not with the credentials that published.
Go deeper

Was this page helpful?

Your answer goes to the docs team.