The availability of features may depend on your plan type. Contact your Customer Success Manager if you have any questions.
Dev GuideAPI Reference
Dev GuideAPI ReferenceUser GuideGitHubDev CommunityOptimizely AcademySubmit a ticketLog In
Dev Guide

Authentication API

How to access your Experimentation Events Export with the Optimizely Experimentation Authentication API.

Use the Optimizely Authentication API to access your Experimentation Events Export. Exchange a Personal Access Token for temporary Amazon Web Services (AWS) or Google Cloud Platform (GCP) credentials. Then use those credentials to read the Amazon S3 or Google Cloud Storage (GCS) bucket for your account and download data programmatically.

API overview

Optimizely Experimentation Authentication API endpoints

  • AWS (Amazon S3)https://api.optimizely.com/v2/export/credentials
  • GCP (Google Cloud Storage)https://api.optimizely.com/v2/export/credentials/gcp

Query parameters

The AWS endpoint (/export/credentials) accepts the following query parameter. The GCP endpoint (/export/credentials/gcp) takes no parameters and issues a token that is valid for one hour.

Parameter

Description

duration

The expiration window for your credentials. The default and maximum is one hour. Select a value between 15 minutes and one hour, using h for hours or m for minutes.

Example:
https://api.optimizely.com/v2/export/credentials?duration=1h

Refresh these credentials with your Personal Access Token.

REST API reference

Complete Optimizely Experimentation REST API reference:

Acquire temporary AWS credentials with the Authentication API

Generate a Personal Access Token

Generate a Personal Access Token (PAT) in Optimizely by following the Optimizely Personal Access Token support article.

Request AWS credentials with your PAT

Copy your Personal Access Token into the Authorization header of a GET request sent to the Authentication API's /export/credentials endpoint.

The following cURL request sends your PAT to the AWS credentials endpoint:

curl -H "Authorization: Bearer PERSONAL_ACCESS_TOKEN" -X GET https://api.optimizely.com/v2/export/credentials\?duration\=1h

The endpoint returns a JSON response with your temporary credentials:

{
 "credentials": {
   "accessKeyId": "ACCESS_KEY_ID",
   "secretAccessKey": "SECRET_ACCESS_KEY",
   "sessionToken": "SESSION_TOKEN",
   "expiration": 1591026407394
 },
 "s3Path": "s3://optimizely-events-data/v1/account_id=123"
}

The response contains an accessKeyId, a secretAccessKey, and a sessionToken, which you use in the next step to validate your credentials.

📘

Note

Skip this step if you already have credentials for the other data export services. Reuse the same credentials to access your Experimentation Events Export data. Those credentials are less secure than ones issued through the Authentication API, but they work.

Validate your credentials

Verify you can read the Optimizely S3 bucket with the temporary credentials.

  1. Install the AWS CLI.

  2. Export your accessKeyId, secretAccessKey, and sessionToken as environment variables:

    export AWS_ACCESS_KEY_ID=ACCESS_KEY_ID
    export AWS_SECRET_ACCESS_KEY=SECRET_ACCESS_KEY
    export AWS_SESSION_TOKEN=SESSION_TOKEN
  3. Copy your Optimizely account ID. To find your account ID, see Account name, ID, and multi-account login in Optimizely Experimentation.

  4. List the files in your S3 decisions directory, using your account ID and a given date:

    aws s3 ls s3://optimizely-events-data/v1/account_id=ACCOUNT_ID/type=decisions/date=YYYY-MM-DD/

    The output lists the experiments for which users received decisions that day.

📘

Note

The trailing forward slash is required because your credentials grant access to only one folder in the Optimizely Experimentation Amazon S3 bucket.

  1. Because your exported data is encrypted, access it using one of the following clients:
    • AWS CLI version 1.11.108 or later
    • AWS SDKs released after May 2016

Extract your data

To access your Experimentation Events Export data programmatically, use the accessKeyId, secretAccessKey, and sessionToken values returned in Request AWS credentials with your PAT. These credentials let you download files from Optimizely Experimentation's S3 bucket. To copy these files to your own S3 bucket, download them locally first, then upload them to your bucket with your S3 credentials. See the AWS documentation on working with objects.

