2023.2 EN DE

    Show / Hide Table of Contents

    REST API Settings

    Description

    REST API allows external tools to control X-Creator using HTTP requests (including CORS support). All API requests have to be prefixed with the IP address of the X-Creator, the configured port, "api" and the API version. Example of a valid API request: http://192.168.0.1:9696/api/v1/experiences

    Environment Configuration

    Enable the REST API module so it is available for the Environment.

    X-Creator Configuration

    Enable the REST API module for one X-Creator in the Environment that should receive the REST requests and use the IP of this X-Creator when sending the requests.

    Port
    The port on which the requests are received

    Authentication
    Enables to define a Bearer Token (case sensitive) that must be added to the header of each request to access all endpoints. 'Bearer' has to be capitalized in the authorization header.

    X-Web Control

    width75

    Configuration

    • By starting the application, a default config file is created next to the executable if no config file found
    • Set values in config.json before starting the application to start with desired configuration (IPs, ports and crestron endpoints)
    Warning

    Do not position the executable inside of a directory with admin rights (recommend directory e.g.: C:\Users\Public\Documents)

    Config Sample File

    The following sample can be used as a starting point and copy-pasted to the config.json file. It contains all default values.

    {
        "WEB_CONTROL_PORT": "9697",
        "CREATOR_REST_API_IP": "http://192.168.0.100",
        "CREATOR_REST_API_PORT": "9696",
        "PIN_CODE": "9999",
        "CRESTRON_IP": "http://192.168.0.200",
        "CRESTRON_HOME_PATH": "/home",
        "CRESTRON_X_PANEL_URL": "https://192.168.1.11/shell-template/index.html?ipId=11"
    }
    

    API Documentation

    All endpoints require a valid bearer token in the Authorization header when Authentication is enabled; every response below can additionally return 401 in that case.

    Error response body

    Every error response (4xx/5xx) carries a JSON body with the status code and a human-readable reason, matching the shape of successful responses:

    { "status": 404, "message": "No experience with specified ID found" }
    

    Media layer object

    The layer endpoints (/slides/{id}/layers, /slides/current/layers, /media/{mediaId}/layer) describe each media layer with this object. Transform values are normalized rather than in pixels:

    Field Type Description
    mediaLayerId string Unique ID of the layer.
    mediaId string ID of the media the layer displays.
    mediaType string Media type, e.g. Image, Video, Text, Web, AssetBundle, Shape.
    name string Display name of the media.
    position { "x", "y" } Normalized position. x spans the canvas width, y spans the canvas height (0–1 covers the canvas).
    size { "x", "y" } Normalized size. Both x (width) and y (height) are relative to the canvas width.
    rotation number Rotation in degrees.
    crop { "x", "y", "z", "w" } Crop fractions (0–1) per edge: x=top, y=bottom, z=left, w=right. Also adjusts position/size to match, unless those are set in the same request.
    visible bool Whether the layer is shown.
    alpha number Opacity, 0–1.
    zOrder int Stacking order; higher values are drawn in front. Relative only — not guaranteed 0-based or contiguous, and values differ between the active slide (normalized) and other slides (raw stored values).
    locked bool Whether the layer is locked against edits.
    fixedAspectRatio bool Whether width and height stay locked to the media's aspect ratio.
    fullscreen bool Whether the layer fills the whole canvas.
    sectionFullscreen bool Whether the layer fills its section. Mutually exclusive with fullscreen.
    backgroundColor { "r", "g", "b", "a" } Background color behind the media, each channel 0–1.
    isStatic bool Whether the layer is static (persists across every slide). Toggling this also re-maps layerGroup to/from its Static* variant.
    layerGroup string Layer group: Background, Regular, Foreground, StaticBackground, StaticRegular, StaticForeground. Setting a non-static base group (e.g. Foreground) while the layer is static resolves to its Static* counterpart automatically. System-assigned groups (Widget, VideoSource, Audio) can't be set through the API.
    control object or null Media-type-specific control state snapshot, shaped per mediaType — see Media control object. null for media types with no control operations (e.g. Image, AssetBundle, VideoMatrix).

    The canvas dimensions needed to convert normalized values to pixels are returned by /experiences/current as canvasWidth and canvasHeight. Individual layer properties can be updated live with PATCH /layers/{id}; media-type-specific operations (play/pause, page navigation, etc.) are covered in Media Control Endpoints.

    Media control object

    Every response that includes a Media layer object nests the layer's current control state under control, shaped according to its mediaType. To read it for a single layer, use GET /layers/{id}.

    mediaType Fields
    Video isPlaying (bool), playMode (string: Loop, ResetAfterPlay, PlayToEnd, ForwardSlideWhenFinished), volume (0–1), muted (bool), position (0–1, normalized over duration), duration (seconds)
    Audio isPlaying (bool), loop (bool), volume (0–1), muted (bool), position (0–1, normalized over duration), duration (seconds)

    duration is the media's total length in seconds, so position * duration gives the elapsed time — enough to show and seek to a real timecode. It is 0 when the length isn't known (media without duration metadata). | Pdf | currentPage (int, 0-based), interaction (bool) | | Web | webUrl (string) | | Ndi | volume (0–1), muted (bool), colorFormat (string: BGRX_BGRA, UYVY_BGRA, RGBX_RGBA, UYVY_RGBA, Fastest), bandwidth (string: Highest, Lowest, AudioOnly) | | Text | text (string), fontName (string), fontSize (number), fontColor ({ "r", "g", "b", "a" }), alignment (string, Unity TextAnchor member, e.g. UpperLeft), interaction (bool) | | Shape | color ({ "r", "g", "b", "a" }) | | everything else | null — no control operations are exposed for this media type |

    Client object

    The client endpoints (/clients, /clients/current, /clients/{id}) describe a connected client with this object, sourced from the server's internal client-info state rather than a separate schema per client type:

    Field Type Description
    clientId string Unique ID of the client.
    clientName string Display name of the client, or empty if unset.
    clientType string Client role, e.g. Visualisation, Control.
    connectionId int Internal network connection handle, mainly useful for debugging. Not stable across reconnects.
    syncEnabled bool Whether this client follows another client's slide navigation.
    experienceId string ID of the experience this client has joined, or empty if none.
    slideId string ID of the slide this client currently has active, or empty if none.
    slideLoadState string How far the client has got loading slideId, e.g. None, Loading, Settled.
    autoPlayDelayMs int Configured auto-forward delay for this client in milliseconds, or 0 if auto-play is off.
    downloadProgress int Media download progress, 0–100.
    ndi object enabled (bool), mediaIds (array of string) — whether NDI is enabled on this client and which media it currently sources over NDI.
    hardwareInfo object deviceType (string, Unity DeviceType member), deviceName (string), systemMemorySize (int, MB), processorFrequency (int, MHz), graphicsMemorySize (int, MB).

    The list is only as current as the server's own broadcast — a Control client reads the same continuously-synced copy as the host, so all three endpoints work the same regardless of which client answers the request.

    /alive

    GET

    Description
    Is the REST server alive.

    Responses

    Code Description
    200 Successful response
    401 Authentication token not valid

    /experiences

    GET

    Description
    Returns a list of all experiences with names, IDs and if set as favorites.

    Responses

    Code Description Schema
    200 Experience documents object
    401 Authentication token not valid

    /experiences/{id}

    GET

    Description
    Loads the experience with a given ID. If the experience already has a client with sync enabled, this client joins with sync forced off, matching the app's own join behavior — this avoids disturbing clients already synced to that experience.

    Responses

    Code Description
    200 Successful response
    401 Authentication token not valid
    404 No experience with specified ID found

    /experiences/{id}/slides

    GET

    Description
    Returns a list of all slides (name, ID, favorite) for the experience with the given ID, without joining it. If this X-Creator hasn't loaded that experience yet, it is fetched from X-Manager on demand. Only available on a X-Creator running the Host role.

    Responses

    Code Description Schema
    200 Slide documents object
    401 Authentication token not valid
    404 No experience with specified ID found
    500 Fetching the experience from X-Manager failed
    501 This X-Creator is not running the Host role

    /experiences/exit

    GET

    Description
    Leave current experience. Has no effect if no experience is currently loaded.

    Responses

    Code Description
    200 Successful response
    401 Authentication token not valid

    /experiences/current

    GET

    Description
    Returns name and ID of the current experience, plus the canvas pixel dimensions (canvasWidth, canvasHeight) used to convert normalized Media layer object values to pixels.

    Responses

    Code Description Schema
    200 Experience document (name, id, isFavorite, canvasWidth, canvasHeight) object
    401 Authentication token not valid
    404 No experience loaded

    /clients

    GET

    Description
    Returns every connected client as a Client object.

    Responses

    Code Description Schema
    200 Client documents object
    401 Authentication token not valid

    /clients/current

    GET

    Description
    Returns the client answering this request as a Client object.

    Responses

    Code Description Schema
    200 Client document object
    401 Authentication token not valid

    /clients/{id}

    GET

    Description
    Returns the client with the given ID as a Client object.

    Responses

    Code Description Schema
    200 Client document object
    401 Authentication token not valid
    404 No client with specified ID found

    /slides

    GET

    Description
    Returns a list of all slides from the current experience.

    Responses

    Code Description Schema
    200 Slide documents (name, id, isFavorite, timerSeconds) — empty list if no experience is loaded object
    401 Authentication token not valid

    /slides/{id}

    GET

    Description
    Loads the slide with a given ID from the current experience.

    Responses

    Code Description
    200 Successful response
    401 Authentication token not valid
    404 No slide with specified ID found in the current experience

    DELETE

    Description
    Deletes the slide with a given ID from the current experience. If it is the currently active slide, a neighboring slide is activated first.

    Responses

    Code Description
    200 Successful response
    401 Authentication token not valid
    404 No slide with specified ID found in the current experience
    409 Cannot delete the last remaining slide

    /slides/{id}/layers

    GET

    Description
    Returns the media layers of the slide with the given ID from the current experience as Media layer objects.

    Responses

    Code Description Schema
    200 Media layer documents object
    401 Authentication token not valid
    404 No slide with specified ID found in the current experience

    /slides/next

    GET

    Description
    Loads the next slide from the current experience. Several calls arriving in quick succession are collected into a single move covering all of them, so the intermediate slides are skipped rather than each being loaded in turn — see Slide navigation is a request.

    Responses

    Code Description
    200 Successful response
    401 Authentication token not valid
    409 No next slide available

    /slides/previous

    GET

    Description
    Loads the previous slide from the current experience. Several calls arriving in quick succession are collected into a single move covering all of them, so the intermediate slides are skipped rather than each being loaded in turn — see Slide navigation is a request.

    Responses

    Code Description
    200 Successful response
    401 Authentication token not valid
    409 No previous slide available

    /slides/current

    GET

    Description
    Returns name, ID and favorite flag of the current slide.

    Responses

    Code Description Schema
    200 Slide document (name, id, isFavorite, timerSeconds) object
    401 Authentication token not valid
    404 No slide currently active

    /slides/current/layers

    GET

    Description
    Returns the media layers of the currently active slide as Media layer objects.

    Responses

    Code Description Schema
    200 Media layer documents object
    401 Authentication token not valid
    404 No slide currently active

    /slides/save

    POST

    Description
    Saves the currently active slide, capturing its current media layers and controls.

    Responses

    Code Description
    200 Successful response
    401 Authentication token not valid
    403 Saving slides is disabled via X-Manager
    404 No slide currently active

    /slides/{id}/rename

    POST

    Description
    Renames the slide with the given ID. The new name is sent as a JSON body: { "name": "New name" }.

    Responses

    Code Description
    200 Successful response
    400 Missing name in request body
    401 Authentication token not valid
    404 No slide with specified ID found in the current experience

    /slides/{id}/timer

    POST

    Description
    Sets how long the slide with the given ID is shown before auto-forward moves on. The duration is sent as whole seconds in a JSON body: { "seconds": 30 }. Zero removes the timer, which is what DELETE does. There is no upper bound. Setting the timer of the currently active slide restarts its countdown from the new duration.

    Responses

    Code Description
    200 Successful response
    400 seconds is negative
    401 Authentication token not valid
    404 No slide with specified ID found in the current experience

    DELETE

    Description
    Removes the timer from the slide with the given ID, so it is no longer shown for a duration of its own. The auto-forward delay still applies to it afterwards.

    Responses

    Code Description
    200 Successful response
    401 Authentication token not valid
    404 No slide with specified ID found in the current experience

    /auto-forward

    GET

    Description
    Returns the auto-forward countdown of the current experience.

    The countdown does not tick over the network — it is only reported when it starts, stops, is paused or resumed. A caller wanting a live readout counts remainingMs down against its own clock from the moment it read this, exactly as the app's own timer ring does.

    Field Type Description
    slideId string The slide the countdown is running for, empty when none is running.
    running bool Whether the countdown is running rather than paused.
    durationMs int How long the countdown runs in total.
    remainingMs int How much was left when this was read.
    delaySeconds number The auto-forward delay applied to slides without a timer of their own, 0 when auto-forward is off. Fractional when it comes from a client configuration that is not a whole number of seconds.

    Responses

    Code Description Schema
    200 Auto-forward document object
    401 Authentication token not valid

    /auto-forward/delay

    POST

    Description
    Sets the auto-forward delay of the current experience, which applies to every slide that carries no timer of its own. The delay is sent as whole seconds in a JSON body: { "seconds": 10 }. Zero switches auto-forward off — there is no separate enable/disable and no remembered previous value. There is no upper bound.

    The delay set here overrides the one taken from client configuration for as long as the server runs; a restart falls back to client configuration, and nothing is written to any configuration file. A countdown already running for a slide without its own timer restarts from the new delay.

    Responses

    Code Description
    200 Successful response
    400 seconds is negative
    401 Authentication token not valid
    404 Not in an experience

    /auto-forward/pause

    POST

    Description
    Pauses the running countdown. Nobody owns the pause: the app's own timer ring resumes it just as readily as /auto-forward/resume does. Calling it on an already-paused countdown succeeds and changes nothing.

    Pausing is allowed while the presentation is frozen. Freeze already holds the countdown, and pausing on top of it is what keeps the countdown from resuming when freeze is lifted.

    Responses

    Code Description
    200 Successful response
    401 Authentication token not valid
    409 No auto-forward countdown is running

    /auto-forward/resume

    POST

    Description
    Resumes the paused countdown, which carries on from where it stopped rather than starting over. Calling it on an already-running countdown succeeds and changes nothing.

    Responses

    Code Description
    200 Successful response
    401 Authentication token not valid
    409 No auto-forward countdown is running, or the presentation is frozen

    /media

    GET

    Description
    Returns every media item known to the currently joined experience, independent of slide or layer placement.

    Responses

    Code Description Schema
    200 Media documents (mediaId, mediaType, name) object
    401 Authentication token not valid

    /media/{mediaId}/layer

    GET

    Description
    Creates a new media layer for the given media on the currently active slide, positioned near the center of the visible canvas, and returns the created Media layer object.

    Responses

    Code Description Schema
    200 Media layer document object
    401 Authentication token not valid
    404 No media with specified ID found, or no slide currently active

    /layers/{id}

    GET

    Description
    Returns the media layer with the given ID on the currently active slide as a Media layer object, with its current control state nested under control. Use this to refresh a single layer — including a playing video's position — without fetching the whole slide.

    Responses

    Code Description Schema
    200 Media layer document object
    401 Authentication token not valid
    404 No slide currently active, or no media layer with specified ID found

    PATCH

    Description
    Updates individual properties of the media layer with the given ID on the currently active slide. The request body is a JSON object holding any subset of the writable Media layer object fields; only the fields present are applied, the rest stay untouched. Writable fields are position, size, rotation, crop, visible, alpha, zOrder, locked, fullscreen, sectionFullscreen, backgroundColor, isStatic and layerGroup. position, size and crop are sent whole (all their components). fullscreen and sectionFullscreen are mutually exclusive — setting one clears the other.

    Request body sample

    {
        "position": { "x": 0.25, "y": 0.25 },
        "size": { "x": 0.5, "y": 0.28 },
        "rotation": 90,
        "visible": true,
        "alpha": 0.8
    }
    

    Responses

    Code Description
    200 Successful response
    400 Request body is empty, contains no known layer properties, or layerGroup is a system-assigned or unknown group
    401 Authentication token not valid
    404 No slide currently active, or no media layer with specified ID found

    DELETE

    Description
    Deletes the media layer with the given ID from the currently active slide, including its control state.

    Responses

    Code Description
    200 Successful response
    401 Authentication token not valid
    404 No slide currently active, or no media layer with specified ID found

    /shortcuts/{name}

    GET

    Description
    Returns the current state of a shortcut that has readable state. {name} is matched case-insensitively. Only ForceWindowFocus supports this — MouseCursor and ShowWelcomeScreen are pure toggles with nothing to read back.

    Response body sample

    { "enabled": true }
    

    Responses

    Code Description Schema
    200 Current state object
    400 {name} is not ForceWindowFocus
    401 Authentication token not valid
    404 The force-focus watcher isn't active on this instance (editor, non-Windows, or server role)

    POST

    Description
    Fires an app-side shortcut, exactly as pressing its key combination on the X-Creator would. {name} is matched case-insensitively. Only these three shortcuts are exposed:

    {name} Key combination Effect
    MouseCursor Ctrl + M Shows or hides the mouse cursor.
    ShowWelcomeScreen Ctrl + W Shows or hides the welcome screen.
    ForceWindowFocus Alt + Shift + W Turns forcing focus on the X-Creator window on or off.

    MouseCursor and ShowWelcomeScreen are toggles that report no state, so this endpoint can only flip them. ForceWindowFocus is the exception — read its resulting state back with GET /shortcuts/ForceWindowFocus above. No experience needs to be joined.

    Responses

    Code Description
    200 Successful response
    400 Unknown shortcut name, or a shortcut that cannot be triggered remotely
    401 Authentication token not valid

    Media Control Endpoints

    All routes below are POST /v1/layers/{id}/<path>, where {id} is a mediaLayerId, and return 200 on success with no body, or the same 400/401/404 codes as other layer routes (400 when the layer's mediaType doesn't support the operation, 404 when the layer doesn't exist). To read the resulting state back, use GET /layers/{id}.

    Scope — some operations apply only to the targeted layer instance ("Layer"); others apply to every layer currently showing the same media item ("Media"), e.g. muting one placement of a video mutes all of them.

    Volume and mute — the video/volume, audio/volume, and ndi/volume operations also set mute, mirroring the volume slider in the app: a volume above 0 unmutes, a volume of 0 mutes. The app's slider reads as 0 for as long as mute is set, whatever volume is behind it, so a volume change that left mute untouched would not be visible there. Send */mute after */volume if the two need to be set independently.

    Video (all Media-scoped)

    Path Body Description
    video/play { "isPlaying": bool } Play or pause at the media's current position; never seeks.
    video/seek { "position": number } Seek without changing play state. 0–1, normalized over the media's duration.
    video/mode { "playMode": string } Loop, ResetAfterPlay, PlayToEnd, or ForwardSlideWhenFinished.
    video/volume { "volume": number } 0–1. Also unmutes, or mutes at 0.
    video/mute { "mute": bool }

    Audio (all Layer-scoped)

    Path Body Description
    audio/play { "play": bool } Play or pause at the media's current position; never seeks.
    audio/position { "position": number } Seek. 0–1, normalized over the media's duration.
    audio/loop { "loop": bool }
    audio/volume { "volume": number } 0–1. Also unmutes, or mutes at 0.
    audio/mute { "mute": bool }

    Pdf (all Layer-scoped)

    Path Body Description
    pdf/page { "page": int } Jump to a 0-based page number.
    pdf/next-page none Advance one page, clamped to the last page.
    pdf/previous-page none Go back one page, clamped to page 0.
    pdf/first-page none Jump to page 0.
    pdf/last-page none Jump to the last page.
    pdf/interaction { "interaction": bool } Toggles direct interaction (scrolling) with the PDF on the layer.
    pdf/enable-scrolling none Re-enables dispatching the current page while scrolling manually.

    Web (Layer-scoped)

    Path Body Description
    web/url { "url": string } Loads a new URL.
    web/navigate { "direction": string } Back, Forward, or Reload.

    Ndi (all Media-scoped)

    Path Body Description
    ndi/volume { "volume": number } 0–1. Also unmutes, or mutes at 0.
    ndi/mute { "mute": bool }
    ndi/color-format { "colorFormat": string } BGRX_BGRA, UYVY_BGRA, RGBX_RGBA, UYVY_RGBA, or Fastest.
    ndi/bandwidth { "bandwidth": string } Highest, Lowest, or AudioOnly.

    Text

    Path Scope Body Description
    text/text Media { "text": string }
    text/font Layer { "fontName": string }
    text/font-size Layer { "fontSize": number }
    text/font-color Layer { "fontColor": { "r", "g", "b", "a" } }
    text/alignment Layer { "alignment": string } Unity TextAnchor member, e.g. UpperLeft, MiddleCenter.
    text/interaction Layer { "interaction": bool }

    Shape (Layer-scoped)

    Path Body Description
    shape/color { "color": { "r", "g", "b", "a" } }

    Not exposed: freeze (any media type), NDI PTZ (ndi/ptz/*) and camera presets, Web scale/interaction/interaction-authority, and AssetBundle/VideoMatrix controls entirely.

    Samples

    Load next slide:
    http://192.168.0.1:9696/api/v1/slides/next

    Request all experiences:
    http://192.168.0.1:9696/api/v1/experiences

    Request the media layers of the current slide:
    http://192.168.0.1:9696/api/v1/slides/current/layers

    Update a media layer's opacity (PATCH with a JSON body { "alpha": 0.5 }):
    http://192.168.0.1:9696/api/v1/layers/<layerId>

    Tools

    Built-in Test Console

    Opening http://<ip>:<port>/ (the same host and port as the API) in a browser serves a built-in interactive console for sending requests and inspecting responses without any external tooling.

    Troubleshooting

    Response Code 400 - Bad Request

    If a required field is missing from the request (e.g. name when renaming a slide), the status code "400 Bad Request" is returned.

    Response Code 401 - Unauthorized

    If Authentication is enabled and the request is missing a valid Authorization: Bearer <token> header, the status code "401 Unauthorized" is returned.

    Response Code 404 - Not Found

    If a non-existent endpoint is requested, or the requested experience/slide does not exist (or is not currently loaded), the status code "404 Not Found" is returned.

    Response Code 403 - Forbidden

    If saving slides has been disabled via X-Manager, the status code "403 Forbidden" is returned.

    Response Code 409 - Conflict

    If the requested slide navigation cannot be performed in the current situation (e.g. no next/previous slide available, or attempting to delete the last remaining slide), the status code "409 Conflict" is returned.

    Slide navigation is a request

    Slide navigation (/slides/next, /slides/previous, /slides/{id}/activate) asks the server of the shared experience to change the active slide, so that all clients of that experience show the same slide. A "200" response confirms that the request was accepted and passed on, not that the slide has already changed.

    /slides/next and /slides/previous calls that arrive close together are collected into a single move covering all of them — moving three slides ahead by calling /slides/next three times in quick succession loads only the slide arrived at, not each one passed on the way. /slides/{id}/activate is never collected like this, since it already names the exact slide it wants.

    The server can still decide not to carry a request out, for example when it is superseded by another activation before it is applied. No slide change happens then, and the response is still "200". Read /slides/current to find out which slide is active now.

    Response Code 500 - Internal Server Error

    If this error occurs please contact the administrator. The status code "500 Internal Server Error" is returned.

    Response Code 501 - Not Implemented

    Returned by endpoints that require this X-Creator to be running the Host role (e.g. looking up slides of an experience without joining it) when it isn't.

    
    ☀
    ☾
    Back to top
    Generated by DocFX
    ☀
    ☾