The Camayak Content Publishing API
Beta documentation. All specifications subject to change
Introduction
The Content API allows Camayak customers the ability to unidirectionally publish approved assignments to delivery platforms not directly supported by Camayak.
Some example use cases for the Content API:
- Publishing approved assignments as Facebook Posts
- Publishing approved assignments as Tumblr Posts
- Publishing the images included in an approved assignment to Flickr
- Send a message to a Slack channel when an assignment is published
- Publishing approved assignments to a bespoke web-delivery platform
- Publishing approved assignments to a content management system not directly supported by Camayak
The Content API consists to two parts:
- A Webhook system to inform customer systems of newly approved and retracted content by sending an HTTP POST request to a customer-specified URL.
- A Content API REST endpoint allowing customers to fetch approved (published) assignments from Camayak.
The Webhook
Webhooks are a way for an application like Camayak to notify other systems that an event has happened. Without Webooks, the other system would have to continuously poll the Camayak Content API for new assignments, which is a waste of resources and can introduce delays equal to the poll time.
Instead, by using a Webhook, the other system can be notified, within seconds, of a newly published assignment in Camayak.
Webhook events types
The Webhook provides for notification of 3 events:
- validate – a test event used to confirm that the receiving system for the Webhook is up and running, and can be contacted over the Internet.
- publish – When an assignment is approved in Camayak, this event is sent to the receiving system.
- retract – When an assignment is retracted in Camayak, this event is sent to the receiving system.
Webhook security
Since your Webhook URL is open to the internet, we highly recommend taking advantage of Camayak’s “shared secret” functionality to digitally sign the Webhook requests, as well as add an additional layer of security to the Content API endpoint. The “shared secret” is entered when you are creating the Content API platform in Camayak.
When a “shared secret” has been entered for a Content API platform, the Webhook requests generated by Camayak will be signed with a digital signature generated from your shared secret, your API key and the current time (in Epoch seconds). The signature is an HMAC-SHA1 hash.
The signature is included in the Webhook request in an HTTP header called Camayak-Signature
.
To confirm that the request is valid, generate a corresponding HMAC-SHA1 hash using the same data, and compare the values – if they match, the request is valid.
Since the request may take some time to transit the Internet, and there may be some small difference in the times on the server generating the signature, and the server validating the signature, when validating, you will have to generate a number of signatures representing times a few seconds into the future and the past. Furthermore, your validating server must be timesynced so it has the correct current time.
Sample PHP code for validating the Camayak-Signature
can be found here.
The Webhook request
The Webhook request will be sent as an HTTP POST to the URL specified when the publishing destination was configured.
The body of the HTTP POST request will be:
{ "event": "publish || retract || validate", "event_id": "35fd37f4-8c57-11e3-b4c4-425861b86ab6", "resource_uri": "https://publishing.camayak.com/v1/content/d7b6bee1-a484-4021-ba68-ff2163e9fdee" }
The event
property specifies whether this is a test event (validate), or whether the assignment is being approved for publishing (publish) or un-published and retracted (retract).
The event_id
property is a unique ID for this event. This can be useful to determine if the receiving system has already processed this event, in the possible case that the Webhook event gets re-sent by the Camayak content publishing API due to some issue communicating with the receiving system, but the receiving system did already process the event successfully.
The resource_uri
property is a URL pointing to the Camayak content publishing API, which can be used to retrieve the assignment data.
Handling Webhook events
Validate
The validate
Webhook event is sent when creating a new Content API Platform and when going to the Manage Publishing Destinations in Camayak.
No Camayak-Signature
header is sent on a validate
Webhook event, so when handling the validate
event, verification of the signature should be skipped.
The Webhook response to a validate
event should be a simple plain-text response of “pong”.
Example:
if (event === "validate") { res.send('pong', { 'Content-Type': 'text/plain' }, 200); }
if($event->event === 'validate') { header('Content-Type: text/plain'); die('pong'); }
Publish
The publish
Webhook event is sent when an assignment is first approved, and on any subsequent approval after the assignment has been updated.
Retract
The retract
Webhook event is sent when an assignment is “un-published” in Camayak. The intent of “un-publishing” and the retract
event is to remove the assignment from view.
The Webhook response
The Camayak content publishing API expects the system receiving the Webhook to respond with an HTTP 200 (technically, any 2xx-level) response code. Such a response acknowledges that the Webhook was received and successfully processed.
Any other response code will be considered a failure, and the Camayak content publishing API will continue to try to send the Webhook. Retries will have an increasing delay between attempts, and after a certain number attempts, the Camayak content publishing API will mark the event as failed and notify the editor who approved the assignment.
The Webhook POST response can contain an optional body containing information that adds significant value in Camayak, as well as in the API integration. By specifying a published_url
in the response, Camayak can show links to the published assignment. By specifying a published_id
, Camayak will return that ID in any subsequent API responses, simplifying the process of connecting assignments in Camayak with assignments in custom publishing integration.
Params:
published_id
: a unique ID used to identify the assignment outside of Camayak.published_url
: a URL for the published assignment. Used to link to the assignment from inside Camayak.published_at
: an ISO 8601 UTC date representing the date and time the assignment was published.
Example:
{ "published_id": "857673754", "published_url": "http://www.example.com/stories/857673754/", "published_at": "2014-05-19T20:53:48.359755Z" }
The Content API
Endpoint
The Camayak content publishing API consists of a single read-only endpoint:
`https://content.camayak.com/v1/content
.`
Authentication
Requests to the Content API must include your API key (created when the Content API Platform is created) in the URL as a query string named api_key
.
If you have specified a shared secret
when creating the Content API Platform, then requests must also include a generated signature in the URL as a query string named api_sig
.
Example:
https://content.camayak.com/v1/content/?api_key=<your_api_key>&api_sig=<generated_signature>
Generating a signature using the shared secret
The signature is an HMAC-SHA1 hash of the current time in Epoch seconds, your API key, and the shared secret. In pseudo-code:
data = epoch_second_as_string + api_key key = shared_secret signature = HMAC-SHA1(data,key)
Sample Javascript/Node code for generating a signature can be found here.
Sample PHP code for generating a signature can be found here in the calculate_signature
function.
Collection: GET https://publishing.camayak.com/v1/content/
Params:
published_at__gte
: Select assignments published after a date and time.published_at__lte
: Select assignments published before a date and time.retracted_at__gte
: Select assignments retracted after a date and time.retracted_at__lte
: Select assignments retracted before a date and time.updated_at__gte
: Select assignments updated after a date and time.updated_at__lte
: Select assignments updated before a date and time.
Date formats should be in ISO 8601 UTC format: YYYY-MM-DDTHH:MM:SSZ
Response:
Returns an array of assignments sorted by published_at
date, most recent first.
{ "objects": [ { "bylines": [ { "email": "ed@camayak.com", "first_name": "Edward", "last_name": "Smith", "order": 1, "override": "", "portfolio": "http://portfolios.camayak.com/edward-smith", "uuid": "8f491cfe-3879-4392-80cd-a720a52eb983" } ], "content": "<p>Sandwiched between Eastern European...</p>", "created": "2014-05-19T20:53:39.025876Z", "heading": "Zala Springs Resort, Lake Balaton, Hungary", "subheading": "", "media": [ { "caption": "A picture of Zala Springs Resort", "title": "Zala Springs", "featured": false, "type": "image/jpeg", "url": "https://cmyk-main.s3.amazonaws.com/..." }, { "caption": "", "title": "", "featured": false, "type": "image/jpeg", "url": "https://cmyk-main.s3.amazonaws.com/..." } ], "slug": "sample slug", "desk": "Blog Posts", "published_at": "2014-05-19T20:53:48.359755Z", "published_id": "86320646476", "published_url": null, "resource_uri": "/v1/content/8c4ceab0-d4a4-446b-874f-d27569c5da0f/", "retracted_at": "2014-05-21T01:26:16.378954Z", "scheduled_publication": "2014-05-19T20:53:48.359755Z", "taxonomies": { "Category": { "controlled": true, "hierarchical": true, "multivalued": true, "values": [ { "parent_id": null, "uuid": "5cf76df1-a77f-43f3-83cf-66cd5d9e66b2", "value": "Uncategorized" } ] }, "Tags": { "controlled": false, "hierarchical": false, "multivalued": true, "values": [ { "parent_id": null, "uuid": "46597eca-ff83-42b7-a585-7ea3e3bdefa0", "value": "Vacation" }, { "parent_id": null, "uuid": "8e772e26-abcc-422c-af62-e481b38bfd2d", "value": "Hungary" }, { "parent_id": null, "uuid": "ab72a386-9f0a-4a92-a022-3cf7de4d4131", "value": "Investment" } ] } }, "teaser": "", "updated": "2014-05-21T01:28:50.605182Z", "uuid": "8c4ceab0-d4a4-446b-874f-d27569c5da0f" }, {...}, {...} ], "meta": { "total_count": 20, "previous": null, "limit": 20, "offset": 0, "next": "/v1/content/?limit=20&offset=20" } }
Examples:
Return any assignments published after Oct 28, 2013 at 09:00:13 UTC:
GET https://publishing.camayak.com/v1/content/?published_at__gte=2013-10-28T09:00:13Z
Return any assignments published after Dec 1, 2013 at 00:00 UTC and before Dec 31, 2013 23:59:59 UTC:
GET https://publishing.camayak.com/v1/content/?published_at__gte=2013-12-01T00:00:00Z&published_at__lte=2013-12-31T23:59:59Z
Detail:
GET https://publishing.camayak.com/v1/content/{id}
Params:
None
Response:
Returns an assignment.
{ "bylines": [ { "email": "ed@camayak.com", "first_name": "Edward", "last_name": "Smith", "order": 1, "override": "", "portfolio": "http://portfolios.camayak.com/edward-smith", "uuid": "8f491cfe-3879-4392-80cd-a720a52eb983" } ], "content": "<p>Sandwiched between Eastern European ‘hotspots’ like Poland and Croatia, and the established property industries of Austria and Germany, old ‘Central’ Europe is also starting to house the confidence of western-influenced, luxury development. Hungary – a country with a deep and transient social history – is one nation which now looks set to embrace greater international recognition as a truly stunning holiday location. <br /></p><p>...</p><p>Town Houses with two bedrooms are available from around 1324 square feet, starting at EUR 215,000 (around £148,000), with the larger, four bedroom Golf Lodges also available, from EUR 240,000 (around £165,000). Apartments meanwhile could provide the ideal investment for the weekend golfer in need of a nearby getaway. Clubhouse and Spa apartments start at EUR 150,000 (£103,000) and like all of the resort’s offers, include en-suite bedrooms and stylish open plan living areas. Garden apartments near the Clubhouse start at EUR 128,000 (£88,000) and are the smallest and cheapest options, though they also come with two bedrooms. Packages are also offered by the developer to design the interior of your home. As part of the retail price, which excludes VAT, Zala Springs use BKR International to provide Tax Advice, which includes the arrangement of a company purchase, to ensure that stamp duty and VAT charges do not apply. Hungarian banks offer 70% mortgages, with interest rates currently under 7%.</p>", "created": "2014-05-19T20:53:39.025876Z", "heading": "Zala Springs Resort, Lake Balaton, Hungary", "subheading": "", "media": [ { "caption": "", "title": "", "featured": false, "type": "image/jpeg", "url": "https://cmyk-main.s3.amazonaws.com/250b7bbb-09dc-4476-bdee-fa2de2950755/034384d3-c275-4369-b17f-3c4d66e9f4a8.jpg?Signature=PUMIf9mzwYhFuqT8%2F0RKGOax7DY%3D&Expires=1400692304&AWSAccessKeyId=AKIAJYKKDYI2DPMOLA2Q" }, { "caption": "", "title": "", "featured": false, "type": "image/jpeg", "url": "https://cmyk-main.s3.amazonaws.com/250b7bbb-09dc-4476-bdee-fa2de2950755/516068ca-6806-4ae2-8360-67d52c10d3f6.jpg?Signature=HIUNt3EPptOOCAuM4lLvfUYqYCQ%3D&Expires=1400692304&AWSAccessKeyId=AKIAJYKKDYI2DPMOLA2Q" } ], "slug": "my slug", "desk": "Blog Posts", "published_at": "2014-05-19T20:53:48.359755Z", "published_id": "86320646476", "published_url": null, "resource_uri": "/v1/content/8c4ceab0-d4a4-446b-874f-d27569c5da0f/", "retracted_at": "2014-05-21T01:26:16.378954Z", "scheduled_publication": "2014-05-19T20:53:48.359755Z", "taxonomies": { "Category": { "controlled": true, "hierarchical": true, "multivalued": true, "values": [ { "parent_id": null, "uuid": "5cf76df1-a77f-43f3-83cf-66cd5d9e66b2", "value": "Uncategorized" } ] }, "Tags": { "controlled": false, "hierarchical": false, "multivalued": true, "values": [ { "parent_id": null, "uuid": "46597eca-ff83-42b7-a585-7ea3e3bdefa0", "value": "Vacation" }, { "parent_id": null, "uuid": "8e772e26-abcc-422c-af62-e481b38bfd2d", "value": "Hungary" }, { "parent_id": null, "uuid": "ab72a386-9f0a-4a92-a022-3cf7de4d4131", "value": "Investment" } ] } }, "teaser": "", "updated": "2014-05-21T01:28:50.605182Z", "uuid": "8c4ceab0-d4a4-446b-874f-d27569c5da0f" }
Examples:
Returns a specific assignment:
GET https://publishing.camayak.com/v1/content/d7b6bee1-a484-4021-ba68-ff2163e9fdee/
Adding a Content API publishing destination
To start using the Camayak content publishing API, a customer Admin must configure a new API Publishing destination within Camayak.
- Under your organization name in the menu bar of Camayak, select Publishing Destinations
- Mouse over Add new publishing destination and select “Content API”
- In the modal, enter the following information:
- A name for the publishing destination. This is what will appear in the Camayak application.
- A Webhook url. This is the URL the Camayak content publishing API will make an HTTP POST request to when assignments are approved and retracted in Camayak. It is highly recommended that this is a secure (HTTPS) URL.
- Check whether you want to use Signed Requests for the Camayak content publishing API. This is recommended for security. For more information, please see the section on Signed Requests
- Enter a “shared secret” string. This string will be used as part of the Signed Requests
- Click Save. After creating the publishing destination, and validating that the Webhook URL you provided is working, you will be provided with an API key that must accompany all requests to the Camayak content publishing API. This key must be kept secret, and treated as a password. For more information, please see the section on Security.
Now that the content API publishing destination has been created, it can be chosen as a publishing destination for any existing or new assignments.
When those assignments are approved, the Camayak content publishing API will make a web hook call your server informing you of the approval.
Example Application
An example application which posts approved assignments to Tumblr is available at https://github.com/camayak/contentapi-node-tumblr/. This example app is designed to be run on Heroku, but could be adapted to run on any node platform.
The example application is a work in progress.