Skip to content
Product Documentation

How To Restore A Document From An Older Revision

We all make mistakes. Sometimes our mistake is publishing a revision unintentionally with the Draft API. This guide demonstrates how to restore a document from an older revision.

Goals

At the end of this guide, a user will be able to load an arbitrary document revision and set it as the document’s draft and published revisions.

Prerequisites

  • Knowledge of the following Draft API concepts:
    • document
    • revision
    • draft vs published revision
  • Experience with ANS
  • Knowledge of HTTP, HTTP authentication, and cURL

Step-By-Step Guide

This guide starts with a circulated document that has been published.

Document:

{
"id": "IXMKZP5SPVHKTJVGFF6FEGJECQ",
"draft_revision_id": "RGJV3JF7QRDRNM5FK22G3DAQZY",
"published_revision_id": "XHPXJG22KRAF7H5USWLNFSPRDY",
"first_published_at": "2019-09-25T12:36:51.278Z",
"last_published_at": "2019-09-25T12:36:51.278Z",
"created_at": "2019-09-25T12:26:07.201Z",
"updated_at": "2019-09-25T12:36:51.19Z",
"type": "STORY"
}

Circulation:

{
"circulations": [
{
"document_id": "IXMKZP5SPVHKTJVGFF6FEGJECQ",
"website_id": "testing",
"website_url": "/2019/09/25/guide-title",
"website_primary_section": {
"type": "reference",
"referent": {
"type": "section",
"id": "/programming",
"website": "testing"
}
},
"website_sections": [
{
"type": "reference",
"referent": {
"type": "section",
"id": "/programming",
"website": "testing"
}
}
]
}
]
}

Step 1: Edit Document without Publishing Changes

This step is a typical publisher workflow that involves editing and saving changes to a document without publishing. First, let’s retrieve the document’s draft revision for editing.

Terminal window
curl --request GET \
--header 'Authorization: Bearer <TOKEN>' \
--url https://api.{{org}}.arcpublishing.com/draft/v1/story/IXMKZP5SPVHKTJVGFF6FEGJECQ/revision/RGJV3JF7QRDRNM5FK22G3DAQZY

API response:

{
"id": "RGJV3JF7QRDRNM5FK22G3DAQZY",
"document_id": "IXMKZP5SPVHKTJVGFF6FEGJECQ",
"ans": {
"type": "story",
"version": "0.10.2",
"canonical_website": "testing",
"created_date": "2019-09-25T12:26:07.201Z",
"last_updated_date": "2019-09-25T12:36:51.190Z",
"headlines": {
"basic": "Guide Title"
},
"owner": {
"id": "testing"
}
},
"created_at": "2019-09-25T12:26:07.201Z",
"updated_at": "2019-09-25T12:36:51.19Z",
"type": "DRAFT"
}

Next, let’s edit the draft revision by changing headlines.basic to Guide Edit 1 and saving it.

curl --request PUT \
--header 'Authorization: Bearer <TOKEN>' \
--url https://api.{{org}}.arcpublishing.com/draft/v1/story/IXMKZP5SPVHKTJVGFF6FEGJECQ/revision/draft \
--data '{
"ans": {
"_id": "IXMKZP5SPVHKTJVGFF6FEGJECQ",
"type": "story",
"version": "0.10.2",
"canonical_website": "testing",
"created_date": "2019-09-25T12:26:07.201Z",
"last_updated_date": "2019-09-25T12:36:51.190Z",
"headlines": {
"basic": "Guide Edit 1"
},
"owner": {
"id": "testing"
}
}
}'

API response:

{
"id": "CY26R7VVJZFY5GCJLINJKUDZD4",
"document_id": "IXMKZP5SPVHKTJVGFF6FEGJECQ",
"ans": {
"type": "story",
"version": "0.10.2",
"canonical_website": "testing",
"created_date": "2019-09-25T12:26:07.201Z",
"last_updated_date": "2019-09-25T13:08:21.296Z",
"headlines": {
"basic": "Guide Edit 1"
},
"owner": {
"id": "testing"
}
},
"created_at": "2019-09-25T12:26:07.201Z",
"updated_at": "2019-09-25T13:08:21.296Z",
"type": "DRAFT"
}

