API Conventions
Overview
The Optimizely v2 REST API has been implemented with the intention to make the lives of developers easy. Below is a list of all the important API conventions that apply to our entire API.
Authentication
There are two methods of authenticating with the v2 API: using OAuth 2.0 and by generating a personal token. Anyone building an application that will be customer facing should use OAuth 2.0. If you are building on our API for an internal tool or you just want to explore what is possible it is easier
to use a Personal Token. Personal Tokens are for server-to-server communication only and should NOT be shared with anyone else under any circumstances.
curl -H "Authorization: Bearer abcdefg123456" \
"https://api.optimizely.com/v2/projects"
OAuth 2.0
OAuth 2.0 provides a friendly interface for the users of your app to allow your tool to make API requests on their behalf.
If you want to set up OAuth 2.0 authentication for your app, please see our OAuth 2.0 guide.
You can use easy-access to easily get an access token.
Get OAuth 2.0 access token with easy-access
easy_access optimizely
Personal Tokens
Personal Tokens are an easy way to authenticate with the Optimizely API. If you are an Admin in your account, you can generate a token for yourself that won't expire until you revoke the token. Personal Tokens can be used with the same headers as OAuth 2.0 access tokens.
Personal Tokens are for server-to-server communication only and should NOT be shared with anyone else under any circumstances.
Read here how you can generate and use a Personal Token.
Classic Tokens (deprecated)
The v1 API used a token system where an Admin could generate tokens on behalf of anyone in an account. The tokens were generated on
https://app.optimizely.com/tokens. This authentication mechanism is no longer available for the v2 API and has been replaced by Personal Tokens (see previous section).
Errors
Optimizely uses conventional HTTP response codes to indicate the success or failure of an API request. In general, codes in the 2xx range indicate success, codes in the 4xx range indicate an error that failed given the information provided (e.g., a required parameter was omitted, a change failed, etc.), and codes in the 5xx range indicate an error with Optimizely's servers.
When a 4xx or 5xx status code is returned, Optimizely includes a JSON body in the response with a property uuid
. If you contact Optimizely with a question regarding a failing request, be sure to mention the uuid
of the error.
{} 4xx Error
Parameter and Type | Description |
---|---|
message | A message with more information about the error that occurred. |
uuid | A unique identifier for the error that you experienced. All relevant information regarding your error is stored in Optimizely's systems and can be found with this unique identifier. When you contact Optimizely about your error, be sure to mention the |
code | A unique identifier for the category of the error. This is sometimes the HTTP status code. |
HTTP status code summary
Response | What to expect |
---|---|
200 - OK | Your request was correctly formatted and the resource you requested is returned |
201 - Created | Returned when a POST request was successful |
202 - Accepted | Returned when a PUT request was successful |
204 - No Content | Returned when your DELETE request was successful |
400 - BadRequest | Can happen if your request did not have a valid JSON body. It might help to specify a |
401 - Unauthorized | Your API token was missing or not in the correct format |
403 - Forbidden | You provided an API token but it was invalid or revoked or you don't have read/write access to the entity you're trying to view/edit |
404 - Not Found | The id used in the request was inaccurate or you didn't have permission to view/edit it |
409 - Conflict | The resources you are trying to reach is in conflict |
413 - Payload Too Large | The data that you want to send to Optimizely is too large |
429 - Too Many Requests | You went over your rate limit. Wait until the X-RATELIMIT-RESET header reaches 0 and X-RATELIMIT-REMAINING is reset to X-RATELIMIT-LIMIT. See the rate limiting section for more info |
5xx - Server Error | Something went horribly wrong! Optimizely engineers have been informed, but please don't hesitate to contact us. |
Example error response body
{
"message": "Authentication failed",
"code": "403",
"uuid": "1f910547-5587-42ff-9e53-76c71d582983"
}
Pagination
List requests will be paginated to 25 items by default. It is possible to adjust the amount of returned objects by using the ?per_page
parameter. The maximum value for ?per_page
is 100. By using the ?page
parameter you can access all the pages.
The ?page
value will default to 1.
Example request
curl -H \
"Authorization: Bearer abcdefg123456" \
"https://api.optimizely.com/v2/projects?page=3&per_page=10" --verbose
Link Header
Every response to a list request has LINK headers to relevant other pages.
This LINK response header contains one or more Hypermedia link relations, some of which may require expansion as URI templates. If there are less than per_page
objects at that endpoint and they are on page 1, there will be no Link header in the response because there are no relevant links to be returned.
Header | Value |
---|---|
next | The link relation for the immediate next page of results |
last | The link relation for the last page of results |
prev | The link relation for the immediate previous page of results |
Link header example
LINK: <https://api.optimizely.com/v2/projects?page=2&per_page=25>; rel=next, <https://api.optimizely.com/v2/projects?page=3&per_page=25>; rel=last
Rate limiting
Rate Limit enforcement has been temporarily disabled.
Response headers
Status: 200 OK
X-RATELIMIT-LIMIT: 100
X-RATELIMIT-REMAINING: 99
X-RATELIMIT-RESET: 1477716420.0
Current Rate Limits:
REST API Endpoint | Rate Limit (per minute) |
---|---|
/v1/experiments/{experiment_id}/results | 20 |
/v1/experiments/{experiment_id}/stats | 20 |
/v2/campaigns/{campaign_id}/results | 20 |
/v2/experiments/{experiment_id}/results | 20 |
All other /v2 endpoints | 100 |
The Optimizely API has a Global rate limit and some endpoints have a endpoint specific rate limit. The global rate limit is a limit for the total amount of calls you are making to our API, regardless of which endpoint. An endpoint-specific rate limit is always less than the global rate limit.
When you have reached your limit, you will get a 429 - Too Many Requests
response code.
Every response contains three headers that indicate where you are against your rate limit:
Header | Value |
---|---|
X-RATELIMIT-LIMIT | The limit for this endpoint |
X-RATELIMIT-REMAINING | The amount of calls remaining for this endpoint |
X-RATELIMIT-RESET | The X-RateLimit-Reset header provides a Unix UTC timestamp, letting you know the exact time that your fresh new rate limit kicks in. |
Versioning
When we make backwards-incompatible changes to the API, we release a new major
version of the API. The latest major version is v2.
At the moment of writing (October 29 2016) there are two major versions: v1 and v2.
The most important difference between v1 and v2 is how they interact with our
various products.
The v1 API will keep working as long as Optimizely Classic is around.
Version | Works with |
---|---|
v1 |
|
v2 |
|
Backwards-compatible
The main difference between backward compatible and backward incompatible changes is that backward compatible changes only enhance functionality and don't change the behavior of existing fields on all endpoints. This guarantees that your app is not impacted by changes done by us.
Changes that we do consider backwards-compatible are:
- Adding new API resources.
- Adding new optional request parameters to existing API methods.
- Adding new properties to existing API responses.
- Changing the order of properties in existing API responses.
- Changing the length or format of object IDs or other opaque strings.
We aim to make as few backwards-incompatible changes as possible.
Optimizely Classic objects
The v2 API is designed for Optimizely X. Optimizely X shares some of the data models with Optimizely Classic. Other data models are replaced by a similar concept.
When you request a Classic object through the v2 API, we will try to map the Classic fields as close as possible to Optimizely X fields. Because Optimizely X introduces a lot of new concepts, it is not possible to write to Optimizely Classic objects with the v2 API.
Our goal is to give anyone access to their Optimizely Classic data through the v2 API. If a field for an old object is missing, please let us know by submitting a ticket to the developer support team.
When you request experiment results for a Classic experiment, you will get a redirect (302) to the v1 API result endpoint.
If you are migrating from Optimizely Classic to Optimizely X it will be helpful to check the migration section.
OpenAPI / Swagger
We have used the OpenAPI specification to define all our REST endpoints. By doing so, we made sure our REST API reference is always up to date and that API clients in any language can easily be generated.
By using the https://api.optimizely.com/v2/swagger.json
file in a client, the client knows what actions are possible with the Optimizely API.
To generate a client in a specific language, go to http://generator.swagger.io/.
Some popular clients are the Node/JavaScript client swagger-js and the Python client Bravado.
Read more about Swagger and the OpenAPI here: http://swagger.io/.
Location of swagger.json
https://api.optimizely.com/v2/swagger.json
Example use of the JavaScript client
var token = 'abcdefg123456';
var swaggerPromise = new SwaggerClient({
url: "https://api.optimizely.com/v2/swagger.json",
usePromise: true
});
var authentication = {
clientAuthorizations: {
token: new SwaggerClient.ApiKeyAuthorization('Authorization', "Bearer " + token, 'header'),
}
};
swaggerPromise.then(function(client) {
return client.Projects.list_projects({
responseContentType: 'application/json'
}, authentication);
}).then(function(result) {
console.log(result.obj)
});
Required fields
Some of the fields are not marked as required but have a conditional requirement. There are situation where if field A is set, field B needs to be set as well. Another example is that Experiments within a Web Project require the actions to be set on Variations within the Experiment. Experiments in a Full Stack project don't have this requirement. If you try to create an object without a field that is required, Optimizely will respond with an error that indicates which field is missing.
Updated over 2 years ago