This FAQ section is for users currently using Story API NPRML
(XML
) output who need to migrate over to CDS JSON. Story API is now deprecated as of 2024. All users of Story API are currently being contacted as a reminder to migrate from using Story API queries or plugins to ones backed by CDS.
- Differences between Story API (
api.npr.org
) and CDS- What will happen to the Story API now that CDS is here?
- Is there an Allow List in CDS for IP addresses similar to the one used in Story API?
- Is there a full text attribute inside of CDS similar to “fullText” from the Story API?
- Will there be new IDs for content in CDS versus Story API?
- I’m a user who has content already in CDS that made its way there through Story API ingest. Am I able to edit or delete that content now in CDS?
- Does the CDS have a notion of a story attribution?
- Story API collections versus CDS Collections
- Common Story API queries and their CDS (Or other service) equivalent solution
- You want an RSS or MediaRSS Feed
- You want to find a specific story by ID
- You want to search for multiple specific story IDs
- You want to query for items in an aggregation
- You want to choose a specific number of results
- You want to search for only audio stories within an aggregation (e.g. A Podcast)
- You want to search for stories from a particular station (295 etc.)
- You want to filter for dates and sort by dates
- You want to find assets like images, audio, bylines etc.
- You wan tto track the News aggregation or Top Stories
Differences between Story API (api.npr.org
) and CDS
Launched as a public alpha release on June 30 2008, the Story API to this day serves content to many users, primarily stations with custom integrations. It also allows for publishing and sharing content to users.
What will happen to the Story API now that CDS is here?
The Story API is currently slated for retirement in early 2024 (As of the writing of this document). NPR has will continue to support the Story API has a read-only API after that retirement date. Those stations who want to publish content to NPR need to do so either through Grove for Stations or custom integrations that use CDS (Like the Wordpress plugin or Drupal module).
If you are a station or other user migrating from a service using the Story API to one that uses CDS, then this guide is catered for you.
Is there an Allow List in CDS for IP addresses similar to the one used in Story API?
No, there is not. Once you get an API key for CDS, you are all set!
Is there a full text attribute inside of CDS similar to “fullText” from the Story API?
In the Story API we had a notion of “Full Text” versus “normal text” attributes. In CDS we make no distinction between these types. Text will simply have all markup and formatting included.
For more tips like this about fields in Story API versus fields in CDS, see our comprehensive Story API to CDS field guide.
Will there be new IDs for content in CDS versus Story API?
For data that is published and consumed by Story API today, no. However, NPR may change IDs for new content further in the future. These new IDs would only be present in the CDS API.
I’m a user who has content already in CDS that made its way there through Story API ingest. Am I able to edit or delete that content now in CDS?
The short answer is: yes. If you have a CDS Key with an authorizedOrgServiceIds
array that contains one or more services in a documents authorizedOrgServiceIds
array, then you can edit and delete said document. For more on authentication and how that impacts your permissions in CDS, see the authorization getting started guide here.
Does the CDS have a notion of a story attribution?
Not natively like in the Story API, but the information for making your own attribution. See this guide for making your own attribution similar to Story API’s <div> element.
Story API collections versus CDS Collections
Story API had a more all-in-one approach to querying collections. If you looked up a collection for, say, Animals
ID 1132
, you only had to go to https://api.npr.org/query?id=1132&apiKey=mykey
and you would not only see data on the collection (title
, teaser
, etc) but also a <list>
object containing <story>
elements. The story
elements represented actual content inside that collection.
For CDS, we lean on using the query API to retrieve items from a collection. Fetching the collection by e.g. /v1/documents/1132
only returns information about the collection as a document and NOT anything about documents attached to that collection. While that may seem complex, it allows for the flexibility of changing a collection parent without having to change all associated children (Which was the case in the Story API).
So how do you do get items from a collection in CDS? Here’s the quick version but see our in-depth query endpoint documentation for more:
/v1/documents?collectionIds=1132&sort=publishDateTime:desc&limit=10
The above would give you the 10 most recently published stories tagged in the Animals
collection.
Common Story API queries and their CDS (Or other service) equivalent solution
This section acts as more of a quick solution (“Cookbook”) for common Story API queries converted to modern-day, CDS-backed solutions.
NOTE: All of the Story API examples below are going to show the API path instead of the fully qualified domain name and protocol. We’re also omitting the required apiKey
parameter. This is to focus on the query parameters in the examples.
You want an RSS or MediaRSS feed
Old Story API Query: /query?id=1004output=rss,mediaRss,Podcast,podcast
Suggested change: Go to https://feeds.npr.org/1004/rss.xml
. This will present you with an RSS output of the same data. 1004
is an example aggregation. To see a list of all aggregations, see The table of aggregations.
You want to find a specific story by id
Story API Query: /query?id={id}
Suggested solution: Use CDS: /v1/documents/{id}
See the documents endpoints guide for more.
You want to search for multiple specific story ids
Story API Query: /query?id=1,2
Suggested solution: Use CDS and the ids
parameter: /v1/documents?ids=1,2
For more on querying and all other parameters for querying, including ids
, see this guide.
You want to query for items in an aggregation
Story API Query: /query?id={aggId}
where aggId
is an aggregation (e.g. Topic, Series etc). This returned a list of items representing children of that agg.
Suggested solution: Using collectionIds
in CDS Searching for stories in an agg is no longer the same /query?id=
param, you must use ?collectionIds
. See this querying guide for more information. For a list of relevant CDS aggregations see this table.
You want to choose a specific number of results
Story API Query: /query?numResults={number}
Suggested solution: Use CDS and the limit
query parameter: /v1/documents?limit={number}
For more on using limit
in querying see this section of the querying guide.
You want to search for only audio stories within an aggregation (e.g. A podcast).
Story API Query: /query?id={aggId}&fields=audio
Suggested solution: Use CDS and query for specific profileIds
:
In CDS queries you can use profileIds
to ensure certain types of content are returned in the results. There is no support for a fields
type parameter as in Story API. In this case, to return content with audio in it, we use the has-audio profile which requires a document have an audio
asset.
/v1/documents?profileIds=has-audio&collectionIds=510298
Keep in mind that CDS documents can contain different types of audio. If you are looking for the “main” audio for a story, be sure to use the audio asset that is tagged primary
in the audio
array:
"audio": [
{
"href": "#/assets/5678",
"rels": ["primary", "headline"]
}
]
For more on has-audio and audio tagging see this guide.
For more on profiles, see the profiles section.
You want to search for stories from a particular station (295, etc).
Story API Query: /query?orgId={orgId}
Suggested solution: Use CDS and the ownerHrefs
query parameter:
/v1/documents?ownerHrefs=https://organization.api.npr.org/v4/services/{serviceId}
For help on finding your Service ID via your Organization ID (orgId
) use this URL:
https://organization.api.npr.org/v4/legacy/organizations/{orgId}
The returned results should have a services
array including an object with an id
value which you use as the serviceId
.
For more on querying by ownerHrefs
and other parameters see this guide.
You want to filter for dates and sort by dates
Story API Query: /query?sort=dateAsc
, query?startDate=yyyy-MM-dd
to search through a particular date
Suggested solution: Use the CDS sort
parameter with publishDateTime
:
Sorts a collection 1004
by date time descending:
/v1/documents?sort=publishDateTime:desc&collectionIds=1004
…Or ascending:
/v1/documents?sort=publishDateTime:asc&collectionIds=1004
Searching via editorial
sort (See the querying guide for more information) which places ordered content before unordered content in a collection:
/v1/documents?sort=editorial&collectionIds=1004
For more on querying by date and other methods see this guide.
You want to find assets like images, audio, bylines, etc.
Story API Query: /query?fields=titles,teasers,storyDate,byline,audio,textWithHtml,image,organization,parent,layout
In CDS, all fields are returned on a query. So there is no support for limiting or adding fields via a fields
type parameter. profileIds
can be used to ensure your query returns documents with certain properties (e.g. Images, Audio or a layout). Below we’re unioning has-audio
, renderable
and has-images
to ensure there is content returned with audio, a layout and images.
/v1/documents?collectionIds=1001&sort=editorial&limit=10&profileIds=has-images&profileIds=has-audio&profileIds=renderable
For more on profiles, see the profiles section.
Within images
and audio
arrays, there are internal-link
objects that are used to link to an asset in the CDS doc and also tag that asset with a semantic meaning. images
has a rel
enum of primary
, promo-*
labeled rels and so on. For most story content, you will likely want the promo-*
tagged image as that is meant to be the promotional image for a story.
For the audio
array, you want to follow the link for the audio asset tagged with the primary rel type in most cases.
For more on the images
array see this profile section.
For more on the audio
array see this profile section.
You want to track the News aggregation or Top Stories
Story API Query::
/query?numResults=10&id=1001&sort=assigned
Suggested solution: Query using CDS using the collectionIds=1001
parameter with editorial
sort and limit
:
/v1/documents?collectionIds=1001&limit=10&sort=editorial
For more on querying in CDS see this guide.