Developer API

Surreal CMS provides a RESTful API so you can integrate your own applications with our service. Before your application can use the Developer API, you’ll need to enable it in Settings.

Once you enable access, an API key will be generated for you. This is what you’ll use to authenticate with the API, so protect this key just like you would a password!


Every request sent to the API must be over SSL and must include the following HTTP header along with your API key for authentication.

X-Surreal-CMS-API-Key: your-api-key-here

Each account is authorized up to 10,000 API requests per day. If you exceed this limit, the API will reject all further requests until the following day.

Making requests

All URLs referenced in the documentation have the following base.

To make a request to the API, append any of the following routes while using the appropriate HTTP method. Some routes require parameters. Details about each route can be found by selecting the description.

A note about PUT requests: Due to the way our API processes PUT requests, REST clients will need to use POST instead of PUT and set the following header:

X-HTTP-Method-Override: PUT


HTTP URL Description
POST /sites Creates a site
GET /sites Gets a list of sites
GET /sites/<site-id> Gets a single site
PUT /sites/<site-id> Updates a site
DELETE /sites/<site-id> Deletes a site

Sites / Styles

HTTP URL Description
GET /sites/<site-id>/styles Gets styles for a site
PUT /sites/<site-id>/styles Updates styles for a site

Sites / Snippets

HTTP URL Description
POST /sites/<site-id>/snippets Creates a snippet
GET /sites/<site-id>/snippets Gets a list of snippets
GET /sites/<site-id>/snippets/<snippet-id> Gets a single snippet
PUT /sites/<site-id>/snippets/<snippet-id> Updates a snippet
DELETE /sites/<site-id>/snippets/<snippet-id> Deletes a snippet

Sites / Templates

HTTP URL Description
POST /sites/<site-id>/templates Creates a template
GET /sites/<site-id>/templates Gets a list of templates
GET /sites/<site-id>/templates/<template-id> Gets a single template
PUT /sites/<site-id>/templates/<template-id> Updates a template
DELETE /sites/<site-id>/templates/<template-id> Deletes a template

Sites / Pages

HTTP URL Description
POST /sites/<site-id>/pages Enables a page
GET /sites/<site-id>/pages Gets a list of pages
GET /sites/<site-id>/pages/<page-id> Gets a single page
DELETE /sites/<site-id>/pages/<page-id> Disables a page

Sites / Pages / Revisions

HTTP URL Description
GET /sites/<site-id>/pages/<page-id>/revisions Gets a list of revisions
GET /sites/<site-id>/pages/<page-id>/revisions/<revision-id> Gets a single revision
DELETE /sites/<site-id>/pages/<page-id>/revisions/<revision-id> Deletes a revision


HTTP URL Description
POST /users Creates a user
GET /users Gets a list of users
GET /users/<user-id> Gets a single user
PUT /users/<user-id> Updates a user
DELETE /users/<user-id> Deletes a user

Users / Permissions

HTTP URL Description
GET /users/<user-id>/permissions Gets permissions
PUT /users/<user-id>/permissions Updates permissions

Users / Notifications

HTTP URL Description
POST /users/<user-id>/notifications Turns notifications on
GET /users/<user-id>/notifications Tells if notifications are on
DELETE /users/<user-id>/notifications Turns notifications off

Users / Login

HTTP URL Description
POST /users/<user-id>/login Generates a login token

Handling responses

Every request to the API will return one of the following HTTP codes.

Code Status What it means
200 Success Everything went as expected
401 Unauthorized Your API key is missing or incorrect
422 Unprocessable Entity Your request could not be completed for some reason
429 Too Many Requests You have exceeded the daily rate limit
500 Internal Server Error Something didn't work right on our end

In addition, each response body will include a JSON string with a status property. The status will either be success or error.

If the status is error, an error code and message will also be provided. For example:

    "status": "error",
    "errorCode": "1100",
    "errorMessage": "Invalid API key"

If the status is success, additional data may exist depending on the operation.

API error codes

Code Description
1000 Request was not submitted over SSL
1100 Invalid or missing API key
1150 Daily request limit exceeded
1200 Invalid or missing fields
2000 Invalid site
2100 Unable to create site
2200 Unable to update site
2300 Invalid template
2400 Unable to create template
2500 Unable to update template
2600 Invalid page
2700 Unable to enable page
2800 Invalid revision
3000 Invalid user
3100 Unable to create user
3200 Unable to update user
3300 Master administrators cannot be deleted
3400 Email address already in use
3500 Password is not long enough
3600 Invalid user type
3700 User cannot receive notifications
4000 Invalid snippet
4100 Unable to create snippet
4200 Unable to update snippet

Referencing objects by ID

IDs are guaranteed, meaning they will not change for the life of an object (a site, a user, etc.). Methods that create an object will return an ID. Methods that reference the object will require that ID. You can also obtain an object’s ID using a list-all method.

For efficiency and convenience, it’s a good idea to store these IDs in your own app. This allows you to easily reference objects using the API without having to search for them each time.


Here are some examples you can paste into your command line. You’ll need to change the API key and any IDs in the request. The examples use cURL, so you’ll need to have that installed on your machine for these to work.

List the first five sites in your account
$ curl --request GET --header "X-Surreal-CMS-API-Key: YOUR_API_KEY" --data "count=5&offset=0"

Create a site
$ curl --request POST --header "X-Surreal-CMS-API-Key: YOUR_API_KEY" --data "url="

Delete a site
$ curl --request DELETE --header "X-Surreal-CMS-API-Key: YOUR_API_KEY"

List the first five users in your account
$ curl --request GET --header "X-Surreal-CMS-API-Key: YOUR_API_KEY" --data "count=5&offset=0"

HTTP Clients

The examples above use the command line version of cURL to give you an idea of how requests should be formed. If you’re using PHP, there’s a cURL module that’s usually available out-of-the-box.

Alternatively, you can use a third-party library such as Guzzle to make requests to the API.