Skip to main content

How to Circulate with Draft API and Auto-Generate the Circulation URL

The purpose of this guide is to be a walkthrough on how to auto-generate an URL for an existing document.

Requirements

This guide assumes that:

  • You have already created a document

  • The document has not been published

  • You want to circulate the document to a specific website and section

  • You want to auto-generate the URL based on a pre-configured format rule

  • You are familiar with the basic usage of the API (HTTP, Auth, etc).

If you have not used the API before, or need a refresher, refer to the Draft API documentation and Getting Started with the Draft API.

Initial concepts

On the Arc XP Platform, there are two types of content: historical content, and new content. Historical content already has a URL. New content is new, and therefore, at some point before publication, needs a URL to be generated (ie decided) for it.

The way URLs are generated is by using rules. I.e., if the content matches certain criteria, then we will generate its URL using a predefined set of rules. For example, this could be:

  • If the content is a story (as opposed to a gallery or video)

  • URL might be (space for clarity): / YEAR / MONTH / DAY - ARTICLE_TITLE /

Such rules are called formats. As described above, a format is:

  • A set of conditions (which can be empty, like a "match all")

  • A pattern describing how the URL is generated from known information (metadata and fields)

  • A priority, to ensure that more specific rules are applied first, and global rules last

Formats are specific to a particular website. If you operate in multi-site mode, you will need to define formats for each of your websites.

Checking existing format rules

You can request the list of format rules currently available for a specific website:

curl --request GET \
  --header 'Authorization: Bearer <TOKEN>' \
  --url https://api.{{org}}.arcpublishing.com/draft/v1/url-format-rule/<website_id>

Response:

{
  "rules": [
    {
      "id": "1557513374591",
      "format": "author/%lastName%_%firstName%/",
      "priority": 10,
      "criteria": {
        "type": "author"
      }
    },
    {
      "id": "default",
      "format": "%publish_date|year()%/%publish_date|month()%/%publish_date|day()%/%headlines.basic|slugify()%/",
      "priority": 100000
    }
  ]
}

Existing Document

Let's assume we have an existing document, 5YR4HVCCC5HQ5AVVRR65O7CKTM. Let's take a look at the document:

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

Response:

{
  "id": "5YR4HVCCC5HQ5AVVRR65O7CKTM",
  "draft_revision_id": "IJ7NENOG7ZDFBAV2WC4G4B2IDE",
  "created_at": "2019-09-24T19:07:21.165Z",
  "updated_at": "2019-09-24T19:07:21.165Z",
  "type": "STORY"
}

And the list of revisions:

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

Response:

{
  "revisions": [
    {
      "id": "IJ7NENOG7ZDFBAV2WC4G4B2IDE",
      "document_id": "5YR4HVCCC5HQ5AVVRR65O7CKTM",
      "ans": {
        "type": "story",
        "created_date": "2019-09-24T19:07:21.165Z",
        "last_updated_date": "2019-09-24T19:07:21.165Z",
        "headlines": {
          "basic": "A cute temporary story"
        }
      },
      "created_at": "2019-09-24T19:07:21.165Z",
      "updated_at": "2019-09-24T19:07:21.165Z",
      "type": "DRAFT"
    }
  ]
}

The only revision available for this document is of type draft. Which means that the document hasn't been published yet.

If we try to look at its current circulations:

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

Response:

{
  "circulations": []
}

We can see that the document hasn't been circulated to any websites as well.

Publishing the Document

Now that we've established that the document is new, and it hasn't been published or circulated yet, we proceed to publish it. Let's go ahead:

curl --request POST \
  --header 'Authorization: Bearer <TOKEN>' \
  --header 'Content-Type: application/json' \
  --url https://api.{{org}}.arcpublishing.com/draft/v1/story/5YR4HVCCC5HQ5AVVRR65O7CKTM/revision/published

Response:

{
  "id": "IMVXHY5G7NAHVFV2WJ3AMKSDSU",
  "document_id": "5YR4HVCCC5HQ5AVVRR65O7CKTM",
  "ans": {
    "additional_properties": {
      "has_published_copy": false
    },
    "created_date": "2019-09-24T19:07:21.165Z",
    "display_date": "2019-09-24T19:11:24.975Z",
    "first_publish_date": "2019-09-24T19:11:24.975Z",
    "headlines": {
      "basic": "A cute temporary story"
    },
    "last_updated_date": "2019-09-24T19:11:24.869Z",
    "publish_date": "2019-09-24T19:11:24.975Z",
    "type": "story",
    "version": "0.10.2",
    "canonical_website": "testing"
  },
  "created_at": "2019-09-24T19:07:21.165Z",
  "updated_at": "2019-09-24T19:11:24.869Z",
  "type": "PUBLISHED"
}

Let's look at the document revisions now:

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

Response:

