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.
All URLs referenced in the documentation have the following base.
https://edit-content.com/api/v1
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 |
DescriptionAdds a new site to your account and returns the corresponding site ID. Parameters
Example Response{ "status": "success", "site": { "id": 10000 } } |
||
GET | /sites | Gets a list of sites |
DescriptionGets a list of sites from your account. Parameters
Example Response{ "status": "success", "total": 10, "count": 5, "offset": 0, "sites": [ { "id": "10000", "url": "http:\/\/your-site.com\/", "lockdown": "off", "site_date": "2015-01-01 12:00:00" }, ... ] } |
||
GET | /sites/<site-id> | Gets a single site |
DescriptionGets the specified site from your account. Remember that usernames and passwords are never returned for security reasons. ParametersNone Example Response{ "status": "success", "site": { "id": "10000", "url": "http:\/\/example.com\/", "protocol": "ftp", "port": "21", "server": "ftp.example.com", "path": "\/public_html\/", "images": "images/", "lockdown": "off", "site_date": "2015-01-01 12:00:00" } } |
||
PUT | /sites/<site-id> | Updates a site |
DescriptionUpdates a site. You can specify one or more parameters when using this method. ParametersThe parameters for this method are identical to those for creating a site. Example Response{ "status": "success" } |
||
DELETE | /sites/<site-id> | Deletes a site |
DescriptionDeletes a site from your account. ParametersNone Example Response{ "status": "success" } |
HTTP | URL | Description |
---|---|---|
GET | /sites/<site-id>/styles | Gets styles for a site |
DescriptionGets custom styles for the specified site. If no styles are set, the styles property will be an empty string. ParametersNone Example Response{ "status": "success", "styles": ".your-styles { color: cyan; }" } |
||
PUT | /sites/<site-id>/styles | Updates styles for a site |
Description
Updates custom styles for
the specified site. Custom styles cannot be deleted. To
remove existing styles, call this method with Parameters
Example Response{ "status": "success" } |
HTTP | URL | Description |
---|---|---|
POST | /sites/<site-id>/snippets | Creates a snippet |
DescriptionCreates a snippet for the specified site and returns the corresponding ID. Parameters
Example Response{ "status": "success", "snippet": { "id": 10000 } } |
||
GET | /sites/<site-id>/snippets | Gets a list of snippets |
DescriptionGets a list of snippets for the specified site. ParametersNone Example Response{ "status": "success", "snippets": [ { "id": "10000", "name": "My Snippet" }, ... ] } |
||
GET | /sites/<site-id>/snippets/<snippet-id> | Gets a single snippet |
DescriptionGets a single snippet. ParametersNone Example Response{ "status": "success", "snippet": { "id": "10000", "name": "My Snippet", "code": "<p>...<\/p>" } } |
||
PUT | /sites/<site-id>/snippets/<snippet-id> | Updates a snippet |
DescriptionUpdates a snippet. ParametersThe parameters for this method are identical to those for creating a snippet. Example Response{ "status": "success" } |
||
DELETE | /sites/<site-id>/snippets/<snippet-id> | Deletes a snippet |
DescriptionDeletes a snippet. ParametersNone Example Response{ "status": "success" } |
HTTP | URL | Description |
---|---|---|
POST | /sites/<site-id>/templates | Creates a template |
DescriptionCreates a template for the specified site and returns the corresponding ID. Parameters
Example Response{ "status": "success", "template": { "id": 10000 } } |
||
GET | /sites/<site-id>/templates | Gets a list of templates |
DescriptionGets a list of templates for the specified site. ParametersNone Example Response{ "status": "success", "templates": [ { "id": "10000", "name": "My Template", "extension": "html" }, ... ] } |
||
GET | /sites/<site-id>/templates/<template-id> | Gets a single template |
DescriptionGets a single template. ParametersNone Example Response{ "status": "success", "template": { "id": "10000", "name": "My Template", "extension": "html", "source": "<html>...<\/html>" } } |
||
PUT | /sites/<site-id>/templates/<template-id> | Updates a template |
DescriptionUpdates a template. ParametersThe parameters for this method are identical to those for creating a template. Example Response{ "status": "success" } |
||
DELETE | /sites/<site-id>/templates/<template-id> | Deletes a template |
DescriptionDeletes a template. ParametersNone Example Response{ "status": "success" } |
HTTP | URL | Description |
---|---|---|
POST | /sites/<site-id>/pages | Enables a page |
DescriptionEnables a page for editing in the CMS. This will not create any files on your server. Any pages you enable through the API should already exist on your server. Parameters
Example Response{ "status": "success", "page": { "id": 10000 } } |
||
GET | /sites/<site-id>/pages | Gets a list of pages |
DescriptionGets a list of pages for the specified site. This method only returns pages that are enabled for editing. Parameters
Example Response{ "status": "success", "total": 10, "count": 5, "offset": 0, "pages": [ { "id": "10000", "label": "My Page Label", "path": "my-page.html" }, ... ] } |
||
GET | /sites/<site-id>/pages/<page-id> | Gets a single page |
DescriptionGets a single page. ParametersNone Example Response{ "status": "success", "page": { "id": "10000", "label": "My Page Label", "path": "my-page.html" } } |
||
DELETE | /sites/<site-id>/pages/<page-id> | Disables a page |
DescriptionDisables a page and removes it from the CMS. This will not remove any files from your server. ParametersNone Example Response{ "status": "success" } |
HTTP | URL | Description |
---|---|---|
GET | /sites/<site-id>/pages/<page-id>/revisions | Gets a list of revisions |
DescriptionGets a list of revisions for the specified page. This method returns revisions in reverse chronological order. Parameters
All revision types, including Example Response{ "status": "success", "total": 10, "count": 5, "offset": 0, "revisions": [ { "id": "10000", "site_id": "20000", "page_id": "30000", "user_id": "40000", "type": "history", "revision_date": "2015-01-014 14:32:28", "autopublish_date": "0000-00-00 00:00:00" }, ... ] } |
||
GET | /sites/<site-id>/pages/<page-id>/revisions/<revision-id> | Gets a single revision |
DescriptionGets a single revision. ParametersNone Example Response{ "status": "success", "revision": { "id": "10000", "site_id": "20000", "page_id": "30000", "user_id": "40000", "type": "history", "page_data": { "properties": { "title": "This is the page title", "description": "This is the meta description.", "keywords": "These are the meta keywords" }, "regions": { "region-id-1": "<p>HTML for #region-id-1<\/p>", "region-id-2": "<p>HTML for #region-id-2<\/p>", ... } }, "revision_date": "2015-01-014 14:32:28", "autopublish_date": "0000-00-00 00:00:00" } } |
||
DELETE | /sites/<site-id>/pages/<page-id>/revisions/<revision-id> | Deletes a revision |
DescriptionDeletes a revision. ParametersNone Example Response{ "status": "success" } |
HTTP | URL | Description |
---|---|---|
POST | /users | Creates a user |
DescriptionCreates a user and returns the corresponding ID. This method will not assign permissions to a user — that must be done in a separate request. Parameters
Example Response{ "status": "success", "user": { "id": 10000 } } |
||
GET | /users | Gets a list of users |
DescriptionGets a list of users from your account. Parameters
Example Response{ "status": "success", "total": 10, "count": 5, "offset": 0, "users": [ { "id": "10000", "name": "John Doe", "email": "john.doe@example.com", "type": "client", "privileges": "*", "user_date": "2015-01-01 12:00:00" }, ... ] } |
||
GET | /users/<user-id> | Gets a single user |
DescriptionGets a single user from your account. ParametersNone Example Response{ "status": "success", "user": { "id": "10000", "name": "John Doe", "email": "john.doe@example.com", "type": "client", "privileges": "*", "user_date": "2015-01-01 12:00:00" } } |
||
PUT | /users/<user-id> | Updates a user |
DescriptionUpdates a user. ParametersThe parameters for this method are identical to those for creating a user. Example Response{ "status": "success" } |
||
DELETE | /users/<user-id> | Deletes a user |
DescriptionDeletes a user from your account. ParametersNone Example Response{ "status": "success" } |
HTTP | URL | Description |
---|---|---|
GET | /users/<user-id>/permissions | Gets permissions |
Description
Gets permissions for the specified user.
The response includes a list of site IDs and the corresponding
pages that the user has access to. If the value for a given
site is For admin users, the result will always be an empty array since they automatically have access to all sites. ParametersNone Example Response{ "status": "success", "permissions": { "10000": [ ← site #10000 "20000", ← page #20000 "20001" ← page #20001 ], "10001": "*" ← all pages on site #10001 } } |
||
PUT | /users/<user-id>/permissions | Updates permissions |
DescriptionUpdates permissions for the specified user. Parameters
Formatting the Permissions Array
To give a user access to all pages on a site, your PUT data should look like this: All pages on site #10000 permissions[10000]=* Only two pages on site #10000 (page #20000 and #20001) permissions[10000][]=20000&permissions[10000][]=20001 All pages on two different sites permissions[10000]=*&permissions[10001]=* Example Response{ "status": "success" } |
HTTP | URL | Description |
---|---|---|
POST | /users/<user-id>/notifications | Turns notifications on |
DescriptionTurns notifications on for the specified user and site. Only admins can receive notifications, so an error will be received if this method is called for a non-admin user. Parameters
Example Response{ "status": "success" } |
||
GET | /users/<user-id>/notifications | Tells if notifications are on |
DescriptionTells whether or not this user has notifications enabled for the specified user/site. Parameters
Example Response{ "status": "success", "notifications": true } |
||
DELETE | /users/<user-id>/notifications | Turns notifications off |
DescriptionTurns notifications off for the specified user/site. Parameters
Example Response{ "status": "success" } |
HTTP | URL | Description |
---|---|---|
POST | /users/<user-id>/login | Generates a login token |
DescriptionGenerates a time-sensitive token that can be used to login a user by redirecting them to a special URL. Tokens are only valid for 15 minutes and cannot be reused. If this method is called more than once for the same user, only the most recent token will be honored. This method is intended for applications that have their own custom authentication system. Do not call this method unless the user has successfully logged in to your own application! To log the user in, redirect their browser to:
http://edit-content.com/login?token=<token>
If you’re using a custom domain, replace &logout-redirect=http://your-domain.com/ ParametersNone Example Response{ "status": "success", "token": "2mLICQQ0gXEQygUgQN2ISIo5FsHrO1Jwbx0m3WX3aLM5eJIOS1BwuIXdgo1P" } |
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.
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 |
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" https://edit-content.com/api/v1/sites Create a site $ curl --request POST --header "X-Surreal-CMS-API-Key: YOUR_API_KEY" --data "url=http://example.com/&protocol=ftp&server=ftp.example.com&port=21&username=user&password=password&path=/httpdocs/" https://edit-content.com/api/v1/sites Delete a site $ curl --request DELETE --header "X-Surreal-CMS-API-Key: YOUR_API_KEY" https://edit-content.com/api/v1/sites/YOUR_SITE_ID 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" https://edit-content.com/api/v1/users
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.