Skip to main content

APIs

Basic workflow

In order to run an experimentation you have to do the following actions

  • create an experiment with variant
  • when a user interact with your application
    • mark variant displayed for the user
    • mark variant won for the user if the variant is a success

Data model

An experiment has the following structure :

{
"id": "izanami:example:button",
"name": "My experiment",
"description": "The description ...",
"enabled": true,
"variants": [
{
"id": "A",
"name": "Variant A",
"description": "Variant A is about ...",
"traffic": 0.5
},
{
"id": "B",
"name": "Variant B",
"description": "Variant B is about ...",
"traffic": 0.5
}
]
}

Basic CRUD operations

List all

The query params are optional and the value used in this example are the default one.

curl -X GET \
'http://localhost:9000/api/experiments?pattern=*&page=1&pageSize=15' \
-H 'Content-Type: application/json' \
-H 'Izanami-Client-Id: xxxx' \
-H 'Izanami-Client-Secret: xxxx' | jq

Will respond with a 200 status code:

{
"results": [
{
"id": "izanami:example:button",
"name": "My First experiment",
"description": "See what people like the most about ...",
"enabled": true,
"variants": [
{
"id": "A",
"name": "Variant A",
"description": "Variant A is about ...",
"traffic": 0.5,
"currentPopulation": 3
},
{
"id": "B",
"name": "Variant B",
"description": "Variant B is about ...",
"traffic": 0.5,
"currentPopulation": 3
}
]
}
],
"metadata": {
"page": 1,
"pageSize": 15,
"count": 1,
"nbPages": 1
}
}

Create an experiment

curl -X POST \
'http://localhost:9000/api/experiments' \
-H 'Content-Type: application/json' \
-H 'Izanami-Client-Id: xxxx' \
-H 'Izanami-Client-Secret: xxxx' \
-d '
{
"id": "izanami:test:button:color",
"name": "Red button or Blue Button",
"description": "Which button is the best ...",
"enabled": true,
"variants": [
{
"id": "A",
"name": "Red button",
"description": "Variant A is the red button",
"traffic": 0.5
},
{
"id": "B",
"name": "Variant B",
"description": "Variant B is the blue button",
"traffic": 0.5
}
]
}
' | jq

Will respond with a 201 status code:

{
"id": "izanami:test:button:color",
"name": "Red button or Blue Button",
"description": "Which button is the best ...",
"enabled": true,
"variants": [
{
"id": "A",
"name": "Red button",
"description": "Variant A is the red button",
"traffic": 0.5
},
{
"id": "B",
"name": "Variant B",
"description": "Variant B is the blue button",
"traffic": 0.5
}
]
}

Get an experiment

curl -X GET \
'http://localhost:9000/api/experiments/izanami:test:button:color' \
-H 'Content-Type: application/json' \
-H 'Izanami-Client-Id: xxxx' \
-H 'Izanami-Client-Secret: xxxx' \
| jq

Will respond with a 200 status code:

{
"id": "izanami:test:button:color",
"name": "Red button or Blue Button",
"description": "Which button is the best ...",
"enabled": true,
"variants": [
{
"id": "A",
"name": "Red button",
"description": "Variant A is the red button",
"traffic": 0.5
},
{
"id": "B",
"name": "Variant B",
"description": "Variant B is the blue button",
"traffic": 0.5
}
]
}

Update an experiment

curl -X PUT \
'http://localhost:9000/api/experiments/izanami:test:button:color' \
-H 'Content-Type: application/json' \
-H 'Izanami-Client-Id: xxxx' \
-H 'Izanami-Client-Secret: xxxx' \
-d '
{
"id": "izanami:test:button:color",
"name": "Red button or Blue Button",
"description": "Which button is the better ...",
"enabled": true,
"variants": [
{
"id": "A",
"name": "Red button",
"description": "Variant A is the red button",
"traffic": 0.5
},
{
"id": "B",
"name": "Variant B",
"description": "Variant B is the blue button",
"traffic": 0.5
}
]
}
' | jq

Will respond with a 200 status code:

{
"id": "izanami:test:button:color",
"name": "Red button or Blue Button",
"description": "Which button is the better ...",
"enabled": true,
"variants": [
{
"id": "A",
"name": "Red button",
"description": "Variant A is the red button",
"traffic": 0.5
},
{
"id": "B",
"name": "Variant B",
"description": "Variant B is the blue button",
"traffic": 0.5
}
]
}