{
  "revisions": [
    {
      "id": "IJ7NENOG7ZDFBAV2WC4G4B2IDE",
      "document_id": "5YR4HVCCC5HQ5AVVRR65O7CKTM",
      "ans": {
        "type": "story",
        "created_date": "2019-09-24T19:07:21.165Z",
        "last_updated_date": "2019-09-24T19:07:21.165Z",
        "headlines": {
          "basic": "A cute temporary story"
        }
      },
      "created_at": "2019-09-24T19:07:21.165Z",
      "updated_at": "2019-09-24T19:07:21.165Z",
      "type": "DRAFT"
    },
    {
      "id": "IMVXHY5G7NAHVFV2WJ3AMKSDSU",
      "document_id": "5YR4HVCCC5HQ5AVVRR65O7CKTM",
      "ans": {
        "type": "story",
        "created_date": "2019-09-24T19:07:21.165Z",
        "last_updated_date": "2019-09-24T19:11:24.869Z",
        "headlines": {
          "basic": "A cute temporary story"
        }
      },
      "created_at": "2019-09-24T19:07:21.165Z",
      "updated_at": "2019-09-24T19:11:24.869Z",
      "type": "PUBLISHED"
    },
    {
      "id": "OLIM6EYJW5DYND3ZMVLZNNQWBQ",
      "document_id": "5YR4HVCCC5HQ5AVVRR65O7CKTM",
      "ans": {
        "type": "story",
        "created_date": "2019-09-24T19:07:21.165Z",
        "last_updated_date": "2019-09-24T19:11:24.931Z",
        "headlines": {
          "basic": "A cute temporary story"
        }
      },
      "created_at": "2019-09-24T19:07:21.165Z",
      "updated_at": "2019-09-24T19:11:24.931Z",
      "type": "DRAFT"
    }
  ]
}

Publishing the document did the following:

  • It created a copy of the current draft revision (IJ7NENOG7ZDFBAV2WC4G4B2IDE -> IMVXHY5G7NAHVFV2WJ3AMKSDSU)

  • It published the newly created revision (IMVXHY5G7NAHVFV2WJ3AMKSDSU)

  • It made a copy of the published revision and set it as the new draft revision (OLIM6EYJW5DYND3ZMVLZNNQWBQ)

It's important to know that a published revision can't be yet accessed by readers until it has been circulated, which we will do in the next step.

Circulating the Document

To make a document available on a website, after publishing it, will require to circulate it. On each website, a document can belong to one or more sections. Whether the document belongs to one, two, or many sections, there is usually a section that is considered "primary". This section is the "home", so to speak, of the document. It is also usually reflected in the URL of the document. Additional sections increase reach and readership. With that in mind, let's add the circulation:

curl --request PUT \
  --header 'Authorization: Bearer <TOKEN>' \
  --header 'Content-Type: application/json' \
  --url https://api.{{org}}.arcpublishing.com/draft/v1/story/5YR4HVCCC5HQ5AVVRR65O7CKTM/circulation/<website_id> \
  --data '{
    "document_id": "5YR4HVCCC5HQ5AVVRR65O7CKTM",
    "website_id": "<website_id>",
    "website_primary_section": {
      "type": "reference",
      "referent": {
        "id": "/news",
        "type": "section",
        "website": "<website_id>"
      }
    },
    "website_sections": [
      {
        "type": "reference",
        "referent": {
          "id": "/news",
          "type": "section",
          "website": "<website_id>"
        }
      }
    ]
  }'

Response:

{
  "document_id": "5YR4HVCCC5HQ5AVVRR65O7CKTM",
  "website_id": "<website_id>",
  "website_url": "/2019/09/24/a-cute-temporary-story/",
  "website_primary_section": {
    "type": "reference",
    "referent": {
      "type": "section",
      "id": "/news",
      "website": "<website_id>"
    }
  },
  "website_sections": [
    {
      "type": "reference",
      "referent": {
        "type": "section",
        "id": "/news",
        "website": "<website_id>"
      }
    }
  ]
}

Looking at the response, we can see that the document has been correctly circulated, and the URL has been automatically generated following the related format rule.

Our document was of type STORY, and looking at all the available format rules, the matching one with the highest priority was:

{
  "_id": "default",
  "format": "%publish_date|year()%/%publish_date|month()%/%publish_date|day()%/%headlines.basic|slugify()%/",
  "priority": 100000
}

"Dynamic" information is enclosed within % characters. So, for example, %publish_date|year()% is one single token.

If we break the above format up, we get:

FIELD

TRANSFORMATION

VALUE

publish_date

year()

2019

publish_date

month()

09

publish_date

day()

24

headlines.basic

slugify()

a-cute-temporary-story

Putting it all together, we have: "/2019/09/24/a-cute-temporary-story/"

If we look again at the document circulations:

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

Response:

{
  "circulations": [
    {
      "document_id": "5YR4HVCCC5HQ5AVVRR65O7CKTM",
      "website_id": "<website_id>",
      "website_url": "/2019/09/24/a-cute-temporary-story/",
      "website_primary_section": {
        "type": "reference",
        "referent": {
          "type": "section",
          "id": "/news",
          "website": "<website_id>"
        }
      },
      "website_sections": [
        {
          "type": "reference",
          "referent": {
            "type": "section",
            "id": "/news",
            "website": "<website_id>"
          }
        }
      ]
    }
  ]
}

The document is now published and circulated, ready to be viewed by your readers.

Keep in mind that an URL will be automatically generated for the specific document by applying to the document ANS the highest priority rule for the type of document. To perform an auto-generation of the URL, the circulation object given in input to the endpoint should not have set the field website_url. Having that field set will try to assign the declared URL to the document, returning a failure message in case of collisions.

Note

Don’t forget the trailing slash on all urls.