NAV 'Navigation
javascript

Introduction

The Winterlight Platform API allows partners to submit audio samples of speech and get back features which can be used to detect and monitor neurodegenerative or psychiatric disease symptoms.

Concepts Overview

The following is a list of high-level concepts that are important to internalize before progressing further down the documentation.

Sensitive Data

Winterlight categorizes data that is associated with an individual as sensitive data and any resource that contains sensitive data as a sensitive data resource. For example, the participant and sample resources are considered to be sensitive data because they could contain personally identifiable information. When you create a sensitive data resource you will need to specify the geographic region (via a zone) in which it will be stored. Winterlight allows data to be stored in Canada or the USA. You are responsible for selecting the geographic region most appropriate to your contractual or legal obligations.

All resources that are not specifically annotated as sensitive data are categorized as generic resources and presumed to not contain sensitive data. Generic resources can be stored and/or transferred cross-regionally/internationally. You cannot select the geographic region of generic resources. Examples of generic resources include teams and projects.

More information can be found in Winterlight’s Privacy Policy.

Transcription Modes

Our speech pipeline analyzes two aspects of speech: the acoustic component (how words are said) and the linguistic component (what words are said). The acoustic component is extracted directly from the audio, while the linguistic component requires a transcript. We can obtain transcripts from human transcriptionists (this is referred as “manual” transcription) or using automatic speech recognition (this is referred as “asr” transcription). The mode of transcription you have access to is determined by your project.

Insights

An insight is any piece of data generated for the use of or as the result of Winterlight speech analysis. Examples of insights include transcripts, speech features or models.

Resources Overview

All of the following resources are defined in additional detail further down in this documentation. This list explains all the high-level concepts so you have a sense of familiarity when you later encounter it again.

Teams

The team resource represents your organization and contains all other resources (see below). Every user will belong to a team and there must be at least one admin user who will be able to create new users.

Your team is created by a Winterlight employee during your account creation.

Projects

A project is associated with a team.

The project resource defines the configuration for data collection and processing. It describes what kind of audio samples can be submitted and at what cost.

Projects are created by a Winterlight employee during your account creation. If a new configuration is requested, additional projects can be created upon request. Generally every time you sign a new agreement or need a different set of services, it will result in a new project being created.

Zones

A zone is associated with a project.

The zone resource determines where sensitive data resources are geographically stored. For example, all participants in a Canadian zone would have their data physically stored on servers in Canada. Depending on the zone’s region, you will need to call the API with a specific url. Note that since the zone points to where sensitive data is located and does not contain sensitive data itself, it is considered to be a generic resource.

It is also important to note that while data will be stored in the zone selected, it may be processed in another geographic zone. For example, data stored in the US zone will be processed in Canada if it is selected for manual transcription.

You can create any number of zones in a single project.

Participants

A participant is associated with a zone.

The participant resource represents the individual whose speech is being analyzed.

You can create any number of participants in a zone.

Samples

A sample is associated with a participant.

The sample resource represents a single instance of speech for a participant.

Each sample will have a task (such as “Picture Description”), a stimulus specific to that task (such as “Cookie Theft”) and language. The specific combination of task, stimulus and languages you can submit tasks for is determined by the project.

You will be provided resources on how to administer the Winterlight assessment on your application in a separate document.

You can submit any number of samples for any given participant, but you will be invoiced for them as outlined per your agreement if the participant belongs to a live zone.

A sample can have multiple reports sub-resource which contain insights from the analysis.

Example Workflow

The following is a high-level overview of what it takes to successfully submit a single audio sample to Winterlight API for analysis:

  1. You are assigned an administer API token that is associated with your team. Using that API token you can create more API tokens or if necessary, delete existing API tokens (e.g. if you want to rotate them every 90 days).
  2. Based on your agreement, a project will be created. This will determine what speech tasks are supported, what languages are supported, what feature version is used, what kind of transcription is used and so forth.
  3. You create zones for your project. You will likely create a sandbox zone while you initially integrate with this API. Once you have successfully submitted an audio sample, you can then confidently create training and live zones. The number of zones you will need to create will be based on your own use-case.
  4. You create participants for the zone. You can create them as they are registered to your application/study/clinical trial or just-in-time right before you submit the audio sample.
  5. The participant completes the Winterlight assessment in your application which will generate an audio file.
  6. You create a sample resource with the specifications of the assessment that was completed.
  7. Upload the audio file for the sample. Uploading the audio submits the sample for analysis. You will no longer be able to modify the sample after this point.
  8. You will receive the analysis to the callback defined in the zone. If the analysis could not be completed, you will receive a callback with the reason why.

There are a number of steps, but it is a fairly linear and uncomplicated process.

Making Requests

Authentication

When your team is created you will be provided with an API token. You must make requests to the endpoints described in this documentation by providing the API token in the request header. The header will look something like:

Authorization: Bearer wl.{your-api-token-id}.{you-api-token-secret}

Request Headers

If the accept and content-type headers are not provided, the API will use the default of application/json. The content-type only accepts either application/json or multi-part/form-data.

Response Wrapper

Successful Requests

Successful requests return JSON structured like this:

{
"ok": true,
"status": 200,
"data": {
"//": "..."
}
}

The standard response from the API is JSON with these fields:

field type description
ok bool True if the request was successful (i.e. 2XX).
status integer The status code of the request.
data object The requested resource. Will be an array of objects if multiple resources are requested. May be null or undefined.

Failed Requests

Failed requests return JSON structured like this:

{
"ok": false,
"status": 404,
"error": "NOT_FOUND"
}
field type description
ok bool False if the request failed (i.e. 4XX or 5XX).
status integer The status code of the request.
error string A machine-readable cause for the error.
reason object A verbose explanation in case of failed validation.

Rate Limiting

Clients that make a large number of requests in a short period of time may be rate-limited, which will result in a response with status code 429: Too Many Requests. Simply waiting before issuing new requests will expire the rate-limit.

The body of a rate-limited response will be HTML, not JSON. This can be an issue if your client always expect response to be JSON. It is recommended to check if the the status code is 429 before parsing the response.

We will change 429s to return a JSON body in future releases.

Rate-limited responses look like this:

<html>
<head>
<title>429 Too Many Requests</title>
</head>
<body>
<center><h1>429 Too Many Requests</h1></center>
<hr />
<center>nginx</center>
</body>
</html>

Resource Ids

All resource ids will have a 21-character guid with an alphabet of 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz- (see nanoid for more information). If you are storing this id in a SQL database, it is recommended to use the ascii character set for column rather than utf8 to reduce the space used to 63 to 21 bytes.

Dates

All dates are in the UTC timezone. When you pass date values in the API they must be in one of the following formats:

Format Description
2021-04-04T12:12:34.000Z A ISO 8601 string. Default format for javascript.
2021-04-04 Date without time. The hours, minutes and seconds will be zero’ed out in the database.
1617538354000 Numeric value of the date as the number of milliseconds. Default format for javascript.

Me Parameter Keyword

There are cases when the id for a resource can be inferred based on your user and you can use the me keyword. his saves the step of having to lookup value from your database when making the request.

For example, instead of having to specify the full id of your team (GET api-us.winterlightlabs.com/api/v1/teams/vyy5bHHXSbZ2PaNHz4c7f) you can instead use the me keyword (GET api-us.winterlightlabs.com/api/v1/teams/me) to get your current team.

Meta Field

When creating a zone, participant or zone you can set a meta field which allows you to store additional information about the resource. You can later access this value when requesting the resource and it will be returned to you in webhook callbacks. When the meta value is returned in a webhook, you will receive the meta values you set for the zone, participant and sample (if relevant).

There are two primary use cases for providing meta:

  1. You want to pass in your additional ids to allow for easier processing when you receive webhook callback.
  2. You are collaborating directly with Winterlight and want to provide additional information about the data that would be normally transferred via a spreadsheet.

Endpoint Special Properties

Each endpoint will have the following table specifying any of its special properties:

Property Applicable?
Requires team admin permissions? Yes/No
Requires region-specific url due to sensitive data? Yes/No
Can result in invoice charges? Yes/No
Is activity recorded in audit logs? Yes/No

Country and Language Fields

A locale is made up of a language (e.g. en) and a country (e.g. CA). While you can write a locale as a single string en-CA, within the platform they are represented as two separate fields: locale_country_code and locale_language_code. This is because we may have situations where the language is known for a participant, but the country (or dialect) is unknown. If you see a field with the prefix locale_ it usually refers to someone’s spoken language. If you see country_code without the locale_ prefix, then that field is referring to the country only.

You can find the complete list of valid country codes and language codes in the reference section.

Difference between language_code and language_id

If the field suffix ends with _code or _id indicates its functionality. If it ends with _code it will accept all possible values under its specification (e.g. language_code will accept every possible language code). If it ends with _id that indicates that it only accepts a subset of values (e.g. language_id is the list of languages that Winterlight supports).

Teams

The team resource represents your organization. All resources you can access are direct or indirect children of your team.

Your team is created by a Winterlight employee during your account creation.

Fields

An example team resource:

{
"id": "vyy5bHHXSbZ2PaNHz4c7f",
"name": "Winterlight Labs",
"currency": "CAD",
"created_at": "2018-01-01T12:12:12.000Z"
}
Name Type Description
id string 21-character guid.
name string The name of your team. Max length 64 characters.
currency string The currency you are invoiced in.
created_at date The date your team was created.

Children Resources

Get a single Team

const axios = require('axios');

const subdomain = '...';
const apiToken = '...';
const teamId = '...';

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/teams/${teamId}`,
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
});

This endpoint retrieves a specific team. In almost all cases you can only access your own team.

You can use the me keyword to get your current team.

Special Properties

Property Applicable?
Requires team admin permissions? No
Requires region-specific url due to sensitive data? No
Can result in invoice charges? No
Is activity recorded in audit logs? No

Request Parameters

Example response:

{
"status": 200,
"ok": true,
"data": {
"id": "vyy5bHHXSbZ2PaNHz4c7f",
"name": "Winterlight Labs",
"currency": "CAD",
"created_at": "2018-01-01T12:12:12.000Z"
}
}

GET {host}.winterlightlabs.com/api/v1/teams/{id}

Parameter Type Description
host string Any valid winterlight region url.
id string The id of the team or me.

Update a Team

const axios = require('axios');

const subdomain = '...';
const apiToken = '...';
const teamId = '...';

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/teams/${teamId}`,
method: 'PATCH',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
data: JSON.stringify({
name: 'Summerdark Labs',
}),
});

This endpoint allows you to modify some properties of your team. Some properties, like the currency, cannot be modified directly and requires contacting Winterlight support to make that change for you.

You can use the me keyword to get your current team.

Special Properties

Property Applicable?
Requires team admin permissions? Yes
Requires region-specific url due to sensitive data? No
Can result in invoice charges? No
Is activity recorded in audit logs? No

Request Parameters

Example response:

{
"status": 200,
"ok": true,
"data": {
"id": "vyy5bHHXSbZ2PaNHz4c7f",
"name": "Summerdark Labs",
"currency": "CAD",
"created_at": "2018-01-01T12:12:12.000Z"
}
}

PATCH {host}.winterlightlabs.com/api/v1/teams/{id}

Parameter Type Description
host string Any valid winterlight region url.
id string The id of the team or me.
name string The display name for the team. Max length 64 characters.

API Tokens

An API Token is a user resource sub-type that allows you to programmatically call the API. An API token is associated with a team.

Security

The API token has an id which is public information and secret which needs to be stored securely. We use the id to identify your API token and the secret to confirm its identity by comparing it against a hashed value in the database. You can use the API token to make a request by setting the Authorization header to be Bearer wl.{id}.{secret}. For example, the following would be a valid header with for example API token: Bearer wl.DwP3qnDcHsaB4V6Ti-wb-.5wARAv5mh875E3NkVBxwDg4riqa7mTA7Fjb3QVa.

Unlike tokens given directly to a person-type user which have a predetermined and limited session duration, API tokens are long-lived and are valid until they are explicitly deleted. As a result, it is highly recommended that you routinely rotate the token. The expires_at field specifies when you should rotate the token (typically 90 days after creation). We will never automatically invalidate your token. You can rotate a token by creating a new token and then deleting the old one.

Fields

An example api token resource:

{
"id": "DwP3qnDcHsaB4V6Ti-wb-",
"prefix": "wl",
"secret": "5wARAv5mh875E3NkVBxwDg4riqa7mTA7Fjb3QVa",
"token": "wl.DwP3qnDcHsaB4V6Ti-wb-.5wARAv5mh875E3NkVBxwDg4riqa7mTA7Fjb3QVa",
"team_id": "vyy5bHHXSbZ2PaNHz4c7f",
"name": "Develop",
"description": "Whatever additional notes you want here.",
"is_team_admin": false,
"created_at": "2020-01-01T12:12:12.000Z",
"last_used_at": null,
"expires_at": "2020-04-01T12:12:12.000Z"
}
Name Type Description
id string 21-character guid public key for the token
prefix string identifies the type of api token being provided.
secret string 42-character secret that authorizes the request.
token string The combination of prefix, id and secret to be passed for requests.
team_id string 21-character guid for your team.
name string A human-readable name to identify the token.
note string A human-readable description.
is_team_admin bool Can call admin-level endpoints.
created_at date The date your api token was created.
last_used_at date The date your api token was last used. Null if never used.
expires_at date The recommended date to delete this token.

