NAV
HTTP

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.

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

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"
}
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": {}
}
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

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:

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.

{
  "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