Skip to main content

ZeroLight™ SpotLight™ Public API


Version: 2.3.0

Last updated: 28-01-2026


Introduction​

This document details the usage of the SpotLight public API.

Applications Available​

  • Gallery – Generate packs of predefined images to support your brand
  • Brochure – Generate high quality personalised PDFs for customers
  • Web – Generate a personalised microsite for your customers from a pre-defined template
  • Video – Generate a video based on a pre-defined sequence template created in the 'Take' application
  • AR Model – Generate a digital twin of your asset for use in AR experiences

Conventions​

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC2119.


API Fundamentals​

The API is available at https://spotlightsuite.com. It follows the JSON API specification.

The API has the following stipulations

  • All requests MUST use HTTPS, the API is not available over vanilla HTTP
  • All routes MUST provide an authorisation token via the x-access-token header
  • All routes MUST provide a team identifier via an x-team-id header unless explicitly documented as not required for the specific route
  • Users MUST have API permissions on the given team to perform requests
  • All routes are prefixed with /api/external/
  • All Order routes are prefixed with /api/external/orders/
  • All requests and responses MUST use the application/vnd.api+json content type
  • All requests support a charset value of UTF-8. Any other value will be rejected. If charset is omitted, it is assumed to be UTF-8

Responses​

All routes abide by the JSON API spec, i.e., a response MAY contain a data or errors top level property but will never contain both.

Additionally responses MAY include an OPTIONAL top level meta field. This field, if present, MAY include a non-empty list of warnings. It is recommended that any returned warnings are logged at 'warning' level within the client's application backend. It is the integrators responsibility to monitor these warnings and update their implementation accordingly.

An example of a warning could be advance notice of a deprecation - and has the structure below.

    {
"data": {
"id": "5c6acb07ec045209437f1f01",
"status": "pending",
"timestamp": "2019-02-18T15:11:03.591Z",
"transaction": "5c6acb07ec045209437f1f02"
},
"meta": {
"warnings": [
{
"id": "4059118ff2441cec577a07737c1e819e",
"code": "API_MISSING_TEAM",
"title": "x-team-id missing from request headers",
"detail": "Access to the API endpoint '/external/orders/shutter-packs' without passing an x-team-id will be deprecated after 31-10-2022 and result in a 400 error",
"links": {
"about": "https://resources.zerolight.com/docs/spotlight/spotlightreference/"
}
}
]
}
}

Note: Warnings may be issued in addition to Errors.

Pagination​

Page based pagination is supported on responses that return lists of data

Query Parameters​

ParameterTypeDescriptionRequired
page[size]numberAmount of orders per page (max 100)false
page[number]numberPage Number (0 based)false

Pagination responses​

Page information is returned within the meta block as follows below.

Example response to a paginated query

  "data": [...],
"meta": {
"pagination": {
"page[size]": 50,
"page[number]": 0,
"totalCount": 250,
"hasMore": true
}
}
  • page[size]: The current page size which was queried (This number may not match the number of items in the data array when it is the final page).
  • page[number]: The current page number queried.
  • totalCount: Count of all documents matching the current filter parameters.
  • hasMore: A boolean value which is true if this is not the last page.

Routes​

The following section details the usage of each route and its expected response from requests.

Teams​

List team memberships​

Note: This route is one of the few routes within the API which the header x-team-id is OPTIONAL. As this route used to interrogate which teams are available to the current x-access-token bearer.

The type of service is indicated in the response for each team. serviceType can be one of Palette or OmniStream. The type of service determines the parameters required on order request calls - and MAY result in different response data.

Note: This route is NOT paginated.

URL​

/api/external/teams

Method​

GET

Query Parameters​

none

Data Parameters​

none

Headers​

Content-Type: application/vnd.api+json
x-access-token: <YOUR_TOKEN>