Create an API Token

const axios = require('axios');

const subdomain = '...';
const apiToken = '...';

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/api-tokens`,
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
data: JSON.stringify({
name: 'Sandbox Token',
note: 'Please use for the Sandbox Zone only!',
is_team_admin: false,
}),
});

This endpoint creates a new API token. It will be automatically associated with your team. It is important to store the token or secret upon receiving the response. This is the only time the secret and token will be visible as plain-text!

Special Properties

Property Applicable?
Requires team admin permissions? Yes
Requires region-specific url due to sensitive data? No
Can result in invoice charges? No
Is activity recorded in audit logs? Yes

Request Parameters

Example response:

{
"status": 201,
"ok": true,
"data": {
"id": "DwP3qnDcHsaB4V6Ti-wb-",
"prefix": "wl",
"secret": "5wARAv5mh875E3NkVBxwDg4riqa7mTA7Fjb3QVa",
"token": "wl.DwP3qnDcHsaB4V6Ti-wb-.5wARAv5mh875E3NkVBxwDg4riqa7mTA7Fjb3QVa",
"team_id": "vyy5bHHXSbZ2PaNHz4c7f",
"name": "Sandbox Token",
"note": "Please use for the Sandbox Zone only!",
"is_team_admin": false,
"secret": "5wARAv5mh875E3NkVBxwDg4riqa7mTA7Fjb3QVa-tN",
"created_at": "2020-01-01T12:12:12.000Z",
"last_used_at": null,
"expires_at": "2020-04-01T12:12:12.000Z"
}
}

POST {host}.winterlightlabs.com/api/v1/api-tokens

Parameter Type Description
host string Any valid winterlight region url.
name string Required. A human-readable name to identify the token.
note string A human-readable description.
is_team_admin bool Does the token have team admin permissions? Default false.

Get a single API Token

const axios = require('axios');

const subdomain = '...';
const apiToken = '...';
const apiTokenId = '...';

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/api-tokens/${apiTokenId}`,
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
});

This endpoint retrieves a specific API token.

You can use the me keyword to get information about your current token. Only team admins can see all API tokens for the team.

Special Properties

Property Applicable?
Requires team admin permissions? Maybe
Requires region-specific url due to sensitive data? No
Can result in invoice charges? No
Is activity recorded in audit logs? No

Request Parameters

Example response:

{
"status": 200,
"ok": true,
"data": {
"id": "DwP3qnDcHsaB4V6Ti-wb-",
"team_id": "vyy5bHHXSbZ2PaNHz4c7f",
"name": "Sandbox Token",
"note": "Please use for the Sandbox Zone only!",
"is_team_admin": false,
"created_at": "2020-01-01T12:12:12.000Z",
"last_used_at": "2020-02-01T12:12:12.000Z",
"expires_at": "2020-04-01T12:12:12.000Z"
}
}

GET {host}.winterlightlabs.com/api/v1/api-tokens/{id}

Parameter Type Description
host string Any valid winterlight region url.
id string The id of the API token or me.

Get all API Tokens

const axios = require('axios');

const subdomain = '...';
const apiToken = '...';

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/api-tokens`,
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
});

This endpoint retrieves all API tokens for your team.

Special Properties

Property Applicable?
Requires team admin permissions? Yes
Requires region-specific url due to sensitive data? No
Can result in invoice charges? No
Is activity recorded in audit logs? No

Request Parameters

Example response:

{
"status": 200,
"ok": true,
"data": [
{
"id": "DwP3qnDcHsaB4V6Ti-wb-",
"team_id": "vyy5bHHXSbZ2PaNHz4c7f",
"name": "Sandbox Token",
"note": "Please use for the Sandbox Zone only!",
"is_team_admin": false,
"created_at": "2020-01-01T12:12:12.000Z",
"last_used_at": "2020-02-01T12:12:12.000Z",
"expires_at": "2020-04-01T12:12:12.000Z"
},
{
"id": "eqSCtJOfNUihRUh7Zac0W",
"team_id": "vyy5bHHXSbZ2PaNHz4c7f",
"name": "Production Token",
"note": null,
"is_team_admin": false,
"created_at": "2021-01-01T12:12:12.000Z",
"last_used_at": "2021-02-01T12:12:12.000Z",
"expires_at": "2021-04-01T12:12:12.000Z"
}
]
}

GET {host}.winterlightlabs.com/api/v1/api-tokens

Parameter Type Description
host string Any valid winterlight region url.

Delete an API Token

const axios = require('axios');

const subdomain = '...';
const apiToken = '...';
const apiTokenId = '...';

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/api-tokens/${apiTokenId}`,
method: 'DELETE',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
});

This endpoint deletes a specific API token. A token cannot delete itself and will instead return a 403 Forbidden error.

Special Properties

Property Applicable?
Requires team admin permissions? Yes
Requires region-specific url due to sensitive data? No
Can result in invoice charges? No
Is activity recorded in audit logs? Yes

Request Parameters

Example response:

{
"status": 200,
"ok": true
}

DELETE {host}.winterlightlabs.com/api/v1/api-tokens/{id}

Parameter Type Description
host string Any valid winterlight region url.
id string The id of the API token.

Projects

The project resource defines the configuration for data collection and processing. It describes what kind of audio samples can be submitted, at what cost and what kind of analysis results you will receive as determined by your agreement. Projects could represent a clinical trial, a research study or an entire app.

Projects are cross-regional and do not directly have sensitive data associated with them. Instead you create zones which are region-specific to store sensitive data. Practically speaking, if a project would be a global clinical trial, then the zones would be the jurisdictions where the clinical trials are held.

Projects are created by a Winterlight employee during your account creation. Please contact your account manager to make changes to your projects or create new ones.

Fields

An example project resource:

{
"id": "DwP3qnDcHsaB4V6Ti-wb-",
"team_id": "vyy5bHHXSbZ2PaNHz4c7f",
"name": "XYZ Clinical Trial",
"note": "The winterlight assessment will be administered on weeks 1, 4 and 12.",
"project_tasks": [
{
"language_id": "en",
"task_id": "picture_description",
"stimulus_id": "winterlight_family_in_the_kitchen",
"transcription_modes": ["manual"],
"max_audio_duration": 300.0
},
{
"language_id": "en",
"task_id": "picture_description",
"stimulus_id": "winterlight_living_room",
"transcription_modes": ["manual"],
"max_audio_duration": 300.0
}
],
"required_participant_fields": [
"external_id",
"birth_year",
"birth_month",
"birth_day"
],
"required_sample_fields": ["external_id", "sample_source"],
"region_ids": ["ca", "us"],
"is_sandbox_only": false,
"supported_insights": ["v1/features"],
"default_insights": ["v1/features"],
"can_specify_insights": false,
"created_at": "2020-01-01T12:12:12.000Z"
}
Name Type Description
id string 21-character guid.
team_id string 21-character guid for your team.
name string A human-readable name for the project. Max length 64 characters.
note string A human-readable description.
project_tasks array See “Project Tasks” section.
required_participant_fields array See the “participant” resource.
required_sample_fields array See the “sample” resource.
region_ids array The supported zone regions for this project.
is_sandbox_only bool If true, only “sandbox” zones can be created in this project.
supported_insights array See the “Insights” section.
default_insights array See the “Insights” section.
can_specify_insights bool See the “Insights” section.
created_at date The date your project was created.

Project Tasks

The project task sub-resource defines what types of audio samples you can submit. Any sample submitted that is not the exact combination of language_id, task_id, stimulus_id listed will result in a 400 UNSUPPORTED_TASK error. Requesting a transcription mode that isn’t supported by the language/task/stimulus combination in question will result in a 400 UNSUPPORTED_TRANSCRIPTION_MODE error.

Name Type Description
language_id string 2-character ISO 639-1 language code (e.g. “en”).
task_id string A machine-readable name for a supported speech task.
stimulus_id string A machine-readable name for a speech task stimulus (if applicable).
max_audio_duration float The largest audio sample that can be submitted (measured in seconds).
transcription_modes string Available transcription methods. Valid options are “manual” and “asr”.

Children Resources

Get a single Project

const axios = require('axios');

const subdomain = '...';
const project = '...';
const apiToken = '...';

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/projects/${projectId}`,
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
});

This endpoint retrieves a specific project.

Special Properties

Property Applicable?
Requires team admin permissions? No
Requires region-specific url due to sensitive data? No
Can result in invoice charges? No
Is activity recorded in audit logs? No

Request Parameters

Example response:

{
"status": 200,
"ok": true,
"data": {
"id": "DwP3qnDcHsaB4V6Ti-wb-",
"team_id": "vyy5bHHXSbZ2PaNHz4c7f",
"name": "XYZ Clinical Trial",
"note": "The winterlight assessment will be administered on weeks 1, 4 and 12.",
"created_at": "2020-01-01T12:12:12.000Z",
"project_tasks": [
{
"language_id": "en",
"task_id": "picture_description",
"stimulus_id": "winterlight_family_in_the_kitchen",
"transcription_modes": ["manual"],
"max_audio_duration": 300.0
},
{
"language_id": "en",
"task_id": "picture_description",
"stimulus_id": "winterlight_living_room",
"transcription_modes": ["manual"],
"max_audio_duration": 300.0
}
],
"required_participant_fields": [
"external_id",
"birth_year",
"birth_month",
"birth_day"
],
"required_sample_fields": ["external_id", "sample_source"],
"region_ids": ["ca", "us"],
"is_sandbox_only": false,
"supported_insights": ["v1/features"],
"default_insights": ["v1/features"],
"can_specify_insights": false,
"created_at": "2020-01-01T12:12:12.000Z"
}
}

GET {host}.winterlightlabs.com/api/v1/projects/{id}

Parameter Type Description
host string The zone’s region_host.
id string The id of the project.

Get all Projects

const axios = require('axios');

const subdomain = '...';
const apiToken = '...';

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/projects`,
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
});

This endpoint retrieves all projects for your team.

Special Properties

Property Applicable?
Requires team admin permissions? No
Requires region-specific url due to sensitive data? No
Can result in invoice charges? No
Is activity recorded in audit logs? No

Request Parameters

Example response:

{
"status": 200,
"ok": true,
"data": [
{
"id": "DwP3qnDcHsaB4V6Ti-wb-",
"team_id": "vyy5bHHXSbZ2PaNHz4c7f",
"name": "XYZ Clinical Trial",
"note": "The winterlight assessment will be administered on weeks 1, 4 and 12.",
"created_at": "2020-01-01T12:12:12.000Z",
"project_tasks": [
{
"language_id": "en",
"task_id": "picture_description",
"stimulus_id": "winterlight_family_in_the_kitchen",
"transcription_modes": ["manual"],
"max_audio_duration": 300.0
},
{
"language_id": "en",
"task_id": "picture_description",
"stimulus_id": "winterlight_living_room",
"transcription_modes": ["manual"],
"max_audio_duration": 300.0
}
],
"required_participant_fields": [
"external_id",
"birth_year",
"birth_month",
"birth_day"
],
"region_ids": ["ca", "us"],
"required_sample_fields": ["external_id", "sample_source"],
"is_sandbox_only": false,
"supported_insights": ["v1/features"],
"default_insights": ["v1/features"],
"can_specify_insights": false,
"created_at": "2020-01-01T12:12:12.000Z"
}
]
}

GET {host}.winterlightlabs.com/api/v1/projects

Parameter Type Description
host string The zone’s region_host.

Update a Project

const axios = require('axios');

