HomeGuidesAPI Reference
Submit Documentation FeedbackJoin Developer CommunityOptimizely GitHubOptimizely NuGetLog In

API Conventions

This topic describes conventions used for Optimizely's REST API.

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 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. This authentication mechanism is no longer available for the v2 API and has been replaced by Personal Tokens (see the 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 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 TypeDescription
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 uuidvalue.
code
string
A unique identifier for the category of the error. This is sometimes the HTTP status code.

HTTP status code summary

ResponseWhat to expect
200 - OKYour request was correctly formatted and the resource you requested is returned
201 - CreatedReturned when a POST request was successful
202 - AcceptedReturned when a PUT request was successful
204 - No ContentReturned when your DELETE request was successful
400 - BadRequestCan 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 - UnauthorizedYour API token was missing or not in the correct format
403 - ForbiddenYou 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 FoundThe id used in the request was inaccurate or you didn't have permission to view/edit it
409 - ConflictThe resources you are trying to reach is in conflict
413 - Payload Too LargeThe data that you want to send to Optimizely is too large
429 - Too Many RequestsYou 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 ErrorSomething 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.

HeaderValue
nextThe link relation for the immediate next page of results
lastThe link relation for the last page of results
prevThe 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 EndpointRate Limit (per minute)
/v1/experiments/{experiment_id}/results20
/v1/experiments/{experiment_id}/stats20
/v2/campaigns/{campaign_id}/results20
/v2/experiments/{experiment_id}/results20
All other /v2 endpoints100

The Optimizely 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.

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:

HeaderValue
X-RATELIMIT-LIMITThe limit for this endpoint
X-RATELIMIT-REMAININGThe amount of calls remaining for this endpoint
X-RATELIMIT-RESETThe 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 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 is around.

VersionWorks with
v1 Optimizely Classic Web
Optimizely DCP (Dynamic Customer Profiles)
v2 Optimizely Classic Web (READ-ONLY)
Optimizely X Web
Soon: Optimizely X Full Stack
Soon: Optimizely X Mobile
Soon: Optimizely X 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 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 Optimizely 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 situations 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.