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
Writing contentPage 11 of 25Updated
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.
{
"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
{
"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
Record
Make a revision live
Delete a revision
Pages, books, units, book pages, blog posts, FAQ pages and questions, product descriptions
{"activeRevision": <id>} on the record's edit route
Not through the API
Custom entity records
The same, or PUT /cdna-api/custom-entities/activate-revision/{record}/{revision}
PUT /cdna-api/forms/activate-form-revision/{form} with {"revision_id": <id>}
Not through the API
Files and images
PUT /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.
{
"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.