📘

Note

The credentials expire after one hour. Configure a process to refresh them. For more, see Using temporary security credentials with AWS resources.

Acquire temporary GCP credentials with the Authentication API

The GCP flow mirrors the AWS flow described in Acquire temporary AWS credentials with the Authentication API. Generate a Personal Access Token as described in Generate a Personal Access Token, then exchange it for a temporary GCP token.

Request GCP credentials with your PAT

Copy your Personal Access Token into the Authorization header of a GET request sent to the Authentication API's /export/credentials/gcp endpoint.

The following cURL request sends your PAT to the GCP credentials endpoint:

curl -H "Authorization: Bearer PERSONAL_ACCESS_TOKEN" -X GET https://api.optimizely.com/v2/export/credentials/gcp

The endpoint returns a JSON response with your temporary GCP token:

{
  "token": "gcp_access_token",
  "uri": "gs://optimizely-e3-123"
}

The response contains a token (a Google OAuth 2.0 access token) and the uri of the Google Cloud Storage bucket for your account. The token grants read-only access and expires after one hour.

Validate your GCP credentials

Verify you can read the Optimizely GCS bucket with the temporary token.

  1. Install the Google Cloud CLI.

  2. Export your token as an environment variable:

    export CLOUDSDK_AUTH_ACCESS_TOKEN=TOKEN

    The Google Cloud CLI sends this value as a bearer token. The CLI does not refresh or validate the token, so request a fresh one when it expires.

  3. Copy your Optimizely account ID. To find your account ID, see Account name, ID, and multi-account login in Optimizely Experimentation.

  4. List the files in your GCS decisions directory, using your account ID and a given date:

    gcloud storage ls gs://optimizely-e3-ACCOUNT_ID/v1/account_id=ACCOUNT_ID/type=decisions/date=YYYY-MM-DD/

    The output lists the experiments for which users received decisions that day.

📘

Note

Use gcloud storage rather than gsutil, which is deprecated for Cloud Storage.

Extract your GCS data

Download your data with the Google Cloud CLI:

gcloud storage cp -r gs://optimizely-e3-ACCOUNT_ID/v1/account_id=ACCOUNT_ID/type=decisions/date=YYYY-MM-DD/ .

Your token grants read-only access, so you cannot write to the Optimizely bucket. To keep a copy, download the files locally or copy them to your own GCS bucket using your own credentials.

📘

Note

The token expires after one hour. Configure a process to refresh it by calling the /export/credentials/gcp endpoint again with your Personal Access Token.

Sample code

The following sample programs handle the credential exchange and refresh loop for you. Copy them into your own project and replace the YOUR_* placeholders with your account-specific values.

AWS (boto3)

The following sample code creates a boto3 S3 client that uses the Optimizely Authentication API and automatically refreshes credentials every hour:

#!/usr/bin/env python3

from botocore.credentials import RefreshableCredentials
from botocore.session import get_session
from datetime import datetime
import requests as r
import boto3
import pytz
import sys


class BearerAuth(r.auth.AuthBase):
    """
    Bearer authentication class that integrates with requests'
    native authentication mechanism.
    """

    def __init__(self, token):
        """
        Args:
            token (str): Bearer token used to authenticate requests to an API
        """
        self.token = token

    def __call__(self, request):
        """Sets the Authorization header on the current HTTP request.
        Args:
            request (request): The current HTTP request object.
        Returns:
            request: The current HTTP request with additional
                     Authorization header
        """
        request.headers['Authorization'] = f"Bearer {self.token}"
        return request


