Skip to content

HTTP REST API

Exaplay 3 exposes an HTTP REST API for programmatic control of compositions, Playlists, Timelines, and media playback. This is the same API used by the Exaplay web UI and is suitable for integration with external show control systems, custom applications, and automation scripts.

Naming note: The Exaplay UI calls this composition type a Playlist. The wire protocol still uses the original cuelist identifier (composition type string, request names such as cuelist.seek, status fields such as CUEINDEX). This is intentional so existing integrations continue to work — treat cuelist and CueList in the protocol as synonyms for Playlist in the UI.

Connection

ParameterValue
ProtocolHTTP
Default Port8123
Content-Typeapplication/json

All commands are sent as POST requests to http://<host>:8123/project with a JSON body. The req field in the body specifies the command.


Composition Transport

These commands control playback of any composition (CueList or Timeline).

All transport commands are sent as POST /project requests with the req field. For composition.play there is also a convenience shortcut — see below.

req valueRequired fieldsDescription
composition.playsrc-uidStart playback
composition.pausesrc-uidPause playback
composition.stopsrc-uidStop playback
composition.set-timesrc-uid, timeSeek to position (seconds)
composition.nextsrc-uidAdvance to the next cue/item (CueList only)
composition.prevsrc-uidGo back to the previous cue/item (CueList only)

Example: Seek a composition to 30 seconds

http
POST /project HTTP/1.1
Content-Type: application/json

{
  "req": "composition.set-time",
  "src-uid": 12345678,
  "time": 30.0
}

Response: 200 OK

Play by name — POST /composition/play

A convenience endpoint that locates a composition by name (or UID) and starts playback without requiring an upfront GET /project lookup.

Fields:

FieldTypeDescription
namestringName of the composition to play
src-uidintegerUID of the composition (alternative to name)

Provide either name or src-uid. If both are present, the first composition matching either value is played.

http
POST /composition/play HTTP/1.1
Content-Type: application/json

{
  "name": "Main Show"
}

Response: 200 OK — composition found and started Response: 400 Bad Request — neither name nor src-uid provided Response: 404 Not Found — no composition matches the given name or UID


Cue Commands

Trigger a cue in a specific composition — cue.go

Triggers a cue inside one specific composition, addressed by the composition's UID. This is the endpoint to use when several compositions contain cues with the same name and /cue/trigger (below) would be ambiguous.

req valueRequired fieldsDescription
cue.gocomp-uid, cue or nameTrigger a cue by index or name in the given composition
cue.executecomp-uid, cue-uidTrigger a cue by its UID in the given composition
cue.nextcomp-uidAdvance to the next item (Playlist compositions only)
cue.prevcomp-uidGo back to the previous item (Playlist compositions only)

Fields:

FieldTypeDescription
comp-uidintegerThe UID of the target composition (from GET /project)
cueintegerTimeline: the cue's variable index · Playlist: the 1-based item position
namestringCue/item name (case-insensitive, within this composition) — alternative to cue
cue-uidintegerThe cue object's UID (cue.execute only)

Behaviour of cue.go:

  • Timeline — the playhead jumps to the cue's time offset, then the cue's action (play/pause/stop/custom) is executed.
  • Playlist — the item at the given 1-based position starts playing.

Example: Trigger cue 5 in composition UID 12345678

http
POST /project HTTP/1.1
Content-Type: application/json

{
  "req": "cue.go",
  "comp-uid": 12345678,
  "cue": 5
}

Example: Trigger the cue named "Blackout" in composition UID 12345678

http
POST /project HTTP/1.1
Content-Type: application/json

{
  "req": "cue.go",
  "comp-uid": 12345678,
  "name": "Blackout"
}

Response: 200 OK (or 404 if the composition/cue does not exist, 500 if triggering failed)

Trigger a cue by name across all compositions — POST /cue/trigger

This is a separate endpoint (not a req on /project): POST http://<host>:8123/cue/trigger. It searches all compositions in project order — Timeline cues by name or variable index, Playlist items by name or variable index — and fires the first match.