When a draft revision is saved, a copy of the updated draft revision is returned. Notice that headlines.basic reflects our change.

Next, let’s edit the draft revision again by changing headlines.basic to Guide Edit 2 and saving it.

curl --request PUT \
--header 'Authorization: Bearer <TOKEN>' \
--url https://api.{{org}}.arcpublishing.com/draft/v1/story/IXMKZP5SPVHKTJVGFF6FEGJECQ/revision/draft \
--data '{
"ans": {
"_id": "IXMKZP5SPVHKTJVGFF6FEGJECQ",
"type": "story",
"version": "0.10.2",
"canonical_website": "testing",
"created_date": "2019-09-25T12:26:07.201Z",
"last_updated_date": "2019-09-25T13:08:21.296Z",
"headlines": {
"basic": "Guide Edit 2"
},
"owner": {
"id": "testing"
}
}
}'

API response:

{
"id": "UWGSF5OJTNHX7EJRFUR44FMNQQ",
"document_id": "IXMKZP5SPVHKTJVGFF6FEGJECQ",
"ans": {
"type": "story",
"version": "0.10.2",
"canonical_website": "testing",
"created_date": "2019-09-25T12:26:07.201Z",
"last_updated_date": "2019-09-25T13:18:24.392Z",
"headlines": {
"basic": "Guide Edit 2"
},
"owner": {
"id": "testing"
}
},
"created_at": "2019-09-25T12:26:07.201Z",
"updated_at": "2019-09-25T13:18:24.392Z",
"type": "DRAFT"
}

Notice headlines.basic reflects our change.

Saving a draft revision does not affect the published revision. Let’s verify this by retrieving the document’s published revision; the published revision’s id can be found at the top of the guide in the document JSON.

Terminal window
curl --request GET \
--header 'Authorization: Bearer <TOKEN>' \
--url https://api.{{org}}.arcpublishing.com/draft/v1/story/IXMKZP5SPVHKTJVGFF6FEGJECQ/revision/XHPXJG22KRAF7H5USWLNFSPRDY

API response:

{
"id": "XHPXJG22KRAF7H5USWLNFSPRDY",
"document_id": "IXMKZP5SPVHKTJVGFF6FEGJECQ",
"ans": {
"type": "story",
"version": "0.10.2",
"canonical_website": "testing",
"created_date": "2019-09-25T12:26:07.201Z",
"last_updated_date": "2019-09-25T12:36:51.101Z",
"headlines": {
"basic": "Guide Title"
},
"owner": {
"id": "testing"
}
},
"created_at": "2019-09-25T12:26:07.201Z",
"updated_at": "2019-09-25T12:36:51.101Z",
"type": "PUBLISHED"
}

Notice that headlines.basic is still Guide Title for the published revision.

Step 2: Publish Changes

This step publishes our most recently saved draft revision which has a headlines.basic value of Guide Edit 2.

Terminal window
curl --request POST \
--header 'Authorization: Bearer <TOKEN>' \
--url https://api.{{org}}.arcpublishing.com/draft/v1/story/IXMKZP5SPVHKTJVGFF6FEGJECQ/revision/published

API response:

{
"id": "YXGISUDDR5DAZKJV34YYTVVTAM",
"document_id": "IXMKZP5SPVHKTJVGFF6FEGJECQ",
"ans": {
"type": "story",
"version": "0.10.2",
"canonical_website": "testing",
"created_date": "2019-09-25T12:26:07.201Z",
"display_date": "2019-09-25T12:36:51.278Z",
"publish_date": "2019-09-25T13:23:21.065Z",
"first_publish_date": "2019-09-25T12:36:51.278Z",
"last_updated_date": "2019-09-25T13:23:20.940Z",
"headlines": {
"basic": "Guide Edit 2"
},
"owner": {
"id": "testing"
}
},
"created_at": "2019-09-25T12:26:07.201Z",
"updated_at": "2019-09-25T13:23:20.94Z",
"type": "PUBLISHED"
}

The Draft API returns the updated published revision when it is saved. Notice headlines.basic reflects the title of our last saved draft revision.

Let’s retrieve the document to verify which revisions are set for draft and published.

