Getting started

New to CDS? Get started here with this guide before moving on to the API Reference.

Authorization & Permissions

Clients in CDS have permissions based around their Authorization Token; this means the actions a client is authorized to take is tied to their token. Clients should only ever use their token for accessing CDS and tokens should be used with one client only. If you have another client you’d like to interact with CDS, let us know and we’ll supply an additional token! If your client needs additional permissions such as additional authorizedOrgServiceIds, please reach out to Member Partnership!

If your client is intending to publish content to CDS, we will also provide a document ID prefix to use. For more information on document ID prefixes, see below.

Requesting a Key

If you are a Member Station and need a CDS key, reach out to Member Partnership.

Read Permissions

By default, all Authorized clients have read access to all CDS data. As long as a client is using a valid Authorization Token, there is no technical restrictions on which client can retrieve which data. However, there are guidelines to follow for premium content. Please read this premium content guide and refer to the CDS API Terms of Use for information on how to handle premium content.

Write Permissions

The documents a client can create/modify/delete in CDS are determined with the following rules:

1. Document Prefix

Every CDS client is assigned a string as its “document ID prefix”. All documents created by this client MUST have IDs that begin with this prefix.

As an example, if your client has the document ID prefix tst, some possible valid IDs would be:

tst-1234       
tst-my-document
tst-tst-tst

Some invalid IDs would be:

1234
1234-tst
my-document-tst-1234

In addition to creation, clients are able to modify and delete any document with an ID matching their document ID prefix. That is to say, clients are able to modify and delete any document they’ve created!

2. authorizedOrgServiceIds

If a document does not have an ID prefix matching the client’s, that client can still modify or delete it if it has a matching authorizedOrgServiceIds entry.

Every CDS document has an attribute called authorizedOrgServiceIds; this attribute is defined in the document profile. This attribute is an array containing a list of Organization Service Service IDs; for an in-depth explanation of these IDs, see the Organization Service documentation. An example of this array is below:

"authorizedOrgServiceIds": [
  "s1",
  "s150"
]

Clients also have a list of authorized Organization Service IDs. When a client tries to modify or delete a document that has a non-matching prefix, CDS will compare the client’s authorized IDs against the document’s authorizedOrgServiceIds array. If there is a matching entry, the client is authorized. If there is no matching entry, the client’s action will be rejected and CDS will return a 403.

By default, clients have an empty set of authorized Organization Service IDs, meaning they can only modify and delete documents they have created. In order to add an ID to your client’s list, email Member Partnership!

Using an Authorization Token

When interacting with an endpoint of CDS that requires Authorization, the Authorization Token must be provided as an Authorization bearer token header. An example using curl is below:

$ curl -s \
    -H 'Authorization: Bearer YOUR-TOKEN-GOES-HERE' \
    https://content.api.npr.org/v1/documents/1002

Getting started: Retrieving

Data stored in CDS is stored as “documents”. Each document is represented as a JSON payload, which can be retrieved at any time from CDS.

There are two ways to retrieve content from CDS: single-document retrieval and querying. For now, let’s retrieve a single document.

Using your Authentication Token, place a GET request to https://content.api.npr.org/v1/documents/773675421. Using curl, this request might look like the following:

$ curl -s \
  -H 'Authorization: Bearer YOUR-TOKEN-HERE' \
  https://content.api.npr.org/v1/documents/773675421

You should receive a 200 response, with a JSON document body:

{
  "resources": [
    {
      "id": "773675421",
      "profiles": [
        {
          "href": "/v1/profiles/story",
          "rels": [
            "type"
          ]
        },
...

Let’s take a look at some key parts of this document!

The anatomy of a document

Every document must contain a set of standard attributes in order to be considered “valid” when published to CDS.

Document IDs

"id": "773675421"

Every document in CDS has an ID that identifies it. CDS IDs are strings conforming to a specific set of requirements; for more on generating valid IDs, see publishing to CDS.

Profiles

"profiles": [
  {
    "href": "/v1/profiles/story",
    "rels": [
      "type"
    ]
  },
  ...

CDS profiles are sets of constraints that a CDS document must conform to in order to be ingested. Documents list their own profiles; meaning that if a document lists the story profile, then it is claiming that it conforms to the constraints set out by that profile.

At a bare minimum, all documents in CDS must list the document profile (and conform to its constraints). In order to be ingested as a standalone document, they must also list the publishable profile.

For a full list of profiles, see the Profiles page.

Assets & subdocuments

"assets": {
  "773675422": {
    "id": "773675422",
    "profiles": [
      {
        "href": "/v1/profiles/audio",
        "rels": [
          "type"
        ]
      },
...

Publishable CDS documents can contain “assets” (also called “subdocuments”). Assets themselves are documents; meaning they have IDs and profiles! As documents, they have to list the document profile.

Assets represent pieces of a document; these can be blocks of text, pieces of audio, images, or more. All are stored in the assets attribute, which is a JSON object storing each asset with its id as the key.

"collections": [
  {
    "href": "/v1/documents/1122",
    "rels": [
        "topic",
        "theme",
        "slug"
    ],
...

CDS documents can contain relative to links to other documents. These links indicate inter-document relationships. Document links are, by definition, one-way relationships (although a two-way relationship can be established by linking each document to the other).

The collections array is the most common method of establishing a relationship between documents; loosely, it indicates that one document “belongs” to another document’s collection. For more information on collections, see the collections documentation.

Organization data

"owners": [
  {
    "href": "https://organization.api.npr.org/v4/services/s1"
  }
]
"brandings": [
  {
    "href": "https://organization.api.npr.org/v4/services/s1"
  }
]

In addition to linking to other documents, CDS documents can link to organizational data; that is, a document can have a relationship with an organizational entity. These relationships are defined by the owners and brandings arrays. For information on how to use these arrays and links, see the publishable profile documentation.

This document links to Services defined via NPR’s Organization Service (“Org V4”). While CDS does not guarantee that all organizational information will be hosted by Org V4, this is the most common case. For more information on Org V4, see the public Organization Service documentation.

Getting started: Publishing


NOTE: This sectino is only applicable to clients with write-permissions to CDS. If your client does not have write permissions, this section may not be useful to you.


Publishing data to CDS is the process of serializing a document, then sending it to CDS for validation and ingestion. This involves several steps:

  • Selecting a set of profiles that the document is intended to implement
  • Assembling a document based on those profiles
  • Making a call to CDS with the document’s data

This process is the same for documents being newly created, or existing documents being re-published with updates.

Selecting profiles

The profiles present on a document determine the overall structure. Before a document can be created and ingested into CDS, a set of profiles must be selected for it. These profiles will define what attributes exist on the document itself, and what format they should take.

At minimum, all standalone documents published to CDS must list the following:

Documents may also list and implement any profile from the profiles list.

Once the set of profiles is assembled, one must be selected as the type profile. The type profile indicates to clients that this profile should be considered when determining the primary method of handling this document.

Assembling a document

This section walks through the process of assembling a document piece by piece into a full JSON payload. Obviously, this is just an example; in real life, CDS documents are generated automatically by various upstream clients. But hopefully this provides some insight into how a new client should go about assembling a document.

Our document will start as an empty JSON object:

{}

As we go through the following steps, we’ll add attributes and fields to this object until we have a full, publishable CDS document.

Step 1: ID

The first step to creating a document is to define the id field. IDs must be unique across standalone documents; if a document is published with the same ID as an existing CDS document, it’s considered an update (not a creation).

When choosing an ID, clients must conform to the following rules:

  • The ID must begin with the prefix defined for the client. For example, if my client was assigned the prefix abc, all documents my client produces must begin with the string abc (so, for example, abc-1, abc-2, etc.)
  • The ID must only contain lowercase alphanumeric characters and dashes.

Document IDs will be validated against the document ID schema; if an ID does not match this schema, it will be rejected.

{
  "id": "<your ID here>"
}

Step 2: Profiles

Each profile you’ve selected for your document must be listed as a link in the document’s profiles array. Each entry in this array will be an object with an href attribute, the value of which will be the relative link to the profile itself. So if your document is listing the story profile, it will contain the following entry in its profiles array:

{
  "href": "/v1/profiles/story"
}

The type profile should have an additional rels array with the "type" string present:

{
  "href": "/v1/profiles/story",
  "rels": [
    "type"
  ]
}

The document so far:

{
  "id": "<your ID here>",
  "profiles": [
    {
      "href": "/v1/profiles/publishable",
      "rels": [
          "interface"
      ]
    },
    {
      "href": "/v1/profiles/document"
    },
    {
      "href": "/v1/profiles/story",
      "rels": [
        "type"
      ]
    }
  ]
}

Step 3: Organizational data

In order to be searchable and brandable, the document needs to link to some organization data. Your orgnization should have a Service ID that it is assigned for these purposes; if it doesn’t, reach out to NPR Digital Media to find out what it is.

The owners and brandings arrays will contain links to your Service’s entry in the Organization Service; each of these arrays have different functions, but in this case both should contain the same entry. For more information on these arrays and their usages, see the publishable profile documentation.

Add both owners and brandings to your document. In these arrays, add an object with an href attribute, the value of which will be:

"https://organization.api.npr.org/v4/services/<your service ID>"

All together, the document will look like the following:

{
  "id": "<your ID here>",
  "profiles": [
    {
      "href": "/v1/profiles/publishable",
      "rels": [
          "interface"
      ]
    },
    {
      "href": "/v1/profiles/document"
    },
    {
      "href": "/v1/profiles/story",
      "rels": [
        "type"
      ]
    }
  ],
  "owners": [
    {
      "href": "https://organization.api.npr.org/v4/services/<your service ID>"
    }
  ],
  "brandings": [
    {
      "href": "https://organization.api.npr.org/v4/services/<your service ID>"
    }
  ]
}

Step 4: Title

The final step to assembling a document is adding a title:

{
  "id": "<your ID here>",
  "title": "<your title here>",
  "profiles": [
    {
      "href": "/v1/profiles/publishable",
      "rels": [
          "interface"
      ]
    },
    {
      "href": "/v1/profiles/document"
    },
    {
      "href": "/v1/profiles/story",
      "rels": [
        "type"
      ]
    }
  ],
  "owners": [
    {
      "href": "https://organization.api.npr.org/v4/services/<your service ID>"
    }
  ],
  "brandings": [
    {
      "href": "https://organization.api.npr.org/v4/services/<your service ID>"
    }
  ]
}

Your document is complete!

Publishing the document to CDS

Once the document is assembled, the final step is to publish it to CDS. Using your authorization token, make a PUT call to the /v1/documents/<document ID> endpoint; set the body to the document you’ve assembled.

Using curl, this call would look like:

$ curl -s \
    -X PUT \
    -H 'Authorization: Bearer <your key here>' \
    -d '@./path/to/your/document.json' \
    https://content.api.npr.org/v1/documents/<your document ID here>

If successful, this call should return a 200 status code, and a copy of the document CDS has ingested. The document itself will be cleaned and have additional metadata provided by the ingestion process.

A note on dates in CDS documents

Throughout the profiles you will see mention of date fields using the RFC3339 format. Please note that these fields also need to use UTC time in order for our analytics services and other services that use date queries to pick up your content.

Next Steps

To dive in further on CDS and get into Core Concepts, full API documentation for endpoints and to learn more about profiles, See our API Reference.


© 2024 npr