const subdomain = '...';
const projectId = '...';
const apiToken = '...';

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/projects/${projectId}`,
method: 'PATCH',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
data: JSON.stringify({
name: 'A different name',
}),
});

This endpoint allows you to modify some properties of your project.

Special Properties

Property Applicable?
Requires team admin permissions? Yes
Requires region-specific url due to sensitive data? No
Can result in invoice charges? No
Is activity recorded in audit logs? Yes

Request Parameters

Example response:

{
"status": 200,
"ok": true,
"data": {
"id": "DwP3qnDcHsaB4V6Ti-wb-",
"team_id": "vyy5bHHXSbZ2PaNHz4c7f",
"name": "A different name",
"note": "The winterlight assessment will be administered on weeks 1, 4 and 12.",
"project_tasks": [
{
"language_id": "en",
"task_id": "picture_description",
"stimulus_id": "winterlight_family_in_the_kitchen",
"transcription_modes": ["manual"],
"max_audio_duration": 300.0
},
{
"language_id": "en",
"task_id": "picture_description",
"stimulus_id": "winterlight_living_room",
"transcription_modes": ["manual"],
"max_audio_duration": 300.0
}
],
"required_participant_fields": [
"external_id",
"birth_year",
"birth_month",
"birth_day"
],
"required_sample_fields": ["external_id", "sample_source"],
"region_ids": ["ca", "us"],
"is_sandbox_only": false,
"supported_insights": ["v1/features"],
"default_insights": ["v1/features"],
"can_specify_insights": false,
"created_at": "2020-01-01T12:12:12.000Z"
}
}

PATCH {host}.winterlightlabs.com/api/v1/projects/{id}

Parameter Type Description
host string The zone’s region_host.
id string The id of the project.
name string Required. A display name for the project. Max length 64 characters.
note string A human-readable description.

Zones

The zone resource stores and partitions participant data for any given project. You can create any number of zones in a single project. A zone, unlike a project, is associated with a specific geographic region. A Canadian zone would mean that the data (including sensitive data) in that zone would be physically stored on servers in Canada. You can have multiple zones in the same region.

There are two types of zones:

Organization

While your application will have its own system to organize data, you will want to define separate zones for various operational reasons. The following are examples where you may want to or need to create additional zones.

You do not need to always divide your data into distinct zones. If you’re running a clinical trial, outside of geographic reasons you do not need to define a separate zone for each clinical site since you would want the data to be analyzed together. In this example, you could instead have a single project for the multinational clinical trial and a zone for each geographic region.

Regional Urls

Requesting data from the incorrect region will return the following error:

{
"ok": false,
"status": 400,
"error": "INCORRECT_REGION",
"location": "https://api-ca.winterlightlabs.com/api/v1/samples/tIZKtyZ_9_xb-z3sXsUzy"
}

Depending on the zone’s region, you will need to call the API with a specific url (the region_host property of the zone). The transfer of sensitive data across jurisdictions can be regulated, so it is imperative to ensure you submit data to the correct region.

Region Url
Canada https://api-ca.winterlightlabs.com
USA https://api-us.winterlightlabs.com

You can call any of the regional API urls for non-sensitive data data, but you must use the zone’s regional url when calling endpoints that may contain sensitive data. If you attempt to request sensitive data from the incorrect region, you will 400 INCORRECT_REGION status code and response body will have a location field with the correct regional url. Since this is not a 301 or 309 redirection, your request will not be automatically redirected.

Webhooks

When creating a zone you can pass a webhook_url and webhook_secret to receive callbacks to various events. The API will send POST callbacks to the webhook_url with a x-winterlight-secret={webhook_secret} header for authentication. You must ensure that the webhook_url destination complies with the legal storage requirements of the data and your own contractual obligations.

When creating a zone you will also need to pass a webhook_secret (at least 32 characters) which will be used to authenticate via a x-winterlight-secret header in webhook_url http requests. You cannot view the webhook_secret once it is set (aside from the last 4 digits), but it can be overwritten. Currently, webhook callback is attempted only once.

The possible webhook events are defined in the Webhooks section.

Fields

An example zone resource:

{
"id": "JMW5IcFQ6rAJDbRAeuQXR",
"zone_type": "live",
"team_id": "vyy5bHHXSbZ2PaNHz4c7f",
"project_id": "DwP3qnDcHsaB4V6Ti-wb-",
"region_id": "ca",
"region_host": "https://api-ca.winterlightlabs.com",
"country_codes": ["CA", "FR"],
"name": "Canadian and European Clinical Sites",
"note": "Includes EU data.",
"webhook_url": "https://example.com/v1/some-callback-url",
"webhook_secret": "04751888d21e47d1851a9b77a6a34d35",
"meta": {
"whatever_you_put_in_meta": "will_be_echoed_back"
},
"created_at": "2020-01-01T12:12:12.000Z"
}
Name Type Description
id string 21-character guid.
zone_type string Either “sandbox” or “live”.
team_id string 21-character guid for zone’s team.
project_id string 21-character guid for zone’s project.
region_id string 2-character id. Either “us” or “ca”. Determines where data is stored.
region_host string Url to make requests against zone resources.
country_codes array List of 2-character id based on ISO 3166-1 alpha-2. Used for compliance tracking.
name string A human-readable name for the zone. Max length 64 characters.
note string A human-readable description.
webhook_url string The https url that will receive events for samples in the zone.
webhook_secret string At least 32 characters. Authenticate callbacks via the x-winterlight-secret header.
meta object Any valid object. This will be returned alongside any webhook callback.
created_at date The date your zone was created.

Children Resources

Create a Zone

const axios = require('axios');

const subdomain = '...';
const apiToken = '...';

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/zones`,
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
data: JSON.stringify({
zone_type: 'sandbox',
project_id: 'DwP3qnDcHsaB4V6Ti-wb-',
region_id: 'ca',
country_codes: ['CA', 'FR'],
name: 'Rater Training',
note: 'Meant to allow raters to practice administering tasks',
webhook_url: 'https://example.com/v1/some-callback-url',
webhook_secret: '04751888d21e47d1851a9b77a6a34d35',
meta: {
whatever_you_put_in_meta: 'will_be_echoed_back',
},
}),
});

This endpoint creates a new zone. Note that zone_type and region_id cannot be changed once set. The zone that the region is determined by the project’s region_ids field; trying to create a zone in a unsupported region will result in a 400 INVALID_REGION_ID error. Trying to create a non-sandbox zone in a project where is_sandbox_only=true will result in a 400 SANDBOX_ONLY_PROJECT error.

Special Properties

Property Applicable?
Requires team admin permissions? Yes
Requires region-specific url due to sensitive data? No
Can result in invoice charges? No
Is activity recorded in audit logs? Yes

Request Parameters

Example response:

{
"status": 201,
"ok": true,
"data": {
"id": "JMW5IcFQ6rAJDbRAeuQXR",
"zone_type": "sandbox",
"project_id": "DwP3qnDcHsaB4V6Ti-wb-",
"region_id": "ca",
"region_host": "https://api-ca.winterlightlabs.com",
"country_codes": ["CA", "FR"],
"name": "Rater Training",
"note": "Meant to allow raters to practice administering tasks",
"webhook_url": "https://example.com/v1/some-callback-url",
"webhook_secret": "****************************4d35",
"meta": {
"whatever_you_put_in_meta": "will_be_echoed_back"
},
"created_at": "2020-01-01T12:12:12.000Z"
}
}

POST {host}.winterlightlabs.com/api/v1/zones

Parameter Type Description
host string Any valid winterlight region url.
zone_type string Required. Either “sandbox” or “live”.
project_id string Required. 21-character guid for zone’s project.
region_id string Required. 2-character id. Either “us” or “ca”. Determines where data is stored.
country_codes array Required. List of 2-character id based on ISO 3166-1 alpha-2. Used for compliance tracking.
name string Required. A human-readable name for the zone. Max length 64 characters.
note string A human-readable description.
webhook_url string (W) The https url that will receive events for samples in the zone.
webhook_secret string (W) At least 32 characters. Authenticate callbacks via the x-winterlight-secret header.
meta object Any valid object. This will be returned alongside any webhook callback.

All fields marked with a (W) are optional, but if one of the values is defined, all must be defined.

Get a single Zone

const axios = require('axios');

const subdomain = '...';
const zoneId = '...';
const apiToken = '...';

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/zones/${zoneId}`,
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
});

This endpoint retrieves a specific zone. The webhook_secret value is hidden aside for the last four digits.

Special Properties

Property Applicable?
Requires team admin permissions? No
Requires region-specific url due to sensitive data? No
Can result in invoice charges? No
Is activity recorded in audit logs? No

Request Parameters

Example response:

{
"status": 200,
"ok": true,
"data": {
"id": "JMW5IcFQ6rAJDbRAeuQXR",
"zone_type": "sandbox",
"project_id": "DwP3qnDcHsaB4V6Ti-wb-",
"region_id": "ca",
"region_host": "https://api-ca.winterlightlabs.com",
"country_codes": ["CA", "FR"],
"name": "Rater Training",
"note": "Meant to allow raters to practice administering tasks",
"webhook_url": "https://example.com/v1/some-callback-url",
"webhook_secret": "****************************4d35",
"meta": {
"whatever_you_put_in_meta": "will_be_echoed_back"
},
"created_at": "2020-01-01T12:12:12.000Z"
}
}

GET {host}.winterlightlabs.com/api/v1/zones/{id}

Parameter Type Description
host string Any valid winterlight region url.
id string The id of the zone.

Get all Zones

const axios = require('axios');

const subdomain = '...';
const apiToken = '...';

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/zones`,
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
});

This endpoint retrieves all zones for your team. The webhook_secret value is hidden aside for the last four digits.

Special Properties

Property Applicable?
Requires team admin permissions? No
Requires region-specific url due to sensitive data? No
Can result in invoice charges? No
Is activity recorded in audit logs? No

Request Parameters

Example response:

{
"status": 200,
"ok": true,
"data": [
{
"id": "JMW5IcFQ6rAJDbRAeuQXR",
"zone_type": "sandbox",
"project_id": "DwP3qnDcHsaB4V6Ti-wb-",
"region_id": "ca",
"region_host": "https://api-ca.winterlightlabs.com",
"country_codes": ["CA", "FR"],
"name": "Rater Training",
"note": "Meant to allow raters to practice administering tasks",
"webhook_url": "https://example.com/v1/some-callback-url",
"webhook_secret": "****************************4d35",
"meta": {
"whatever_you_put_in_meta": "will_be_echoed_back"
},
"created_at": "2020-01-01T12:12:12.000Z"
}
]
}

GET {host}.winterlightlabs.com/api/v1/zones

Parameter Type Description
host string Any valid winterlight region url.

Update a Zone

const axios = require('axios');

const subdomain = '...';
const zoneId = '...';
const apiToken = '...';

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/zones/${zoneId}`,
method: 'PATCH',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
data: JSON.stringify({
country_codes: ['CA', 'FR', 'DE'],
webhook_secret: '147981e1c1ad4d5c97d94802fdf2c23d',
meta: {
whatever_you_put_in_meta: 'will_be_echoed_back',
and_can_be: 'extended',
},
}),
});

This endpoint allows you to modify some properties of your zone.

Special Properties

Property Applicable?
Requires team admin permissions? Yes
Requires region-specific url due to sensitive data? No
Can result in invoice charges? No
Is activity recorded in audit logs? Yes

Request Parameters

Example response:

{
"status": 200,
"ok": true,
"data": {
"id": "JMW5IcFQ6rAJDbRAeuQXR",
"zone_type": "sandbox",
"project_id": "DwP3qnDcHsaB4V6Ti-wb-",
"region_id": "ca",
"region_host": "https://api-ca.winterlightlabs.com",
"country_codes": ["CA", "FR", "DE"],
"name": "Rater Training",
"note": "Meant to allow raters to practice administering tasks",
"webhook_url": "https://example.com/v1/some-callback-url",
"webhook_secret": "****************************c23d",
"meta": {
"whatever_you_put_in_meta": "will_be_echoed_back",
"and_can_be": "extended"
},
"created_at": "2020-01-01T12:12:12.000Z"
}
}

PATCH {host}.winterlightlabs.com/api/v1/zones/{id}

Parameter Type Description
host string Any valid winterlight region url.
id string The id of the zone.
country_codes array List of 2-character id based on ISO 3166-1 alpha-2. Used for compliance tracking.
name string A human-readable name for the zone. Max length 64 characters.
note string A human-readable description.
webhook_url string The https url that will receive events for samples in the zone.
webhook_secret string At least 32 characters. Authenticate callbacks via the x-winterlight-secret header.
meta object Any valid object. This will be returned alongside any webhook callback.

Participants

The participant represents a single person and their demographic information.

By default, some of the fields for the participant are marked as optional, but they can be flagged as required in the project’s required_participant_fields property dependent on the nature of your project.

Fields

An example participant resource:

{
"id": "ggG305vkzYyAT3dL3yaOS",
"team_id": "vyy5bHHXSbZ2PaNHz4c7f",
"project_id": "FZI37LUxznExdKuxuZArv",
"zone_id": "YEV8qyUpIdcHWonkhau5E",
"external_id": "external.123",
"external_label": "healthy_week_234",
"birth_year": 1989,
"birth_month": 11,
"birth_day": 6,
"sex": "male",
"education_in_years": 19,
"native_locale_country_code": "CA",
"native_locale_language_code": "en",
"meta": {
"whatever_you_want": "for_example_diagnosis_labels"
},
"created_at": "2021-07-13T07:29:49.000Z"
}
Name Type Description
id string 21-character guid.
team_id string 21-character guid for participant’s team.
project_id string 21-character guid for participant’s project.
zone_id string 21-character guid for participant’s zone.
external_id string Your system’s id for the participant.
external_label string A label for the participant (e.g. healthy control).
birth_year integer A valid birth year.
birth_month integer A valid birth month (starting with 1 for January).
birth_day integer A valid birth day (starting with 1).
sex string One of “male”, “female” or “other”.
education_in_years integer See the table below.
native_locale_country_code string 2-character code for their native locale country (e.g. CA for Canada).
native_locale_language_code string 2-character code for their native locale language (e.g. en for English).
meta object Any valid object. This will be returned alongside any webhook callback.
created_at date The date your participant was created.

The native_locale_country_code and native_locale_language_code fields are used to record the participant’s first spoken language. This may be different from the language they use to complete the assessments. It is possible to provide only native_locale_language_code, but you cannot have native_locale_country_code by itself.

Education

The education_in_years property is calculated by looking at the furthest they have progressed when it comes to education. These values are normalized to the Canadian school system. Partial completion is still considered, so if a participant only completed two years of university, their total would be 14 years.

Years Description
8 Completed elementary school.
12 Completed high school.
14 Completed trade school/college/apprenticeship.
16 Completed undergraduate degree.
18 Completed masters degree.
21 Completed PhD.

Children Resources

Create a Participant

const axios = require('axios');

const subdomain = '...';
const apiToken = '...';

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/participants`,
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
data: JSON.stringify({
zone_id: 'YEV8qyUpIdcHWonkhau5E',
external_id: 'external.123',
external_label: 'healthy_week_234',
birth_year: 1989,
birth_month: 11,
birth_day: 6,
sex: 'male',
education_in_years: 19,
native_locale_country_code: 'CA',
native_locale_language_code: 'en',
meta: {
whatever_you_want: 'for_example_diagnosis_labels',
},
}),
});