Success Response​

  • Code: 200 OK
  • Headers:
    Content-Type: application/vnd.api+json
  • Content:
    {
"data": [
{
"teamId": "5ea96707dd4089351817c0dc",
"teamOem": "zerolight",
"teamName": "ZeroLight PreLive",
"serviceType": "Palette"
},
{
"teamId": "61c0d89eee02c20fed2eefdd",
"teamOem": "zerolight",
"teamName": "ZeroLight Live",
"serviceType": "Palette"
}
{
"teamId": "61c0d89eee02c20fed2eafde",
"teamOem": "zerolight",
"teamName": "ZeroLight Omnistream",
"serviceType": "OmniStream"
}
],

}

The client application selects one of the teams and passes that team id in subsequent requests using the x-team-id header.

Error Response​

If, for example x-access-token is not provided:

  • Code: 401 Unauthorized
  • Headers:
    Content-Type: application/vnd.api+json
  • Content:
    {
"errors": [
{
"title": "User is not authorised",
"id": "05500c036ef9952365859a849c36e1ca"
}
],
"message": "User is not authorised"
}

Team details​

Returns details about the specified team - including a list of assets (cars) available on this team

URL​

/api/external/teams/<WORKING_TEAM_ID>

Note: For this route, the URL parameter <WORKING_TEAM_ID> MUST match the x-team-id header.

Method​

GET

Query Parameters​

none

Data Parameters​

none

Headers​

Content-Type: application/vnd.api+json
x-access-token: <YOUR_TOKEN>
x-team-id: <WORKING_TEAM_ID>

Success Response​

  • Code: 200 OK
  • Headers:
    Content-Type: application/vnd.api+json
  • Content:
    {
"data": {
"teamId": "5ea96707dd4089351817c0dd",
"teamOem": "zerolight",
"teamName": "ZeroLight PreLive",
"serviceType": "Palette",
"assets": [
{
"uid": "pagani%20huayra%202015",
"manufacturer": "pagani",
"model": "huayra",
"year": "2015",
"name": "pagani huayra 2015",
"displayName": "pagani huayra",
"version": "car.pagani.huayra.2015_56eab718-eddd-4f50-9fff-c144d06d7a51"
},
{...}
]
}
}

NOTE: For OmniStream service-types the details of the returned assets will include app, project, id instead of manufacturer, model, year.


Content Enumeration​

Paginated queries for available content for use in order creation requests. If content has been flagged for UI use only it will not be returned here. Content created by, or shared with the current user will be returned subject to any asset or team restrictions.

URLs​

/api/external/content/template/microsite /api/external/content/template/frame_pack

Method​

GET

Query Parameters​

ParameterTypeDescriptionRequired
page[size]numberAmount of content per page (max 100)false
page[number]numberPage Number (0 based)false
filter[assetUid]stringAsset uid eg: "pagani%20huayra%202015"RECOMMENDED *
filter[search]stringSearches displayName, uid and description. prefix with * for an internal string searchfalse
filter[owners]stringSingle or comma-separated list of known ownerIds (matches when any specified owner matches)false
filter[tags]stringSingle or comma-separated list of tag string values (matches content when all specified tags match)false

* Note: A filter[assetUid] parameter is strongly recommended to ensure all relevant content for a particular asset is returned. If this parameter is omitted - the ONLY content that will be returned will be content suitable for any asset available on the current team.

Data Parameters​

none

Headers​

Content-Type: application/vnd.api+json
x-access-token: <YOUR_TOKEN>
x-team-id: <WORKING_TEAM_ID>

Success Response​

  • Code: 200 OK
  • Headers:
    Content-Type: application/vnd.api+json
  • Content:
    {
"data": [
{
"_id": "6980a52ba0930cbbe8fa3244",
"context": "template",
"subcontext": "microsite",
"displayName": "omnistream-microsite",
"tags": [
{
"type": "user",
"value": "approved",
"added": "2025-12-17T08:19:43.176Z"
}
],
"ownerId": "5838500c32b7f52fe83ff4b3",
"created": "2026-02-02T13:22:51.613Z",
"modified": "2026-02-05T14:30:28.495Z",
"uid": "omnistream-microsite",
"description": "A microsite template with hero section and gallery"
},
...
],
"meta": {
"pagination": {
"page[size]": 10,
"page[number]": 0,
"totalCount": 8,
"hasMore": false
}
}
}

