API Reference

Important Things to Know

Before making a call to Primal API, here are some helpful things to keep in mind:

  1. Any call to the API requires you provide your Primal username and password as part of the Basic HTTP Authentication headers in your call.
  2. Any call to the API also requires that you provide the following header values to identify the particular application you are making the call on behalf of:
    • Primal-App-ID – Your Primal application’s ID.
    • Primal-App-Key – Your Primal application’s key value.

Managing Interest Graphs

Add topics to an interest graph

Once a topic is added, Primal extends the topic with semantic terms to create an interest graph and collects interesting content on the topic.

POST https://api.primal.com/v1/topics
Content-Type application/json
Sample body {
“uris” : [
“technology”,
“design/wearable tech”
] }
Sample Response [
{
“id”: “/topics/design/wearable%20tech”,
“skos:prefLabel”: “wearable tech”
},
{
“id”: “/topics/technology”,
“skos:prefLabel”: “technology”
}
]

Get a list of topics in an interest graph

GET https://api.primal.com/v1/topics
Sample Response {
“topics”: [
{
“id”: “/topics/design”,
“skos:prefLabel”: “design”
},
{
“id”: “/topics/design/wearable+tech”,
“skos:prefLabel”: “wearable tech”
},
{
“id”: “/topics/technology”,
“skos:prefLabel”: “technology”
}
] }

Delete a topic from an interest graph

Note that topics are organized in a hierarchical manner, where deleting a higher level topic will also delete all of its sub-topics. For example, DELETE /topics/design will delete /topics/design and/topics/design/wearable+tech.

DELETE https://api.primal.com/v1/topics/{topic}
Sample Response 200 OK

Getting Content

You can control the output format of any content retrieval call by setting the “Accept” header to one of the following values:

  • application/rss+xml – Return the output in RSS 2.0 format (default)
  • application/json – Return the output in JSON format.

Get an overview of trending content

