API Conventions
This topic describes conventions used for Optimizely's REST API.
Authentication
There are two methods of authenticating with Optimizely Web Experimentation API: using OAuth 2.0 and generating a personal token. Anyone building an application that is customer-facing should use OAuth 2.0. If you are building on the 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 Web Experimentation API . If you are an Administrator in your account, you can generate a token for yourself that will not 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)
Optimizely Web Experimentation version 1 API used a token system where an Administrator could generate tokens on behalf of anyone in an account. This authentication mechanism is no longer available for the Optimizely Web Experimentation API and has been replaced by Personal Tokens (see the previous section).
Errors
Optimizely Web Experimentation 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 API (2.0) includes a JSON body in the response with the 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 string | A message with more information about the error that occurred. |
uuid string | 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 uuid value. |
code string | 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 Content-Type: application/json header in your request. If you sent valid JSON, the error may also reference specific fields that were invalid |
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
Optimizely Web Experimentation API has a Global rate limit and some endpoints have an 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.
Currently, Optimizely Web Experimentation only has a rate limit for the e3-auth-service API endpoint, which is 100 requests per hour.
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. |
Status: 200 OK
X-RATELIMIT-LIMIT: 100
X-RATELIMIT-REMAINING: 99
X-RATELIMIT-RESET: 1477716420.0
Versioning
When we make backward-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 Web is around.
Version | Works with |
---|---|
v1 | Optimizely Classic Web Optimizely DCP (Dynamic Customer Profiles) |
v2 | Optimizely Classic Web (READ-ONLY) Optimizely Web Experimentation Soon: Optimizely Feature Experimentation Soon: Optimizely Mobile Soon: Optimizely OTT Soon: Optimizely DCP |
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 backward-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 backward-incompatible changes as possible.
Optimizely Classic Web objects
Optimizely Web Experimentation REST API is designed for Optimizely Web Experimentation which shares some of the data models with Optimizely Classic Web. Other data models are replaced by a similar concept.
When you request a Classic Web object through Optimizely Web Experimentation REST API, we will try to map the Classic Web fields as close as possible to Optimizely Web Experimentation fields. Because Optimizely Web Experimentation introduces many new concepts, it is not possible to write to Optimizely Classic Web objects with the Optimizely Web Experimentation REST API.
Our goal is to give anyone access to their Optimizely Classic Web data through the Optimizely Web Experimentation REST API. If a field for an old object is missing, please let us know by submitting a ticket to the Optimizely support team.
When you request experiment results for a Classic Web experiment, you will get a redirect (302) to the Optimizely API version 1 result endpoint.
If you are migrating from Optimizely Classic Web to Optimizely Web Experimentation 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 Open API on the OpenAPI website.
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 situations where if field A is set, field B needs to be set as well. Another example is that Experiments within a Optimizely Web Experimentation Project require the actions to be set on Variations within the Experiment. Experiments in a Optimizely Feature Experimentation 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 10 months ago