Dev guideAPI Reference
Dev guideAPI ReferenceUser GuideGitHubNuGetDev CommunityDoc feedbackLog In

Use Optimizely Agent

Optimizely Agent provides REST APIs that enable running feature flag rules, such as A/B tests and targeted flag deliveries.

Optimizely Agent provides equivalent functionality to all our regular, language-specific SDKs. At Optimizely Agent's core is the Optimizely Go SDK.

Running feature flag rules

The Decide endpoint buckets a user into a feature flag variation as part of a flag rule. It chooses between multiple enabled or one disabled variation for a flag. Flag rules include A/B tests and targeted feature flag deliveries. To run a flag rule, use the following:

POST /v1/decide?keys={flagKey}

In the request application/json body, include the userId and any decideOptions. The full request looks like

curl --location --request POST 'http://localhost:8080/v1/decide?keys=YOUR_FLAG_1&keys=YOUR_FLAG_2'
--header 'X-Optimizely-SDK-Key: YOUR_SDK_KEY'
--header 'Accept: text/event-stream'
--header 'Content-Type: application/json'
--data-raw '{
"decideOptions": [
],
"userId": "string",
"userAttributes": {
   "additionalProp1": {}
  }
}

This returns an array of OptimizelyDecision objects that contain all the information you need to run your flag rule, such as:

  • the decision to bucket this user into an enabled or disabled feature flag variation.
  • any corresponding feature flag variable values.

For example:

{
    "userContext": {
        "UserId": "test-user",
        "Attributes": {
            "logged-in": true,
            "location": "usa"
        }
    },
    "flagKey": "my-feature-flag",
    "ruleKey": "my-a-b-test",
      "enabled": false,
    "variationKey": "control_variation"
    "variables": {
        "my-var-1": "cust-val-default-1",
        "my-var-2": "cust-va1-default-2"
    },
    "reasons": []
}

The response is determined by the A/B tests and targeted deliveries defined for the supplied feature key, following the same rules as any Optimizely Feature Experimentation SDK.

🚧

Important

If the user is bucketed into an A/B test, this endpoint dispatches a decision event.

Authentication

To authenticate, pass your SDK key as a header named X-Optimizely-SDK-Key in your API calls to Optimizely Agent. You can find your SDK key in app.optimizely.com under Settings > Environments > SDK Key. Remember each environment has its own SDK key.

Get all decisions

  • To get all feature flag decisions for a visitor in a single request, omit the feature flag parameter:
    POST /v1/decide

  • To get decisions for multiple keys, specify multiple keys parameters, for example:
    keys=flag_key_1&keys=flag_key_2

  • To receive only the enabled feature flags for a visitor use a decide option in the application/json request body:

--header 'Content-Type: application/json' \
--data-raw '{
   "userId": "test-user"
   "decideOptions": [
      "ENABLED_FLAGS_ONLY"
   ]
}'

Track conversions

To track events, use the tracking endpoint:

POST /v1/track?eventKey={eventKey}

There is no response body for successful conversion event requests.

Advanced Audience Targeting

📘

Note

Fetching qualified segments and sending events through the Advanced Audience Targeting integration is in beta. Contact your Customer Success Manager for more information or register now on Optimizely.com.

Fetch qualified segments

You can fetch all qualified segments for the user ID by calling the decide endpoint:

POST /v1/decide?keys={flagKey}

with fetchSegments set to True:

For example:

#============================
# Fetch qualified segments
#============================

params = {"keys": "my-feature-flag"}
payload = {
    "userId": "test-user",
    "decideOptions": [
        "ENABLED_FLAGS_ONLY",
        "INCLUDE_REASONS"
    ],
    "userAttributes": {},
    "fetchSegments": True,
}

response = s.post(url = 'http://localhost:8080/v1/decide', params=params, json=payload)

print(response.json())

Example response:

{
    "variationKey": "variation_b",
    "enabled": true,
    "ruleKey": "ab_experiment",
    "flagKey": "my-feature-flag",
    "userContext": {
        "userId": "test-user",
        "attributes": {}
    },
    "reasons": ["Audiences for experiment ab_experiment collectively evaluated to true."]
}

After you fetch the segments, they are cached. This means that if the same user requests the segments again (when new user contexts are created), Agent can retrieve the audience segment information from the cache rather than from the remote ODP server.

If you would like to bypass caching, you can add the following options to the payload JSON object:

  • "fetchSegmentsOptions": ["IGNORE_CACHE"] – Bypass segments cache for lookup and save.
  • "fetchSegmentsOptions": ["RESET_CACHE"] – Reset all segments cache.

For example:

params = {"keys": "my-feature-flag"}
payload = {
    "userId": "test-user",
    "decideOptions": [
        "ENABLED_FLAGS_ONLY",
        "INCLUDE_REASONS"
    ],
    "userAttributes": {},
    "fetchSegments": True,
    "fetchSegmentsOptions":["RESET_CACHE"]
}

response = s.post(url = 'http://localhost:8080/v1/decide', params=params, json=payload)

print(response.json())

Send ODP Events

Send data to the ODP server by calling the send-odp-eventendpoint:

POST /v1/send-odp-event

You can then use this data to analyze user behavior and optimize experiences across different channels and touchpoints.

Use the send-odp-event endpoint to

  • merge or stitch users together and determine which event is associated with which customer.
  • send various types of events and actions, such as pageviews, clicks, form submissions, and others. You can include additional data to provide more context and information about the event being tracked.

For example, by connecting an email address identifier with a fs_user_id identifier, you can use the send-odp-event endpoint to send events that are associated with both identifiers. This enables you to track and analyze the behavior of a specific user across different touchpoints and devices.

You cannot create or update user profile data like name or address with the send-odp-event endpoint. Instead, you can use the ODP API or ODP UI to manage customer profiles.

ParameterTypeDescription
action
required
stringSpecifies the subcategory of the event type, used to track the app and user lifecycle. The call fails with the following error: ODP action is not valid (cannot be empty) if null or empty.
typestringThe type of event to be sent. Set to "fullstack" if not specified.
identifiersDictionary<string, string>A key-value map of user identifiers. At least one key-value pair is required.
dataDictionary<string, object>The event data in a key-value map. The value can be any type (string, number, or boolean.) You can use null values, but they become empty strings.

The Python SDK adds default event data to the given data dictionary. Sending the same key when creating your Dictionary overwrites the default data values.

  • "idempotence_id":<UUID created by the Python SDK>

  • "data_source_type":"sdk"

  • "data_source":"python-sdk"

  • "data_source_version":<Python SDK version implemented>

#============================
# Send ODP event
#============================
payload = {
    "type": "test_type",
    "data": {
        "idempotence_id": "abc-1234",
        "data_source_type": "agent",
    },
    "identifiers": {"user_id": "test_user_1"},
    "action": "test_action",
}

response = s.post(url = 'http://localhost:8080/v1/send-odp-event', params={}, json=payload)

print(response.json())

Example of successful response:

{
    "success": true
}

This response only indicates that the event was successfully queued in the event queue. It is not a guarantee that event was successfully delivered.

If the event was sent successfully, meaning it has left the event queue, then there should be no errors logged. If unsuccessful, then error should be visible in Agent logs, for example 400 BadRequest.

API reference

For more details on Optimizely Agent's APIs, see the complete Agent API Reference.