GET https://api.primal.com/v1/content?{params}
Sample Response
(JSON)
{
“content”: [
{
“dc:source”: “http://primal.com”,
“primal:embeddedVideo”: null,
“primal:contentScore”: 0.611,
“dc:identifier”: “http://content.primal.com/~learn?url=http%3A%2F%2Ffeedproxy.google.com%2F%7Er%2FMashable%2F%7E3%2F0ZJYzlxIA%2F&lid=en-sMgKOQQXzsXWagkwQxQyQHVIjLpCTSzDLOfO4Gonm19xU8sOZ_DLExCzD-JH3vv3sudnlUWl1PHw%3D%3D”,
“dc:type”: “NewsArticle”,
“dc:abstract”: “Social-sharing company Klout has been acquired by Lithium Technologies …”,
“dc:title”: “Klout Snapped Up by Lithium Technologies”,
“primal:altImage”: null,
“primal:thumbnail”: null,
“dc:relation”: “http://feedproxy.google.com/~r/Mashable/~3/0ZJYzlxIAcc/”,
“primal:fromQuery”: “technology”,
“primal:sourceOrder”: “1.149”,
“dc:date”: “March 27, 2014 12:25:42 PM EDT”,
“dc:memberOf”: “primal/Web”,
“primal:ExtendedProperty”: {},
“dc:publisher”: “feeds.feedburner.com”,
“dc:description”: “Social-sharing company Klout has been acquired by Lithium Technologies. Read more … More about Acquisitions, Klout, Business, and Apps Software”,
“dc:subject”: [
“/content/technology”,
“/content/technology/startup”,
“/content/technology/klout”,
“/content/technology/lithium+technologies”
] }
] }
Sample Response
(RSS)
<?xml version=”1.0″ encoding=”utf-8″?>
<rss xmlns:content=”http://purl.org/rss/1.0/modules/content/” version=”2.0″ xmlns:media=”http://search.yahoo.com/mrss/”>
<channel>
<title>Your latest content recommendations from Primal</title>
<link>http://content.primal.com?lid=en-sMgKOXzsXWagkwQxaaRnCteLa7Q2viXn0qI8-8%3D</link>
<description>Primal aggregates online content from the Web and targets it to your specific topics of interest.</description>
<language>en-us</language>
<copyright>Copyright 2014, Primal Fusion Inc.</copyright>
<webMaster>support@primal.com (Primal Support)</webMaster>
<lastBuildDate>Thu, 27 Mar 2014 17:26:24 GMT</lastBuildDate>
<docs>http://www.rssboard.org/rss-specification</docs>
<ttl>0</ttl>
<image>
<url>http://about.primal.com/images/icons/primal.png</url>
<title>Primal</title>
<link>http://corp.primal.com</link>
</image>
<item>
<title>Klout Snapped Up by Lithium Technologies</title>
<link>http://content.primal.com/~learn?url=http%3A%2F%2Ffeedproxy.google.com%2F%7Er%2FMashable%2F%7E3%2F0ZJYzlxIAcc%2F&lid=en-sMgKOQQXzsXWagkwQxQyQHVIjLpCTSzPntxJnzDLOfO4Gonm19xU8sOZ_DLExCzD-JH3vv3sudnlUWl1PHw%3D%3D</link>
<description>Social-sharing company Klout has been acquired by Lithium Technologies …</description>
<content:encoded>
<![CDATA[
<p>Social-sharing company Klout has been acquired by Lithium Technologies …</p>
]]>
</content:encoded>
<category domain=”https://api.primal.com/v1/content/technology?lid=en-sMgKOXzsXWagkwQxaaRnCteLa7Q2viXn0qI8-8%3D”>technology</category>
<category domain=”https://api.primal.com/v1/content/technology/startup?lid=en-sMgKOXzsXWagkwQxaaRnCteLa7Q2viXn0qI8-8%3D”>startup</category>
<category domain=”https://api.primal.com/v1/content/technology/klout?lid=en-sMgKOXzsXWagkwQxaaRnCteLa7Q2viXn0qI8-8%3D”>klout</category>
<category domain=”https://api.primal.com/v1/content/technology/lithium+technologies?lid=en-sMgKOXzsXWagkwQxaaRnCteLa7Q2viXn0qI8-8%3D”>lithium technologies</category>
<guid isPermaLink=”true”>http://feedproxy.google.com/~r/Mashable/~3/0ZJYzlxIAcc/</guid>
<pubDate>Thu, 27 Mar 2014 16:25:42 GMT</pubDate>
<source url=”http://corp.primal.com”>Primal</source>
</item>
</channel>
</rss>
Optional URL Parameters
Name Description
primal:contentScore:min Set the minimum score value for content to be returned. Valid values range from 0.0 to 1.0 (e.g. 0.8).

If you do not set this value, Primal uses 0.6 as a default.

Note that you cannot provide both a primal:contentScore:min andprimal:contentScore:max in the same call.

primal:contentScore:max Set the maximum score value for content to be returned. Valid values range from 0.0 to 1.0 (e.g. 0.4).

If you do not set this value, Primal uses 0.6 as a default.

Note that you cannot provide both a primal:contentScore:min andprimal:contentScore:max in the same call.

primal:contentCount:max Specify the maximum number of content items in the result set.
dc:memberOf Specify if you want to return content from a specific source collection. For Primal sources, use “primal/{SourceName}”. For your own custom sources, use “user/{SourceName}”.

Get content about a specific topic

GET https://api.primal.com/v1/content/{topic}?{params}
Sample Response Same as the overview call shown above, however it will only include content annotated with {topic}.
Optional URL Parameters
Name Description
primal:contentScore:min Set the minimum score value for content to be returned. Valid values range from 0.0 to 1.0 (e.g. 0.8).

If you do not set this value, Primal uses 0.6 as a default.

Note that you cannot provide both a primal:contentScore:min andprimal:contentScore:max in the same call.