Terminal window
curl --request GET \
--header 'Authorization: Bearer <TOKEN>' \
--url https://api.{{org}}.arcpublishing.com/draft/v1/story/IXMKZP5SPVHKTJVGFF6FEGJECQ

API response:

{
"id": "IXMKZP5SPVHKTJVGFF6FEGJECQ",
"draft_revision_id": "V7XV2QVWDFEMZGFKBJVIOYQIME",
"published_revision_id": "YXGISUDDR5DAZKJV34YYTVVTAM",
"first_published_at": "2019-09-25T12:36:51.278Z",
"last_published_at": "2019-09-25T13:23:21.065Z",
"created_at": "2019-09-25T12:26:07.201Z",
"updated_at": "2019-09-25T13:23:21.025Z",
"type": "STORY"
}

As expected, draft_revision_id points to the last draft revision we saved in Step 1 and published_revision_id points to the published revision returned during our publish action.

Step 3: Restore Previously Published Revision

But, wait! We didn’t mean to publish headline Guide Edit 2! This step demonstrates how to find the previously published revision and restore it. First, lets retrieve the list of revision summaries for the document.

Terminal window
curl --request GET \
--header 'Authorization: Bearer <TOKEN>' \
--url https://api.{{org}}.arcpublishing.com/draft/v1/story/IXMKZP5SPVHKTJVGFF6FEGJECQ/revision

API response:

{
"revisions": [
{
"id": "ZGGUHWCIWRFRZOGQDBBKDNR55U",
"document_id": "IXMKZP5SPVHKTJVGFF6FEGJECQ",
"ans": {
"type": "story",
"created_date": "2019-09-25T12:26:07.201Z",
"last_updated_date": "2019-09-25T12:26:07.201Z",
},
"created_at": "2019-09-25T12:26:07.201Z",
"updated_at": "2019-09-25T12:26:07.201Z",
"type": "DRAFT"
},
{
"id": "LRE2UKHEHJDQLN7IMPWTOACKZU",
"document_id": "IXMKZP5SPVHKTJVGFF6FEGJECQ",
"ans": {
"type": "story",
"created_date": "2019-09-25T12:26:07.201Z",
"last_updated_date": "2019-09-25T12:35:15.727Z",
"headlines": {
"basic": "Guide Title"
}
},
"created_at": "2019-09-25T12:26:07.201Z",
"updated_at": "2019-09-25T12:35:15.727Z",
"type": "DRAFT"
},
{
"id": "XHPXJG22KRAF7H5USWLNFSPRDY",
"document_id": "IXMKZP5SPVHKTJVGFF6FEGJECQ",
"ans": {
"type": "story",
"created_date": "2019-09-25T12:26:07.201Z",
"last_updated_date": "2019-09-25T12:36:51.101Z",
"headlines": {
"basic": "Guide Title"
}
},
"created_at": "2019-09-25T12:26:07.201Z",
"updated_at": "2019-09-25T12:36:51.101Z",
"type": "PUBLISHED"
},
{
"id": "RGJV3JF7QRDRNM5FK22G3DAQZY",
"document_id": "IXMKZP5SPVHKTJVGFF6FEGJECQ",
"ans": {
"type": "story",
"created_date": "2019-09-25T12:26:07.201Z",
"last_updated_date": "2019-09-25T12:36:51.190Z",
"headlines": {
"basic": "Guide Title"
}
},
"created_at": "2019-09-25T12:26:07.201Z",
"updated_at": "2019-09-25T12:36:51.19Z",
"type": "DRAFT"
},
{
"id": "3AKU4S7A6VCO5A44CEAJOLWVQ4",
"document_id": "IXMKZP5SPVHKTJVGFF6FEGJECQ",
"ans": {
"type": "story",
"created_date": "2019-09-25T12:26:07.201Z",
"last_updated_date": "2019-09-25T12:49:15.670Z",
"headlines": {
"basic": "Guide Title"
}
},
"created_at": "2019-09-25T12:26:07.201Z",
"updated_at": "2019-09-25T12:49:15.67Z",
"type": "PUBLISHED"
},
{
"id": "L57XAMA6GFDDLCWZP4HA6QJ2RA",
"document_id": "IXMKZP5SPVHKTJVGFF6FEGJECQ",
"ans": {
"type": "story",
"created_date": "2019-09-25T12:26:07.201Z",
"last_updated_date": "2019-09-25T12:49:15.930Z",
"headlines": {
"basic": "Guide Title"
}
},
"created_at": "2019-09-25T12:26:07.201Z",
"updated_at": "2019-09-25T12:49:15.93Z",
"type": "DRAFT"
},
{
"id": "CY26R7VVJZFY5GCJLINJKUDZD4",
"document_id": "IXMKZP5SPVHKTJVGFF6FEGJECQ",
"ans": {
"type": "story",
"created_date": "2019-09-25T12:26:07.201Z",
"last_updated_date": "2019-09-25T13:08:21.296Z",
"headlines": {
"basic": "Guide Edit 1"
}
},
"created_at": "2019-09-25T12:26:07.201Z",
"updated_at": "2019-09-25T13:08:21.296Z",
"type": "DRAFT"
},
{
"id": "UWGSF5OJTNHX7EJRFUR44FMNQQ",
"document_id": "IXMKZP5SPVHKTJVGFF6FEGJECQ",
"ans": {
"type": "story",
"created_date": "2019-09-25T12:26:07.201Z",
"last_updated_date": "2019-09-25T13:18:24.392Z",
"headlines": {
"basic": "Guide Edit 2"
}
},
"created_at": "2019-09-25T12:26:07.201Z",
"updated_at": "2019-09-25T13:18:24.392Z",
"type": "DRAFT"
},
{
"id": "YXGISUDDR5DAZKJV34YYTVVTAM",
"document_id": "IXMKZP5SPVHKTJVGFF6FEGJECQ",
"ans": {
"type": "story",
"created_date": "2019-09-25T12:26:07.201Z",
"last_updated_date": "2019-09-25T13:23:20.940Z",
"headlines": {
"basic": "Guide Edit 2"
}
},
"created_at": "2019-09-25T12:26:07.201Z",
"updated_at": "2019-09-25T13:23:20.94Z",
"type": "PUBLISHED"
},
{
"id": "V7XV2QVWDFEMZGFKBJVIOYQIME",
"document_id": "IXMKZP5SPVHKTJVGFF6FEGJECQ",
"ans": {
"type": "story",
"created_date": "2019-09-25T12:26:07.201Z",
"last_updated_date": "2019-09-25T13:23:21.025Z",
"headlines": {
"basic": "Guide Edit 2"
}
},
"created_at": "2019-09-25T12:26:07.201Z",
"updated_at": "2019-09-25T13:23:21.025Z",
"type": "DRAFT"
}
]
}