This endpoint creates a new participant. A participant cannot be moved to a different zone once it is created.

Special Properties

Property Applicable?
Requires team admin permissions? No
Requires region-specific url due to sensitive data? Yes
Can result in invoice charges? No
Is activity recorded in audit logs? Yes

Request Parameters

Example response:

{
"status": 201,
"ok": true,
"data": {
"id": "ggG305vkzYyAT3dL3yaOS",
"project_id": "FZI37LUxznExdKuxuZArv",
"zone_id": "YEV8qyUpIdcHWonkhau5E",
"external_id": "external.123",
"external_label": "healthy_week_234",
"birth_year": 1989,
"birth_month": 11,
"birth_day": 6,
"sex": "male",
"education_in_years": 19,
"native_locale_country_code": "CA",
"native_locale_language_code": "en",
"meta": {
"whatever_you_want": "for_example_diagnosis_labels"
},
"created_at": "2021-07-13T07:29:49.000Z"
}
}

POST {host}.winterlightlabs.com/api/v1/participants

Parameter Type Description
host string Any valid winterlight region url.
zone_id string Required. 21-character guid for participant’s zone.
external_id string (•) Your system’s id for the participant.
external_label string (•) A label for the participant (e.g. healthy control).
birth_year integer (•) A valid birth year.
birth_month integer (•) A valid birth month (starting with 1 for January).
birth_day integer (•) A valid birth day (starting with 1).
sex string (•) One of “male”, “female” or “other”.
education_in_years integer (•) See the table in the main participant section.
native_locale_country_code string (•) 2-character code for their native locale country (e.g. CA for Canada).
native_locale_language_code string (•) 2-character code for their native locale language (e.g. en for English).
meta object Any valid object. This will be returned alongside any webhook callback.

All fields marked with a (•) can be marked as required dependent on the project required_participant_fields value.

Update a Participant

const axios = require('axios');

const subdomain = '...';
const participantId = '...';
const apiToken = '...';

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/participants/${participantId}`,
method: 'PATCH',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
data: JSON.stringify({
external_id: 'a_new_external_id',
external_label: 'a_new_external_label',
meta: {
whatever_you_want: 'for_example_different_diagnosis_labels',
},
}),
});

This endpoint updates a participant. Only fields that do not affect analysis may be modified after the participant is created.

Special Properties

Property Applicable?
Requires team admin permissions? No
Requires region-specific url due to sensitive data? Yes
Can result in invoice charges? No
Is activity recorded in audit logs? Yes

Request Parameters

Example response:

{
"status": 200,
"ok": true,
"data": {
"id": "ggG305vkzYyAT3dL3yaOS",
"project_id": "FZI37LUxznExdKuxuZArv",
"zone_id": "YEV8qyUpIdcHWonkhau5E",
"external_id": "a_new_external_id",
"external_label": "a_new_external_label",
"birth_year": 1989,
"birth_month": 11,
"birth_day": 6,
"sex": "male",
"education_in_years": 19,
"native_locale_country_code": "CA",
"native_locale_language_code": "en",
"meta": {
"whatever_you_want": "for_example_diagnosis_labels"
},
"created_at": "2021-07-13T07:29:49.000Z"
}
}

PATCH {host}.winterlightlabs.com/api/v1/participants/{id}

Parameter Type Description
host string Any valid winterlight region url.
id string The id of the participant.
external_id string Your system’s id for the participant.
external_label string A label for the participant (e.g. healthy control).
meta object Any valid object. This will be returned alongside any webhook callback.

Omitting a field will leave it unmodified. Passing null will nullify it.

Get a single Participant

const axios = require('axios');

const subdomain = '...';
const participantId = '...';
const apiToken = '...';

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/participants/${participantId}`,
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
});

This endpoint retrieves a specific participant.

Special Properties

Property Applicable?
Requires team admin permissions? No
Requires region-specific url due to sensitive data? Yes
Can result in invoice charges? No
Is activity recorded in audit logs? Yes

Request Parameters

Example response:

{
"status": 200,
"ok": true,
"data": {
"id": "ggG305vkzYyAT3dL3yaOS",
"team_id": "vyy5bHHXSbZ2PaNHz4c7f",
"project_id": "FZI37LUxznExdKuxuZArv",
"zone_id": "YEV8qyUpIdcHWonkhau5E",
"external_id": "external.123",
"external_label": "healthy_week_234",
"birth_year": 1989,
"birth_month": 11,
"birth_day": 6,
"sex": "male",
"education_in_years": 19,
"native_locale_country_code": "CA",
"native_locale_language_code": "en",
"meta": {
"whatever_you_want": "for_example_diagnosis_labels"
},
"created_at": "2021-07-13T07:29:49.000Z"
}
}

GET {host}.winterlightlabs.com/api/v1/participants/{id}

Parameter Type Description
host string Any valid winterlight region url.
id string The id of the participant.

Get all Participants

const axios = require('axios');

const subdomain = '...';
const zoneId = '...';
const apiToken = '...';

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/participants?zone_id=${zoneId}`,
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
});

This endpoint retrieves all participants for the specified zone.

Special Properties

Property Applicable?
Requires team admin permissions? No
Requires region-specific url due to sensitive data? Yes
Can result in invoice charges? No
Is activity recorded in audit logs? Yes

Request Parameters

Example response:

{
"status": 200,
"ok": true,
"data": [
{
"id": "ggG305vkzYyAT3dL3yaOS",
"team_id": "vyy5bHHXSbZ2PaNHz4c7f",
"project_id": "FZI37LUxznExdKuxuZArv",
"zone_id": "YEV8qyUpIdcHWonkhau5E",
"external_id": "external.123",
"external_label": "healthy_week_234",
"birth_year": 1989,
"birth_month": 11,
"birth_day": 6,
"sex": "male",
"education_in_years": 19,
"native_locale_country_code": "CA",
"native_locale_language_code": "en",
"meta": {
"whatever_you_want": "for_example_diagnosis_labels"
},
"created_at": "2021-07-13T07:29:49.000Z"
}
]
}

GET {host}.winterlightlabs.com/api/v1/participants

Parameter Type Description
host string Any valid winterlight region url.
zone_id string Required. 21-character guid for the zone you want participants from.

Delete a Participant

const axios = require('axios');

const subdomain = '...';
const participantId = '...';
const apiToken = '...';

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/participants/${participantId}`,
method: 'DELETE',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
});

This endpoint deletes a participant. You cannot delete a participant once it has samples associated with it.

Special Properties

Property Applicable?
Requires team admin permissions? No
Requires region-specific url due to sensitive data? Yes
Can result in invoice charges? No
Is activity recorded in audit logs? Yes

Request Parameters

Example response:

{
"status": 200,
"ok": true,
"data": {
"id": "ggG305vkzYyAT3dL3yaOS"
}
}

DELETE {host}.winterlightlabs.com/api/v1/participants/{id}

Parameter Type Description
host string Any valid winterlight region url.
id string The id of the participant.

Samples

The sample resource represents a completed speech task by a participant.

Each sample will have a task (such as “Picture Description”), a stimulus specific to that task (such as “Cookie Theft”), language and transcription mode. The specific combination of task, stimulus, languages and transcription modes you can submit tasks for is determined by the project. You can only submit samples for tasks supported by your project. Attempting to submit an unsupported task will result in a 400 UNSUPPORTED_TASK error. Please contact your account manager to make changes to your project if necessary.

By default, some of the fields for the sample are marked as optional, but they can be flagged as required in the project’s required_sample_fields property dependent on the nature of your project.

Fields

An example sample resource:

{
"id": "tIZKtyZ_9_xb-z3sXsUzy",
"team_id": "vyy5bHHXSbZ2PaNHz4c7f",
"project_id": "FZI37LUxznExdKuxuZArv",
"zone_id": "YEV8qyUpIdcHWonkhau5E",
"participant_id": "ggG305vkzYyAT3dL3yaOS",
"locale_country_code": "CA",
"language_id": "en",
"task_id": "picture_description",
"stimulus_id": "winterlight_picnic",
"transcription_mode": "manual",
"sample_state": "success",
"sample_source": "self_administered",
"session_order": null,
"administered_at": "2021-04-04T00:00:00.000Z",
"audio_file_id": "gNw16GBfP3QueX7MgqPJN",
"audio_file_md5": "e579af75b24bc28806c4dc27a4bb3d5b",
"audio_file_duration": 120.24,
"insights": ["v1/features"],
"reports": [
{
"id": "zp8q5-FtyfI8w4934bghR",
"status": "success",
"error_id": null,
"error_source": null,
"features": {
"id": "mviEBibuufW2f4P5L1FbU",
"insight_name": "v1/features",
"insight_type": "features",
"type": "json/ieee-754",
"version": "0.52.0",
"created_at": "2021-07-28T19:34:16.000Z"
},
"aggregate_features": {
"id": "EbUxzNxYTk4qm1ymvYM45",
"insight_name": "v1/aggregate_features",
"insight_type": "aggregate_features",
"type": "json/ieee-754",
"version": "0.15.0",
"created_at": "2021-07-28T19:34:16.000Z"
},
"transcript": {
"id": "hFLV02yZIRW_SUuQ1rqtd",
"insight_name": "v1/transcript",
"insight_type": "transcript",
"type": "json",
"version": "2.0.0",
"created_at": "2021-07-28T19:34:16.000Z"
},
"qa_tags": {
"id": "_yL6iH5rAHbMUHkuer-We",
"insight_name": "v1/transcript",
"insight_type": "transcript",
"type": "json",
"version": "0.2.0",
"created_at": "2021-07-28T19:34:16.000Z"
},
"created_at": "2021-07-28T19:34:16.000Z"
}
],
"external_id": "external-sample-id",
"external_label": null,
"meta": {
"whatever_you_want": "for_example_task_instructions_used"
},
"created_at": "2021-07-15T19:01:30.000Z",
"submitted_at": "2021-07-15T19:01:30.000Z"
}
Name Type Description
id string 21-character guid.
team_id string 21-character guid for sample’s team.
project_id string 21-character guid for sample’s project.
zone_id string 21-character guid for sample’s zone.
participant_id string 21-character guid for sample’s participant.
locale_country_code string 2-character code for their native locale country (e.g. CA for Canada).
language_id string 2-character ISO 639-1 language code (e.g. “en”)
task_id string A machine-readable name for a supported speech task.
stimulus_id string A machine-readable name for a speech task stimulus (if applicable).
transcription_mode string The requested transcription method for the sample.
sample_state string See “Sample States” section below.
sample_source string See “Sample Sources” section below.
session_order integer The session number for the sample (starting with 1). Multiple samples can be submitted for the same session.
administered_at date The date the task was completed by the participant. Used to determine task order.
audio_file_id string 21-character guid to identify the submitted audio file for asset tracking.
audio_file_md5 string A md5 of the submitted audio file.
audio_file_duration float The duration of the submitted audio file in seconds to four digits of precision.
insights array See “Insights” section.
reports array See “Reports” section.
external_id string Your system’s id for the sample.
external_label string A label for the sample. Can be used to store the original filename or a descriptive label (e.g. baseline visit).
meta object Any valid object. This will be returned alongside any webhook callback.
created_at date The date the sample was created.
submitted_at date The date the sample audio was uploaded and the sample was submitted for processing.

Sample Sources

How and where the Winterlight tasks have been administered affect the quality and nature of the audio. Providing a sample_source field allows us to potentially compensate for noise or other anomalies in the audio.

Value Description
self_administered The participant completed the task themselves without assistance.
caregiver The participant completed the task themselves with the aid of a trained caregiver.
rater_in_person The task was administered by a rater or other trained professional in-person.
rater_via_phone The task was administered by a rater or other trained professional over the phone.
rater_via_video The task was administered by a rater or other trained professional during a video call.

Sample States

You can inspect the sample_state value to see the status of your sample.

Value Description
draft The sample resource was created, but no audio file has been uploaded.
pending An audio file has been uploaded and the sample has been submitted for analysis.
error An error occurred in the processing or the file was invalid (e.g. no human speech).
success The sample has been successfully analyzed and a report was generated.

