> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trackplay.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Save a settings draft

> Saves a partial or full settings payload without publishing it. The payload is merged recursively over whatever is already drafted, or over the live settings if there is no draft yet, so you only need to send the option groups you are changing.

The merged payload is validated with the same rules the dashboard's Customize screen enforces, so an invalid value in any option group fails the whole request. Nothing is published: the player a viewer sees is unchanged until you call deploy.

Requires a token with the `videos:write` scope.



## OpenAPI

````yaml /api-reference/openapi.json post /videos/{video}/draft
openapi: 3.1.0
info:
  title: TrackPlay API
  description: >-
    Send conversions and events to TrackPlay, and read them back. Authenticated
    with scoped tokens you mint in the dashboard.
  version: 1.0.0
servers:
  - url: https://app.trackplay.io/api/v1
    description: App API. Conversions, videos, webhooks.
  - url: https://e.trackplay.io
    description: Events API. High-volume event ingest.
security:
  - bearerAuth: []
tags:
  - name: Videos
    description: Create, read, update, and delete videos, and read workspace metadata.
  - name: Video settings
    description: Save a settings draft, publish it live, and read or restore past deploys.
  - name: Uploads
    description: >-
      Upload a source video file in one request or in resumable chunks, and poll
      its processing status.
  - name: Captions and chapters
    description: >-
      Manage caption tracks, chapter markers, AI-generated segments, and CTA
      cards on a video.
  - name: Playlists
    description: Group videos into a playlist or course, and manage the videos inside it.
  - name: Webhooks
    description: Subscribe a URL to TrackPlay lifecycle events and test deliveries.
  - name: Zapier
    description: >-
      The REST-hook endpoints Zapier calls to connect a workspace and manage
      triggers.
  - name: Analytics
    description: Read play, retention, event, and conversion analytics for a video.
  - name: Exports
    description: Queue and download bulk analytics exports.
  - name: Conversions
    description: Report a sale or a lead, from your own server or from a browser fallback.
  - name: Events
    description: Send a custom event tied to a viewer's session.
  - name: Identity
    description: Resolve a viewer's identity from the page, with no token required.
paths:
  /videos/{video}/draft:
    post:
      tags:
        - Video settings
      summary: Save a settings draft
      description: >-
        Saves a partial or full settings payload without publishing it. The
        payload is merged recursively over whatever is already drafted, or over
        the live settings if there is no draft yet, so you only need to send the
        option groups you are changing.


        The merged payload is validated with the same rules the dashboard's
        Customize screen enforces, so an invalid value in any option group fails
        the whole request. Nothing is published: the player a viewer sees is
        unchanged until you call deploy.


        Requires a token with the `videos:write` scope.
      operationId: draftVideoSettings
      parameters:
        - name: video
          in: path
          required: true
          schema:
            type: integer
          description: The video's numeric ID.
        - name: Idempotency-Key
          in: header
          required: false
          schema:
            type: string
          description: >-
            Retry-safe key. The first response for a given key is cached for 24
            hours and replayed on a repeat, with `Idempotency-Replayed: true`
            set.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SettingsPayload'
      responses:
        '200':
          description: The full merged draft.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DraftResponse'
        '401':
          description: >-
            `AUTH_REQUIRED`: no token sent. `INVALID_TOKEN`: the token is
            invalid, expired, or revoked.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '403':
          description: '`INSUFFICIENT_SCOPE`: the token does not carry `videos:write`.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '404':
          description: No video with that ID exists in this workspace.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LaravelNotFoundError'
        '422':
          description: Validation failed on the merged settings payload.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationError'
        '429':
          description: Rate limited. 60 requests per minute per token.
components:
  schemas:
    SettingsPayload:
      type: object
      additionalProperties: true
      description: >-
        A partial or full settings payload, keyed by option-group column name,
        for example `style_options`, `playback_options`, `autoplay_options`,
        `progress_options`, `actions_options`, `pixels_options`,
        `continue_watching_options`, `turbo_options`, `timed_events_options`,
        `captions_options`, `chapters_options`, `cta_cards_options`,
        `playlist_options`, `engagement_options`, `lead_form_options`,
        `watch_gate_options`, `cross_device_resume_options`, `notes_options`, or
        `quiz_options`. Send only the groups you want to change. Each group has
        its own validation rules, the same ones the dashboard's Customize screen
        enforces, so a malformed value inside any group fails the whole request
        with a 422.
    DraftResponse:
      type: object
      properties:
        draft:
          type: object
          additionalProperties: true
          description: >-
            The full merged draft: the new payload merged recursively over
            whatever was already drafted or live.
        version:
          type: 'null'
          description: >-
            Always `null`. A draft is not a version. A version is only created
            on deploy.
    ApiError:
      type: object
      description: The error shape the app API returns on a failed read or export.
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              description: >-
                A stable error code, e.g. `INSUFFICIENT_SCOPE`,
                `VIDEO_NOT_FOUND`, `EXPORT_NOT_FOUND`.
            message:
              type: string
              description: What went wrong, in plain English.
    LaravelNotFoundError:
      type: object
      description: >-
        The default not-found body Laravel returns when a route model lookup
        fails (`findOrFail`). It carries no stable error code, unlike the app's
        own `{"error": {"code": ...}}` shape used on hand-written error paths in
        this API.
      properties:
        message:
          type: string
          examples:
            - No query results for model [App\\Models\\WorkspaceVideo] 481
    ValidationError:
      type: object
      description: >-
        Laravel's default validation-failure body. `errors` maps each invalid
        field to its list of messages.
      properties:
        message:
          type: string
          examples:
            - The given data was invalid.
        errors:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        A scoped token minted in **Settings → API tokens**. Send it as
        `Authorization: Bearer tplt_…` or `X-API-Key: tplt_…`.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.