Experience API
Table of contents
Overview
The Experience API is the core of Ninetailed. It returns profiles, JSON representations of visitors and their activity, in response to events. The Experience API is highly performant because of its deployment on the edge.
Endpoints
Create profile
[POST]https://experience.ninetailed.co/v2/organizations/{organizationId}/environments/{environmentSlug}/profiles
Path parameters
Parameter | Type | Description |
---|---|---|
environmentSlug |
string | The slug of the environment of the profile to retrieve. |
organizationId |
string | The ID of the organization of the profile to retrieve. |
Request
const response = await fetch('https://experience.ninetailed.co/v2/organizations/{organizationId}/environments/{environmentSlug}/profiles', {
method: 'POST',
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
"events": [
{
"channel": "web",
"context": {
"app": {
"name": "Ninetailed Analytics SDK",
"version": "1.0.0"
},
"library": {
"name": "Ninetailed Analytics SDK",
"version": "1.0.0"
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36",
"campaign": {},
"locale": "en-US",
"page": {
"path": "/",
"query": {
"utm_campaign": "example_campaign",
"utm_content": "example_content"
},
"referrer": "",
"search": "?utm_campaign=example_campaign&utm_content=example_content",
"url": "https://example.com/?utm_campaign=example_campaign&utm_content=example_content"
}
},
"messageId": "abcd1234-efgh-5678-90ab-cdef11122222",
"anonymousId": "anonymous1",
"type": "page",
"properties": {
"title": "Sample Page",
"url": "https://example.com/?utm_campaign=example_campaign&utm_content=example_content",
"path": "/",
"hash": "",
"search": "?utm_campaign=example_campaign&utm_content=example_content",
"width": "1920",
"height": "1080",
"query": {
"utm_campaign": "example_campaign",
"utm_content": "example_content"
},
"referrer": ""
}
}
]
}),
});
const data = await response.json();
curl -L \
-X POST \
-H 'Content-Type: application/json' \
'https://experience.ninetailed.co/v2/organizations/{organizationId}/environments/{environmentSlug}/profiles' \
-d '{"events":[{"channel":"web","context":{"app":{"name":"Ninetailed Analytics SDK","version":"1.0.0"},"library":{"name":"Ninetailed Analytics SDK","version":"1.0.0"},"userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36","campaign":{},"locale":"en-US","page":{"path":"/","query":{"utm_campaign":"example_campaign","utm_content":"example_content"},"referrer":"","search":"?utm_campaign=example_campaign&utm_content=example_content","url":"https://example.com/?utm_campaign=example_campaign&utm_content=example_content"}},"messageId":"abcd1234-efgh-5678-90ab-cdef11122222","anonymousId":"anonymous1","type":"page","properties":{"title":"Sample Page","url":"https://example.com/?utm_campaign=example_campaign&utm_content=example_content","path":"/","hash":"","search":"?utm_campaign=example_campaign&utm_content=example_content","width":"1920","height":"1080","query":{"utm_campaign":"example_campaign","utm_content":"example_content"},"referrer":""}}]}'
import requests
response = requests.post(
"https://experience.ninetailed.co/v2/organizations/{organizationId}/environments/{environmentSlug}/profiles",
headers={"Content-Type":"application/json"},
json={"events":[{"channel":"web","context":{"app":{"name":"Ninetailed Analytics SDK","version":"1.0.0"},"library":{"name":"Ninetailed Analytics SDK","version":"1.0.0"},"userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36","campaign":{},"locale":"en-US","page":{"path":"/","query":{"utm_campaign":"example_campaign","utm_content":"example_content"},"referrer":"","search":"?utm_campaign=example_campaign&utm_content=example_content","url":"https://example.com/?utm_campaign=example_campaign&utm_content=example_content"}},"messageId":"abcd1234-efgh-5678-90ab-cdef11122222","anonymousId":"anonymous1","type":"page","properties":{"title":"Sample Page","url":"https://example.com/?utm_campaign=example_campaign&utm_content=example_content","path":"/","hash":"","search":"?utm_campaign=example_campaign&utm_content=example_content","width":"1920","height":"1080","query":{"utm_campaign":"example_campaign","utm_content":"example_content"},"referrer":""}}]}
)
data = response.json()
POST /v2/organizations/{organizationId}/environments/{environmentSlug}/profiles HTTP/1.1
Host: experience.ninetailed.co
Content-Type: application/json
Content-Length: 1028
Accept: */*
{
"events": [
{
"channel": "web",
"context": {
"app": {
"name": "Ninetailed Analytics SDK",
"version": "1.0.0"
},
"library": {
"name": "Ninetailed Analytics SDK",
"version": "1.0.0"
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36",
"campaign": {},
"locale": "en-US",
"page": {
"path": "/",
"query": {
"utm_campaign": "example_campaign",
"utm_content": "example_content"
},
"referrer": "",
"search": "?utm_campaign=example_campaign&utm_content=example_content",
"url": "https://example.com/?utm_campaign=example_campaign&utm_content=example_content"
}
},
"messageId": "abcd1234-efgh-5678-90ab-cdef11122222",
"anonymousId": "anonymous1",
"type": "page",
"properties": {
"title": "Sample Page",
"url": "https://example.com/?utm_campaign=example_campaign&utm_content=example_content",
"path": "/",
"hash": "",
"search": "?utm_campaign=example_campaign&utm_content=example_content",
"width": "1920",
"height": "1080",
"query": {
"utm_campaign": "example_campaign",
"utm_content": "example_content"
},
"referrer": ""
}
}
]
}
Response
{
"message": "Missing or invalid data.",
"data": {},
"error": {
"code": "ERR_INVALID_DATA"
}
}
{
"message": "Organization or environment not found",
"data": {},
"error": {
"code": "ERR_CONFIG_NOT_FOUND"
}
}
{
"message": "The profile received too many requests in a short amount of time (These can also be internal requests based on your merge events). Please backoff.",
"data": {},
"error": {
"code": "ERR_PROFILE_OVERLOAD"
}
}
{
"message": "Internal Server Error",
"data": {},
"error": {
"code": "ERR_INTERNAL_SERVER_ERROR"
}
}
Update profile
[POST]https://experience.ninetailed.co/v2/organizations/{organizationId}/environments/{environmentSlug}/profiles/{profileId}
Path parameters
Parameter | Type | Description |
---|---|---|
environmentSlug |
string | The slug of the environment of the profile to retrieve. |
organizationId |
string | The ID of the organization of the profile to retrieve. |
profileId |
string | The ID of the profile to retrieve. |
Request
const response = await fetch('https://experience.ninetailed.co/v2/organizations/{organizationId}/environments/{environmentSlug}/profiles/{profileId}', {
method: 'POST',
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
"events": [
{
"channel": "web",
"context": {
"app": {
"name": "Ninetailed Analytics SDK",
"version": "0.2.0"
},
"library": {
"name": "Ninetailed React Analytics SDK",
"version": "0.2.0"
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36",
"campaign": {},
"locale": "en-US",
"page": {
"path": "/",
"query": {},
"referrer": "",
"search": "",
"url": "https://example.com/"
}
},
"messageId": "58f358f2-a858-11ed-afa1-0242ac120002",
"anonymousId": "18635fe9cc665fd113547e897c13862b",
"timestamp": "2022-10-10T14:36:51.262Z",
"type": "identify",
"traits": {
"favAnimal": "fox"
},
"userId": "asdf"
}
],
"options": {
"locale": "en"
}
}),
});
const data = await response.json();
curl -L \
-X POST \
-H 'Content-Type: application/json' \
'https://experience.ninetailed.co/v2/organizations/{organizationId}/environments/{environmentSlug}/profiles/{profileId}' \
-d '{"events":[{"channel":"web","context":{"app":{"name":"Ninetailed Analytics SDK","version":"0.2.0"},"library":{"name":"Ninetailed React Analytics SDK","version":"0.2.0"},"userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36","campaign":{},"locale":"en-US","page":{"path":"/","query":{},"referrer":"","search":"","url":"https://example.com/"}},"messageId":"58f358f2-a858-11ed-afa1-0242ac120002","anonymousId":"18635fe9cc665fd113547e897c13862b","timestamp":"2022-10-10T14:36:51.262Z","type":"identify","traits":{"favAnimal":"fox"},"userId":"asdf"}],"options":{"locale":"en"}}'
import requests
response = requests.post(
"https://experience.ninetailed.co/v2/organizations/{organizationId}/environments/{environmentSlug}/profiles/{profileId}",
headers={"Content-Type":"application/json"},
json={"events":[{"channel":"web","context":{"app":{"name":"Ninetailed Analytics SDK","version":"0.2.0"},"library":{"name":"Ninetailed React Analytics SDK","version":"0.2.0"},"userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36","campaign":{},"locale":"en-US","page":{"path":"/","query":{},"referrer":"","search":"","url":"https://example.com/"}},"messageId":"58f358f2-a858-11ed-afa1-0242ac120002","anonymousId":"18635fe9cc665fd113547e897c13862b","timestamp":"2022-10-10T14:36:51.262Z","type":"identify","traits":{"favAnimal":"fox"},"userId":"asdf"}],"options":{"locale":"en"}}
)
data = response.json()
POST /v2/organizations/{organizationId}/environments/{environmentSlug}/profiles/{profileId} HTTP/1.1
Host: experience.ninetailed.co
Content-Type: application/json
Content-Length: 649
Accept: */*
{
"events": [
{
"channel": "web",
"context": {
"app": {
"name": "Ninetailed Analytics SDK",
"version": "0.2.0"
},
"library": {
"name": "Ninetailed React Analytics SDK",
"version": "0.2.0"
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36",
"campaign": {},
"locale": "en-US",
"page": {
"path": "/",
"query": {},
"referrer": "",
"search": "",
"url": "https://example.com/"
}
},
"messageId": "58f358f2-a858-11ed-afa1-0242ac120002",
"anonymousId": "18635fe9cc665fd113547e897c13862b",
"timestamp": "2022-10-10T14:36:51.262Z",
"type": "identify",
"traits": {
"favAnimal": "fox"
},
"userId": "asdf"
}
],
"options": {
"locale": "en"
}
}
Response
{
"message": "Missing or invalid data.",
"data": {},
"error": {
"code": "ERR_INVALID_DATA"
}
}
{
"message": "Organization or environment not found",
"data": {},
"error": {
"code": "ERR_CONFIG_NOT_FOUND"
}
}
{
"message": "The profile received too many requests in a short amount of time (These can also be internal requests based on your merge events). Please backoff.",
"data": {},
"error": {
"code": "ERR_PROFILE_OVERLOAD"
}
}
{
"message": "Internal Server Error",
"data": {},
"error": {
"code": "ERR_INTERNAL_SERVER_ERROR"
}
}
Get profile
[GET]https://experience.ninetailed.co/v2/organizations/{organizationId}/environments/{environmentSlug}/profiles/{profileId}
Path parameters
Parameter | Type | Description |
---|---|---|
environmentSlug |
string | The slug of the environment of the profile to retrieve. |
organizationId |
string | The ID of the organization of the profile to retrieve. |
profileId |
string | The ID of the profile to retrieve. |
Request
const response = await fetch('https://experience.ninetailed.co/v2/organizations/{organizationId}/environments/{environmentSlug}/profiles/{profileId}', {
method: 'GET',
headers: {},
});
const data = await response.json();
curl -L \
'https://experience.ninetailed.co/v2/organizations/{organizationId}/environments/{environmentSlug}/profiles/{profileId}'
import requests
response = requests.get(
"https://experience.ninetailed.co/v2/organizations/{organizationId}/environments/{environmentSlug}/profiles/{profileId}",
headers={},
)
data = response.json()
GET /v2/organizations/{organizationId}/environments/{environmentSlug}/profiles/{profileId} HTTP/1.1
Host: experience.ninetailed.co
Accept: */*
Response
{
"message": "Missing or invalid data.",
"data": {},
"error": {
"code": "ERR_INVALID_DATA"
}
}
{
"message": "Organization or environment not found",
"data": {},
"error": {
"code": "ERR_CONFIG_NOT_FOUND"
}
}
{
"message": "The profile received too many requests in a short amount of time (These can also be internal requests based on your merge events). Please backoff.",
"data": {},
"error": {
"code": "ERR_PROFILE_OVERLOAD"
}
}
{
"message": "Internal Server Error",
"data": {},
"error": {
"code": "ERR_INTERNAL_SERVER_ERROR"
}
}
Batch create or update user profiles
You can also use the endpoints of this API to push data from your own existing customer data systems into Ninetailed profiles in real-time, in periodic batches, or in bulk, as part of a first-time migration.
This endpoint upserts profiles, meaning that when events are passed for profile IDs that do not yet exist, profiles at those IDs will be created. This ensures that you do not have to check whether profiles at specific IDs exist prior to migration.
This endpoint accepts up to 200 events, with a maximum of 50 identify
events, across a maximum of 50 unique profiles.
Batch upsert profiles
[POST]https://experience.ninetailed.co/v2/organizations/{organizationId}/environments/{environmentSlug}/events
Path parameters
Parameter | Type | Description |
---|---|---|
environmentSlug |
string | The slug of the environment of the profile to retrieve. |
organizationId |
string | The ID of the organization of the profile to retrieve. |
Request
const response = await fetch('https://experience.ninetailed.co/v2/organizations/{organizationId}/environments/{environmentSlug}/events', {
method: 'POST',
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
"events": [
{
"channel": "web",
"context": {
"app": {
"name": "Ninetailed Analytics SDK",
"version": "0.2.0"
},
"library": {
"name": "Ninetailed React Analytics SDK",
"version": "0.2.0"
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36",
"campaign": {},
"locale": "en-US",
"page": {
"path": "/",
"query": {
"utm_campaign": "example_campaign",
"utm_content": "example_content"
},
"referrer": "",
"search": "?utm_campaign=example_campaign&utm_content=example_content",
"url": "https://example.com/?utm_campaign=example_campaign&utm_content=example_content"
}
},
"messageId": "58f358f2-a858-11ed-afa1-0242ac120002",
"anonymousId": "18635fe9cc665fd113547e897c13862b",
"timestamp": "2022-01-01T00:00:00.000Z",
"type": "page",
"properties": {
"title": "Sample Page",
"url": "https://example.com/?utm_campaign=example_campaign&utm_content=example_content",
"path": "/",
"hash": "",
"search": "?utm_campaign=example_campaign&utm_content=example_content",
"width": 1419,
"height": 1226,
"query": {
"utm_campaign": "example_campaign",
"utm_content": "example_content"
},
"referrer": ""
}
},
{
"channel": "web",
"context": {
"app": {
"name": "Ninetailed Analytics SDK",
"version": "0.2.0"
},
"library": {
"name": "Ninetailed React Analytics SDK",
"version": "0.2.0"
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36",
"campaign": {},
"locale": "en-US",
"page": {
"path": "/",
"query": {
"utm_campaign": "example_campaign",
"utm_content": "example_content"
},
"referrer": "",
"search": "?utm_campaign=example_campaign&utm_content=example_content",
"url": "https://example.com/?utm_campaign=example_campaign&utm_content=example_content"
}
},
"messageId": "58f358f2-a858-11ed-afa1-0242ac120002",
"anonymousId": "18635fe9cc665fd113547e897c13862b",
"userId": "user1",
"traits": {},
"timestamp": "2022-01-01T00:00:00.000Z",
"type": "identify"
},
{
"channel": "web",
"context": {
"app": {
"name": "Ninetailed Analytics SDK",
"version": "0.2.0"
},
"library": {
"name": "Ninetailed React Analytics SDK",
"version": "0.2.0"
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36",
"campaign": {},
"locale": "en-US",
"page": {
"path": "/",
"query": {
"utm_campaign": "example_campaign",
"utm_content": "example_content"
},
"referrer": "",
"search": "?utm_campaign=example_campaign&utm_content=example_content",
"url": "https://example.com/?utm_campaign=example_campaign&utm_content=example_content"
}
},
"messageId": "58f358f2-a858-11ed-afa1-0242ac120002",
"anonymousId": "18635fe9cc665fd113547e897c13862b",
"timestamp": "2022-01-01T00:00:00.000Z",
"type": "page",
"properties": {
"title": "Sample Page",
"url": "https://example.com/?utm_campaign=example_campaign&utm_content=example_content",
"path": "/",
"hash": "",
"search": "?utm_campaign=example_campaign&utm_content=example_content",
"width": 1419,
"height": 1226,
"query": {
"utm_campaign": "example_campaign",
"utm_content": "example_content"
},
"referrer": ""
}
},
{
"channel": "web",
"context": {
"app": {
"name": "Ninetailed Analytics SDK",
"version": "0.2.0"
},
"library": {
"name": "Ninetailed React Analytics SDK",
"version": "0.2.0"
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36",
"campaign": {},
"locale": "en-US",
"page": {
"path": "/",
"query": {
"utm_campaign": "example_campaign",
"utm_content": "example_content"
},
"referrer": "",
"search": "?utm_campaign=example_campaign&utm_content=example_content",
"url": "https://example.com/?utm_campaign=example_campaign&utm_content=example_content"
}
},
"messageId": "58f358f2-a858-11ed-afa1-0242ac120002",
"anonymousId": "18635fe9cc665fd113547e897c13862b",
"userId": "user1",
"traits": {},
"timestamp": "2022-01-01T00:00:00.000Z",
"type": "identify"
},
{
"channel": "web",
"context": {
"app": {
"name": "Ninetailed Analytics SDK",
"version": "0.2.0"
},
"library": {
"name": "Ninetailed React Analytics SDK",
"version": "0.2.0"
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36",
"campaign": {},
"locale": "en-US",
"page": {
"path": "/",
"query": {
"utm_campaign": "example_campaign",
"utm_content": "example_content"
},
"referrer": "",
"search": "?utm_campaign=example_campaign&utm_content=example_content",
"url": "https://example.com/?utm_campaign=example_campaign&utm_content=example_content"
}
},
"messageId": "58f358f2-a858-11ed-afa1-0242ac120002",
"anonymousId": "18635fe9cc665fd113547e897c13862b",
"timestamp": "2022-01-01T00:00:00.000Z",
"type": "page",
"properties": {
"title": "Sample Page",
"url": "https://example.com/?utm_campaign=example_campaign&utm_content=example_content",
"path": "/",
"hash": "",
"search": "?utm_campaign=example_campaign&utm_content=example_content",
"width": 1419,
"height": 1226,
"query": {
"utm_campaign": "example_campaign",
"utm_content": "example_content"
},
"referrer": ""
}
}
]
}),
});
const data = await response.json();
curl -L \
-X POST \
-H 'Content-Type: application/json' \
'https://experience.ninetailed.co/v2/organizations/{organizationId}/environments/{environmentSlug}/events' \
-d '{"events":[{"channel":"web","context":{"app":{"name":"Ninetailed Analytics SDK","version":"0.2.0"},"library":{"name":"Ninetailed React Analytics SDK","version":"0.2.0"},"userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36","campaign":{},"locale":"en-US","page":{"path":"/","query":{"utm_campaign":"example_campaign","utm_content":"example_content"},"referrer":"","search":"?utm_campaign=example_campaign&utm_content=example_content","url":"https://example.com/?utm_campaign=example_campaign&utm_content=example_content"}},"messageId":"58f358f2-a858-11ed-afa1-0242ac120002","anonymousId":"18635fe9cc665fd113547e897c13862b","timestamp":"2022-01-01T00:00:00.000Z","type":"page","properties":{"title":"Sample Page","url":"https://example.com/?utm_campaign=example_campaign&utm_content=example_content","path":"/","hash":"","search":"?utm_campaign=example_campaign&utm_content=example_content","width":1419,"height":1226,"query":{"utm_campaign":"example_campaign","utm_content":"example_content"},"referrer":""}},{"channel":"web","context":{"app":{"name":"Ninetailed Analytics SDK","version":"0.2.0"},"library":{"name":"Ninetailed React Analytics SDK","version":"0.2.0"},"userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36","campaign":{},"locale":"en-US","page":{"path":"/","query":{"utm_campaign":"example_campaign","utm_content":"example_content"},"referrer":"","search":"?utm_campaign=example_campaign&utm_content=example_content","url":"https://example.com/?utm_campaign=example_campaign&utm_content=example_content"}},"messageId":"58f358f2-a858-11ed-afa1-0242ac120002","anonymousId":"18635fe9cc665fd113547e897c13862b","userId":"user1","traits":{},"timestamp":"2022-01-01T00:00:00.000Z","type":"identify"},{"channel":"web","context":{"app":{"name":"Ninetailed Analytics SDK","version":"0.2.0"},"library":{"name":"Ninetailed React Analytics SDK","version":"0.2.0"},"userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36","campaign":{},"locale":"en-US","page":{"path":"/","query":{"utm_campaign":"example_campaign","utm_content":"example_content"},"referrer":"","search":"?utm_campaign=example_campaign&utm_content=example_content","url":"https://example.com/?utm_campaign=example_campaign&utm_content=example_content"}},"messageId":"58f358f2-a858-11ed-afa1-0242ac120002","anonymousId":"18635fe9cc665fd113547e897c13862b","timestamp":"2022-01-01T00:00:00.000Z","type":"page","properties":{"title":"Sample Page","url":"https://example.com/?utm_campaign=example_campaign&utm_content=example_content","path":"/","hash":"","search":"?utm_campaign=example_campaign&utm_content=example_content","width":1419,"height":1226,"query":{"utm_campaign":"example_campaign","utm_content":"example_content"},"referrer":""}},{"channel":"web","context":{"app":{"name":"Ninetailed Analytics SDK","version":"0.2.0"},"library":{"name":"Ninetailed React Analytics SDK","version":"0.2.0"},"userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36","campaign":{},"locale":"en-US","page":{"path":"/","query":{"utm_campaign":"example_campaign","utm_content":"example_content"},"referrer":"","search":"?utm_campaign=example_campaign&utm_content=example_content","url":"https://example.com/?utm_campaign=example_campaign&utm_content=example_content"}},"messageId":"58f358f2-a858-11ed-afa1-0242ac120002","anonymousId":"18635fe9cc665fd113547e897c13862b","userId":"user1","traits":{},"timestamp":"2022-01-01T00:00:00.000Z","type":"identify"},{"channel":"web","context":{"app":{"name":"Ninetailed Analytics SDK","version":"0.2.0"},"library":{"name":"Ninetailed React Analytics SDK","version":"0.2.0"},"userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36","campaign":{},"locale":"en-US","page":{"path":"/","query":{"utm_campaign":"example_campaign","utm_content":"example_content"},"referrer":"","search":"?utm_campaign=example_campaign&utm_content=example_content","url":"https://example.com/?utm_campaign=example_campaign&utm_content=example_content"}},"messageId":"58f358f2-a858-11ed-afa1-0242ac120002","anonymousId":"18635fe9cc665fd113547e897c13862b","timestamp":"2022-01-01T00:00:00.000Z","type":"page","properties":{"title":"Sample Page","url":"https://example.com/?utm_campaign=example_campaign&utm_content=example_content","path":"/","hash":"","search":"?utm_campaign=example_campaign&utm_content=example_content","width":1419,"height":1226,"query":{"utm_campaign":"example_campaign","utm_content":"example_content"},"referrer":""}}]}'
import requests
response = requests.post(
"https://experience.ninetailed.co/v2/organizations/{organizationId}/environments/{environmentSlug}/events",
headers={"Content-Type":"application/json"},
json={"events":[{"channel":"web","context":{"app":{"name":"Ninetailed Analytics SDK","version":"0.2.0"},"library":{"name":"Ninetailed React Analytics SDK","version":"0.2.0"},"userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36","campaign":{},"locale":"en-US","page":{"path":"/","query":{"utm_campaign":"example_campaign","utm_content":"example_content"},"referrer":"","search":"?utm_campaign=example_campaign&utm_content=example_content","url":"https://example.com/?utm_campaign=example_campaign&utm_content=example_content"}},"messageId":"58f358f2-a858-11ed-afa1-0242ac120002","anonymousId":"18635fe9cc665fd113547e897c13862b","timestamp":"2022-01-01T00:00:00.000Z","type":"page","properties":{"title":"Sample Page","url":"https://example.com/?utm_campaign=example_campaign&utm_content=example_content","path":"/","hash":"","search":"?utm_campaign=example_campaign&utm_content=example_content","width":1419,"height":1226,"query":{"utm_campaign":"example_campaign","utm_content":"example_content"},"referrer":""}},{"channel":"web","context":{"app":{"name":"Ninetailed Analytics SDK","version":"0.2.0"},"library":{"name":"Ninetailed React Analytics SDK","version":"0.2.0"},"userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36","campaign":{},"locale":"en-US","page":{"path":"/","query":{"utm_campaign":"example_campaign","utm_content":"example_content"},"referrer":"","search":"?utm_campaign=example_campaign&utm_content=example_content","url":"https://example.com/?utm_campaign=example_campaign&utm_content=example_content"}},"messageId":"58f358f2-a858-11ed-afa1-0242ac120002","anonymousId":"18635fe9cc665fd113547e897c13862b","userId":"user1","traits":{},"timestamp":"2022-01-01T00:00:00.000Z","type":"identify"},{"channel":"web","context":{"app":{"name":"Ninetailed Analytics SDK","version":"0.2.0"},"library":{"name":"Ninetailed React Analytics SDK","version":"0.2.0"},"userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36","campaign":{},"locale":"en-US","page":{"path":"/","query":{"utm_campaign":"example_campaign","utm_content":"example_content"},"referrer":"","search":"?utm_campaign=example_campaign&utm_content=example_content","url":"https://example.com/?utm_campaign=example_campaign&utm_content=example_content"}},"messageId":"58f358f2-a858-11ed-afa1-0242ac120002","anonymousId":"18635fe9cc665fd113547e897c13862b","timestamp":"2022-01-01T00:00:00.000Z","type":"page","properties":{"title":"Sample Page","url":"https://example.com/?utm_campaign=example_campaign&utm_content=example_content","path":"/","hash":"","search":"?utm_campaign=example_campaign&utm_content=example_content","width":1419,"height":1226,"query":{"utm_campaign":"example_campaign","utm_content":"example_content"},"referrer":""}},{"channel":"web","context":{"app":{"name":"Ninetailed Analytics SDK","version":"0.2.0"},"library":{"name":"Ninetailed React Analytics SDK","version":"0.2.0"},"userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36","campaign":{},"locale":"en-US","page":{"path":"/","query":{"utm_campaign":"example_campaign","utm_content":"example_content"},"referrer":"","search":"?utm_campaign=example_campaign&utm_content=example_content","url":"https://example.com/?utm_campaign=example_campaign&utm_content=example_content"}},"messageId":"58f358f2-a858-11ed-afa1-0242ac120002","anonymousId":"18635fe9cc665fd113547e897c13862b","userId":"user1","traits":{},"timestamp":"2022-01-01T00:00:00.000Z","type":"identify"},{"channel":"web","context":{"app":{"name":"Ninetailed Analytics SDK","version":"0.2.0"},"library":{"name":"Ninetailed React Analytics SDK","version":"0.2.0"},"userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36","campaign":{},"locale":"en-US","page":{"path":"/","query":{"utm_campaign":"example_campaign","utm_content":"example_content"},"referrer":"","search":"?utm_campaign=example_campaign&utm_content=example_content","url":"https://example.com/?utm_campaign=example_campaign&utm_content=example_content"}},"messageId":"58f358f2-a858-11ed-afa1-0242ac120002","anonymousId":"18635fe9cc665fd113547e897c13862b","timestamp":"2022-01-01T00:00:00.000Z","type":"page","properties":{"title":"Sample Page","url":"https://example.com/?utm_campaign=example_campaign&utm_content=example_content","path":"/","hash":"","search":"?utm_campaign=example_campaign&utm_content=example_content","width":1419,"height":1226,"query":{"utm_campaign":"example_campaign","utm_content":"example_content"},"referrer":""}}]}
)
data = response.json()
POST /v2/organizations/{organizationId}/environments/{environmentSlug}/events HTTP/1.1
Host: experience.ninetailed.co
Content-Type: application/json
Content-Length: 4804
Accept: */*
{
"events": [
{
"channel": "web",
"context": {
"app": {
"name": "Ninetailed Analytics SDK",
"version": "0.2.0"
},
"library": {
"name": "Ninetailed React Analytics SDK",
"version": "0.2.0"
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36",
"campaign": {},
"locale": "en-US",
"page": {
"path": "/",
"query": {
"utm_campaign": "example_campaign",
"utm_content": "example_content"
},
"referrer": "",
"search": "?utm_campaign=example_campaign&utm_content=example_content",
"url": "https://example.com/?utm_campaign=example_campaign&utm_content=example_content"
}
},
"messageId": "58f358f2-a858-11ed-afa1-0242ac120002",
"anonymousId": "18635fe9cc665fd113547e897c13862b",
"timestamp": "2022-01-01T00:00:00.000Z",
"type": "page",
"properties": {
"title": "Sample Page",
"url": "https://example.com/?utm_campaign=example_campaign&utm_content=example_content",
"path": "/",
"hash": "",
"search": "?utm_campaign=example_campaign&utm_content=example_content",
"width": 1419,
"height": 1226,
"query": {
"utm_campaign": "example_campaign",
"utm_content": "example_content"
},
"referrer": ""
}
},
{
"channel": "web",
"context": {
"app": {
"name": "Ninetailed Analytics SDK",
"version": "0.2.0"
},
"library": {
"name": "Ninetailed React Analytics SDK",
"version": "0.2.0"
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36",
"campaign": {},
"locale": "en-US",
"page": {
"path": "/",
"query": {
"utm_campaign": "example_campaign",
"utm_content": "example_content"
},
"referrer": "",
"search": "?utm_campaign=example_campaign&utm_content=example_content",
"url": "https://example.com/?utm_campaign=example_campaign&utm_content=example_content"
}
},
"messageId": "58f358f2-a858-11ed-afa1-0242ac120002",
"anonymousId": "18635fe9cc665fd113547e897c13862b",
"userId": "user1",
"traits": {},
"timestamp": "2022-01-01T00:00:00.000Z",
"type": "identify"
},
{
"channel": "web",
"context": {
"app": {
"name": "Ninetailed Analytics SDK",
"version": "0.2.0"
},
"library": {
"name": "Ninetailed React Analytics SDK",
"version": "0.2.0"
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36",
"campaign": {},
"locale": "en-US",
"page": {
"path": "/",
"query": {
"utm_campaign": "example_campaign",
"utm_content": "example_content"
},
"referrer": "",
"search": "?utm_campaign=example_campaign&utm_content=example_content",
"url": "https://example.com/?utm_campaign=example_campaign&utm_content=example_content"
}
},
"messageId": "58f358f2-a858-11ed-afa1-0242ac120002",
"anonymousId": "18635fe9cc665fd113547e897c13862b",
"timestamp": "2022-01-01T00:00:00.000Z",
"type": "page",
"properties": {
"title": "Sample Page",
"url": "https://example.com/?utm_campaign=example_campaign&utm_content=example_content",
"path": "/",
"hash": "",
"search": "?utm_campaign=example_campaign&utm_content=example_content",
"width": 1419,
"height": 1226,
"query": {
"utm_campaign": "example_campaign",
"utm_content": "example_content"
},
"referrer": ""
}
},
{
"channel": "web",
"context": {
"app": {
"name": "Ninetailed Analytics SDK",
"version": "0.2.0"
},
"library": {
"name": "Ninetailed React Analytics SDK",
"version": "0.2.0"
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36",
"campaign": {},
"locale": "en-US",
"page": {
"path": "/",
"query": {
"utm_campaign": "example_campaign",
"utm_content": "example_content"
},
"referrer": "",
"search": "?utm_campaign=example_campaign&utm_content=example_content",
"url": "https://example.com/?utm_campaign=example_campaign&utm_content=example_content"
}
},
"messageId": "58f358f2-a858-11ed-afa1-0242ac120002",
"anonymousId": "18635fe9cc665fd113547e897c13862b",
"userId": "user1",
"traits": {},
"timestamp": "2022-01-01T00:00:00.000Z",
"type": "identify"
},
{
"channel": "web",
"context": {
"app": {
"name": "Ninetailed Analytics SDK",
"version": "0.2.0"
},
"library": {
"name": "Ninetailed React Analytics SDK",
"version": "0.2.0"
},
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36",
"campaign": {},
"locale": "en-US",
"page": {
"path": "/",
"query": {
"utm_campaign": "example_campaign",
"utm_content": "example_content"
},
"referrer": "",
"search": "?utm_campaign=example_campaign&utm_content=example_content",
"url": "https://example.com/?utm_campaign=example_campaign&utm_content=example_content"
}
},
"messageId": "58f358f2-a858-11ed-afa1-0242ac120002",
"anonymousId": "18635fe9cc665fd113547e897c13862b",
"timestamp": "2022-01-01T00:00:00.000Z",
"type": "page",
"properties": {
"title": "Sample Page",
"url": "https://example.com/?utm_campaign=example_campaign&utm_content=example_content",
"path": "/",
"hash": "",
"search": "?utm_campaign=example_campaign&utm_content=example_content",
"width": 1419,
"height": 1226,
"query": {
"utm_campaign": "example_campaign",
"utm_content": "example_content"
},
"referrer": ""
}
}
]
}
Response
{
"message": "Missing or invalid data.",
"data": {},
"error": {
"code": "ERR_INVALID_DATA"
}
}
{
"message": "Organization or environment not found",
"data": {},
"error": {
"code": "ERR_CONFIG_NOT_FOUND"
}
}
{
"message": "The profile received too many requests in a short amount of time (These can also be internal requests based on your merge events). Please backoff.",
"data": {},
"error": {
"code": "ERR_PROFILE_OVERLOAD"
}
}
{
"message": "Internal Server Error",
"data": {},
"error": {
"code": "ERR_INTERNAL_SERVER_ERROR"
}
}
Tips
- We highly recommend that you use the
profileID
that is returned by the Ninetailed profile once you have identified the user. Retrieving and updating profiles with this returned ID is more performant than using an ID you have supplied when creating or aliasing a profile. - The payload you supply to these endpoints can be sent with the
content-type
header set as eitherapplication/json
ortext/plain
. We recommend that you usetext/plain
whenever possible to minimize request roundtrip time by avoiding triggering a CORS preflight request. Our SDKs automatically send requests astext/plain
. - If you want to ensure that a user's location is not resolved is part of a create profile or update profile endpoint request, you can either:
- Set an empty string or object, whichever is applicable, to each
context.location
argument, OR - Not set
location
or supplylocation: undefined
orlocation: {}
, do not supplylocation
as an option, and setcontext.library.version
to a string that represents a semver of3.14
or greater.
- Set an empty string or object, whichever is applicable, to each
Types
Response
The returned response of each API endpoint is a data structure indicating the complete representation of the profile(s) and the Ninetailed Experiences & variants that the Experience API has selected for the profile(s). Endpoints that only alter one profile (Create, Update, and Get), only a single profile is returned, while the Batch Upsert Profile Point returns an array of altered profiles.
/**
* One or more ProfileWithSelectedVariants oojects are returned, dpeending on the endpoint uses
*/
type ProfileWithSelectedVariants = {
profile: Profile;
experiences: SelectedVariantInfo[];
};
Profile
A profile is a a wholistic representation of a single user. The Ninetailed Experience API computes and returns a visitor's profile
in response to page
, track
, and identify
events. The profile is also used within Ninetailed's Experience SDKs to determine the appropriate experience variants and Merge Tag values to render.
type Profile = {
id: string;
stableId: string;
random: number;
audiences: string[];
traits: Record<string, any>; // Any valid JSON
location: {
coordinates?: {
latitude: number;
longitude: number;
} | undefined;
city?: string | undefined;
postalCode?: string | undefined;
region?: string | undefined;
regionCode?: string | undefined;
country?: string | undefined;
countryCode?: string | undefined;
continent?: string | undefined;
timezone?: string | undefined;
};
session: {
id: string;
isReturningVisitor: boolean;
landingPage: {
path: string;
url: string;
query: Record<string, string>;
referrer: string;
search: string;
};
count: number;
activeSessionLength: number;
averageSessionLength: number;
};
}
Experience
Each response from the Experience API also returns an array of experience assigned to the profile. you may see this typed in the SDKs as `SelectedVariantInfo Experiences must be published in the content source to be returned on the Experience API. Each experience indicates the variant index (0 = control, 1 = variant 1, etc.) and the content source IDs of content to show.
type Experience = {
experienceId: string;
variantIndex: number;
variants: Record<string, string>;
}
type SelectedVariantInfo = Experience; // The type name used in our SDKs
The key of each variants
Record is the content source's ID of the baseline or control content. The value of each variant Record is the content source's ID of the applicable variant content. When the variant index is 0, the key and value are the same, otherwise they will be different.
{
"experiences": [
{ "experienceId": "1", "variantIndex": 0, "variants": {"entryA": "entryA"}}
{ "experienceId": "2", "variantIndex": 1, "variants": {"entryB": "entryC"}}
]
}
Event
Each POST endpoint accepts arrays of events as part of requests. Events are the building blocks of profiles; they indicate the actions taken and attributes of individual profiles so those profiles can be segmented into Audiences.
type Event = {
anonymousId: string; // Only when using the batch endpoint, otherwise the anonymous ID is in the URL
channel: 'web' | 'mobile' | 'server' | 'client';
context: {
app?: {
name: string;
version: string;
},
// Powers `has viewed page` UTM parameter Audience conditions
campaign?: {
name: string;
source: string;
medium: string;
term: string;
content: string;
},
// Describes the library making the request
library: {
name: string;
version: string;
},
locale?: string; // ISO 639-1 + ISO 3166-2, e.g., "en-US"
// Optionally supply an object to merge with API-resolved location, if the option is set
location?: {
coordinates?: {
latitude: number;
longitude: number
},
city?: string; // Use proper capitalization of the city name
postalCode?: string;
region?: string;
regionCode?: string; // ISO 3166-2
country?: string;
countryCode?: string; // ISO 3166-2
continent?: string;
timezone?: string;
},
// Used for various `has viewed page` Audience conditions
page?: {
path: string;
query: Record<string, string>; // Object of query:value pairs
referrer: string; // Use full URL including protocol, path, and query string
search: string; // Full querystring, e.g., "?query=value"
url: string; // Use full URL including protocol, path, and query string
}
userAgent?: string
}
messageId: string; // Generate a UUID
timestamp: Date; // Typically assigned as Date.now()
type: "page" | "track" | "identify";
event?: string; // Required when type === "track"
userId?: string; // Required when type === "identify"
traits?: Record<string, any>; // Any vaild JSON. Required when type === 'identify'
// Required when type === "page" or type == "event"
properties?: {
// The following five properties must be set when type === "page"
// Not required for events of type == "track"
path: string;
query: Record<string, string>; // Object of query:value pairs
referrer: string; // Use full URL including protocol, path, and query string
search: string; // Full querystring, e.g., "?query=value"
url: string; // Use full URL including protocol, path, and query string
// Any additional properties that can be parsed as valid JSON may be set here
[string]?: any;
}
}
Options
The API endpoints also accept options to modify the behaviour of the request. These are available only on the create profile and update profile endpoint (not the batch upsert endpoint).
type CreateOrUpdateProfilePayload = {
events: Event[];
options?: Options;
}
type Options: = {
features?: Feature[];
}
type Feature = "location" | "ip-enrichment"
- Specifying
location
will attempt to resolve the location of the user based on the IP of the request and where it ingresses to the Experience API.- If you do not want location to be resolved when sending events, do not add
location
as a feature option and ensure thatcontext.library.version
is set on any accompanying event as a string representing a semver greater than3.14
.
- If you do not want location to be resolved when sending events, do not add
- Specifying
ip-enrichment
will attempt to resolve firmographic data with a connected Albacross API Key. See Albacross for more information.
Traits
traits
are arbitrary JSON data set by identify
events. Traits are shallow merged together; the most recent value of a given trait key overwrites the prior value.
Traits are useful for custom segmentation using has trait
rules. Additionally, traits can serve as snippets for dynamic inline personalizations.
Example for an inline Personalization:
const headline = `Hey ${profile.traits.firstname}`
.
type Traits = {
[key: string]: string | number | boolean | Traits;
};
// example
const traits: Traits = {
"firstname": "Max",
"address": {
"street": "Allee 33"
},
"company": "Wayne Enterprises, Inc."
}