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.
Inter-document links
"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 section 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 stringabc
(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 common question: Where do assets for a story come from?
**You’ll notice the example we just went through has no mention of images, video or anything embellishing the story. Where do those pieces of content come from in CDS?
Documents in CDS can contain a variety of assets, all found within the assets
array as defined in the publishable profile. assets
will have within itself an array of key-value pairs. The key
will be an Asset ID
that you generate. The value
is the JSON representing the asset as it conforms to the selected profile type (e.g. audio).
What is the protocol for an asset ID? The only protocol is that the asset ID must be unique within your CDS document. It does not have to universally unique; all the links for your assets will be internal links meaning we’re only pointing to another location within the current JSON and not within all of CDS. So how to make an asset ID? You can enumerate integers, you can attach a prefix of e.g. audio
for audio assets and a an enumerated digit or GUID and so on. It’s up to you! The only rule is that you keep it unique within your document you’re publishing.
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. See our tutorial on UTC time for more help.
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.