primal:contentScore:max Set the maximum score value for content to be returned. Valid values range from 0.0 to 1.0 (e.g. 0.4).

If you do not set this value, Primal uses 0.6 as a default.

Note that you cannot provide both a primal:contentScore:min andprimal:contentScore:max in the same call.

primal:contentCount:max Specify the maximum number of content items in the result set.
dc:memberOf Specify if you want to return content from a specific source collection. For Primal sources, use “primal/{SourceName}”. For your own custom sources, use “user/{SourceName}”.

Advanced: Managing Users

Important: Primal’s User Management functions are only available to enterprise customers. If you would like access to this functionality, please contact us to make the necessary arrangements.

Create a user

Use this call to create a new user associated with your Primal account. Users created in this manner are not full-fledged Primal user accounts. They are delegates to your own account, and as such, any activity that utilizes this user’s interests will be billed against your own account limits and quotas.

A successful response to this call will return you the username that you need to refer to this new user as. It is a combination of your Primal username, and the username requested in the call. In order to make calls to Primal as this new user, you simply replace your own credentials in the HTTP Basic Auth headers with the username provided in the call result and the password you provided.

Note: The user’s password is subject to Primal’s password complexity rules. It must be at least 6 characters long.

POST https://api.primal.com/v1/users
Content-Type application/json
Sample body {
“name”: “newUser”,
“password”: “password”
}
Sample 201 Response {
“id”: “/users/myUser%21newUser”,
“name”: “myUser!newUser”,
“lid”: “abcd1234″
}

Get a list of users

This call will return you a list of all of the users associated with your Primal account, in JSON format.

GET https://api.primal.com/v1/users
Sample 200 Response {
“users”: [
{
“id”: “/users/myUser%21user1″,
“name”: “myUser!user1″,
“lid”: “abcd1234″
},
{
“id”: “/users/myUser%21user2″,
“name”: “myUser!user2″,
“lid”: “wxyz9876″
}
] }

Delete a user

Use this call to delete a user and his/her associated interest data. Note that this information cannot be recovered!

DELETE https://api.primal.com/v1/users/{name}

Change a user’s password

This call will allow you to set the password to a particular value for one of the users associated with your Primal account.

POST https://api.primal.com/v1/users/{name}
Content-Type application/json
Sample body {
“password”: “newPassword”
}

Advanced: Managing Content Sources

Get a list of all available sources

Most popular Primal sources that anyone has access to:

  • /sources/primal/News: A collection of high quality news and blog sources.
  • /sources/primal/Images: A collection of image sources.
  • /sources/primal/Videos: A collection of video sources.
