Fictioneers APIs
Scroll down for code samples, example requests and responses.
The Fictioneers platform provides several APIs which enable integrators to build and manage rich interactive experiences for their users.
All APIs expect HTTPS, follow RESTful patterns, implement OpenAPI standards, and return JSON.
Get started at https://api.fictioneers.co.uk.
SDKs
Language native SDKs are available on the Fictioneer GitHub.
These libraries include utility wrappers to reduce boilerpate, strongly typed resource objects to enhance developer experience in your IDE, and examples of common patterns to follow.
A quick start guide is also available.
Versioning
To ensure a robust service any backward incompatible changes to the API are made alongside a version increment.
The latest version is served from the route domain for convienience, with specific revisions served from a /v<version_number>
prefixed URI.
For example /users/me
and /v1/users/me
both serve version one (the current version).
Authentication
Depending on the target API and your integration architecture, one of the following is required in the HTTP Authorization
header:
Access Token
Short lived tokens (1 hour) associated with a particular user.
Access Tokens can only be used to authenticate with the Audience API.
Secret API Keys
Secret API Keys should be treated as confidential (just like a password).
You should only reference them in trusted environments (e.g. backend servers) - and not store them in untrusted environments (mobile apps, single page web apps) or version controlled code bases.
Secret API keys can be used to authenticate against the Audience, Auth or Admin API.
Visible API Key
Visible API Keys are used to identify which project a HTTP request is linked to.
They are not used as an authentication mechanism to access sensitive data (e.g. the Admin API), and are safe to embed in untrusted environments (e.g mobile app and single page web app code).
Visible API keys can only be used to authenticate against the Auth API (to mint an access token for anonymous users).
Semantic Prefix
To help avoid confusion when referencing these different types of API Keys, all API Keys have a s_
(secret) or v_
(visible) prefix. For example: s_3852a7882e93c230.vBVrdhmf-pjhSG7ugrU9eJi4mlBi2BcJ3FyG0cBMVY0
Table Reference
Auth API | Audience API | Admin API | |
---|---|---|---|
Visible API Key | Yes | No | No |
Secret API Key | Yes | Yes | Yes |
Access Token | No | Yes | No |
Core Resouces
The Fictioneers domain model consists of the following core objects, each with a corresponding resource in the API:
Timeline
The root object which contains the timeline events, rows, conditions, and beats which describe the narrative and interaction available for users.
User
Represents a user of your experience. For example someone logging into the mobile app you have built to render your Fictioneers timeline.
Narrative data including where they are on timeline, their current variable values, and if they are currently blocked by any progression conditions are also stored on the User object.
User Timeline Events
Represents stateful timeline events - including the content attached to each event and the links which the user can follow.
Links
This object represents a connections between two events which can be followed by a user.
Links can be be used to build paths through timelines and provider the user with choice during their experience.
Each link can have conditions which must be satisfied before the link can be followed by the user.
User Timeline Events State Changes
Represents a state change to a user timeline event.
Collectively these objects form an event log of everything interaction that resulted in an event state change for the user.
Auth API
Authentication service used to generate Access Tokens for the Audience API. A visible or secret API Key is required in the HTTP Authorization header.
Generate an access token.
Code samples
curl -X POST https://api.fictioneers.co.uk/v1/auth/token \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: API_KEY'
POST /v1/auth/token
Access Tokens are tied to a specific user, shorted lived (1 hour), and can only be used to authenticate with the Audience API.
Body parameter
{
"user_id": "4L9MN83KOS"
}
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
body | body | TokenRequest | true | none |
» user_id | body | string | true | User ID scoped to the Access Token being generated. |
Example responses
200 Response
{
"access_token": "ryJhbGciOiJSUzI1NiIsImtpZCI6IjQ7OTQ5ZDdkNDA3ZmVjOXIyYWM4ZDYzNWVjYmEwYjdhOTE0LWQ4ZmIiLCJ0eXAiOiJK",
"expires_in": 3600
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Successful Response | TokenResponse |
422 | Unprocessable Entity | Validation Error | HTTPValidationError |
Introspect an access token.
Code samples
curl -X POST https://api.fictioneers.co.uk/v1/auth/introspect-token \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: API_KEY'
POST /v1/auth/introspect-token
Inspect an access token generated by the authentication API, to view metadata including the expiry datetime.
Body parameter
{
"access_token": "ryJhbGciOiJSUzI1NiIsImtpZCI6IjQ7OTQ5ZDdkNDA3ZmVjOXIyYWM4ZDYzNWVjYmEwYjdhOTE0LWQ4ZmIiLCJ0eXAiOiJK"
}
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
body | body | TokenIntrospectRequest | true | none |
» access_token | body | string | true | Access Token to introspect |
Example responses
200 Response
{
"is_active": true,
"user_id": "4L9MN83KOS",
"expires_in": 3600
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Successful Response | TokenIntrospectResponse |
422 | Unprocessable Entity | Validation Error | HTTPValidationError |
Audience API
The Audience API allows you to drive narrative experiences with access scoped to a particular user. This API is the core of any client-driven experience.
Retrieve current user
Code samples
curl -X GET https://api.fictioneers.co.uk/v1/users/me \
-H 'Accept: application/json' \
-H 'fictioneers-user-id: string' \
-H 'Authorization: API_KEY'
GET /v1/users/me
Retrieve detailed representation of the current user.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
fictioneers-user-id | header | string | false | none |
Example responses
200 Response
{
"data": {
"id": "0HJviYCWMZVYowT7ujWtb7rUEpE3",
"variables": {
"points": "100",
"deadline": "2023-03-15T10:35:26.336571"
},
"current_step": 0,
"current_beat": {
"id": "KLJviYC7MNS7owT7ujWtb7rIHB6",
"name": "Act 1 Beat 3"
},
"new_beat_available": {
"id": "PYztAWXDPnz4BM6qDzx4",
"name": "Act 1 Beat 4"
},
"waiting_for_condition_id": "SzamHkfkMHWpaOUqWOy6",
"waiting_for_condition_datetime": "2023-02-03T09:00:00",
"end_of_timeline_reached": true,
"datetime_guards_disabled": false,
"pause_at_beats": false,
"active_timeline_id": "nevLb8KWPejFV0t0dy9L"
},
"error": {
"detail": "string",
"content": [
{}
]
},
"meta": {
"user": {
"id": "0HJviYCWMZVYowT7ujWtb7rUEpE3",
"variables": {
"points": "100",
"deadline": "2023-03-15T10:35:26.336571"
},
"current_step": 0,
"current_beat": {
"id": "KLJviYC7MNS7owT7ujWtb7rIHB6",
"name": "Act 1 Beat 3"
},
"new_beat_available": {
"id": "PYztAWXDPnz4BM6qDzx4",
"name": "Act 1 Beat 4"
},
"waiting_for_condition_id": "SzamHkfkMHWpaOUqWOy6",
"waiting_for_condition_datetime": "2023-02-03T09:00:00",
"end_of_timeline_reached": true,
"datetime_guards_disabled": false,
"pause_at_beats": false,
"active_timeline_id": "nevLb8KWPejFV0t0dy9L"
},
"changed_timeline_events": [],
"changed_timeline_event_states": [],
"service_status": "ONLINE"
}
}
401 Response
{
"meta": {},
"error": {
"code": 401,
"message": "Unauthorized."
},
"data": {}
}
403 Response
{
"meta": {},
"error": {
"code": 403,
"message": "Forbidden."
},
"data": {}
}
404 Response
{
"meta": {},
"error": {
"code": 404,
"message": "Not Found."
},
"data": {}
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Successful Response | UserResponse |
401 | Unauthorized | Authentication Required | None |
403 | Forbidden | Forbidden | None |
404 | Not Found | Forbidden | None |
422 | Unprocessable Entity | Validation Error | HTTPValidationError |
Response Schema
Delete current user
Code samples
curl -X DELETE https://api.fictioneers.co.uk/v1/users/me \
-H 'Accept: application/json' \
-H 'fictioneers-user-id: string' \
-H 'Authorization: API_KEY'
DELETE /v1/users/me
Delete the user and any user associated objects from the current timeline.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
fictioneers-user-id | header | string | false | none |
Example responses
401 Response
{
"meta": {},
"error": {
"code": 401,
"message": "Unauthorized."
},
"data": {}
}
403 Response
{
"meta": {},
"error": {
"code": 403,
"message": "Forbidden."
},
"data": {}
}
404 Response
{
"meta": {},
"error": {
"code": 404,
"message": "Not Found."
},
"data": {}
}
422 Response
{
"detail": [
{
"loc": [
"string"
],
"msg": "string",
"type": "string"
}
]
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
204 | No Content | Successful Response | None |
401 | Unauthorized | Authentication Required | None |
403 | Forbidden | Forbidden | None |
404 | Not Found | Forbidden | None |
422 | Unprocessable Entity | Validation Error | HTTPValidationError |
Response Schema
Create new user
Code samples
curl -X POST https://api.fictioneers.co.uk/v1/users \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'fictioneers-user-id: string' \
-H 'Authorization: API_KEY'
POST /v1/users
Create a new audience user for a Fictioneers powered experience.
Body parameter
{
"published_timeline_id": "5UNDJoOUBDfSoMlW97a",
"timezone": "Europe/London",
"disable_time_guards": false,
"pause_at_beats": false,
"max_steps": 0,
"variables": {
"credits": "100"
}
}
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
fictioneers-user-id | header | string | false | none |
body | body | CreateUserRequest | true | none |
» published_timeline_id | body | string | true | Published Timeline ID which the created user should be placed on |
» timezone | body | string | true | none |
» disable_time_guards | body | boolean | false | Feature flag to bypass time based guards per user. |
» pause_at_beats | body | boolean | false | Feature flag to toggle pausing execution of progression at beat markers. |
» max_steps | body | integer | false | The maximum amount of steps that should be progressed. Use null to progress until you meet a blocking condition. |
» variables | body | object | false | Override default variable values. |
»» additionalProperties | body | string | false | none |
Example responses
200 Response
{
"data": {
"id": "0HJviYCWMZVYowT7ujWtb7rUEpE3",
"variables": {
"points": "100",
"deadline": "2023-03-15T10:35:26.336571"
},
"current_step": 0,
"current_beat": {
"id": "KLJviYC7MNS7owT7ujWtb7rIHB6",
"name": "Act 1 Beat 3"
},
"new_beat_available": {
"id": "PYztAWXDPnz4BM6qDzx4",
"name": "Act 1 Beat 4"
},
"waiting_for_condition_id": "SzamHkfkMHWpaOUqWOy6",
"waiting_for_condition_datetime": "2023-02-03T09:00:00",
"end_of_timeline_reached": true,
"datetime_guards_disabled": false,
"pause_at_beats": false,
"active_timeline_id": "nevLb8KWPejFV0t0dy9L"
},
"error": {
"detail": "string",
"content": [
{}
]
},
"meta": {
"user": {
"id": "0HJviYCWMZVYowT7ujWtb7rUEpE3",
"variables": {
"points": "100",
"deadline": "2023-03-15T10:35:26.336571"
},
"current_step": 0,
"current_beat": {
"id": "KLJviYC7MNS7owT7ujWtb7rIHB6",
"name": "Act 1 Beat 3"
},
"new_beat_available": {
"id": "PYztAWXDPnz4BM6qDzx4",
"name": "Act 1 Beat 4"
},
"waiting_for_condition_id": "SzamHkfkMHWpaOUqWOy6",
"waiting_for_condition_datetime": "2023-02-03T09:00:00",
"end_of_timeline_reached": true,
"datetime_guards_disabled": false,
"pause_at_beats": false,
"active_timeline_id": "nevLb8KWPejFV0t0dy9L"
},
"changed_timeline_events": [],
"changed_timeline_event_states": [],
"service_status": "ONLINE"
}
}
401 Response
{
"meta": {},
"error": {
"code": 401,
"message": "Unauthorized."
},
"data": {}
}
403 Response
{
"meta": {},
"error": {
"code": 403,
"message": "Forbidden."
},
"data": {}
}
404 Response
{
"meta": {},
"error": {
"code": 404,
"message": "Not Found."
},
"data": {}
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Successful Response | UserResponse |
401 | Unauthorized | Authentication Required | None |
403 | Forbidden | Forbidden | None |
404 | Not Found | Forbidden | None |
422 | Unprocessable Entity | Validation Error | HTTPValidationError |
Response Schema
Progress along the timeline.
Code samples
curl -X POST https://api.fictioneers.co.uk/v1/users/me/progress-step \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'fictioneers-user-id: string' \
-H 'Authorization: API_KEY'
POST /v1/users/me/progress-step
Progress along the timeline.
Body parameter
{
"max_steps": 1,
"pause_at_beats": true
}
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
fictioneers-user-id | header | string | false | none |
body | body | ProgressEventsRequest | true | none |
» max_steps | body | integer | false | The maximum amount of steps that should be progressed. Use null to progress until you meet a blocking condition. |
» pause_at_beats | body | boolean | false | Should beat guards be respected when progressing |
Example responses
200 Response
{
"data": {
"id": "0HJviYCWMZVYowT7ujWtb7rUEpE3",
"variables": {
"points": "100",
"deadline": "2023-03-15T10:35:26.336571"
},
"current_step": 0,
"current_beat": {
"id": "KLJviYC7MNS7owT7ujWtb7rIHB6",
"name": "Act 1 Beat 3"
},
"new_beat_available": {
"id": "PYztAWXDPnz4BM6qDzx4",
"name": "Act 1 Beat 4"
},
"waiting_for_condition_id": "SzamHkfkMHWpaOUqWOy6",
"waiting_for_condition_datetime": "2023-02-03T09:00:00",
"end_of_timeline_reached": true,
"datetime_guards_disabled": false,
"pause_at_beats": false,
"active_timeline_id": "nevLb8KWPejFV0t0dy9L"
},
"error": {
"detail": "string",
"content": [
{}
]
},
"meta": {
"user": {
"id": "0HJviYCWMZVYowT7ujWtb7rUEpE3",
"variables": {
"points": "100",
"deadline": "2023-03-15T10:35:26.336571"
},
"current_step": 0,
"current_beat": {
"id": "KLJviYC7MNS7owT7ujWtb7rIHB6",
"name": "Act 1 Beat 3"
},
"new_beat_available": {
"id": "PYztAWXDPnz4BM6qDzx4",
"name": "Act 1 Beat 4"
},
"waiting_for_condition_id": "SzamHkfkMHWpaOUqWOy6",
"waiting_for_condition_datetime": "2023-02-03T09:00:00",
"end_of_timeline_reached": true,
"datetime_guards_disabled": false,
"pause_at_beats": false,
"active_timeline_id": "nevLb8KWPejFV0t0dy9L"
},
"changed_timeline_events": [],
"changed_timeline_event_states": [],
"service_status": "ONLINE"
}
}
401 Response
{
"meta": {},
"error": {
"code": 401,
"message": "Unauthorized."
},
"data": {}
}
403 Response
{
"meta": {},
"error": {
"code": 403,
"message": "Forbidden."
},
"data": {}
}
404 Response
{
"meta": {},
"error": {
"code": 404,
"message": "Not Found."
},
"data": {}
}
409 Response
{
"meta": {},
"error": {
"code": 409,
"message": "Service Unavailable - Potentially due to contention."
},
"data": {}
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Successful Response | UserResponse |
401 | Unauthorized | Authentication Required | None |
403 | Forbidden | Forbidden | None |
404 | Not Found | Forbidden | None |
409 | Conflict | Service Unavailable - Potentially due to contention. | None |
422 | Unprocessable Entity | Validation Error | HTTPValidationError |
Response Schema
List user timeline events
Code samples
curl -X GET https://api.fictioneers.co.uk/v1/user-timeline-events \
-H 'Accept: application/json' \
-H 'fictioneers-user-id: string' \
-H 'Authorization: API_KEY'
GET /v1/user-timeline-events
List endpoint for user timeline events.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
fictioneers-user-id | header | string | false | none |
Example responses
200 Response
{
"data": [
{
"id": "kNSI3QNGVj3OwByy43ze",
"state": "ACTIVE",
"available_step_index": 1,
"available_beat": {
"id": "KLJviYC7MNS7owT7ujWtb7rIHB6",
"name": "Act 1 Beat 3"
},
"links": [
{
"id": "kNSI3QNGVj3OwByy43ze:MN7S90NBDJNSJS",
"to_event_id": "MN7S90NBDJNSJS",
"label": "Accept the mission!",
"followable": false,
"last_followed_at": "2023-02-03T09:01:23",
"condition_datetime": "2023-02-03T09:00:00"
}
],
"thread_id": "PYztAWXDPnz4BM6qDzx4",
"row_id": "7D83C0It0Kpm62ZQ1gt9",
"row_name": "My row title",
"row_description": "My row description",
"previous_in_row_timeline_event_id": "IM50smQ3suY3nGOXNjp4",
"next_in_row_timeline_event_id": "s1sad1DkWZephtcJDmtM",
"related_timeline_event_ids": [
"MN7S90NBDJNSJS"
],
"narrative_event_id": "0nfWvgIlDZVk5yndCLKm",
"narrative_event_title": "My narrative event",
"narrative_event_description": "My narrative event description",
"narrative_event_content": [
{
"content_id": "MN7S90NBDJ",
"content_type": "BlogPost",
"provider_id": "Contentful"
},
{
"content_id": "EL4S90NNDL",
"content_type": "BlogPost",
"provider_id": "Contentful"
}
],
"narrative_event_state_changes_content": {
"AVAILABLE": [
{
"content_id": "MN7S90NBDJ",
"content_type": "BlogPost",
"provider_id": "Contentful"
},
{
"content_id": "EL4S90NNDL",
"content_type": "BlogPost",
"provider_id": "Contentful"
}
],
"VISITED": [
{
"content_id": "MN7S90NBDJ",
"content_type": "BlogPost",
"provider_id": "Contentful"
}
]
},
"narrative_event_custom_data": {
"button_text": "Press me"
}
}
],
"error": {
"detail": "string",
"content": [
{}
]
},
"meta": {
"user": {
"id": "0HJviYCWMZVYowT7ujWtb7rUEpE3",
"variables": {
"points": "100",
"deadline": "2023-03-15T10:35:26.336571"
},
"current_step": 0,
"current_beat": {
"id": "KLJviYC7MNS7owT7ujWtb7rIHB6",
"name": "Act 1 Beat 3"
},
"new_beat_available": {
"id": "PYztAWXDPnz4BM6qDzx4",
"name": "Act 1 Beat 4"
},
"waiting_for_condition_id": "SzamHkfkMHWpaOUqWOy6",
"waiting_for_condition_datetime": "2023-02-03T09:00:00",
"end_of_timeline_reached": true,
"datetime_guards_disabled": false,
"pause_at_beats": false,
"active_timeline_id": "nevLb8KWPejFV0t0dy9L"
},
"changed_timeline_events": [],
"changed_timeline_event_states": [],
"service_status": "ONLINE"
}
}
401 Response
{
"meta": {},
"error": {
"code": 401,
"message": "Unauthorized."
},
"data": {}
}
403 Response
{
"meta": {},
"error": {
"code": 403,
"message": "Forbidden."
},
"data": {}
}
404 Response
{
"meta": {},
"error": {
"code": 404,
"message": "Not Found."
},
"data": {}
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Successful Response | UserTimelineEventListResponse |
401 | Unauthorized | Authentication Required | None |
403 | Forbidden | Forbidden | None |
404 | Not Found | Forbidden | None |
422 | Unprocessable Entity | Validation Error | HTTPValidationError |
Response Schema
Follow a link
Code samples
curl -X POST https://api.fictioneers.co.uk/v1/user-timeline-events/{user_timeline_event_id}/follow-link \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'fictioneers-user-id: string' \
-H 'Authorization: API_KEY'
POST /v1/user-timeline-events/{user_timeline_event_id}/follow-link
Update the state of the current event to COMPLETED and make the target of the link AVAILABLE (if it has also been reached by step based progression).
Body parameter
{
"link_id": "kNSI3QNGVj3OwByy43ze:MN7S90NBDJNSJS"
}
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
user_timeline_event_id | path | string | true | none |
fictioneers-user-id | header | string | false | none |
body | body | FollowLinkRequest | true | none |
» link_id | body | string | true | The link ID to follow |
Example responses
200 Response
{
"data": {
"id": "kNSI3QNGVj3OwByy43ze",
"state": "ACTIVE",
"available_step_index": 1,
"available_beat": {
"id": "KLJviYC7MNS7owT7ujWtb7rIHB6",
"name": "Act 1 Beat 3"
},
"links": [
{
"id": "kNSI3QNGVj3OwByy43ze:MN7S90NBDJNSJS",
"to_event_id": "MN7S90NBDJNSJS",
"label": "Accept the mission!",
"followable": false,
"last_followed_at": "2023-02-03T09:01:23",
"condition_datetime": "2023-02-03T09:00:00"
}
],
"thread_id": "PYztAWXDPnz4BM6qDzx4",
"row_id": "7D83C0It0Kpm62ZQ1gt9",
"row_name": "My row title",
"row_description": "My row description",
"previous_in_row_timeline_event_id": "IM50smQ3suY3nGOXNjp4",
"next_in_row_timeline_event_id": "s1sad1DkWZephtcJDmtM",
"related_timeline_event_ids": [
"MN7S90NBDJNSJS"
],
"narrative_event_id": "0nfWvgIlDZVk5yndCLKm",
"narrative_event_title": "My narrative event",
"narrative_event_description": "My narrative event description",
"narrative_event_content": [
{
"content_id": "MN7S90NBDJ",
"content_type": "BlogPost",
"provider_id": "Contentful"
},
{
"content_id": "EL4S90NNDL",
"content_type": "BlogPost",
"provider_id": "Contentful"
}
],
"narrative_event_state_changes_content": {
"AVAILABLE": [
{
"content_id": "MN7S90NBDJ",
"content_type": "BlogPost",
"provider_id": "Contentful"
},
{
"content_id": "EL4S90NNDL",
"content_type": "BlogPost",
"provider_id": "Contentful"
}
],
"VISITED": [
{
"content_id": "MN7S90NBDJ",
"content_type": "BlogPost",
"provider_id": "Contentful"
}
]
},
"narrative_event_custom_data": {
"button_text": "Press me"
}
},
"error": {
"detail": "string",
"content": [
{}
]
},
"meta": {
"user": {
"id": "0HJviYCWMZVYowT7ujWtb7rUEpE3",
"variables": {
"points": "100",
"deadline": "2023-03-15T10:35:26.336571"
},
"current_step": 0,
"current_beat": {
"id": "KLJviYC7MNS7owT7ujWtb7rIHB6",
"name": "Act 1 Beat 3"
},
"new_beat_available": {
"id": "PYztAWXDPnz4BM6qDzx4",
"name": "Act 1 Beat 4"
},
"waiting_for_condition_id": "SzamHkfkMHWpaOUqWOy6",
"waiting_for_condition_datetime": "2023-02-03T09:00:00",
"end_of_timeline_reached": true,
"datetime_guards_disabled": false,
"pause_at_beats": false,
"active_timeline_id": "nevLb8KWPejFV0t0dy9L"
},
"changed_timeline_events": [],
"changed_timeline_event_states": [],
"service_status": "ONLINE"
}
}
401 Response
{
"meta": {},
"error": {
"code": 401,
"message": "Unauthorized."
},
"data": {}
}
403 Response
{
"meta": {},
"error": {
"code": 403,
"message": "Forbidden."
},
"data": {}
}
404 Response
{
"meta": {},
"error": {
"code": 404,
"message": "Not Found."
},
"data": {}
}
409 Response
{
"meta": {},
"error": {
"code": 409,
"message": "Service Unavailable - Potentially due to contention."
},
"data": {}
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Successful Response | UserTimelineEventDetailResponse |
401 | Unauthorized | Authentication Required | None |
403 | Forbidden | Forbidden | None |
404 | Not Found | Forbidden | None |
409 | Conflict | Service Unavailable - Potentially due to contention. | None |
422 | Unprocessable Entity | Validation Error | HTTPValidationError |
Response Schema
List event state changes
Code samples
curl -X GET https://api.fictioneers.co.uk/v1/user-timeline-event-state-changes \
-H 'Accept: application/json' \
-H 'fictioneers-user-id: string' \
-H 'Authorization: API_KEY'
GET /v1/user-timeline-event-state-changes
List endpoint for user timeline event state changes implicitly filtered by the authenticated user ID.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
content_type | query | string | false | none |
fictioneers-user-id | header | string | false | none |
Example responses
200 Response
{
"data": [
{
"state": "ACTIVE",
"state_changed_at": "2019-08-24T14:15:22Z",
"state_change_content": [
{
"content_id": "MN7S90NBDJ",
"content_type": "BlogPost",
"provider_id": "Contentful"
},
{
"content_id": "EL4S90NNDL",
"content_type": "BlogPost",
"provider_id": "Contentful"
}
],
"timeline_event_id": "PYztAWXDPnz4BM6qDzx4",
"thread_id": "7D83C0It0Kpm62ZQ1gt9",
"row_id": "i55GFxgI3AODsW9OacUz",
"row_name": "string",
"narrative_event_id": "0nfWvgIlDZVk5yndCLKm",
"narrative_event_title": "My narrative event",
"narrative_event_description": "My narrative event description"
}
],
"error": {
"detail": "string",
"content": [
{}
]
},
"meta": {
"user": {
"id": "0HJviYCWMZVYowT7ujWtb7rUEpE3",
"variables": {
"points": "100",
"deadline": "2023-03-15T10:35:26.336571"
},
"current_step": 0,
"current_beat": {
"id": "KLJviYC7MNS7owT7ujWtb7rIHB6",
"name": "Act 1 Beat 3"
},
"new_beat_available": {
"id": "PYztAWXDPnz4BM6qDzx4",
"name": "Act 1 Beat 4"
},
"waiting_for_condition_id": "SzamHkfkMHWpaOUqWOy6",
"waiting_for_condition_datetime": "2023-02-03T09:00:00",
"end_of_timeline_reached": true,
"datetime_guards_disabled": false,
"pause_at_beats": false,
"active_timeline_id": "nevLb8KWPejFV0t0dy9L"
},
"changed_timeline_events": [],
"changed_timeline_event_states": [],
"service_status": "ONLINE"
}
}
401 Response
{
"meta": {},
"error": {
"code": 401,
"message": "Unauthorized."
},
"data": {}
}
403 Response
{
"meta": {},
"error": {
"code": 403,
"message": "Forbidden."
},
"data": {}
}
404 Response
{
"meta": {},
"error": {
"code": 404,
"message": "Not Found."
},
"data": {}
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Successful Response | UserTimelineEventStateChangeListResponse |
401 | Unauthorized | Authentication Required | None |
403 | Forbidden | Forbidden | None |
404 | Not Found | Forbidden | None |
422 | Unprocessable Entity | Validation Error | HTTPValidationError |
Response Schema
Admin API
Admin service to programatically manage timelines and timeline users. A secret API Key is required in the HTTP Authorization header.
list all published timelines
Code samples
curl -X GET https://api.fictioneers.co.uk/v1/timelines \
-H 'Accept: application/json' \
-H 'Authorization: API_KEY'
GET /v1/timelines
list all published timelines which users can be placed on.
Example responses
200 Response
[
{
"id": "0nfWvgIlDZVk5yndCLKm",
"title": "Alice's Adventure In Wonderland",
"description": "A 30 day immersive experience in Wonderland."
}
]
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Successful Response | Inline |
Response Schema
Status Code 200
Response Get Timelines V1 Timelines Get
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
Response Get Timelines V1 Timelines Get | [Timeline] | false | none | [API representation of timeline resource.] |
» Timeline | Timeline | false | none | API representation of timeline resource. |
»» id | string | true | none | none |
»» title | string | true | none | none |
»» description | string | false | none | none |
Retrieves timeline
Code samples
curl -X GET https://api.fictioneers.co.uk/v1/timelines/{timeline_id} \
-H 'Accept: application/json' \
-H 'Authorization: API_KEY'
GET /v1/timelines/{timeline_id}
Representation of a single timeline.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
timeline_id | path | string | true | none |
Example responses
200 Response
{
"id": "0nfWvgIlDZVk5yndCLKm",
"title": "Alice's Adventure In Wonderland",
"description": "A 30 day immersive experience in Wonderland."
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Successful Response | Timeline |
422 | Unprocessable Entity | Validation Error | HTTPValidationError |
lists all timeline variables
Code samples
curl -X GET https://api.fictioneers.co.uk/v1/timelines/{timeline_id}/variables \
-H 'Accept: application/json' \
-H 'Authorization: API_KEY'
GET /v1/timelines/{timeline_id}/variables
lists all variables with their default and current values.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
timeline_id | path | string | true | none |
Example responses
200 Response
[
{
"name": "coins",
"scope": "shared",
"default_value": "100",
"value": "200"
}
]
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Successful Response | Inline |
422 | Unprocessable Entity | Validation Error | HTTPValidationError |
Response Schema
Status Code 200
Response List Timeline Variables V1 Timelines Timeline Id Variables Get
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
Response List Timeline Variables V1 Timelines Timeline Id Variables Get | [Variable] | false | none | [API representation of a timeline variable.] |
» Variable | Variable | false | none | API representation of a timeline variable. |
»» name | string | true | none | none |
»» scope | VariableScope | true | none | The scope of a variable. User values are specific to a single user, shared values are across all users on a timeline. |
»» default_value | string | true | none | none |
»» value | string | false | none | Current value of the variable. For user scoped variables this is always None - see an individual user API response for each unique value. |
Enumerated Values
Property | Value |
---|---|
scope | user |
scope | shared |
Get timeline variable
Code samples
curl -X GET https://api.fictioneers.co.uk/v1/timelines/{timeline_id}/variables/{name} \
-H 'Accept: application/json' \
-H 'Authorization: API_KEY'
GET /v1/timelines/{timeline_id}/variables/{name}
Detail representation of a single timeline variable.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
timeline_id | path | string | true | none |
name | path | string | true | none |
Example responses
200 Response
{
"name": "coins",
"scope": "shared",
"default_value": "100",
"value": "200"
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Successful Response | Variable |
422 | Unprocessable Entity | Validation Error | HTTPValidationError |
Update shared variable value
Code samples
curl -X PATCH https://api.fictioneers.co.uk/v1/timelines/{timeline_id}/variables/{name} \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: API_KEY'
PATCH /v1/timelines/{timeline_id}/variables/{name}
Update the value of a shared timeline variable.
Body parameter
{
"value": "200"
}
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
timeline_id | path | string | true | none |
name | path | string | true | none |
body | body | UpdateVariableValue | true | none |
» value | body | string | true | New variable value |
Example responses
200 Response
{
"name": "coins",
"scope": "shared",
"default_value": "100",
"value": "200"
}
409 Response
{
"meta": {},
"error": {
"code": 409,
"message": "Service Unavailable - Potentially due to contention."
},
"data": {}
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Successful Response | Variable |
409 | Conflict | Service Unavailable - Potentially due to contention. | None |
422 | Unprocessable Entity | Validation Error | HTTPValidationError |
Response Schema
lists all timeline events
Code samples
curl -X GET https://api.fictioneers.co.uk/v1/timelines/{timeline_id}/timeline-events \
-H 'Accept: application/json' \
-H 'Authorization: API_KEY'
GET /v1/timelines/{timeline_id}/timeline-events
lists all timeline events on a specific timeline.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
timeline_id | path | string | true | none |
Example responses
200 Response
[
{
"id": "kNSI3QNGVj3OwByy43ze",
"title": "Find the flag!",
"description": "You have 30 seconds to find the flag - go go go!",
"step": 1,
"content_integrations": {
"ACTIVE": [
{
"content_id": {
"example": "MN7S90NBDJ"
},
"content_type": {
"example": "BlogPost"
},
"provider_id": {
"example": "Contentful"
}
}
]
},
"narrative_event_id": "string",
"narrative_event_custom_data": {}
}
]
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Successful Response | Inline |
422 | Unprocessable Entity | Validation Error | HTTPValidationError |
Response Schema
Status Code 200
Response List Timeline Timeline Events V1 Timelines Timeline Id Timeline Events Get
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
Response List Timeline Timeline Events V1 Timelines Timeline Id Timeline Events Get | [TimelineEvent] | false | none | [ ] |
» TimelineEvent | TimelineEvent | false | none | none |
»» id | string | true | none | none |
»» title | string | true | none | none |
»» description | string | false | none | none |
»» step | integer | false | none | none |
»» content_integrations | object | true | none | none |
»»» additionalProperties | [ContentIntegration] | false | none | [Represents content referenced in an external data source to an event state.] |
»»»» ContentIntegration | ContentIntegration | false | none | Represents content referenced in an external data source to an event state. |
»»»»» content_id | string | true | none | none |
»»»»» content_type | string | true | none | none |
»»»»» provider_id | string | true | none | none |
»» narrative_event_id | string | true | none | none |
»» narrative_event_custom_data | object | false | none | none |
»»» additionalProperties | string | false | none | none |
list all timeline users
Code samples
curl -X GET https://api.fictioneers.co.uk/v1/timelines/{timeline_id}/users \
-H 'Accept: application/json' \
-H 'Authorization: API_KEY'
GET /v1/timelines/{timeline_id}/users
list of all users on timeline.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
timeline_id | path | string | true | none |
Example responses
200 Response
[
{
"id": "0HJviYCWMZVYowT7ujWtb7rUEpE3",
"variables": {
"points": "100",
"deadline": "2023-03-15T10:35:26.336571"
},
"current_step": 0,
"current_beat": {
"id": "KLJviYC7MNS7owT7ujWtb7rIHB6",
"name": "Act 1 Beat 3"
},
"new_beat_available": {
"id": "PYztAWXDPnz4BM6qDzx4",
"name": "Act 1 Beat 4"
},
"waiting_for_condition_id": "SzamHkfkMHWpaOUqWOy6",
"waiting_for_condition_datetime": "2023-02-03T09:00:00",
"end_of_timeline_reached": true,
"datetime_guards_disabled": false,
"pause_at_beats": false,
"active_timeline_id": "nevLb8KWPejFV0t0dy9L"
}
]
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Successful Response | Inline |
422 | Unprocessable Entity | Validation Error | HTTPValidationError |
Response Schema
Status Code 200
Response Get Timeline Users V1 Timelines Timeline Id Users Get
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
Response Get Timeline Users V1 Timelines Timeline Id Users Get | [User] | false | none | [API representation of an audience user on a specific timeline.] |
» User | User | false | none | API representation of an audience user on a specific timeline. |
»» id | string | true | none | Unique identifier for the user. |
»» variables | object | true | none | User level variable values |
»»» additionalProperties | string | false | none | none |
»» current_step | integer | false | none | Current step index for user in event delivery sequence |
»» current_beat | Beat¦null | false | none | Current beat based on user narrative progress. |
»»» id | string | false | none | ID of the beat. |
»»» name | string | false | none | Name of the beat. |
»» new_beat_available | Beat¦null | false | none | Denotes if the next beat is available for progression. |
»»» id | string | false | none | ID of the beat. |
»»» name | string | false | none | Name of the beat. |
»» waiting_for_condition_id | string | false | none | Condition currently blocking further progression |
»» waiting_for_condition_datetime | string(date-time) | false | none | If the user is currently blocked due to a time condition, the time at which that condition is expected to pass |
»» end_of_timeline_reached | boolean | true | none | Denotes if all progression conditions have been satisfied. Note this does not mean that all delivery conditions (on threads for example) have been satisfied. |
»» datetime_guards_disabled | boolean | true | none | Testing feature which skips any time guards if enabled. |
»» pause_at_beats | boolean | true | none | Should progression execution pause at beats. |
»» active_timeline_id | string | true | none | none |
Delete all timeline users
Code samples
curl -X DELETE https://api.fictioneers.co.uk/v1/timelines/{timeline_id}/users \
-H 'Accept: application/json' \
-H 'Authorization: API_KEY'
DELETE /v1/timelines/{timeline_id}/users
Delete all users on a timeline.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
timeline_id | path | string | true | none |
Example responses
422 Response
{
"detail": [
{
"loc": [
"string"
],
"msg": "string",
"type": "string"
}
]
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
204 | No Content | Successful Response | None |
422 | Unprocessable Entity | Validation Error | HTTPValidationError |
Retrieves timeline user
Code samples
curl -X GET https://api.fictioneers.co.uk/v1/timelines/{timeline_id}/users/{user_id} \
-H 'Accept: application/json' \
-H 'Authorization: API_KEY'
GET /v1/timelines/{timeline_id}/users/{user_id}
Retrieves timeline user.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
timeline_id | path | string | true | none |
user_id | path | string | true | none |
Example responses
200 Response
{
"id": "0HJviYCWMZVYowT7ujWtb7rUEpE3",
"variables": {
"points": "100",
"deadline": "2023-03-15T10:35:26.336571"
},
"current_step": 0,
"current_beat": {
"id": "KLJviYC7MNS7owT7ujWtb7rIHB6",
"name": "Act 1 Beat 3"
},
"new_beat_available": {
"id": "PYztAWXDPnz4BM6qDzx4",
"name": "Act 1 Beat 4"
},
"waiting_for_condition_id": "SzamHkfkMHWpaOUqWOy6",
"waiting_for_condition_datetime": "2023-02-03T09:00:00",
"end_of_timeline_reached": true,
"datetime_guards_disabled": false,
"pause_at_beats": false,
"active_timeline_id": "nevLb8KWPejFV0t0dy9L"
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Successful Response | User |
422 | Unprocessable Entity | Validation Error | HTTPValidationError |
Delete timeline user
Code samples
curl -X DELETE https://api.fictioneers.co.uk/v1/timelines/{timeline_id}/users/{user_id} \
-H 'Accept: application/json' \
-H 'Authorization: API_KEY'
DELETE /v1/timelines/{timeline_id}/users/{user_id}
Delete timeline user.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
timeline_id | path | string | true | none |
user_id | path | string | true | none |
Example responses
422 Response
{
"detail": [
{
"loc": [
"string"
],
"msg": "string",
"type": "string"
}
]
}
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
204 | No Content | Successful Response | None |
422 | Unprocessable Entity | Validation Error | HTTPValidationError |
list all event state changes for timeline.
Code samples
curl -X GET https://api.fictioneers.co.uk/v1/timelines/{timeline_id}/event-state-changes \
-H 'Accept: application/json' \
-H 'Authorization: API_KEY'
GET /v1/timelines/{timeline_id}/event-state-changes
Returns all event state changes filtered by timeline.
Parameters
Name | In | Type | Required | Description |
---|---|---|---|---|
timeline_id | path | string | true | none |
Example responses
200 Response
[
{
"esc_type": "string",
"narrative_event_id": "string",
"timeline_event_id": "string",
"thread_id": "string",
"beat_id": "string",
"available_step_index": 0,
"processed_step_index": 0,
"workspace_id": "string",
"project_id": "string",
"timeline_id": "string",
"user_id": "string",
"created_at": "2019-08-24T14:15:22Z"
}
]
Responses
Status | Meaning | Description | Schema |
---|---|---|---|
200 | OK | Successful Response | Inline |
422 | Unprocessable Entity | Validation Error | HTTPValidationError |
Response Schema
Status Code 200
Response List All Timeline Event State Changes V1 Timelines Timeline Id Event State Changes Get
Name | Type | Required | Restrictions | Description |
---|---|---|---|---|
Response List All Timeline Event State Changes V1 Timelines Timeline Id Event State Changes Get | [EventStateChange] | false | none | [API representation of the EventStateChange resource.] |
» EventStateChange | EventStateChange | false | none | API representation of the EventStateChange resource. |
»» esc_type | string | true | none | none |
»» narrative_event_id | string | true | none | none |
»» timeline_event_id | string | true | none | none |
»» thread_id | string | false | none | none |
»» beat_id | string | false | none | none |
»» available_step_index | integer | true | none | none |
»» processed_step_index | integer | true | none | none |
»» workspace_id | string | true | none | none |
»» project_id | string | true | none | none |
»» timeline_id | string | true | none | none |
»» user_id | string | true | none | none |
»» created_at | string(date-time) | true | none | none |
Webhooks API
Our webhook API can be used to subscribe to particular events, enabling you to build reactive systems based on real-time user activity.
For example, you might have a decoupled messaging service that is triggered each time a user is created through a user.created
event subscription.
All you need is a URL handler which should expect a HTTP POST
request with a JSON payload from the Fictioneers webhook API.
The following events are available:
- user.created
- user.deleted
- state.changed
- event_hook.created
- beat.entered
For more information on the shape of these payload talk to the Fictioneers engineering team.
Verify Webhook Authenticity
Every webhook request sent from the Fictioneers platform has a Fictioneers-Signature
HTTP header, which can be used to verify the authenticity of the message.
This signature value is a SHA-256 based HMAC.
To calculate if the request comes from a trusted source, and that the request body remains un-tampered, compute the signature and compare it to the header value.
A pseudo code example using Python:
import hashlib
import hmac
import os
from fastapi import Depends
FICTIONEERS_SIGNATURE_HEADER = 'Fictioneers-Signature'
SHARED_SECRET_FOR_WEBHOOK = os.environ['WEBHOOK_SECRET']
async def webhook_signature_valid(request: Request) -> bool:
"""
Compare the source and computed Fictioneer webhook signatures.
"""
sender_webhook_signature = request.headers.get(FICTIONEERS_SIGNATURE_HEADER)
body = await request.body()
client_calculated_signature = hmac.new(
SHARED_SECRET_FOR_WEBHOOK.encode('utf-8'),
body,
digestmod=hashlib.sha256
).hexdigest()
return client_calculated_signature == sender_webhook_signature
Reference
Beat
{
"id": "KLJviYC7MNS7owT7ujWtb7rIHB6",
"name": "Act 1 Beat 3"
}
Properties
Name | Type | Required | Description |
---|---|---|---|
id | string | false | ID of the beat. |
name | string | false | Name of the beat. |
ContentIntegration
{
"content_id": "MN7S90NBDJ",
"content_type": "BlogPost",
"provider_id": "Contentful"
}
Properties
Name | Type | Required | Description |
---|---|---|---|
content_id | string | true | |
content_type | string | true | |
provider_id | string | true |
CreateUserRequest
{
"published_timeline_id": "5UNDJoOUBDfSoMlW97a",
"timezone": "Europe/London",
"disable_time_guards": false,
"pause_at_beats": false,
"max_steps": 0,
"variables": {
"credits": "100"
}
}
Properties
Name | Type | Required | Description |
---|---|---|---|
published_timeline_id | string | true | Published Timeline ID which the created user should be placed on |
timezone | string | true | |
disable_time_guards | boolean | false | Feature flag to bypass time based guards per user. |
pause_at_beats | boolean | false | Feature flag to toggle pausing execution of progression at beat markers. |
max_steps | integer | false | The maximum amount of steps that should be progressed. Use null to progress until you meet a blocking condition. |
variables | object | false | Override default variable values. |
» additionalProperties | string | false |
EventStateChange
{
"esc_type": "string",
"narrative_event_id": "string",
"timeline_event_id": "string",
"thread_id": "string",
"beat_id": "string",
"available_step_index": 0,
"processed_step_index": 0,
"workspace_id": "string",
"project_id": "string",
"timeline_id": "string",
"user_id": "string",
"created_at": "2019-08-24T14:15:22Z"
}
Properties
Name | Type | Required | Description |
---|---|---|---|
esc_type | string | true | |
narrative_event_id | string | true | |
timeline_event_id | string | true | |
thread_id | string | false | |
beat_id | string | false | |
available_step_index | integer | true | |
processed_step_index | integer | true | |
workspace_id | string | true | |
project_id | string | true | |
timeline_id | string | true | |
user_id | string | true | |
created_at | string(date-time) | true |
FollowLinkRequest
{
"link_id": "kNSI3QNGVj3OwByy43ze:MN7S90NBDJNSJS"
}
Properties
Name | Type | Required | Description |
---|---|---|---|
link_id | string | true | The link ID to follow |
GeneralError
{
"detail": "string",
"content": [
{}
]
}
Properties
Name | Type | Required | Description |
---|---|---|---|
detail | string | false | |
content | [object] | false |
HTTPValidationError
{
"detail": [
{
"loc": [
"string"
],
"msg": "string",
"type": "string"
}
]
}
Properties
Name | Type | Required | Description |
---|---|---|---|
detail | [ValidationError] | false |
Meta
{
"user": {
"id": "0HJviYCWMZVYowT7ujWtb7rUEpE3",
"variables": {
"points": "100",
"deadline": "2023-03-15T10:35:26.336571"
},
"current_step": 0,
"current_beat": {
"id": "KLJviYC7MNS7owT7ujWtb7rIHB6",
"name": "Act 1 Beat 3"
},
"new_beat_available": {
"id": "PYztAWXDPnz4BM6qDzx4",
"name": "Act 1 Beat 4"
},
"waiting_for_condition_id": "SzamHkfkMHWpaOUqWOy6",
"waiting_for_condition_datetime": "2023-02-03T09:00:00",
"end_of_timeline_reached": true,
"datetime_guards_disabled": false,
"pause_at_beats": false,
"active_timeline_id": "nevLb8KWPejFV0t0dy9L"
},
"changed_timeline_events": [],
"changed_timeline_event_states": [],
"service_status": "ONLINE"
}
Properties
Name | Type | Required | Description |
---|---|---|---|
user | User | false | API representation of an audience user on a specific timeline. |
changed_timeline_events | [UserTimelineEvent] | false | [Represents a user timeline event.] |
changed_timeline_event_states | [UserTimelineEventStateChange] | false | [Represents a user timeline event state change.] |
service_status | ServiceStatus | false | An enumeration. |
NewUserTimelineEventState
"UNVISITED"
Properties
Name | Type | Required | Description |
---|---|---|---|
NewUserTimelineEventState | string | false | An enumeration. |
Enumerated Values
Property | Value |
---|---|
NewUserTimelineEventState | UNVISITED |
NewUserTimelineEventState | ACTIVE |
NewUserTimelineEventState | VISITED |
ProgressEventsRequest
{
"max_steps": 1,
"pause_at_beats": true
}
Properties
Name | Type | Required | Description |
---|---|---|---|
max_steps | integer | false | The maximum amount of steps that should be progressed. Use null to progress until you meet a blocking condition. |
pause_at_beats | boolean | false | Should beat guards be respected when progressing |
ServiceStatus
"ONLINE"
Properties
Name | Type | Required | Description |
---|---|---|---|
ServiceStatus | string | false | An enumeration. |
Enumerated Values
Property | Value |
---|---|
ServiceStatus | ONLINE |
ServiceStatus | MAINTENANCE |
Timeline
{
"id": "0nfWvgIlDZVk5yndCLKm",
"title": "Alice's Adventure In Wonderland",
"description": "A 30 day immersive experience in Wonderland."
}
Properties
Name | Type | Required | Description |
---|---|---|---|
id | string | true | |
title | string | true | |
description | string | false |
TimelineEvent
{
"id": "kNSI3QNGVj3OwByy43ze",
"title": "Find the flag!",
"description": "You have 30 seconds to find the flag - go go go!",
"step": 1,
"content_integrations": {
"ACTIVE": [
{
"content_id": {
"example": "MN7S90NBDJ"
},
"content_type": {
"example": "BlogPost"
},
"provider_id": {
"example": "Contentful"
}
}
]
},
"narrative_event_id": "string",
"narrative_event_custom_data": {}
}
Properties
Name | Type | Required | Description |
---|---|---|---|
id | string | true | |
title | string | true | |
description | string | false | |
step | integer | false | |
content_integrations | object | true | |
» additionalProperties | [ContentIntegration] | false | [Represents content referenced in an external data source to an event state.] |
narrative_event_id | string | true | |
narrative_event_custom_data | object | false | |
» additionalProperties | string | false |
TokenIntrospectRequest
{
"access_token": "ryJhbGciOiJSUzI1NiIsImtpZCI6IjQ7OTQ5ZDdkNDA3ZmVjOXIyYWM4ZDYzNWVjYmEwYjdhOTE0LWQ4ZmIiLCJ0eXAiOiJK"
}
Properties
Name | Type | Required | Description |
---|---|---|---|
access_token | string | true | Access Token to introspect |
TokenIntrospectResponse
{
"is_active": true,
"user_id": "4L9MN83KOS",
"expires_in": 3600
}
Properties
Name | Type | Required | Description |
---|---|---|---|
is_active | boolean | true | Status of the token. |
user_id | string | false | |
expires_in | integer | false | Time in seconds until the access token expires. |
TokenRequest
{
"user_id": "4L9MN83KOS"
}
Properties
Name | Type | Required | Description |
---|---|---|---|
user_id | string | true | User ID scoped to the Access Token being generated. |
TokenResponse
{
"access_token": "ryJhbGciOiJSUzI1NiIsImtpZCI6IjQ7OTQ5ZDdkNDA3ZmVjOXIyYWM4ZDYzNWVjYmEwYjdhOTE0LWQ4ZmIiLCJ0eXAiOiJK",
"expires_in": 3600
}
Properties
Name | Type | Required | Description |
---|---|---|---|
access_token | string | true | Access Token used to authenticate with Audience APIs. |
expires_in | integer | true | Time in seconds until the Access Token expires. |
UpdateVariableValue
{
"value": "200"
}
Properties
Name | Type | Required | Description |
---|---|---|---|
value | string | true | New variable value |
User
{
"id": "0HJviYCWMZVYowT7ujWtb7rUEpE3",
"variables": {
"points": "100",
"deadline": "2023-03-15T10:35:26.336571"
},
"current_step": 0,
"current_beat": {
"id": "KLJviYC7MNS7owT7ujWtb7rIHB6",
"name": "Act 1 Beat 3"
},
"new_beat_available": {
"id": "PYztAWXDPnz4BM6qDzx4",
"name": "Act 1 Beat 4"
},
"waiting_for_condition_id": "SzamHkfkMHWpaOUqWOy6",
"waiting_for_condition_datetime": "2023-02-03T09:00:00",
"end_of_timeline_reached": true,
"datetime_guards_disabled": false,
"pause_at_beats": false,
"active_timeline_id": "nevLb8KWPejFV0t0dy9L"
}
Properties
Name | Type | Required | Description |
---|---|---|---|
id | string | true | Unique identifier for the user. |
variables | object | true | User level variable values |
» additionalProperties | string | false | |
current_step | integer | false | Current step index for user in event delivery sequence |
current_beat | Beat¦null | false | Current beat based on user narrative progress. |
new_beat_available | Beat¦null | false | Denotes if the next beat is available for progression. |
waiting_for_condition_id | string | false | Condition currently blocking further progression |
waiting_for_condition_datetime | string(date-time) | false | If the user is currently blocked due to a time condition, the time at which that condition is expected to pass |
end_of_timeline_reached | boolean | true | Denotes if all progression conditions have been satisfied. Note this does not mean that all delivery conditions (on threads for example) have been satisfied. |
datetime_guards_disabled | boolean | true | Testing feature which skips any time guards if enabled. |
pause_at_beats | boolean | true | Should progression execution pause at beats. |
active_timeline_id | string | true |
UserResponse
{
"data": {
"id": "0HJviYCWMZVYowT7ujWtb7rUEpE3",
"variables": {
"points": "100",
"deadline": "2023-03-15T10:35:26.336571"
},
"current_step": 0,
"current_beat": {
"id": "KLJviYC7MNS7owT7ujWtb7rIHB6",
"name": "Act 1 Beat 3"
},
"new_beat_available": {
"id": "PYztAWXDPnz4BM6qDzx4",
"name": "Act 1 Beat 4"
},
"waiting_for_condition_id": "SzamHkfkMHWpaOUqWOy6",
"waiting_for_condition_datetime": "2023-02-03T09:00:00",
"end_of_timeline_reached": true,
"datetime_guards_disabled": false,
"pause_at_beats": false,
"active_timeline_id": "nevLb8KWPejFV0t0dy9L"
},
"error": {
"detail": "string",
"content": [
{}
]
},
"meta": {
"user": {
"id": "0HJviYCWMZVYowT7ujWtb7rUEpE3",
"variables": {
"points": "100",
"deadline": "2023-03-15T10:35:26.336571"
},
"current_step": 0,
"current_beat": {
"id": "KLJviYC7MNS7owT7ujWtb7rIHB6",
"name": "Act 1 Beat 3"
},
"new_beat_available": {
"id": "PYztAWXDPnz4BM6qDzx4",
"name": "Act 1 Beat 4"
},
"waiting_for_condition_id": "SzamHkfkMHWpaOUqWOy6",
"waiting_for_condition_datetime": "2023-02-03T09:00:00",
"end_of_timeline_reached": true,
"datetime_guards_disabled": false,
"pause_at_beats": false,
"active_timeline_id": "nevLb8KWPejFV0t0dy9L"
},
"changed_timeline_events": [],
"changed_timeline_event_states": [],
"service_status": "ONLINE"
}
}
Properties
Name | Type | Required | Description |
---|---|---|---|
data | User | false | API representation of an audience user on a specific timeline. |
error | GeneralError¦null | false | Provides details around errors and problems encountered while performing an HTTP operation. |
meta | Meta¦null | false | Provides meta information related to the HTTP request. When progressing an audience user narrative state this includes all timeline events which have been created or update, to avoid a subsequent HTTP request to the API. |
UserTimelineEvent
{
"id": "kNSI3QNGVj3OwByy43ze",
"state": "ACTIVE",
"available_step_index": 1,
"available_beat": {
"id": "KLJviYC7MNS7owT7ujWtb7rIHB6",
"name": "Act 1 Beat 3"
},
"links": [
{
"id": "kNSI3QNGVj3OwByy43ze:MN7S90NBDJNSJS",
"to_event_id": "MN7S90NBDJNSJS",
"label": "Accept the mission!",
"followable": false,
"last_followed_at": "2023-02-03T09:01:23",
"condition_datetime": "2023-02-03T09:00:00"
}
],
"thread_id": "PYztAWXDPnz4BM6qDzx4",
"row_id": "7D83C0It0Kpm62ZQ1gt9",
"row_name": "My row title",
"row_description": "My row description",
"previous_in_row_timeline_event_id": "IM50smQ3suY3nGOXNjp4",
"next_in_row_timeline_event_id": "s1sad1DkWZephtcJDmtM",
"related_timeline_event_ids": [
"MN7S90NBDJNSJS"
],
"narrative_event_id": "0nfWvgIlDZVk5yndCLKm",
"narrative_event_title": "My narrative event",
"narrative_event_description": "My narrative event description",
"narrative_event_content": [
{
"content_id": "MN7S90NBDJ",
"content_type": "BlogPost",
"provider_id": "Contentful"
},
{
"content_id": "EL4S90NNDL",
"content_type": "BlogPost",
"provider_id": "Contentful"
}
],
"narrative_event_state_changes_content": {
"AVAILABLE": [
{
"content_id": "MN7S90NBDJ",
"content_type": "BlogPost",
"provider_id": "Contentful"
},
{
"content_id": "EL4S90NNDL",
"content_type": "BlogPost",
"provider_id": "Contentful"
}
],
"VISITED": [
{
"content_id": "MN7S90NBDJ",
"content_type": "BlogPost",
"provider_id": "Contentful"
}
]
},
"narrative_event_custom_data": {
"button_text": "Press me"
}
}
Properties
Name | Type | Required | Description |
---|---|---|---|
id | string | true | |
state | NewUserTimelineEventState | true | An enumeration. |
available_step_index | integer | true | Identifies the step index in which this event becomes available. |
available_beat | Beat | false | Identifies the beat in which this event becomes available. |
links | [UserTimelineEventLink] | true | Array of link resources which can be followed to other events. |
thread_id | string | false | |
row_id | string | true | |
row_name | string | true | |
row_description | string | false | |
previous_in_row_timeline_event_id | string | false | |
next_in_row_timeline_event_id | string | false | |
related_timeline_event_ids | [string] | true | |
narrative_event_id | string | true | |
narrative_event_title | string | false | |
narrative_event_description | string | false | |
narrative_event_content | [ContentIntegration] | true | [Represents content referenced in an external data source to an event state.] |
narrative_event_state_changes_content | object | true | State change content associated with this event. |
» additionalProperties | [ContentIntegration] | false | [Represents content referenced in an external data source to an event state.] |
narrative_event_custom_data | object | false | |
» additionalProperties | string | false |
UserTimelineEventDetailResponse
{
"data": {
"id": "kNSI3QNGVj3OwByy43ze",
"state": "ACTIVE",
"available_step_index": 1,
"available_beat": {
"id": "KLJviYC7MNS7owT7ujWtb7rIHB6",
"name": "Act 1 Beat 3"
},
"links": [
{
"id": "kNSI3QNGVj3OwByy43ze:MN7S90NBDJNSJS",
"to_event_id": "MN7S90NBDJNSJS",
"label": "Accept the mission!",
"followable": false,
"last_followed_at": "2023-02-03T09:01:23",
"condition_datetime": "2023-02-03T09:00:00"
}
],
"thread_id": "PYztAWXDPnz4BM6qDzx4",
"row_id": "7D83C0It0Kpm62ZQ1gt9",
"row_name": "My row title",
"row_description": "My row description",
"previous_in_row_timeline_event_id": "IM50smQ3suY3nGOXNjp4",
"next_in_row_timeline_event_id": "s1sad1DkWZephtcJDmtM",
"related_timeline_event_ids": [
"MN7S90NBDJNSJS"
],
"narrative_event_id": "0nfWvgIlDZVk5yndCLKm",
"narrative_event_title": "My narrative event",
"narrative_event_description": "My narrative event description",
"narrative_event_content": [
{
"content_id": "MN7S90NBDJ",
"content_type": "BlogPost",
"provider_id": "Contentful"
},
{
"content_id": "EL4S90NNDL",
"content_type": "BlogPost",
"provider_id": "Contentful"
}
],
"narrative_event_state_changes_content": {
"AVAILABLE": [
{
"content_id": "MN7S90NBDJ",
"content_type": "BlogPost",
"provider_id": "Contentful"
},
{
"content_id": "EL4S90NNDL",
"content_type": "BlogPost",
"provider_id": "Contentful"
}
],
"VISITED": [
{
"content_id": "MN7S90NBDJ",
"content_type": "BlogPost",
"provider_id": "Contentful"
}
]
},
"narrative_event_custom_data": {
"button_text": "Press me"
}
},
"error": {
"detail": "string",
"content": [
{}
]
},
"meta": {
"user": {
"id": "0HJviYCWMZVYowT7ujWtb7rUEpE3",
"variables": {
"points": "100",
"deadline": "2023-03-15T10:35:26.336571"
},
"current_step": 0,
"current_beat": {
"id": "KLJviYC7MNS7owT7ujWtb7rIHB6",
"name": "Act 1 Beat 3"
},
"new_beat_available": {
"id": "PYztAWXDPnz4BM6qDzx4",
"name": "Act 1 Beat 4"
},
"waiting_for_condition_id": "SzamHkfkMHWpaOUqWOy6",
"waiting_for_condition_datetime": "2023-02-03T09:00:00",
"end_of_timeline_reached": true,
"datetime_guards_disabled": false,
"pause_at_beats": false,
"active_timeline_id": "nevLb8KWPejFV0t0dy9L"
},
"changed_timeline_events": [],
"changed_timeline_event_states": [],
"service_status": "ONLINE"
}
}
Properties
Name | Type | Required | Description |
---|---|---|---|
data | UserTimelineEvent | false | Represents a user timeline event. |
error | GeneralError¦null | false | Provides details around errors and problems encountered while performing an HTTP operation. |
meta | Meta¦null | false | Provides meta information related to the HTTP request. When progressing an audience user narrative state this includes all timeline events which have been created or update, to avoid a subsequent HTTP request to the API. |
UserTimelineEventLink
{
"id": "kNSI3QNGVj3OwByy43ze:MN7S90NBDJNSJS",
"to_event_id": "MN7S90NBDJNSJS",
"label": "Accept the mission!",
"followable": false,
"last_followed_at": "2023-02-03T09:01:23",
"condition_datetime": "2023-02-03T09:00:00"
}
Properties
Name | Type | Required | Description |
---|---|---|---|
id | string | true | |
to_event_id | string | true | |
label | string | false | Describes the intent of the link |
followable | boolean | true | Can the link be followed |
last_followed_at | string(date-time) | false | Timestamp when the link was last followed. |
condition_datetime | string(date-time) | false | The datetime when the followable value could change. |
UserTimelineEventListResponse
{
"data": [
{
"id": "kNSI3QNGVj3OwByy43ze",
"state": "ACTIVE",
"available_step_index": 1,
"available_beat": {
"id": "KLJviYC7MNS7owT7ujWtb7rIHB6",
"name": "Act 1 Beat 3"
},
"links": [
{
"id": "kNSI3QNGVj3OwByy43ze:MN7S90NBDJNSJS",
"to_event_id": "MN7S90NBDJNSJS",
"label": "Accept the mission!",
"followable": false,
"last_followed_at": "2023-02-03T09:01:23",
"condition_datetime": "2023-02-03T09:00:00"
}
],
"thread_id": "PYztAWXDPnz4BM6qDzx4",
"row_id": "7D83C0It0Kpm62ZQ1gt9",
"row_name": "My row title",
"row_description": "My row description",
"previous_in_row_timeline_event_id": "IM50smQ3suY3nGOXNjp4",
"next_in_row_timeline_event_id": "s1sad1DkWZephtcJDmtM",
"related_timeline_event_ids": [
"MN7S90NBDJNSJS"
],
"narrative_event_id": "0nfWvgIlDZVk5yndCLKm",
"narrative_event_title": "My narrative event",
"narrative_event_description": "My narrative event description",
"narrative_event_content": [
{
"content_id": "MN7S90NBDJ",
"content_type": "BlogPost",
"provider_id": "Contentful"
},
{
"content_id": "EL4S90NNDL",
"content_type": "BlogPost",
"provider_id": "Contentful"
}
],
"narrative_event_state_changes_content": {
"AVAILABLE": [
{
"content_id": "MN7S90NBDJ",
"content_type": "BlogPost",
"provider_id": "Contentful"
},
{
"content_id": "EL4S90NNDL",
"content_type": "BlogPost",
"provider_id": "Contentful"
}
],
"VISITED": [
{
"content_id": "MN7S90NBDJ",
"content_type": "BlogPost",
"provider_id": "Contentful"
}
]
},
"narrative_event_custom_data": {
"button_text": "Press me"
}
}
],
"error": {
"detail": "string",
"content": [
{}
]
},
"meta": {
"user": {
"id": "0HJviYCWMZVYowT7ujWtb7rUEpE3",
"variables": {
"points": "100",
"deadline": "2023-03-15T10:35:26.336571"
},
"current_step": 0,
"current_beat": {
"id": "KLJviYC7MNS7owT7ujWtb7rIHB6",
"name": "Act 1 Beat 3"
},
"new_beat_available": {
"id": "PYztAWXDPnz4BM6qDzx4",
"name": "Act 1 Beat 4"
},
"waiting_for_condition_id": "SzamHkfkMHWpaOUqWOy6",
"waiting_for_condition_datetime": "2023-02-03T09:00:00",
"end_of_timeline_reached": true,
"datetime_guards_disabled": false,
"pause_at_beats": false,
"active_timeline_id": "nevLb8KWPejFV0t0dy9L"
},
"changed_timeline_events": [],
"changed_timeline_event_states": [],
"service_status": "ONLINE"
}
}
Properties
Name | Type | Required | Description |
---|---|---|---|
data | [UserTimelineEvent] | false | [Represents a user timeline event.] |
error | GeneralError¦null | false | Provides details around errors and problems encountered while performing an HTTP operation. |
meta | Meta¦null | false | Provides meta information related to the HTTP request. When progressing an audience user narrative state this includes all timeline events which have been created or update, to avoid a subsequent HTTP request to the API. |
UserTimelineEventStateChange
{
"state": "ACTIVE",
"state_changed_at": "2019-08-24T14:15:22Z",
"state_change_content": [
{
"content_id": "MN7S90NBDJ",
"content_type": "BlogPost",
"provider_id": "Contentful"
},
{
"content_id": "EL4S90NNDL",
"content_type": "BlogPost",
"provider_id": "Contentful"
}
],
"timeline_event_id": "PYztAWXDPnz4BM6qDzx4",
"thread_id": "7D83C0It0Kpm62ZQ1gt9",
"row_id": "i55GFxgI3AODsW9OacUz",
"row_name": "string",
"narrative_event_id": "0nfWvgIlDZVk5yndCLKm",
"narrative_event_title": "My narrative event",
"narrative_event_description": "My narrative event description"
}
Properties
Name | Type | Required | Description |
---|---|---|---|
state | NewUserTimelineEventState | true | An enumeration. |
state_changed_at | string(date-time) | false | |
state_change_content | [ContentIntegration] | true | [Represents content referenced in an external data source to an event state.] |
timeline_event_id | string | true | |
thread_id | string | false | |
row_id | string | true | |
row_name | string | true | |
narrative_event_id | string | true | |
narrative_event_title | string | false | |
narrative_event_description | string | false |
UserTimelineEventStateChangeListResponse
{
"data": [
{
"state": "ACTIVE",
"state_changed_at": "2019-08-24T14:15:22Z",
"state_change_content": [
{
"content_id": "MN7S90NBDJ",
"content_type": "BlogPost",
"provider_id": "Contentful"
},
{
"content_id": "EL4S90NNDL",
"content_type": "BlogPost",
"provider_id": "Contentful"
}
],
"timeline_event_id": "PYztAWXDPnz4BM6qDzx4",
"thread_id": "7D83C0It0Kpm62ZQ1gt9",
"row_id": "i55GFxgI3AODsW9OacUz",
"row_name": "string",
"narrative_event_id": "0nfWvgIlDZVk5yndCLKm",
"narrative_event_title": "My narrative event",
"narrative_event_description": "My narrative event description"
}
],
"error": {
"detail": "string",
"content": [
{}
]
},
"meta": {
"user": {
"id": "0HJviYCWMZVYowT7ujWtb7rUEpE3",
"variables": {
"points": "100",
"deadline": "2023-03-15T10:35:26.336571"
},
"current_step": 0,
"current_beat": {
"id": "KLJviYC7MNS7owT7ujWtb7rIHB6",
"name": "Act 1 Beat 3"
},
"new_beat_available": {
"id": "PYztAWXDPnz4BM6qDzx4",
"name": "Act 1 Beat 4"
},
"waiting_for_condition_id": "SzamHkfkMHWpaOUqWOy6",
"waiting_for_condition_datetime": "2023-02-03T09:00:00",
"end_of_timeline_reached": true,
"datetime_guards_disabled": false,
"pause_at_beats": false,
"active_timeline_id": "nevLb8KWPejFV0t0dy9L"
},
"changed_timeline_events": [],
"changed_timeline_event_states": [],
"service_status": "ONLINE"
}
}
Properties
Name | Type | Required | Description |
---|---|---|---|
data | [UserTimelineEventStateChange] | false | [Represents a user timeline event state change.] |
error | GeneralError¦null | false | Provides details around errors and problems encountered while performing an HTTP operation. |
meta | Meta¦null | false | Provides meta information related to the HTTP request. When progressing an audience user narrative state this includes all timeline events which have been created or update, to avoid a subsequent HTTP request to the API. |
ValidationError
{
"loc": [
"string"
],
"msg": "string",
"type": "string"
}
Properties
Name | Type | Required | Description |
---|---|---|---|
loc | [anyOf] | true |
Name | Type | Required | Description |
---|---|---|---|
» anonymous | string | false |
Name | Type | Required | Description |
---|---|---|---|
» anonymous | integer | false |
Name | Type | Required | Description |
---|---|---|---|
msg | string | true | |
type | string | true |
Variable
{
"name": "coins",
"scope": "shared",
"default_value": "100",
"value": "200"
}
Properties
Name | Type | Required | Description |
---|---|---|---|
name | string | true | |
scope | VariableScope | true | The scope of a variable. User values are specific to a single user, shared values are across all users on a timeline. |
default_value | string | true | |
value | string | false | Current value of the variable. For user scoped variables this is always None - see an individual user API response for each unique value. |
VariableScope
"user"
Properties
Name | Type | Required | Description |
---|---|---|---|
VariableScope | string | false | The scope of a variable. User values are specific to a single user, shared values are across all users on a timeline. |
Enumerated Values
Property | Value |
---|---|
VariableScope | user |
VariableScope | shared |
undefined