The revision summaries returned are sorted in ascending order by updated_at. Draft revisions have a type value of DRAFT and published revisions have a type value of PUBLISHED.

At the end of Step 2, we saw that the current draft revision id is V7XV2QVWDFEMZGFKBJVIOYQIME and the current published revision id is YXGISUDDR5DAZKJV34YYTVVTAM. Notice that the last two items in the revision list are the current draft and published revisions.

The previously published revision can be found by walking up the revision list until we find the next revision where type = PUBLISHED. Did you find revision with id = 3AKU4S7A6VCO5A44CEAJOLWVQ4 as the previous published revision? Notice that 3AKU4S7A6VCO5A44CEAJOLWVQ4’s headlines.basic is Guide Title.

Now that we have the previous published revision’s ID, let’s restore it. First, we will need to retrieve the full revision.

Terminal window
curl --request GET \
--header 'Authorization: Bearer <TOKEN>' \
--url https://api.{{org}}.arcpublishing.com/draft/v1/story/IXMKZP5SPVHKTJVGFF6FEGJECQ/revision/3AKU4S7A6VCO5A44CEAJOLWVQ4

API response:

{
"id": "3AKU4S7A6VCO5A44CEAJOLWVQ4",
"document_id": "IXMKZP5SPVHKTJVGFF6FEGJECQ",
"ans": {
"type": "story",
"version": "0.10.2",
"canonical_website": "testing",
"created_date": "2019-09-25T12:26:07.201Z",
"display_date": "2019-09-25T12:36:51.278Z",
"publish_date": "2019-09-25T12:36:51.278Z",
"first_publish_date": "2019-09-25T12:36:51.278Z",
"last_updated_date": "2019-09-25T12:49:15.670Z",
"headlines": {
"basic": "Guide Title"
},
"owner": {
"id": "testing"
}
},
"created_at": "2019-09-25T12:26:07.201Z",
"updated_at": "2019-09-25T12:49:15.67Z",
"type": "PUBLISHED"
}