GET https://api.primal.com/v1/sources
Sample response {
“user”: [
{
“id”: “/sources/user/MyDefault”,
“name”: “MyDefault”,
“default”: true,
“contents”: {
“urls”: [],
“sources”: [
{
“name”: “News”,
“description”: “A collection of news sources.”,
“id”: “/sources/primal/News”,
“time”: “1week”,
“type”: “General”
},

] }
}
],
“primal”: [
{
“name”: “Food”,
“description”: “”,
“contents”: {
“urls”: [
{ “url”: “http://rss.allrecipes.com/2/3.xml”},
{ “url”: “http://eatingwell.com/rss/tonight.php” },

],
“sources”: [] },
“id”: “/sources/primal/Food”,
“type”: “Specific”
}
] }

You can also access more specific resources by targeting them in the URL in a RESTful manner, for example:

List all Primal sources

GET https://api.primal.com/v1/sources/primal

List all custom user sources

GET https://api.primal.com/v1/sources/user

Get a specific Primal source

GET https://api.primal.com/v1/sources/primal/{Source Name}

Get a specific custom user source

GET https://api.primal.com/v1/sources/user/{Source Name}

Create a custom content source

There are two methods available to define a custom set of content sources for Primal to work with.

Primarily, you can specify the target sources using the JSON format explained below.

Alternatively, you can create a new custom content source by importing an OPML file that outlines a collection of feeds. Using an OPML file requires a PUT command with a slightly different format than the JSON-based POST described below. Content sources created in this manner can not be created as a ‘default’ content source. In order to make a collection that originated from an OPML import act as the ‘default’ content source, you will need to make a second call to explicitly set the new source as the default.

POST https://api.primal.com/v1/sources/user
Content-Type application/json
Sample body {
“name”: “My Technology Collection”,
“default”: false,
“contents”: {
“urls”: [
{“url”: “http://www.cnn.com”},
{“url”: “http://rss.cnn.com/rss/cnn_topstories.rss”}
],
“sources”: [
{“id”: “/sources/primal/News”}
] }
}
Sample 201 response {
“id”: “/sources/user/My%20Technology%20Collection”
}

– or –

PUT https://api.primal.com/v1/sources/user/{Source Name}/contents
Content-Type text/x-opml
Sample Body <?xml version=”1.0″ encoding=”UTF-8″?>
<opml version=”1.0″>
<head>
<title>Sample RSS subscriptions</title>
</head>
<body>
<outline text=”News” title=”News”>
<outline type=”rss” text=”CNN” title=”CNN” xmlUrl=”http://rss.cnn.com/rss/cnn_topstories.rss” htmlUrl=”http://www.cnn.com/index.html?eref=rss_topstories”/>
<outline type=”rss” text=”ABC News” title=”ABC News” xmlUrl=”http://feeds.abcnews.com/abcnews/topstories” htmlUrl=”http://abcnews.go.com/”/>
</outline>
<outline type=”rss” text=”National Geographic” title=”National Geographic” xmlUrl=”http://www.nationalgeographic.com/rss/photography/photo-of-the-day” htmlUrl=”http://photography.nationalgeographic.com/photography/photo-of-the-day/”/>
<outline type=”rss” text=”Hack a Day” title=”Hack a Day” xmlUrl=”http://www.hackaday.com/rss.xml” htmlUrl=”http://hackaday.com”/>
</body>
</opml>

Note: If your OPML file contains a nested hierarchy of feeds, Primal will collapse the hierarchy to two levels of depth.

Append to a custom content source

You can add content sources to a pre-existing custom source using either the JSON or OPML call formats described below:

POST https://api.primal.com/v1/sources/user/{Source Name}/contents
Content-Type application/json
Sample body {
“urls”: [
{“url”: “http://www.cnn.com”},
{“url”: “http://rss.cnn.com/rss/cnn_topstories.rss”}
],
“sources”: [
{“id”: “/sources/primal/Images”}
] }

– or –

POST https://api.primal.com/v1/sources/user/{Source Name}/contents
Content-Type text/x-opml
Sample Body <?xml version=”1.0″ encoding=”UTF-8″?>
<opml version=”1.0″>
<head>
<title>Additional RSS subscriptions</title>
</head>
<body>
<outline type=”rss” text=”Another Site” title=”Another Site” xmlUrl=”http://www.another-interesting-site.com” htmlUrl=”http://www.another-interesting-site.com”/>
<outline type=”rss” text=”More Good Stuff” title=”More Good Stuff” xmlUrl=”http://www.more-good-stuff.com” htmlUrl=”http://www.more-good-stuff.com”/>
</body>
</opml>

Overwrite a custom content source

You can redefine the contents of a custom source using either the JSON or OPML call formats described below:

PUT https://api.primal.com/v1/sources/user/{Source Name}
Content-Type application/json
Sample body {
“name”: “My Technology Collection”,
“default”: false,
“contents”: {
“urls”: [
{“url”: “http://www.cnn.com”},
{“url”: “http://rss.cnn.com/rss/cnn_topstories.rss”}
],
“sources”: [
{“id”: “/sources/primal/Images”}
] }
}

– or –

PUT https://api.primal.com/v1/sources/user/{Source Name}/contents
Content-Type text/x-opml
Sample Body <?xml version=”1.0″ encoding=”UTF-8″?>
<opml version=”1.0″>
<head>
<title>Sample RSS subscriptions</title>
</head>
<body>
<outline text=”News” title=”News”>
<outline type=”rss” text=”CNN” title=”CNN” xmlUrl=”http://rss.cnn.com/rss/cnn_topstories.rss” htmlUrl=”http://www.cnn.com/index.html?eref=rss_topstories”/>
<outline type=”rss” text=”ABC News” title=”ABC News” xmlUrl=”http://feeds.abcnews.com/abcnews/topstories” htmlUrl=”http://abcnews.go.com/”/>
</outline>
<outline type=”rss” text=”National Geographic” title=”National Geographic” xmlUrl=”http://www.nationalgeographic.com/rss/photography/photo-of-the-day” htmlUrl=”http://photography.nationalgeographic.com/photography/photo-of-the-day/”/>
<outline type=”rss” text=”Hack a Day” title=”Hack a Day” xmlUrl=”http://www.hackaday.com/rss.xml” htmlUrl=”http://hackaday.com”/>
</body>
</opml>

Make a custom user source your default source

POST https://api.primal.com/v1/sources/user/{Source Name}
Sample body {
“default”: true
}

Delete a custom source

DELETE https://api.primal.com/v1/sources/user/{Source Name}

HTTP Status Codes

Here are the HTTP Status Codes that can return in response to any of these requests.

Status Code Description
200 Successful call (GET and DELETE)
201 Resources successfully created (POST and PUT)
400 Bad request. The syntax of your request was invalid.
401 Application is not authorized to access the user’s account.
404 The specified source doesn’t exist.
405 The method used (e.g., GET, POST, DELETE, etc.) is not supported by the targeted URI path. The response will also include an Allow header listing the supported methods for the path.
409 The action requested could not be completed. The response will also include a reason. These errors are correctable by the connecting user.

Example: Trying to create a new sub user when your enterprise plan has no more room.

429 Application has been throttled because it has reached its current requests limit.
500 Internal server error. An unexpected problem has occured.
501 Feature not supported.

HTTP Response Headers

Here are the custom HTTP response headers that will be returned on your requests. The headers vary based on the user’s service plan, as well as by the type of user account (whether individual or enterprise).

Note that ratelimit headers only appear if the user’s service plan imposes limits. If there are no limits, the headers will not be present. Also a value of “N/A” will be given in place of real values should issues arise trying to load the user’s service plan.

All Users

These headers will appear regardless of the type of user account, whether individual or enterprise.

Sample Headers “user-state”: “enabled”
“ratelimit-hits-reset”: “minute”
“ratelimit-hits-limit”: “30”
“ratelimit-hits-remaining”: “10”
Name Description
ratelimit-hits-reset The frequency at which your hits-usage is reset.
ratelimit-hits-limit The maximum number of requests your service plan allows within the defined period.
ratelimit-hits-remaining The number of requests remaining within the defined period. Once this limit hits zero, you will get a 429 and will no longer be able to make requests to the service until it resets.
user-state The current state of the user, as on of disabled, enabled or re-enabled. If the user is disabled they cannot make any requests to the system.

The unique state of re-enabled is only applicable to enterprise users utilizing Primal’s auto-billing system.

Individual Users

These headers will appear to any user account, except enterprise user accounts.

Sample Headers “ratelimit-budget-reset”: “month”
“ratelimit-budget-limit”: “1950”
“ratelimit-budget-remaining”: “940”
Name Description
ratelimit-budget-reset The frequency under which your data usage is reset.
ratelimit-budget-limit The maximum data usage your service plan allows within the defined period. Data usage is consumed by the system whenever it needs to obtain new content or semantic data.
ratelimit-budget-remaining The amount of data usage remaining. Once this hits zero, you can still access all the data that Primal has already obtained for you but will not receive any new data until additional budget becomes available.

You can obtain more budget by upgrading your service plan or by waiting until your usage resets.