Body fieldTypeDescription
namestringCue/item name to match (case-insensitive)
numberintegerCue variable index to match (alternative to name)
compstring(optional) Restrict the search to the composition with this variable name
comp-uidinteger(optional) Restrict the search to the composition with this UID
bash
curl -X POST http://192.168.1.5:8123/cue/trigger \
  -H "Content-Type: application/json" \
  -d '{"name": "Scene 1 - Opening"}'

Scoped to one composition — with comp (or comp-uid) only that composition is searched, so identically named cues elsewhere can never fire:

bash
curl -X POST http://192.168.1.5:8123/cue/trigger \
  -H "Content-Type: application/json" \
  -d '{"name": "Blackout", "comp": "comp_act2"}'

Response: 200 OK on the first match, 404 if no cue matched (or the scoped composition does not exist), 400 if neither name nor number was supplied.

Duplicate cue names: without a scope the first match wins, so either keep cue names project-unique or pass comp/comp-uid. Alternatively use cue.go with comp-uid + name.


CueList Commands

Seek within a CueList

Seek the currently playing item in a CueList to a specific time position. Unlike the generic composition.set-time endpoint, this endpoint validates that the target composition is a CueList and returns 400 Bad Request if it is not. Use this endpoint when integrating external control systems that specifically target CueList compositions.

For seeking any composition type (CueList or Timeline), use composition.set-time instead.

req valueRequired fieldsDescription
cuelist.seeksrc-uid, timeSeek CueList playback to position (seconds)

Fields:

FieldTypeDescription
src-uidintegerThe UID of the CueList composition
timefloatTarget position in seconds

Example: Seek a CueList to 15.5 seconds

http
POST /project HTTP/1.1
Content-Type: application/json

{
  "req": "cuelist.seek",
  "src-uid": 12345678,
  "time": 15.5
}

Response: 200 OK


Media Commands

Seek a specific media item

Seek within a specific media item by its UID. This is useful when you know the exact media item (e.g., from a CueList item click).

req valueRequired fieldsDescription
media.set-timesrc-uid, timeSeek a media item to position (seconds)

Fields:

FieldTypeDescription
src-uidintegerThe UID of the media item
timefloatTarget position in seconds

Example: Seek a media item to 10 seconds

http
POST /project HTTP/1.1
Content-Type: application/json

{
  "req": "media.set-time",
  "src-uid": 87654321,
  "time": 10.0
}

Response: 200 OK


Error Responses

HTTP StatusMeaning
200Success
400Bad request (missing or invalid parameters)
404Composition or media item not found
500Internal server error

Cross-Reference: Other Protocols

The same seeking functionality is available via other protocols:

ProtocolCommandDocumentation
TCPset:cuetime,COMPID,SECONDSTCP API
UDPset:cuetime,COMPID,SECONDSUDP API
OSC/exaplay/<comp>/cuetime <seconds>Config → Network → OSC

Examples

Python

python
import requests

HOST = "http://192.168.1.5:8123"

# Seek a cuelist to 30 seconds
requests.post(f"{HOST}/project", json={
    "req": "cuelist.seek",
    "src-uid": 12345678,
    "time": 30.0,
})

# Play a composition
requests.post(f"{HOST}/project", json={
    "req": "composition.play",
    "src-uid": 12345678,
})

# Stop a composition
requests.post(f"{HOST}/project", json={
    "req": "composition.stop",
    "src-uid": 12345678,
})

JavaScript / Node.js

javascript
const HOST = "http://192.168.1.5:8123";

// Seek a cuelist to 15 seconds
await fetch(`${HOST}/project`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    req: "cuelist.seek",
    "src-uid": 12345678,
    time: 15.0,
  }),
});

curl

bash
# Seek a cuelist to 45.5 seconds
curl -X POST http://192.168.1.5:8123/project \
  -H "Content-Type: application/json" \
  -d '{"req":"cuelist.seek","src-uid":12345678,"time":45.5}'

# Play a composition
curl -X POST http://192.168.1.5:8123/project \
  -H "Content-Type: application/json" \
  -d '{"req":"composition.play","src-uid":12345678}'

Exaplay 3 User Documentation