class OptimizelyS3Client(object):
    """
    AWS S3 client using credentials from Optimizely
    """

    EXPORT_CREDENTIALS_URL = 'https://api.optimizely.com/v2/export/credentials'
    CREDENTIALS_IDENTIFIER = 'Optimizely'
    EVENT_EXPORT_BUCKET_REGION = 'us-east-1'

    def __init__(self, token: str):
        """
        Args:
            token (str): Optimizely personal access token
        """
        self.token = token

    def get_bucket_prefix(self, account_id: str) -> str:
        """Get the bucket prefix for a given Optimizely account ID
        Args:
            account_id (str): Optimizely account ID
        Returns:
            str: The S3 bucket prefix to access events data
        """
        return f"v1/account_id={account_id}/"

    def get_creds(self) -> dict:
        """Get AWS credentials from the Optimizely public API
        Returns:
            dict: The AWS credentials for a given Optimizely account
        """
        response = r.get(
            OptimizelyS3Client.EXPORT_CREDENTIALS_URL,
            auth=BearerAuth(self.token)
        )

        node = response.json()
        return node['credentials']

    def as_boto3_s3_client(self):
        """
        Convert the Optimizely S3 client to a standard boto s3
        client with refreshable credentials
        Returns:
            botocore.client.S3: Standard boto3 S3 client
        """
        creds = self.get_creds()

        # The API response is in milliseconds
        expiry_time = int(creds['expiration'] / 1000)

        # boto expects the expiry time to be a UTC datetime
        expiry_time = datetime.fromtimestamp(expiry_time, pytz.utc)

        opz_refreshable_credentials = RefreshableCredentials(
            creds['accessKeyId'],
            creds['secretAccessKey'],
            creds['sessionToken'],
            expiry_time,
            self.get_creds,
            OptimizelyS3Client.CREDENTIALS_IDENTIFIER
        )

        session = get_session()
        session._credentials = opz_refreshable_credentials
        session.set_config_variable('region', OptimizelyS3Client.EVENT_EXPORT_BUCKET_REGION)
        opz_session = boto3.Session(botocore_session=session)
        s3_client = opz_session.client('s3')

        return s3_client


def main():
    EVENT_EXPORT_BUCKET_NAME = 'optimizely-events-data'
    OPTIMIZELY_ACCOUNT_ID = 'YOUR_ACCOUNT_ID'
    OPTIMIZELY_PERSONAL_ACCESS_TOKEN = 'YOUR_PERSONAL_ACCESS_TOKEN'

    optimizely_s3_client = OptimizelyS3Client(OPTIMIZELY_PERSONAL_ACCESS_TOKEN)
    s3_client = optimizely_s3_client.as_boto3_s3_client()

    all_objects = s3_client.list_objects(
        Bucket=EVENT_EXPORT_BUCKET_NAME,
        Prefix=optimizely_s3_client.get_bucket_prefix(OPTIMIZELY_ACCOUNT_ID)
    )
    print(all_objects)


if __name__ == '__main__':
    main()

GCP (google-cloud-storage)

The following sample code exchanges your Personal Access Token for a temporary GCP token and lists your decision files with the google-cloud-storage client library:

#!/usr/bin/env python3

import requests
from google.cloud import storage
from google.oauth2.credentials import Credentials

EXPORT_CREDENTIALS_GCP_URL = "https://api.optimizely.com/v2/export/credentials/gcp"

# Your Optimizely account ID and Personal Access Token.
OPTIMIZELY_ACCOUNT_ID = "YOUR_ACCOUNT_ID"
OPTIMIZELY_PERSONAL_ACCESS_TOKEN = "YOUR_PERSONAL_ACCESS_TOKEN"


def get_gcp_token(pat: str) -> str:
    """Exchange an Optimizely personal access token for a temporary GCP token.

    The returned token grants read-only access and expires after one hour.
    Call this function again to get a fresh token.
    """
    response = requests.get(
        EXPORT_CREDENTIALS_GCP_URL,
        headers={"Authorization": f"Bearer {pat}"},
    )
    response.raise_for_status()
    return response.json()["token"]


def main():
    token = get_gcp_token(OPTIMIZELY_PERSONAL_ACCESS_TOKEN)
    credentials = Credentials(token=token)

    # The client uses your own GCP project for billing and quota.
    client = storage.Client(project="YOUR_GCP_PROJECT", credentials=credentials)
    bucket = client.bucket(f"optimizely-e3-{OPTIMIZELY_ACCOUNT_ID}")

    prefix = f"v1/account_id={OPTIMIZELY_ACCOUNT_ID}/type=decisions/"
    for blob in bucket.list_blobs(prefix=prefix):
        print(blob.name)


if __name__ == "__main__":
    main()