Order Creation​

URL​

/api/external/orders/create

Method​

POST

Headers​

Content-Type: application/vnd.api+json
x-access-token: <YOUR_TOKEN>
x-team-id: <WORKING_TEAM_ID>

Query Parameters​

none

Data Parameters​

Data Parameters (All Service Types)​

The following parameters can be defined in the data request object.

ParameterTypeDescriptionRequired
typestringOrder type (see Order Types)true
assetstringAsset UID string – representing manufacturer, model & year (or app, project & id for OmniStream services )true
callbackstring | ObjectSee section regarding Order Callbacksfalse
carstringDEPRECATED Use of this field will trigger a warning response. Please use the asset field instead.false
. . ....Additional parameters may be required depending on the specified typefalse
Additional Data Parameters (OmniStream Services)​

N/A

Additional Data Parameters (Palette Services)​

When connecting to a Palette service either a prcodes or shortcode must be provided for the asset configuration

ParameterTypeDescriptionRequired
prcodesstringComma separated string. shortcode is ignored if this field is providedfalse
shortcodestringMust be provided if the prcodes field is omitted.false

Example call using JavaScript​

const response = await fetch('https://spotlightsuite.com/api/external/orders/create', {
method: 'POST',
headers: new Headers({
'Content-Type': 'application/vnd.api+json',
'x-access-token': '<YOUR_TOKEN>',
'x-team-id': '<WORKING_TEAM_ID>',
}),
credentials: 'include',
body: JSON.stringify({
data: {
type: 'frame_pack',
asset: 'lamborghini%20urus%202018',
prcodes: 'F14 0E0E,GPC0PC0,GPGMPGM,GPGOPGO,GPGYPGY,GPH8PH8,GPH9PH9',
template: 'frame-pack-lamborghini-urus-2018-pilot',
},
}),
});

// if request was unsuccessful
if (response.body.errors) {
// parse errors
return;
}

console.info(response.data.id); // '5af2f55e8c38f758afef6ef7'

Example Success Response​

  • Code: 202 Accepted
  • Headers:
    Content-Type: application/vnd.api+json
  • Content:
    {
"data": {
"id": "5c6acb07ec045209437f1f01",
"items": [],
"status": "pending",
"timestamp": "2019-02-18T15:11:03.591Z",
"transaction": "5c6acb07ec045209437f1f02",
"templateManifestUid": "5bc3b24f-64c3-44da-affd-6763289d2f6a",
}
}

Notes​

A successful response returns a 202 Accepted HTTP status not 200, this is because the order has been accepted for processing but doesn't instantly complete.

Example Error Response​

If, for example, asset is not provided:

  • Code: 400 Bad Request
  • Headers:
    Content-Type: application/vnd.api+json
  • Content:
    {
"errors": [
{
"title": "asset is invalid",
"detail": "Invalid property 'asset' (string) is required, got 'undefined'",
"id": "7fe691b0-5838-11e8-a129-db216eb107b5"
}
]
}

Order Types​



Generate packs of predefined images to support your brand.

Data Parameters​

Also see the parameters defined for All Order Types.

ParameterType / ValueDescriptionRequired
typeframe_packOrder typetrue
templatestringTemplate UIDtrue


Web (type=microsite)​

Generate a personalised microsite for your customers from a pre-defined template

Data Parameters​

Also see the parameters defined for All Order Types.

ParameterType / ValueDescriptionRequired
typemicrositeOrder typetrue
templatestringTemplate UIDtrue
parametersArrayList of template mapping objects, see Customising Templatesfalse


Video (type=bespoke_video)​

Generate a video based on a pre-defined sequence template created in the 'Take' application.

Data Parameters​

Also see the parameters defined for All Order Types.

