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's 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