Patch an experiment

Partial updates can be done using json patch :

curl -X PATCH \
'http://localhost:9000/api/experiments/izanami:test:button:color' \
-H 'Content-Type: application/json' \
-H 'Izanami-Client-Id: xxxx' \
-H 'Izanami-Client-Secret: xxxx' \
-d '[{"op": "replace", "path": "/name", "value": "Orange button or Blue button"}, {"op": "replace", "path": "/variants/0/name", "value": "Orange button"}]' | jq

Will respond with a 200 status code:

{
"id": "izanami:test:button:color",
"name": "Orange button or Blue button",
"description": "Which button is the best ...",
"enabled": true,
"variants": [
{
"id": "A",
"name": "Orange button",
"description": "Variant A is the red button",
"traffic": 0.5
},
{
"id": "B",
"name": "Variant B",
"description": "Variant B is the blue button",
"traffic": 0.5
}
]
}

Delete an experiment

curl -X DELETE \
'http://localhost:9000/api/experiments/izanami:test:button:color' \
-H 'Content-Type: application/json' \
-H 'Izanami-Client-Id: xxxx' \
-H 'Izanami-Client-Secret: xxxx' \
| jq

Will respond with a 200 status code:

{
"id": "izanami:test:button:color",
"name": "Red button or Blue Button",
"description": "Which button is the better ...",
"enabled": true,
"variants": [
{
"id": "A",
"name": "Red button",
"description": "Variant A is the red button",
"traffic": 0.5
},
{
"id": "B",
"name": "Variant B",
"description": "Variant B is the blue button",
"traffic": 0.5
}
]
}

Operations on Variants

A variant is associated to an end user. To get the variant to display you have to provide a "clientId".

Mark variant as displayed

The mark variant as displayed operation will generate an event of type VariantDisplayedEvent. It will also bind a variant to a user if it'as called for the first time.

curl -X POST \
'http://localhost:9000/api/experiments/izanami:test:button:color/displayed?clientId=ragnar.lodbrock@gmail.com' \
-H 'Content-Type: application/json' \
-H 'Izanami-Client-Id: xxxx' \
-H 'Izanami-Client-Secret: xxxx' | jq

Will respond with a 200 status code:

{
"id": "izanami:test:button:color:A:ragnar.lodbrock@gmail.com:displayed:940975692945817657",
"experimentId": "izanami:test:button:color",
"clientId": "ragnar.lodbrock@gmail.com",
"variant": {
"id": "A",
"name": "Red button",
"description": "Variant A is the red button",
"traffic": 0.5,
"currentPopulation": 1
},
"date": "2017-12-13T17:04:22.338",
"transformation": 0,
"variantId": "A",
"@type": "VariantDisplayedEvent"
}

The following end point return the variant associated to a user :

curl -X GET \
'http://localhost:9000/api/experiments/izanami:test:button:color/variant?clientId=ragnar.lodbrock@gmail.com' \
-H 'Content-Type: application/json' \
-H 'Izanami-Client-Id: xxxx' \
-H 'Izanami-Client-Secret: xxxx' \
| jq

A response with a 200 status code is returned if the variant was marked as displayed at least once. A 404 status code is return if not :

{
"id": "A",
"name": "Red button",
"description": "Variant A is the red button",
"traffic": 0.5,
"currentPopulation": 1
}

Mark variant as won

The mark variant as won operation will generate an event of type VariantWonEvent. This action should be call if the corresponding user "validate" the variant displayed.

curl -X POST \
'http://localhost:9000/api/experiments/izanami:test:button:color/won?clientId=ragnar.lodbrock@gmail.com' \
-H 'Content-Type: application/json' \
-H 'Izanami-Client-Id: xxxx' \
-H 'Izanami-Client-Secret: xxxx' | jq

Will respond with a 200 status code:

{
"id": "izanami:test:button:color:A:ragnar.lodbrock@gmail.com:won:940978218122346556",
"experimentId": "izanami:test:button:color",
"clientId": "ragnar.lodbrock@gmail.com",
"variant": {
"id": "A",
"name": "Red button",
"description": "Variant A is the red button",
"traffic": 0.5,
"currentPopulation": 1
},
"date": "2017-12-13T17:14:24.387",
"transformation": 100,
"variantId": "A",
"@type": "VariantWonEvent"
}