Next, let’s save the revision as the document’s draft revision.

curl --request PUT \
--header 'Authorization: Bearer <TOKEN>' \
--url https://api.{{org}}.arcpublishing.com/draft/v1/story/IXMKZP5SPVHKTJVGFF6FEGJECQ/revision/draft \
--data '{
"ans": {
"_id": "IXMKZP5SPVHKTJVGFF6FEGJECQ",
"type": "story",
"version": "0.10.2",
"canonical_website": "testing",
"created_date": "2019-09-25T12:26:07.201Z",
"display_date": "2019-09-25T12:36:51.278Z",
"publish_date": "2019-09-25T12:36:51.278Z",
"first_publish_date": "2019-09-25T12:36:51.278Z",
"last_updated_date": "2019-09-25T12:49:15.670Z",
"headlines": {
"basic": "Guide Title"
},
"owner": {
"id": "testing"
}
}
}'

API response:

{
"id": "2J6G5YP5OFF5VAQMFJJTV7V2MQ",
"document_id": "IXMKZP5SPVHKTJVGFF6FEGJECQ",
"ans": {
"type": "story",
"version": "0.10.2",
"canonical_website": "testing",
"created_date": "2019-09-25T12:26:07.201Z",
"display_date": "2019-09-25T12:36:51.278Z",
"publish_date": "2019-09-25T12:36:51.278Z",
"first_publish_date": "2019-09-25T12:36:51.278Z",
"last_updated_date": "2019-09-25T14:18:40.310Z",
"headlines": {
"basic": "Guide Title"
},
"owner": {
"id": "testing"
}
},
"created_at": "2019-09-25T12:26:07.201Z",
"updated_at": "2019-09-25T14:18:40.31Z",
"type": "DRAFT"
}

Next, let’s publish the document.

Terminal window
curl --request POST \
--header 'Authorization: Bearer <TOKEN>' \
--url https://api.{{org}}.arcpublishing.com/draft/v1/story/IXMKZP5SPVHKTJVGFF6FEGJECQ/revision/published

API response:

{
"id": "GR4YBSWBZNDMNO354LCLR7CAX4",
"document_id": "IXMKZP5SPVHKTJVGFF6FEGJECQ",
"ans": {
"type": "story",
"version": "0.10.2",
"canonical_website": "testing",
"created_date": "2019-09-25T12:26:07.201Z",
"display_date": "2019-09-25T12:36:51.278Z",
"publish_date": "2019-09-25T14:20:28.014Z",
"first_publish_date": "2019-09-25T12:36:51.278Z",
"last_updated_date": "2019-09-25T14:20:27.910Z",
"headlines": {
"basic": "Guide Title"
},
"owner": {
"id": "testing"
}
},
"created_at": "2019-09-25T12:26:07.201Z",
"updated_at": "2019-09-25T14:20:27.91Z",
"type": "PUBLISHED"
}

Finally, let’s retrieve the document and validate the published revision has changed.

Terminal window
curl --request GET \
--header 'Authorization: Bearer <TOKEN>' \
--url https://api.{{org}}.arcpublishing.com/draft/v1/story/IXMKZP5SPVHKTJVGFF6FEGJECQ

API response:

{
"id": "IXMKZP5SPVHKTJVGFF6FEGJECQ",
"draft_revision_id": "AGWF2OWUEBFDNLBK56MT7ZC5OU",
"published_revision_id": "GR4YBSWBZNDMNO354LCLR7CAX4",
"first_published_at": "2019-09-25T12:36:51.278Z",
"last_published_at": "2019-09-25T14:20:28.014Z",
"created_at": "2019-09-25T12:26:07.201Z",
"updated_at": "2019-09-25T14:20:27.968Z",
"type": "STORY"
}

Notice that the published_revision_id points to the revision returned when we published the document. We have successfully restored the previously published revision.