ParameterType / ValueDescriptionRequired
typebespoke_videoOrder typetrue
templatestringTemplate UIDtrue


Brochure (type=brochure)​

Generate high quality personalised PDFs for customers

Data Parameters​

Also see the parameters defined for All Order Types.

ParameterType / ValueDescriptionRequired
typebrochureOrder typetrue
templatestringTemplate UIDtrue
renderQualityPresetstring enumOutput quality, ['low', 'medium', 'high']false
parametersArrayList of template mapping objects, see Customising Templatesfalse
Render Quality Presets​

The renderQualityPreset property defines the PPI of the output, it defaults to low.

The presets are as follows:

IDPPINotes
low96Default, web quality, jpg
medium150Medium quality, jpg
high300Print quality, png, ray traced reflections


AR Model (type=bespoke_ar)​

Generate a digital twin of your asset for use in AR experiences

Data Parameters​

Also see the parameters defined for All Order Types.

ParameterType / ValueDescriptionRequired
typebespoke_arOrder typetrue
outputFormatstringOne of two file types (glb or usdz)true
targetFileSizeMBnumberA number 1-50 representing MBfalse

Order Callbacks (Webhooks)​

It is possible to request that a webhook is hit on completion (success, failure, cancellation) of your order-request. This method of notification is preferred over polling the order status endpoint.

The callback entry is either a string or an Object. Specifying a string is the shortcut to use a simple GET request callback with no headers. The advanced method using an Object it is possible to specify either GET or POST https verbs, up to 5 headers and 2048 bytes of body data are permitted. The body data may be specified as a raw string or as an Object. The system will add an application/json content header if a body Object is specified.

The values for orderId and status are replaceable using template string syntax ("${orderId}" and "${status}"). These values are replaceable in the uri, and header and body values only (not keys). For security, no additional data is passed to the callback. Once the callback has been received the integration can query the SpotLight API with their authentication credentials to receive the full data for the completed order.

It is the integrator's responsibility to ensure the validity of the callback. And that the callback has not been spoofed from elsewhere on the internet. This can be achieved by passing and verifying a secret token used only for this purpose (the orderId is not sufficient on its own)

SpotLight will attempt to hit the callback one time only. It will log the status of the callback request into its logging system for debugging purposes.

Examples​

In the following simple example the callback is a GET request with the secret and orderId in the uri.

{
"data": {
"type": "frame_pack",
"asset": "lamborghini%20urus%202018",
"prcodes": "F14 0E0E,GPC0PC0,GPGMPGM,GPGOPGO,GPGYPGY,GPH8PH8,GPH9PH9",
"template": "frame-pack-lamborghini-urus-2018-pilot",
"callback": "https://my.webhookhandler.com/spotlight/order/${orderId}?secret=abcd1234abcd1234"
},
}

In the following advanced example the callback is a POST request with a secret token in the header and both the orderId and status in the body.

{
"data": {
"type": "frame_pack",
"asset": "lamborghini%20urus%202018",
"prcodes": "F14 0E0E,GPC0PC0,GPGMPGM,GPGOPGO,GPGYPGY,GPH8PH8,GPH9PH9",
"template": "frame-pack-lamborghini-urus-2018-pilot",
"callback": {
"uri": "https://my.webhookhandler.com/spotlight/order",
"method": "POST",
"headers": {
"x-secret": "abcd1234abcd1234"
},
"body": {
"orderId": "${orderId}",
"status": "${status}"
}
}
}
}

Get Recent Orders​

URL​

/api/external/orders/recent

Method​

GET

Query Parameters​

ParameterTypeDescriptionRequired
page[size]numberAmount of orders per page (max 100)false
page[number]numberPage Number (0 based)false
filter[status]stringOrder Status e.g. completedfalse
filter[type]stringOrder type e.g. bespoke_video, frame_pack, microsite. Multiple order types can be returned by using a comma-separated list, e.g. bespoke_video,frame_packfalse
filter[assetUid]stringCar Uidfalse
filter[orderId]stringOrder IDfalse