The tree API

The tree api will return a set of experiment as a tree form based on a pattern. If the binding between a user and a variant is not done, the association will be done but no event will be generated.

curl -X GET \
'http://localhost:9000/api/tree/experiments?pattern=izanami:test:*&clientId=ragnar.lodbrock@gmail.com' \
-H 'Content-Type: application/json' \
-H 'Izanami-Client-Id: xxxx' \
-H 'Izanami-Client-Secret: xxxx' \
| jq

Will respond with a 200 status code:

{
"izanami": {
"test": {
"button": {
"color": {
"variant": "A"
}
}
}
}
}

Download and Upload

Download and upload is done using the nd-json format.

Download experiments

curl -X GET \
'http://localhost:9000/api/experiments.ndjson' \
-H 'Izanami-Client-Id: xxxx' \
-H 'Izanami-Client-Secret: xxxx' | jq

Will return each item separated by a \n.

{
"id": "izanami:example:button",
"name": "My First experiment",
"description": "See what people like the most about ...",
"enabled": true,
"variants": [
{
"id": "A",
"name": "Variant A",
"description": "Variant A is about ...",
"traffic": 0.5,
"currentPopulation": 3
},
{
"id": "B",
"name": "Variant B",
"description": "Variant B is about ...",
"traffic": 0.5,
"currentPopulation": 3
}
]
}
{
"id": "izanami:test:button:color",
"name": "Red button or Blue Button",
"description": "Which button is the best ...",
"enabled": true,
"variants": [
{
"id": "A",
"name": "Red button",
"description": "Variant A is the red button",
"traffic": 0.5,
"currentPopulation": 1
},
{
"id": "B",
"name": "Variant B",
"description": "Variant B is the blue button",
"traffic": 0.5
}
]
}

Upload experiments

curl -X POST \
'http://localhost:9000/api/experiments.ndjson' \
-H 'Content-Type: application/nd-json' \
-H 'Izanami-Client-Id: xxxx' \
-H 'Izanami-Client-Secret: xxxx' \
-d '...' \
| jq

Will return

{
"success": 2,
"errors": {
"errors": [],
"fieldErrors": {}
}
}

Download bindings

curl -X GET \
'http://localhost:9000/api/experiments/bindings.ndjson' \
-H 'Izanami-Client-Id: xxxx' \
-H 'Izanami-Client-Secret: xxxx' | jq
{
"variantBindingKey": "izanami:example:button:adelegue@yopmail.com",
"variantId": "A"
}
{
"variantBindingKey": "izanami:example:button:ragnar.lodbrock@gmail.com",
"variantId": "B"
}

Upload bindings

curl -X POST \
'http://localhost:9000/api/experiments/bindings.ndjson' \
-H 'Content-Type: application/nd-json' \
-H 'Izanami-Client-Id: xxxx' \
-H 'Izanami-Client-Secret: xxxx' \
-d '...' \
| jq

Download events

curl -X GET \
'http://localhost:9000/api/experiments/events.ndjson' \
-H 'Izanami-Client-Id: xxxx' \
-H 'Izanami-Client-Secret: xxxx' | jq
{
"id": "izanami:example:button:A:adelegue@yopmail.com:displayed:940960339163349002",
"experimentId": "izanami:example:button",
"clientId": "adelegue@yopmail.com",
"variant": {
"id": "A",
"name": "Variant A",
"description": "Variant A is about ...",
"traffic": 0.5,
"currentPopulation": 3
},
"date": "2017-12-13T16:03:21.711",
"transformation": 50,
"variantId": "A",
"@type": "VariantDisplayedEvent"
}
{
"id": "izanami:example:button:A:adelegue@yopmail.com:won:940960356812980243",
"experimentId": "izanami:example:button",
"clientId": "adelegue@yopmail.com",
"variant": {
"id": "A",
"name": "Variant A",
"description": "Variant A is about ...",
"traffic": 0.5,
"currentPopulation": 3
},
"date": "2017-12-13T16:03:25.919",
"transformation": 100,
"variantId": "A",
"@type": "VariantWonEvent"
}

Upload bindings

curl -X POST \
'http://localhost:9000/api/experiments/events.ndjson' \
-H 'Content-Type: application/nd-json' \
-H 'Izanami-Client-Id: xxxx' \
-H 'Izanami-Client-Secret: xxxx' \
-d '...' \
| jq