The audio_file_id, audio_file_md5, and audio_file_duration values will be null until an audio file is uploaded and the sample leaves the draft phase.

If the sample_state is success or error that indicates there is a entry in reports with your result or cause of the error.

Reports

Once the sample is analyzed its sample_state will enter the success or error state and have one or more report sub-resources. A successful report will have one or more insights attached to it. An insight is a single derived value from the sample (e.g. transcript, qa_tags, etc). See the Insights section for more details.

When you call a sample endpoint you will get a truncated result that does not include the insight data due to size constraints. You need to call the report endpoint directly to get the insight results.

Fields

An example successful report resource:

{
"id": "zp8q5-FtyfI8w4934bghR",
"status": "success",
"error_id": null,
"error_source": null,
"features": {
"id": "mviEBibuufW2f4P5L1FbU",
"insight_name": "v1/features",
"insight_type": "features",
"type": "json/ieee-754",
"version": "0.52.0",
"data": "...",
"created_at": "2021-07-28T19:34:16.000Z"
},
"aggregate_features": {
"id": "EbUxzNxYTk4qm1ymvYM45",
"insight_name": "v1/aggregate_features",
"insight_type": "aggregate_features",
"type": "json/ieee-754",
"version": "0.15.0",
"data": "...",
"created_at": "2021-07-28T19:34:16.000Z"
},
"transcript": {
"id": "hFLV02yZIRW_SUuQ1rqtd",
"insight_name": "v1/transcript",
"insight_type": "transcript",
"type": "json",
"version": "2.0.0",
"data": "...",
"created_at": "2021-07-28T19:34:16.000Z"
},
"qa_tags": {
"id": "_yL6iH5rAHbMUHkuer-We",
"insight_name": "v1/transcript",
"insight_type": "transcript",
"type": "json",
"version": "0.2.0",
"data": "...",
"created_at": "2021-07-28T19:34:16.000Z"
},
"created_at": "2021-07-28T19:34:16.000Z"
}

An example error report resource:

{
"id": "euh9_PxiZowd4vjCY9eJ4",
"status": "error",
"error_id": "WRONG_LANGUAGE",
"error_source": "transcription",
"created_at": "2021-07-28T19:34:16.000Z"
}
Name Type Description
id string 21-character guid.
status string Either “success” or “error”.
error_id string See “Report Errors” section. Null if state is “success”.
error_source string See “Report Errors” section. Null if state is “success”.
features object See “Insights” section. Undefined or null if state is “error”.
aggregate_features object See “Insights” section. Undefined or null if state is “error”.
transcript object See “Insights” section. Undefined or null if state is “error”.
qa_tags object See “Insights” section. Undefined or null if state is “error”.
created_at date The date the report was created.

Report Errors

Below is a list of possible error_id and error_source values. The possible report errors are determined by the transcription method. As a general rule, manual transcription is able to catch a wider range of issues and with more detail because it doubles as a quality assurance step.

Error Id Error Source Transcription Modes Meaning
UNSUPPORTED_FILE analysis all The audio file was unable to processed (e.g. wav file is 24-bits).
ADMINISTRATION_ISSUE transcription manual There is explicit commenting on an issue with the task itself in the recording (e.g. picture not showing).
INAUDIBLE_PARTICIPANT transcription manual This sample cannot be transcribed due to inaudible participant speech.
INVALID_AUDIO transcription manual The audio is unusable due to a clear issue with the recording itself.
NO_PARTICIPANT transcription manual This sample cannot be transcribed due to there being no participant in the recording.
WRONG_LANGUAGE transcription manual The majority of the sample has the participant speaking a different language.
NO_SPEECH_DETECTED transcription asr The audio has no detectable human speech.

Children Resources

Create a Sample

const axios = require('axios');

const subdomain = '...';
const apiToken = '...';

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/samples`,
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
data: JSON.stringify({
participant_id: 'ggG305vkzYyAT3dL3yaOS',
language_id: 'en',
task_id: 'picture_description',
stimulus_id: 'winterlight_picnic',
sample_source: 'self_administered',
session_order: 5,
administered_at: '2021-04-04T00:00:00.000Z',
external_id: '456',
external_label: 'subject-123-456_week-5.mp3',
meta: {
task_instruction: 'What do you see in this picture?',
task_timeout: 360,
},
}),
});

This endpoint creates a new sample. A sample cannot be moved to a different zone once it is created. Creating a sample does not immediately submit it for analysis and will be in the draft state. You need to call the POST /api/v1/samples/{id}/audio endpoint afterwards to upload the audio file and submit it.

Special Properties

Property Applicable?
Requires team admin permissions? No
Requires region-specific url due to sensitive data? Yes
Can result in invoice charges? No
Is activity recorded in audit logs? Yes

Request Parameters

Example response:

{
"status": 201,
"ok": true,
"data": {
"id": "tIZKtyZ_9_xb-z3sXsUzy",
"team_id": "vyy5bHHXSbZ2PaNHz4c7f",
"project_id": "FZI37LUxznExdKuxuZArv",
"zone_id": "YEV8qyUpIdcHWonkhau5E",
"participant_id": "ggG305vkzYyAT3dL3yaOS",
"locale_country_code": "CA",
"language_id": "en",
"task_id": "picture_description",
"stimulus_id": "winterlight_picnic",
"transcription_mode": "manual",
"sample_state": "draft",
"sample_source": "self_administered",
"session_order": 5,
"administered_at": "2021-04-04T00:00:00.000Z",
"audio_file_id": null,
"audio_file_md5": null,
"audio_file_duration": null,
"external_id": "456",
"external_label": "subject-123-456_week-5.mp3",
"insights": ["v1/features"],
"reports": [],
"meta": {
"task_instruction": "What do you see in this picture?",
"task_timeout": 360
},
"created_at": "2021-07-15T19:01:30.000Z",
"submitted_at": null
}
}

Note that locale_country_code and language_id refer to the language spoken when completing the assessment and not the participant’s native language.

POST {host}.winterlightlabs.com/api/v1/samples

Parameter Type Description
host string The zone’s region_host.
participant_id string Required. 21-character guid for sample’s participant.
locale_country_code string Required. 2-character code for locale country (e.g. CA for Canada) when completing the task.
language_id string § Required. 2-character code for locale language (e.g. en for English) when completing the task.
task_id string § Required. A machine-readable name for a supported speech task.
stimulus_id string § A machine-readable name for a speech task stimulus (if applicable).
transcription_mode string § The requested transcription method for the sample. Optional if task supports a single mode.
insights array See “Insights” section.
sample_source string See “Sample Sources” section.
session_order integer (•) The session number for the sample (starting with 1).
administered_at date Required. The date the task was completed by the participant. Used to determine task order.
external_id string (•) Your system’s id for the sample.
external_label string (•) A label for the sample. Can be used to store the original filename or a descriptive label (e.g. baseline visit).
meta object Any valid object. This will be returned alongside any webhook callback.

All fields marked with a (•) can be marked as required dependent on the project required_sample_fields value.

All fields marked with a § will be checked against the project’s list of supported tasks.

Submit a Sample

const fs = require('fs');
const axios = require('axios');
const FormData = require('form-data');

const subdomain = '...';
const sampleId = '...';
const apiToken = '...';
const audioFilePath = '...';

const formData = new FormData();
formData.append('audio_file', fs.createReadStream(audioFilePath), {
knownLength: fs.statSync(audioFilePath).size,
});

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/samples/${sampleId}/audio`,
method: 'POST',
headers: {
'Content-Length': formData.getLengthSync(),
Accept: 'application/json',
// Sets the content-type to be "multipart/form-data; boundary={boundary}"
...formData.getHeaders(),
Authorization: `Bearer ${apiToken}`,
},
data: formData,
});

This endpoint uploads the audio file for a sample and submits it for analysis.

Once it is submitted the state will change to pending and will progress automatically through the subsequent states. You will receive a webhook callback upon every state change. If you try to upload another sample after the initial successful upload you will receive a 400 ALREADY_SUBMITTED error.

Audio Requirements

The following audio formats are supported:

Ext Notes
m4a Common recording audio format from smartphones.
mp4 Common recording audio format from smartphones.
webm Common recording audio format from internet browsers.
wav 24-bit is not supported.
mp3
ogg
oga
opus

The following errors can be encountered when trying to upload a file:

Status Error Code Description
400 DURATION_EXCEEDED_LIMIT Duration longer than supported by the project.
400 AUDIO_TOO_SHORT Duration is under 1 second.
400 EMPTY_FILE File has no data.
400 INCOMPLETE_FILE File is missing parts or is unterminated.
400 INVALID_AUDIO File is corrupt or incorrectly typed.
400 MISSING_FILE No file uploaded.
413 FILE_TOO_LARGE File is larger than 150mb.
415 UNKNOWN_FILE_TYPE Could not identify file type.
415 UNSUPPORTED_FILE_TYPE File type is not supported (see list above).

Special Properties

Property Applicable?
Requires team admin permissions? No
Requires region-specific url due to sensitive data? Yes
Can result in invoice charges? Yes
Is activity recorded in audit logs? Yes

Request Parameters

Example response:

{
"status": 201,
"ok": true,
"data": {
"id": "tIZKtyZ_9_xb-z3sXsUzy",
"team_id": "vyy5bHHXSbZ2PaNHz4c7f",
"project_id": "FZI37LUxznExdKuxuZArv",
"zone_id": "YEV8qyUpIdcHWonkhau5E",
"participant_id": "ggG305vkzYyAT3dL3yaOS",
"locale_country_code": "CA",
"language_id": "en",
"task_id": "picture_description",
"stimulus_id": "winterlight_picnic",
"transcription_mode": "manual",
"sample_state": "pending",
"sample_source": "self_administered",
"session_order": 5,
"administered_at": "2021-04-04T00:00:00.000Z",
"audio_file_id": "gNw16GBfP3QueX7MgqPJN",
"audio_file_md5": "e579af75b24bc28806c4dc27a4bb3d5b",
"audio_file_duration": 120.24,
"external_id": "456",
"external_label": "subject-123-456_week-5.mp3",
"insights": ["v1/features"],
"reports": [],
"meta": {
"task_instruction": "What do you see in this picture?",
"task_timeout": 360
},
"created_at": "2021-07-15T19:01:30.000Z",
"submitted_at": "2021-07-15T19:01:30.000Z"
}
}

POST {host}.winterlightlabs.com/api/v1/samples/{id}/audio

Parameter Type Description
host string The zone’s region_host.
id string The id of the sample.
audio_file file Required. The audio recording of the assessment. Must be less than 150mb.

Update a Sample

const axios = require('axios');

const subdomain = '...';
const sampleId = '...';
const apiToken = '...';

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/samples/${sampleId}`,
method: 'PATCH',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
data: JSON.stringify({
external_id: 'updated_external_id',
external_label: 'updated_external_label',
meta: {
some_other_meta: 'data',
},
}),
});

This endpoint updates a sample. Only fields that do not affect analysis may be modified after the sample is created.

Special Properties

Property Applicable?
Requires team admin permissions? No
Requires region-specific url due to sensitive data? Yes
Can result in invoice charges? No
Is activity recorded in audit logs? Yes

Request Parameters

Example response:

{
"status": 201,
"ok": true,
"data": {
"id": "tIZKtyZ_9_xb-z3sXsUzy",
"team_id": "vyy5bHHXSbZ2PaNHz4c7f",
"project_id": "FZI37LUxznExdKuxuZArv",
"zone_id": "YEV8qyUpIdcHWonkhau5E",
"participant_id": "ggG305vkzYyAT3dL3yaOS",
"locale_country_code": "CA",
"language_id": "en",
"task_id": "picture_description",
"stimulus_id": "winterlight_picnic",
"transcription_mode": "manual",
"sample_state": "draft",
"sample_source": "self_administered",
"session_order": 5,
"administered_at": "2021-04-04T00:00:00.000Z",
"audio_file_id": null,
"audio_file_md5": null,
"audio_file_duration": null,
"external_id": "updated_external_id",
"external_label": "updated_external_label",
"insights": ["v1/features"],
"reports": [],
"meta": {
"some_other_meta": "data"
},
"created_at": "2021-07-15T19:01:30.000Z",
"submitted_at": null
}
}

PATCH {host}.winterlightlabs.com/api/v1/samples/{id}

Parameter Type Description
host string The zone’s region_host.
id string Required. 21-character guid for the sample.
external_id string (•) Your system’s id for the sample.
external_label string (•) A label for the sample. Can be used to store the original filename or a descriptive label (e.g. baseline visit).
meta object Any valid object. This will be returned alongside any webhook callback.

All fields marked with a (•) can be marked as required dependent on the project required_sample_fields value.

Get a single Sample

const axios = require('axios');

const subdomain = '...';
const sampleId = '...';
const apiToken = '...';

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/samples/${sampleId}`,
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
});

This endpoint retrieves a specific sample.

Special Properties

Property Applicable?
Requires team admin permissions? No
Requires region-specific url due to sensitive data? Yes
Can result in invoice charges? No
Is activity recorded in audit logs? Yes

Request Parameters

Example response:

{
"status": 200,
"ok": true,
"data": {
"id": "tIZKtyZ_9_xb-z3sXsUzy",
"team_id": "vyy5bHHXSbZ2PaNHz4c7f",
"project_id": "FZI37LUxznExdKuxuZArv",
"zone_id": "YEV8qyUpIdcHWonkhau5E",
"participant_id": "ggG305vkzYyAT3dL3yaOS",
"locale_country_code": "CA",
"language_id": "en",
"task_id": "picture_description",
"stimulus_id": "winterlight_picnic",
"transcription_mode": "manual",
"sample_state": "success",
"sample_source": "self_administered",
"session_order": null,
"administered_at": "2021-04-04T00:00:00.000Z",
"audio_file_id": "gNw16GBfP3QueX7MgqPJN",
"audio_file_md5": "e579af75b24bc28806c4dc27a4bb3d5b",
"audio_file_duration": 120.24,
"insights": ["v1/features"],
"reports": [
{
"id": "zp8q5-FtyfI8w4934bghR",
"status": "success",
"error_id": null,
"error_source": null,
"features": {
"id": "mviEBibuufW2f4P5L1FbU",
"insight_name": "v1/features",
"insight_type": "features",
"type": "json/ieee-754",
"version": "0.52.0",
"created_at": "2021-07-28T19:34:16.000Z"
},
"aggregate_features": {
"id": "EbUxzNxYTk4qm1ymvYM45",
"insight_name": "v1/aggregate_features",
"insight_type": "aggregate_features",
"type": "json/ieee-754",
"version": "0.15.0",
"created_at": "2021-07-28T19:34:16.000Z"
},
"transcript": {
"id": "hFLV02yZIRW_SUuQ1rqtd",
"insight_name": "v1/transcript",
"insight_type": "transcript",
"type": "json",
"version": "2.0.0",
"created_at": "2021-07-28T19:34:16.000Z"
},
"qa_tags": {
"id": "_yL6iH5rAHbMUHkuer-We",
"insight_name": "v1/transcript",
"insight_type": "transcript",
"type": "json",
"version": "0.2.0",
"created_at": "2021-07-28T19:34:16.000Z"
},
"created_at": "2021-07-28T19:34:16.000Z"
}
],
"external_id": "external-sample-id",
"external_label": null,
"meta": {
"whatever_you_want": "for_example_task_instructions_used"
},
"created_at": "2021-07-15T19:01:30.000Z",
"submitted_at": "2021-07-15T19:01:30.000Z"
}
}

GET {host}.winterlightlabs.com/api/v1/samples/{id}

Parameter Type Description
host string The zone’s region_host.
id string The id of the sample.

Get all Samples

const axios = require('axios');

const subdomain = '...';
const participantId = '...';
const apiToken = '...';

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/samples?participant_id=${participantId}`,
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
});

This endpoint retrieves all samples for the specified participant.

Special Properties

Property Applicable?
Requires team admin permissions? No
Requires region-specific url due to sensitive data? Yes
Can result in invoice charges? No
Is activity recorded in audit logs? Yes

Request Parameters

Example response:

{
"status": 200,
"ok": true,
"data": [
{
"id": "tIZKtyZ_9_xb-z3sXsUzy",
"team_id": "vyy5bHHXSbZ2PaNHz4c7f",
"project_id": "FZI37LUxznExdKuxuZArv",
"zone_id": "YEV8qyUpIdcHWonkhau5E",
"participant_id": "ggG305vkzYyAT3dL3yaOS",
"locale_country_code": "CA",
"language_id": "en",
"task_id": "picture_description",
"stimulus_id": "winterlight_picnic",
"transcription_mode": "manual",
"sample_state": "success",
"sample_source": "self_administered",
"session_order": null,
"administered_at": "2021-04-04T00:00:00.000Z",
"audio_file_id": "gNw16GBfP3QueX7MgqPJN",
"audio_file_md5": "e579af75b24bc28806c4dc27a4bb3d5b",
"audio_file_duration": 120.24,
"insights": ["v1/features"],
"reports": [
{
"id": "zp8q5-FtyfI8w4934bghR",
"status": "success",
"error_id": null,
"error_source": null,
"features": {
"id": "mviEBibuufW2f4P5L1FbU",
"insight_name": "v1/features",
"insight_type": "features",
"type": "json/ieee-754",
"version": "0.52.0",
"created_at": "2021-07-28T19:34:16.000Z"
},
"aggregate_features": {
"id": "EbUxzNxYTk4qm1ymvYM45",
"insight_name": "v1/aggregate_features",
"insight_type": "aggregate_features",
"type": "json/ieee-754",
"version": "0.15.0",
"created_at": "2021-07-28T19:34:16.000Z"
},
"transcript": {
"id": "hFLV02yZIRW_SUuQ1rqtd",
"insight_name": "v1/transcript",
"insight_type": "transcript",
"type": "json",
"version": "2.0.0",
"created_at": "2021-07-28T19:34:16.000Z"
},
"qa_tags": {
"id": "_yL6iH5rAHbMUHkuer-We",
"insight_name": "v1/transcript",
"insight_type": "transcript",
"type": "json",
"version": "0.2.0",
"created_at": "2021-07-28T19:34:16.000Z"
},
"created_at": "2021-07-28T19:34:16.000Z"
}
],
"external_id": "external-sample-id",
"external_label": null,
"meta": {
"whatever_you_want": "for_example_task_instructions_used"
},
"created_at": "2021-07-15T19:01:30.000Z",
"submitted_at": "2021-07-15T19:01:30.000Z"
}
]
}

GET {host}.winterlightlabs.com/api/v1/samples

Parameter Type Description
host string The zone’s region_host.
participant_id string Required. 21-character guid for the participant you want samples from.

Get a single Report

const axios = require('axios');

const subdomain = '...';
const reportId = '...';
const apiToken = '...';

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/samples/reports/${reportId}`,
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
});

This endpoint retrieves a specific report. Unlike the list of reports found calling a sample endpoint, requesting the report directly also provides the data values for transcript, qa_tags and any insights that you have requested.

Special Properties

Property Applicable?
Requires team admin permissions? No
Requires region-specific url due to sensitive data? Yes
Can result in invoice charges? No
Is activity recorded in audit logs? Yes

Request Parameters

Example response:

{
"status": 200,
"ok": true,
"data": {
"id": "zp8q5-FtyfI8w4934bghR",
"status": "success",
"team_id": "vyy5bHHXSbZ2PaNHz4c7f",
"project_id": "FZI37LUxznExdKuxuZArv",
"zone_id": "YEV8qyUpIdcHWonkhau5E",
"participant_id": "ggG305vkzYyAT3dL3yaOS",
"sample_id": "tIZKtyZ_9_xb-z3sXsUzy",
"error_id": null,
"error_source": null,
"features": {
"id": "mviEBibuufW2f4P5L1FbU",
"insight_name": "v1/features",
"insight_type": "features",
"type": "json/ieee-754",
"version": "0.52.0",
"data": "...",
"created_at": "2021-07-28T19:34:16.000Z"
},
"aggregate_features": {
"id": "EbUxzNxYTk4qm1ymvYM45",
"insight_name": "v1/aggregate_features",
"insight_type": "aggregate_features",
"type": "json/ieee-754",
"version": "0.15.0",
"data": "...",
"created_at": "2021-07-28T19:34:16.000Z"
},
"transcript": {
"id": "hFLV02yZIRW_SUuQ1rqtd",
"insight_name": "v1/transcript",
"insight_type": "transcript",
"type": "json",
"version": "2.0.0",
"data": "...",
"created_at": "2021-07-28T19:34:16.000Z"
},
"qa_tags": {
"id": "_yL6iH5rAHbMUHkuer-We",
"insight_name": "v1/qa_tags",
"insight_type": "qa_tags",
"type": "json",
"version": "0.2.0",
"data": "...",
"created_at": "2021-07-28T19:34:16.000Z"
},
"created_at": "2021-07-28T19:34:16.000Z"
}
}

GET {host}.winterlightlabs.com/api/v1/samples/reports/{id}

Parameter Type Description
host string The zone’s region_host.
id string The id of the report.

Insights

An insight is any piece of data generated for the use of or as the result of Winterlight speech analysis. Examples of insights include transcripts, speech features or model predictions.

Insights can be found in the report sub-resource and have the following fields:

Name Type Description
id string 21-character guid. This is specific insight for sample.
insight_name string See “Insight Versioning” section.
insight_type string The generic insight type (e.g. “transcript”).
version string See “Insight Versioning” section.
type string See “Insight Data Types” section.
data varies See “Insight Data” section.
created_at date The date the insight was created.

Requesting Insights

When you request a sample you can provide one or more insights in the sample.insights field. The insights you can request for a sample is determined by your project’s project.supported_insights field. By default, every successful report will provide the "v1/transcript" and if possible, "v1/qa_tags" insights.

If your project’s project.can_specify_insights is false then you should not use sample.insights field. Samples for that project will always used the insights specified in the project’s project.default_insights field.

We currently only support the following insights:

Name Description
"v1/transcript" The annotated transcript for the audio sample as JSON. Provide with any v1/* request. Deprecated.
"v1/qa_tags" Tags about the quality of the sample as JSON. Only provided with a v1/* request and when using manual transcription. Deprecated.
"v1/features" Raw features for the audio sample. Provided when explicitly requesting the "v1/features" insight. Deprecated.
"v1/feature_aggregates" Provided when explicitly requesting the "v1/features" insight for picture_description task samples. Deprecated.
"v2/transcript" The annotated transcript for the audio sample as an object. Provide with any v2/* request.
"v2/qa_tags" Tags about the quality of the sample as an object. Only provided with a v1/* request and when using manual transcription.
"v2/features" Raw features for the audio sample that includes norms. Provided when explicitly requesting the "v2/features" insight.
"v2/feature_aggregates" Provided when explicitly requesting the "v2/features" insight for picture_description task samples.

Insight Versioning

The quality of winterlight’s analysis improves over time and that progression is tracked in the insight_name and version fields.

The insight_name determines the structure of the response for the given insight_type and affects how you would parse the data (e.g. the type field could vary across different variants). The insight_name will not change without notice.

The version is the semantic version value (e.g. “4.3.10”) of the data field and will change without notice. An increment in the version represents an improvement of our analysis.

Insight Data Types

Name Data Type Notes
"object" object
"json" string
"json/ieee-754" string See below.

The "json/ieee-754" type refers to JSON that has been extended to include IEEE754 is the Standard for Floating-Point Arithmetic symbols of NaN, Infinity and -Infinity. This form of JSON is not in compliance with the JSON specification and cannot be parsed in some languages without an aid of additional library (e.g. json5 for Javascript). However, since it is convenient when working in a mathematical context there are a number of languages that support it natively. For example, this type of json is generated by default via Python’s json.dumps() function. In the future, we may transition to using fully compliant JSON only.

Insight Data

The data field is the insight (e.g. speech features, transcript, etc) itself in the format indicated by the type field.

The data field is omitted unless you call the report endpoint directly. Note that while the structure or schema of data will stay consistent, the values will change due to advances in our technology or the source being inherently non-deterministic (e.g. manual transcription). Changes in the how values are generated roughly correspond to changes in the version field.

Note that the data value can be quite large and if you’re using a SQL database we recommend using the MEDIUMTEXT column type (up to 1677721 characters string).

Insight - Features

When you request the "v2/features" insight you will get all the extracted features for the sample. If applicable (e.g. for picture_description task samples), you will also get the "v2/aggregate_features" as well.

v2/features

Example “v2/features” insight:

{
"id": "mfcc_mean_0",
"type": "acoustic",
"name": "mfcc_mean_0",
"description": null,
"value": -0.68986894374885,
"value_normalized": -0.68986894374885,
"is_continuous": true,
"norms": {
"mean": 0.0024772348640208926,
"std": 0.0031637458173641156
}
}
Name Type Description
id string A machine-readable id for the feature.
type string How the feature was generated. Either “acoustic” or “text”.
name string A human-readable name for the feature. Currently always the same as its id.
description string A human-readable description for the feature. Currently always null.
value number The feature value. Null if the feature could not be calculated (e.g. there is no speech).
value_normalized number If applicable, this is the feature value divided by a relevant constant (e.g. audio duration). The constant varies feature by feature. If the feature does not have a normalization constant and does not need to be normalized, value_normalized will be the same as value. If value is null, then value_normalized is also null.
is_continuous bool If true, the value has fractional values. Otherwise, it is an integer.
norms object The mean and standard deviation from the norm. This is null if there are no norms for this particular task or language.

v2/aggregate_features

Example “v2/aggregate_features” insight:

{
"id": "ability_to_express_thoughts_and_needs",
"type": "sample",
"name": "Ability to Express Thoughts and Needs",
"description": "How clearly ideas were expressed, including orderly flow of information and how well the words and sentences are connected. The results are expressed relative to a healthy normative group.",
"value": null,
"value_normalized": null,
"value_percentile": null,
"polarity": 1,
"null_description": "Could not be measured because less than two sentences were detected in the transcript. At least two sentences are required to estimate coherence.",
"norms": {
"mean": 1.0855514018557086e-16,
"std": 0.5202166560856382
}
}
Name Type Description
id string A machine-readable id for the feature.
type string How the feature was generated. Currently always “sample”.
name string A human-readable name for the aggregate feature
description string A human-readable description for the aggregate feature
value number The aggregate feature value created from z-scoring its features. This is null if a feature could not be calculated.
value_normalized number The aggregate value z-scored against the norms. This is null if a feature could not be calculated.
value_percentile number A value between 0 and 100 indicating the value percentile.
polarity bool If 1, a larger value indicates a positive correlation with the attribute being measured.
null_description string If the aggregate feature cannot be calculated, this will specify the reason.
norms object The mean and standard deviation from the norm. This is null if there are no norms for this particular task or language.

Webhooks

Webhooks allow you to subscribe to different events from our system. For example, it allows you to receive updated features for existing samples automatically without needing to periodically check an endpoint.

If a webhook_url is defined for a zone, the API will send POST callbacks to the webhook_url with a x-winterlight-secret={zone.webhook_secret} header for authentication.

If a webhook event data would normally be a resource that contains sensitive data, those fields would be omitted. This is to prevent the leaking of sensitive data if webhook_url is misconfigured. In these cases, you can retrieve the complete resource by calling the resource_url specified in the event. Note that any sensitive data in the meta field will not be omitted automatically.

There are the following caveats when it comes to handling webhook events:

The callback will always use the following wrapper:

A example of a webhook event:

{
"event_id": "FZI37LUxznExdKuxuZArv",
"event_type": "v1/system.noop",
"zone_id": "JMW5IcFQ6rAJDbRAeuQXR",
"data": "...",
"meta": {
"zone": "...",
"participant": "...",
"sample": "..."
},
"resource_type": "...",
"resource_url": "...",
"created_at": "2020-01-01T12:12:12.000Z"
}
Name Type Description
event_id string A 21-character idempotent event id.
event_type string The type of the event.
zone_id string A 21-character guid of the webhook zone.
data object Dependent on event_type.
meta object The meta objects for the zone, participant and sample. Null if no meta values defined.
resource_type string The type of the resource for the event. Null if not relevant.
resource_url string The https url to get the affected resource. Null if not relevant.
created_at date The date the event was sent.

When creating a zone you can define a meta object property. The meta value will be returned in the callback. This is useful if you want to track a value using your own id for whatever reason. The meta value is also useful pass along information if you are collaborating directly with Winterlight. There is a meta value for the zone, participant and samples; and they are merged together in the callback.

Event - Report Created

Example event:

{
"event_id": "FZI37LUxznExdKuxuZArv",
"event_type": "v1/sample.report_created",
"zone_id": "JMW5IcFQ6rAJDbRAeuQXR",
"data": {
"id": "zp8q5-FtyfI8w4934bghR",
"status": "success",
"team_id": "vyy5bHHXSbZ2PaNHz4c7f",
"project_id": "FZI37LUxznExdKuxuZArv",
"zone_id": "YEV8qyUpIdcHWonkhau5E",
"participant_id": "ggG305vkzYyAT3dL3yaOS",
"sample_id": "tIZKtyZ_9_xb-z3sXsUzy",
"error_id": null,
"error_source": null,
"created_at": "2021-07-28T19:34:16.000Z"
},
"meta": {
"zone": "...",
"participant": "...",
"sample": "..."
},
"resource_type": "report",
"resource_url": "https://api-ca.winterlightlabs.com/api/v1/samples/reports/zp8q5-FtyfI8w4934bghR",
"created_at": "2020-01-01T12:12:12.000Z"
}
Property Value
Type v1/sample.report_created
Trigger Report created for a sample.
Meta Values Zone, Participant, Sample

This event is sent whenever a report is generated for a sample. The webhook data value is equivalent to what you receive when you call the report endpoint directly, but the insights will be omitted because it may contain sensitive data.

Audit Logs

Any user request related to user management, creation of new projects/zones or interaction with sensitive data is logged for auditing purposes.

Fields

An example audit entry:

{
"team_id": "vyy5bHHXSbZ2PaNHz4c7f",
"project_id": "FZI37LUxznExdKuxuZArv",
"zone_id": "YEV8qyUpIdcHWonkhau5E",
"participant_id": "ovpKemJHhn_ePG94YpNpP",
"sample_id": null,
"timestamp": "2021-01-05T20:03:57.000Z",
"location": "172.20.0.1",
"code": 200,
"user_id": "DwP3qnDcHsaB4V6Ti-wb-",
"user_label": "API Token",
"target_user_id": null,
"target_user_label": null,
"is_sensitive": 1,
"resource": "participant",
"action": "list",
"params": {
"sample_ids": ["CwqM6oTRbPStHecXhOiK9"]
}
}
Name Type Description
team_id string 21-character guid for originating team.
project_id string 21-character guid for originating project.
zone_id string 21-character guid for originating zone, if relevant.
participant_id string 21-character guid for originating participant, if relevant.
sample_id string 21-character guid for originating sample, if relevant.
timestamp date The date event was logged.
location string The ip of where the originating request.
code number Status code of the request.
user_id string 21-character guid for the user who made the request. Null if it’s unauthenticated user.
user_label string A label of the user (e.g. “API Token” or “Winterlight Labs”) who did the action.
target_user_id string 21-character guid for the user affected by the request, if relevant.
target_user_label string A meaningful label of the user who was affected by the the action.
resource string The name of the resource being affected by the action.
action string See “Actions” section below.
params object See “Actions” section below.

Actions and Params

The action field describes the event that occurred. The params property is present for some actions and provides additional context for the action. The list of possible actions are below:

Get Team Audit Logs

const axios = require('axios');

const subdomain = '...';
const teamId = '...';
const apiToken = '...';

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/teams/${teamId}/audit-logs`,
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
});

This endpoint retrieves the last 100 audit log events for the team, projects, users and zones. This does not include any zone children resource of zones (e.g. participants or samples).

Special Properties

Property Applicable?
Requires team admin permissions? No
Requires region-specific url due to sensitive data? No
Can result in invoice charges? No
Is activity recorded in audit logs? No

Request Parameters

Example response:

{
"status": 200,
"ok": true,
"data": [
{
"team_id": "vyy5bHHXSbZ2PaNHz4c7f",
"project_id": "KEdbspOB3BY7vbKfUpruJ",
"zone_id": null,
"timestamp": "2021-08-06T00:14:43.000Z",
"location": "172.20.0.1",
"code": 201,
"user_id": "DwP3qnDcHsaB4V6Ti-wb-",
"user_label": "Winterlight Labs",
"target_user_id": null,
"is_sensitive": 0,
"resource": "project",
"action": "create",
"params": null
}
]
}

GET {host}.winterlightlabs.com/api/v1/teams/{id}/audit-logs

Parameter Type Description
host string Any valid winterlight region url.
id string The id of the team.

Get Zone Audit Logs

const axios = require('axios');

const subdomain = '...';
const zoneId = '...';
const apiToken = '...';

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/zones/${zoneId}/audit-logs`,
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
});

This endpoint retrieves the last 100 audit log events for the zone and all of its children resources.

Special Properties

Property Applicable?
Requires team admin permissions? No
Requires region-specific url due to sensitive data? No
Can result in invoice charges? No
Is activity recorded in audit logs? No

Request Parameters

Example response:

{
"status": 200,
"ok": true,
"data": [
{
"team_id": "vyy5bHHXSbZ2PaNHz4c7f",
"project_id": "FZI37LUxznExdKuxuZArv",
"zone_id": "YEV8qyUpIdcHWonkhau5E",
"participant_id": "ovpKemJHhn_ePG94YpNpP",
"sample_id": "CwqM6oTRbPStHecXhOiK9",
"timestamp": "2021-08-05T19:58:13.000Z",
"location": "172.20.0.1",
"code": 200,
"user_id": "DwP3qnDcHsaB4V6Ti-wb-",
"user_label": "API Token",
"target_user_id": null,
"target_user_label": null,
"is_sensitive": 1,
"resource": "participant",
"action": "read",
"params": null
},
{
"team_id": "vyy5bHHXSbZ2PaNHz4c7f",
"project_id": "FZI37LUxznExdKuxuZArv",
"zone_id": "YEV8qyUpIdcHWonkhau5E",
"participant_id": "ovpKemJHhn_ePG94YpNpP",
"sample_id": null,
"timestamp": "2021-08-05T20:03:57.000Z",
"location": "172.20.0.1",
"code": 200,
"user_id": "DwP3qnDcHsaB4V6Ti-wb-",
"user_label": "API Token",
"target_user_id": null,
"target_user_label": null,
"is_sensitive": 1,
"resource": "participant",
"action": "list",
"params": {
"sample_ids": ["CwqM6oTRbPStHecXhOiK9"]
}
}
]
}

GET {host}.winterlightlabs.com/api/v1/zones/{id}/audit-logs

Parameter Type Description
host string Any valid winterlight region url.
id string The id of the zone.

Billing

The billing resource gives fine-grained access to API usage costs. Whenever you call an endpoint that has the Can result in invoice charges? special property, those charges would be appear here.

Fields

An example billing resource:

{
"cost_type": "depression_insight",
"sample_id": "7lu-L-11u3Rqt8p11c9uI",
"project_id": "FZI37LUxznExdKuxuZArv",
"charged_at": "2021-10-29T23:59:59.000Z",
"invoice_date": "2021-10-31T00:00:00.000Z",
"amount": 3.0
}
Name Type Description
cost_type string See “cost types” below.
sample_id string 21-character guid of the sample that incurred the cost.
project_id string 21-character guid of the project that incurred the cost.
charged_at date The date when the cost was incurred.
invoice_date date See “invoice dates” below.
amount number The amount of the cost in the team’s currency.

Cost Types

Depending on the Winterlight offering that your team has chosen, different uses of the API will incur different costs. The cost_type field is an enum value that indicates the type of event that incurred the cost. Speak with your Winterlight contact to get more detail on how to interpret these values for your plan.

Invoice Dates

If a cost has already been invoiced to you, the invoice date of the corresponding invoice will be specified. If the cost is still pending an invoice, the invoice_date will be null.

Get all Costs

const axios = require('axios');

const subdomain = '...';
const apiToken = '...';
const fromDate = '2021-04-04T00:00:00.000Z';
const toDate = '2021-04-05T00:00:00.000Z';

axios({
url: `https://${subdomain}.winterlightlabs.com/api/v1/billing?from=${fromDate}&to=${toDate}`,
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${apiToken}`,
},
});

This endpoint retrieves all costs that were incurred between from and to for the team associated with the given token.

Special Properties

Property Applicable?
Requires team admin permissions? No
Requires region-specific url due to sensitive data? No
Can result in invoice charges? No
Is activity recorded in audit logs? No

Request Parameters

Example response:

{
"status": 200,
"ok": true,
"data": [
{
"cost_type": "depression_insight",
"sample_id": "7lu-L-11u3Rqt8p11c9uI",
"project_id": "FZI37LUxznExdKuxuZArv",
"charged_at": "2021-11-26T23:59:59.000Z",
"invoice_date": null,
"amount": 3.0
},
{
"cost_type": "depression_insight",
"sample_id": "3mZewtCKOWIjjM_DrBULL",
"project_id": "FZI37LUxznExdKuxuZArv",
"charged_at": "2021-10-20T13:02:37.000Z",
"invoice_date": "2021-10-31T00:00:00.000Z",
"amount": 3.0
},
{
"cost_type": "all_features_insight",
"sample_id": "5AA5rNT-2J5ZRbN8IKbjR",
"project_id": "FZI37LUxznExdKuxuZArv",
"charged_at": "2021-10-08T18:51:21.000Z",
"invoice_date": "2021-10-31T00:00:00.000Z",
"amount": 3.0
}
]
}

GET {host}.winterlightlabs.com/api/v1/billing

Parameter Type Description
host string Costs are team-based, so either region host will work.
from date Start date of the range to retrieve costs for. Defaults to 30 days before to.
to date End date of the range to retrieve costs for. Defaults to the current date+time.

Reference

Status Codes

The Winterlight API uses the following status codes:

Status Meaning
200 Success.
201 Success and a new resource has been created.
400 Bad Request – Your request is invalid.
401 Unauthenticated – You need to be authenticated to access this resource.
403 Forbidden – Insufficient rights or the action is outright not allowed.
404 Not Found – The requested resource does not exist or you do not have permission.
405 Method Not Allowed – You tried to access the endpoint with an invalid method.
413 Payload Too Large – You attached a file that’s too large.
415 Unsupported Media Type - Unsupported content-type header.
429 Too Many Requests – You’ve made too many requests in a short period of time
500 Internal Server Error – We had a problem with our server. Try again later.
503 Service Unavailable – We’re temporarily offline for maintenance. Please try again later.

Error Codes

In the event of a 400 or 500-type error, there will be an error property defined in the JSON response explaining the reason using a machine readable string.

Error Status Meaning
ALREADY_SUBMITTED 400 The sample was already submitted with an audio file.
AUDIO_TOO_SHORT 400 The sample duration is under 1 second.
CANNOT_UPDATE_TASKS 400 Supported tasks/stimuli cannot be changed for this project.
DURATION_EXCEEDED_LIMIT 400 The sample duration exceeded the project task max duration.
EMPTY_FILE 400 Uploaded file has no data.
FAILED_VALIDATION 400 Improperly structured request body. See reason property.
INVALID_REGION_ID 400 Tried to create a zone with a region that is not supported by the project.
FILE_TOO_LARGE 413 File is larger than 150 mb.
FORBIDDEN 403 Your request is forbidden.
INCOMPLETE_FILE 400 File is missing parts.
INCORRECT_REGION 400 Sensitive data resource request from the incorrect region.
INVALID_AUDIO 400 File is corrupt or incorrectly typed.
MISSING_FILE 400 No file was provided in the request.
NOT_AUTHENTICATED 401 Your token is invalid.
NOT_FOUND 404 Resource not found or your permission is insufficient.
SANDBOX_ONLY_PROJECT 400 Tried to create a zone in a project that is marked as sandbox only.
UNEXPECTED_CONTENT_TYPE 415 The “content-type” header was inappropriate for the endpoint.
UNKNOWN_FILE_TYPE 415 Could not identify file type.
UNSUPPORTED_FILE_TYPE 415 File type is not supported.
UNSUPPORTED_LANGUAGE_BY_ZONE 400 The sample language is not supported by the zone.
UNSUPPORTED_TASK 400 The sample language, task and stimuli combination is unsupported.
UNSUPPORTED_TRANSCRIPTION_MODE 400 The transcription mode cannot be used for this task + stimulus.

Valid Country Codes

Code Country
AF Afghanistan
AL Albania
DZ Algeria
AS American Samoa
AD Andorra
AO Angola
AI Anguilla
AG Antigua and Barbuda
AR Argentina
AM Armenia
AW Aruba
AU Australia
AT Austria
AZ Azerbaijan
BS The Bahamas
BH Bahrain
BD Bangladesh
BB Barbados
BY Belarus
BE Belgium
BZ Belize
BJ Benin
BM Bermuda
BT Bhutan
BO Bolivia
BA Bosnia and Herzegovina
BW Botswana
BR Brazil
VG British Virgin Islands
BN Brunei
BG Bulgaria
BF Burkina Faso
BI Burundi
KH Cambodia
CM Cameroon
CA Canada
CV Cape Verde
KY Cayman Islands
CF Central African Republic
TD Chad
CL Chile
CN China
CX Christmas Island
CC Cocos (Keeling) Islands
CO Colombia
KM Comoros
CG Republic of the Congo
CK Cook Islands
CR Costa Rica
CI Cote d’Ivoire
HR Croatia
CU Cuba
CY Cyprus
CZ Czech Republic
DK Denmark
DJ Djibouti
DM Dominica
DO Dominican Republic
EC Ecuador
EG Egypt
SV El Salvador
GQ Equatorial Guinea
ER Eritrea
EE Estonia
ET Ethiopia
FK Falkland Islands (Islas Malvinas)
FO Faroe Islands
FJ Fiji
FI Finland
FR France
GF French Guiana
PF French Polynesia
GA Gabon
GM The Gambia
GE Georgia
DE Germany
GH Ghana
GI Gibraltar
GR Greece
GL Greenland
GD Grenada
GP Guadeloupe
GU Guam
GT Guatemala
GN Guinea
GW Guinea-Bissau
GY Guyana
HT Haiti
VA Holy See (Vatican City)
HN Honduras
HU Hungary
IS Iceland
IN India
ID Indonesia
IR Iran
IQ Iraq
IE Ireland
IL Israel
IT Italy
JM Jamaica
JP Japan
JO Jordan
KZ Kazakhstan
KE Kenya
KI Kiribati
KP North Korea
KR South Korea
KW Kuwait
KG Kyrgyzstan
LA Laos
LV Latvia
LB Lebanon
LS Lesotho
LR Liberia
LY Libya
LI Liechtenstein
LT Lithuania
LU Luxembourg
MK North Macedonia
MG Madagascar
MW Malawi
MY Malaysia
MV Maldives
ML Mali
MT Malta
IM Isle of Man
MH Marshall Islands
MQ Martinique
MR Mauritania
MU Mauritius
YT Mayotte
MX Mexico
FM Federated States of Micronesia
MD Moldova
MC Monaco
MN Mongolia
MS Montserrat
MA Morocco
MZ Mozambique
MM Myanmar (Burma)
NA Namibia
NR Nauru
NP Nepal
NL Netherlands
AN Netherlands Antilles
NC New Caledonia
NZ New Zealand
NI Nicaragua
NE Niger
NG Nigeria
NU Niue
NF Norfolk Island
MP Northern Mariana Islands
NO Norway
OM Oman
PK Pakistan
PW Palau
PS Palestinian Territory
PA Panama
PG Papua New Guinea
PY Paraguay
PE Peru
PH Philippines
PN Pitcairn Islands
PL Poland
PT Portugal
PR Puerto Rico
QA Qatar
RE Reunion
RO Romania
RU Russia
RW Rwanda
KN Saint Kitts and Nevis
LC Saint Lucia
PM Saint Pierre and Miquelon
VC Saint Vincent and the Grenadines
SM San Marino
ST Sao Tome and Principe
SA Saudi Arabia
SN Senegal
SC Seychelles
SL Sierra Leone
SG Singapore
SK Slovakia
SI Slovenia
SB Solomon Islands
SO Somalia
ZA South Africa
ES Spain
LK Sri Lanka
SD Sudan
SR Suriname
SJ Svalbard
SZ Eswatini
SE Sweden
CH Switzerland
SY Syria
TW Taiwan
TJ Tajikistan
TZ Tanzania
TH Thailand
TG Togo
TK Tokelau
TO Tonga
TT Trinidad and Tobago
TN Tunisia
TR Turkey
TM Turkmenistan
TC Turks and Caicos Islands
TV Tuvalu
UG Uganda
UA Ukraine
AE United Arab Emirates
GB United Kingdom
US United States
UM United States Minor Outlying Islands
UY Uruguay
UZ Uzbekistan
VU Vanuatu
VE Venezuela
VN Vietnam
VI Virgin Islands
WF Wallis and Futuna
EH Western Sahara
WS Western Samoa
YE Yemen
CD Democratic Republic of the Congo
ZM Zambia
ZW Zimbabwe
HK Hong Kong
MO Macau
AQ Antarctica
BV Bouvet Island
IO British Indian Ocean Territory
TF French Southern and Antarctic Lands
HM Heard Island and McDonald Islands
SH Saint Helena
GS South Georgia and the South Sandwich Islands
GG Guernsey
RS Serbia
BL Saint Barthélemy
ME Montenegro
JE Jersey
CW Curaçao
MF Saint Martin
SX Sint Maarten
TL Timor-Leste
SS South Sudan
AX Åland Islands
BQ Bonaire
XK Republic of Kosovo

Valid Language Codes

Code Name Localized Name
aa Afar Afaraf
ab Abkhaz аҧсуа бызшәа
ae Avestan avesta
af Afrikaans Afrikaans
ak Akan Akan
am Amharic አማርኛ
an Aragonese aragonés
ar Arabic اللغة العربية
as Assamese অসমীয়া
av Avaric авар мацӀ
ay Aymara aymar aru
az Azerbaijani azərbaycan dili
ba Bashkir башҡорт теле
be Belarusian беларуская мова
bg Bulgarian български език
bh Bihari भोजपुरी
bi Bislama Bislama
bm Bambara bamanankan
bn Bengali বাংলা
bo Tibetan བོད་ཡིག
br Breton brezhoneg
bs Bosnian bosanski jezik
ca Catalan Català
ce Chechen нохчийн мотт
ch Chamorro Chamoru
co Corsican corsu
cr Cree ᓀᐦᐃᔭᐍᐏᐣ
cs Czech čeština
cu Old Church Slavonic ѩзыкъ словѣньскъ
cv Chuvash чӑваш чӗлхи
cy Welsh Cymraeg
da Danish dansk
de German Deutsch
dv Divehi Dhivehi
dz Dzongkha རྫོང་ཁ
ee Ewe Eʋegbe
el Greek Ελληνικά
en English English
eo Esperanto Esperanto
es Spanish Español
et Estonian eesti
eu Basque euskara
fa Persian فارسی
ff Fula Fulfulde
fi Finnish suomi
fj Fijian Vakaviti
fo Faroese føroyskt
fr French Français
fy Western Frisian Frysk
ga Irish Gaeilge
gd Scottish Gaelic Gàidhlig
gl Galician galego
gn Guaraní Avañe’ẽ
gu Gujarati ગુજરાતી
gv Manx Gaelg
ha Hausa هَوُسَ
he Hebrew עברית
hi Hindi हिन्दी
ho Hiri Motu Hiri Motu
hr Croatian Hrvatski
ht Haitian Kreyòl ayisyen
hu Hungarian magyar
hy Armenian Հայերեն
hz Herero Otjiherero
ia Interlingua Interlingua
id Indonesian Bahasa Indonesia
ie Interlingue Interlingue
ig Igbo Asụsụ Igbo
ii Nuosu ꆈꌠ꒿ Nuosuhxop
ik Inupiaq Iñupiaq
io Ido Ido
is Icelandic Íslenska
it Italian Italiano
iu Inuktitut ᐃᓄᒃᑎᑐᑦ
ja Japanese 日本語
jv Javanese basa Jawa
ka Georgian ქართული
kg Kongo Kikongo
ki Kikuyu Gĩkũyũ
kj Kwanyama Kuanyama
kk Kazakh қазақ тілі
kl Kalaallisut kalaallisut
km Khmer ខេមរភាសា
kn Kannada ಕನ್ನಡ
ko Korean 한국어
kr Kanuri Kanuri
ks Kashmiri कश्मीरी
ku Kurdish Kurdî
kv Komi коми кыв
kw Cornish Kernewek
ky Kyrgyz Кыргызча
la Latin latine
lb Luxembourgish Lëtzebuergesch
lg Ganda Luganda
li Limburgish Limburgs
ln Lingala Lingála
lo Lao ພາສາ
lt Lithuanian lietuvių kalba
lu Luba-Katanga Tshiluba
lv Latvian latviešu valoda
mg Malagasy fiteny malagasy
mh Marshallese Kajin M̧ajeļ
mi Māori te reo Māori
mk Macedonian македонски јазик
ml Malayalam മലയാളം
mn Mongolian Монгол хэл
mr Marathi मराठी
ms Malay Bahasa Malaysia
mt Maltese Malti
my Burmese ဗမာစာ
na Nauru Ekakairũ Naoero
nb Norwegian Bokmål Norsk bokmål
nd Northern Ndebele isiNdebele
ne Nepali नेपाली
ng Ndonga Owambo
nl Dutch Nederlands
nn Norwegian Nynorsk Norsk nynorsk
no Norwegian Norsk
nr Southern Ndebele isiNdebele
nv Navajo Diné bizaad
ny Chichewa chiCheŵa
oc Occitan occitan
oj Ojibwe ᐊᓂᔑᓈᐯᒧᐎᓐ
om Oromo Afaan Oromoo
or Oriya ଓଡ଼ିଆ
os Ossetian ирон æвзаг
pa Panjabi ਪੰਜਾਬੀ
pi Pāli पाऴि
pl Polish język polski
ps Pashto پښتو
pt Portuguese Português
qu Quechua Runa Simi
rm Romansh rumantsch grischun
rn Kirundi Ikirundi
ro Romanian Română
ru Russian Русский
rw Kinyarwanda Ikinyarwanda
sa Sanskrit संस्कृतम्
sc Sardinian sardu
sd Sindhi सिन्धी
se Northern Sami Davvisámegiella
sg Sango yângâ tî sängö
si Sinhala සිංහල
sk Slovak slovenčina
sl Slovenian slovenski jezik
sm Samoan gagana fa’a Samoa
sn Shona chiShona
so Somali Soomaaliga
sq Albanian Shqip
sr Serbian српски језик
ss Swati SiSwati
st Southern Sotho Sesotho
su Sundanese Basa Sunda
sv Swedish Svenska
sw Swahili Kiswahili
ta Tamil தமிழ்
te Telugu తెలుగు
tg Tajik тоҷикӣ
th Thai ไทย
ti Tigrinya ትግርኛ
tk Turkmen Türkmen
tl Tagalog Wikang Tagalog
tn Tswana Setswana
to Tonga faka Tonga
tr Turkish Türkçe
ts Tsonga Xitsonga
tt Tatar татар теле
tw Twi Twi
ty Tahitian Reo Tahiti
ug Uyghur ئۇيغۇرچە‎
uk Ukrainian Українська
ur Urdu اردو
uz Uzbek Ўзбек
ve Venda Tshivenḓa
vi Vietnamese Tiếng Việt
vo Volapük Volapük
wa Walloon walon
wo Wolof Wollof
xh Xhosa isiXhosa
yi Yiddish ייִדיש
yo Yoruba Yorùbá
za Zhuang Saɯ cueŋƅ
zh Chinese 中文
zu Zulu isiZulu