Data Parameters​

none

Headers​

Content-Type: application/vnd.api+json
x-access-token: <YOUR_TOKEN>
x-team-id: <WORKING_TEAM_ID>

Success Response​

  • Code: 200 OK
  • Headers:
    Content-Type: application/vnd.api+json
  • Content:
    {
"data": [
{
"id": "b1efe44de2c0283fa4a13d41",
"title": "Video",
"type": "bespoke_video",
"status": "completed",
"created": "2019-08-06T08:50:20.386Z",
"modified": "2019-08-06T08:51:25.296Z",
"timestamp": "2020-04-01T15:18:14.769Z",
"transaction": "d3ad3f4c249f82261ccd1b51",
"asset": "lamborghini%20urus%202018",
"template": "a-bespoke-video-template"
}
]
}

Get Order Status​

URL​

/api/external/orders/:id/status

Method​

GET

Path Parameters​

ParameterTypeDescriptionRequired
:idstringOrder IDtrue

Query Parameters​

none

Data Parameters​

none

Headers​

Content-Type: application/vnd.api+json
x-access-token: <YOUR_TOKEN>
x-team-id: <WORKING_TEAM_ID>

Success Response​

  • Code: 200 OK
  • Headers:
    Content-Type: application/vnd.api+json
  • Content:
    {
"data": {
"status": "completed",
"progress": 100,
"modified": "2020-03-23T16:31:11.695Z"
}
}

Example order statuses include​

const orderStatuses = {
shelf: 'Ready to go but awaiting confirmation',
cart: 'Waiting in cart',
paying: 'During payment processing',
pending: 'Queued behind other processing orders',
processing: 'Processing / rendering',
paused: 'Paused during processing',
completed: 'Completed',
deleted: 'Completed, but removed of viewer sight',
cancelled: 'Removed from cart, or payment failed, never rendered',
failed: 'Failed during payment or processing',
refunding: 'During refund payment-processing',
refunded: 'Was rendered (or failed to render) and has been refunded',
problem: 'Order has been reported as having an issue',
};


Get Order Information​

URL​

/api/external/orders/:id

Method​

GET

Path Parameters​

ParameterTypeDescriptionRequired
:idstringOrder IDtrue

Query Parameters​

none

Data Parameters​

none

Headers​

Content-Type: application/vnd.api+json
x-team-id: <WORKING_TEAM_ID>
x-access-token: <YOUR_TOKEN>

Success Response​

  • Code: 200 OK
  • Headers:
    Content-Type: application/vnd.api+json
  • Content:
    {
"data":
{
"id": "Order ID",
"title": "Shutter",
"type": "shutter",
"status": "completed",
"created": "2022-02-15T14:22:40.813Z",
"modified": "2022-02-15T14:23:00.093Z",
"timestamp": "2022-02-16T09:02:51.689Z",
"asset": "audi etron-au51x 2019",
"transaction": "Transaction ID",
"templateManifestUid": "5bc3b24f-64c3-44da-affd-6763289d2f6a",
}
}

Error Response​

If, for example, a orderId is invalid:

  • Code: 400 Bad Request
  • Headers:
    Content-Type: application/vnd.api+json
  • Content:
    {
"errors": [
{
"title": "Invalid order id",
"detail": "Order ID '1' is not valid.",
"id": "f1a874bd53858f2c72a615fdf3504096"
}
]
}


Get Order Items​

URL​

/api/external/orders/:id/items

Method​

GET

Path Parameters​

ParameterTypeDescriptionRequired
:idstringOrder IDtrue

Query Parameters​

ParameterTypeDescriptionRequired
page[size]numberAmount of items per page (max 100)false
page[number]numberPage Number (0 based)false
filter[mediaType]stringItem mediaType e.g. image/pngfalse

Data Parameters​

none

Headers​

Content-Type: application/vnd.api+json
x-team-id: <WORKING_TEAM_ID>
x-access-token: <YOUR_TOKEN>

Success Response​

  • Code: 200 OK
  • Headers:
    Content-Type: application/vnd.api+json
  • Content:
    {
"data":
[
{
"_id": "Item ID",
"name": "batch_manifest.csv",
"created": "2022-02-15T14:22:58.408Z",
"mediaType": "text/csv",
"url": "#url",
"download": "#url",
"thumbnail": "#url",
"fileSize": 1234,
"metaData": {
...
},
},
{...}
]
}

Error Response​

If, for example, a orderId is invalid:

  • Code: 400 Bad Request
  • Headers:
    Content-Type: application/vnd.api+json
  • Content:
    {
"errors": [
{
"title": "Invalid order id",
"detail": "Order ID '1' is not valid.",
"id": "f1a874bd53858f2c72a615fdf3504096"
}
]
}


Get Order Manifest​

NOTE: this route is DEPRECATED​

URL​

/api/external/orders/:id/manifest

Method​

GET

Path Parameters​

ParameterTypeDescriptionRequired
:idstringOrder IDtrue

Query Parameters​

none

Data Parameters​

none

Headers​

Content-Type: application/vnd.api+json
x-team-id: <WORKING_TEAM_ID>
x-access-token: <YOUR_TOKEN>

Success Response​

  • Code: 200 OK
  • Headers:
    Content-Type: application/vnd.api+json
  • Content:
    {
"data":
{
"id": "Order ID",
"title": "Shutter",
"type": "shutter",
"status": "completed",
"created": "2022-02-15T14:22:40.813Z",
"modified": "2022-02-15T14:23:00.093Z",
"timestamp": "2022-02-16T09:02:51.689Z",
"asset": "audi etron-au51x 2019",
"transaction": "Transaction ID",
"templateManifestUid": "5bc3b24f-64c3-44da-affd-6763289d2f6a",
"items": [
{"_id": "Item ID",
"name": "batch_manifest.csv",
"download": "#url",
"created": "2022-02-15T14:22:58.408Z",
"mediaType": "text/csv",
"uid": "620bb7426c48ba4080736d3a",
"uri": "#url",
"status": "complete",
},
{...}
]
}
}

Error Response​

If, for example, a orderId is invalid:

  • Code: 400 Bad Request
  • Headers:
    Content-Type: application/vnd.api+json
  • Content:
    {
"errors": [
{
"title": "Invalid order id",
"detail": "Order ID '1' is not valid.",
"id": "f1a874bd53858f2c72a615fdf3504096"
}
]
}

Customising Templates​

Templates can be customised using a mapping object within the parameters array of an API POST request.

Only specific templates are editable, if a request is made to customise an unsupported template it SHALL be rejected.

Only specific properties within a template can be customised. The value passed to a template MUST be a string. If a template is passed an invalid value the request SHALL be rejected. If a request attempts to customise a non-customisable field it SHALL be ignored but the request SHALL succeed.

Example parameters mapping list​

const parameters = [
{
value: 'Personalised Title',
maps: [
'data.meta.title.content',
'data.template.hero.title.content',
],
},
{...}
];

The Mapping Object​

Mapping objects consist of value and maps properties. The value property sets the intended value for the output template, the maps property contains a list of paths where the value should be written to.

Each node within maps MUST be a string and MUST use dot notation (.) for the path. Key ([]) notation MUST NOT be used, any paths using key notation SHALL be ignored. Special characters (excluding dot . and underscore _) are forbidden in map paths, any path containing special characters SHALL be ignored.

Adding HTML​

HTML MAY be used in the value of a mapping object with the following stipulations:

  • Elements MUST be one of div, em or span
  • Only title attributes are permitted

Any other HTML elements or attributes will be stripped, the contents within forbidden elements SHALL be retained as shown below.

Raw Input​

<article style="color: red;">Article<script>window.alert('xss')</script><div title="OK"><h1>Heading</h1></div></article>

Parsed Output​

<div title="OK">ArticleHeading</div>