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

# Patch PAL

> Update specific fields of a PAL using [JSON Patch](https://datatracker.ietf.org/doc/html/rfc6902) operations.

### Draft vs live routing

If the PAL has an active [PAL Builder](https://maker.tavus.io/dev) draft, this endpoint **routes to the draft by default**. Live conversations, deployments, and public reads continue to use the previously-published version until you publish (`POST /v2/pals/{pal_id}/publish`) or repeat the request with `?target=live`. PALs without an active draft are unaffected — the patch applies to the live row as it always did.

This default was introduced so an API patch and a PAL Maker edit stay in sync: the Builder reads the draft row, so a PATCH that skipped the draft would produce an editor that still shows the pre-patch state. To bypass the draft, pass `?target=live` — this applies the edit to the live row and resyncs the retained draft from live. Any unpublished draft edits are discarded.

The response always includes `edit_target`, `edited_pal_id`, `live_pal_id`, `draft_pal_id`, and `routing_message` so you can confirm which row was written. Draft-routed responses also include `publish_url`. See [Draft vs live PALs](/sections/conversational-video-interface/pal/draft-and-live) for the full model.

### `layers.conferencing` is live-owned

`layers.conferencing` (the conferencing/Google Meet integration) is deployment config that lives on the live row so meeting invitations continue to work while a draft is open. Regardless of `?target`, any patch that touches `layers.conferencing` (or removes `layers`) is applied to the live PAL and then synced into the open draft, so the draft never carries a stale conferencing config. Consequences:

- `?target=draft` with a conferencing op returns `400`.
- A single request cannot mix conferencing ops with edits to other fields — split the request in two.
- Publishing a stale draft never wipes deployed conferencing config; live conferencing is preserved.


<Info>
  For AI agents, use `https://docs.tavus.io/openapi.yaml` for the full HTTP API contract.
</Info>

<Note>
  If the PAL has an active [PAL Builder](https://maker.tavus.io/dev) draft, this endpoint **writes to the draft by default** — live conversations are unaffected until you call [Publish PAL](/api-reference/pals/publish-pal). Draft-routed responses include a `publish_url`. Pass `?target=live` to write directly to live, discard unpublished edits, and resync the retained draft. `layers.conferencing` is always live-owned. See [Draft vs live PALs](/sections/conversational-video-interface/pal/draft-and-live).
</Note>


## OpenAPI

````yaml patch /v2/pals/{pal_id}
openapi: 3.0.3
info:
  title: Tavus Developer API Collection
  version: 1.0.0
  contact: {}
servers:
  - url: https://tavusapi.com
security:
  - apiKey: []
tags:
  - name: Videos
  - name: Faces
  - name: Voices
  - name: Conversations
  - name: Deployments
  - name: PALs
  - name: Tools
  - name: PAL Tools
  - name: Pronunciation Dictionaries
  - name: Replacements
  - name: Transcriptions
  - name: Documents
paths:
  /v2/pals/{pal_id}:
    parameters:
      - name: pal_id
        in: path
        required: true
        description: The unique identifier of the PAL.
        schema:
          type: string
          example: pcb7a34da5fe
    patch:
      tags:
        - PALs
      summary: Patch PAL
      description: >
        Update specific fields of a PAL using [JSON
        Patch](https://datatracker.ietf.org/doc/html/rfc6902) operations.


        ### Draft vs live routing


        If the PAL has an active [PAL Builder](https://maker.tavus.io/dev)
        draft, this endpoint **routes to the draft by default**. Live
        conversations, deployments, and public reads continue to use the
        previously-published version until you publish (`POST
        /v2/pals/{pal_id}/publish`) or repeat the request with `?target=live`.
        PALs without an active draft are unaffected — the patch applies to the
        live row as it always did.


        This default was introduced so an API patch and a PAL Maker edit stay in
        sync: the Builder reads the draft row, so a PATCH that skipped the draft
        would produce an editor that still shows the pre-patch state. To bypass
        the draft, pass `?target=live` — this applies the edit to the live row
        and resyncs the retained draft from live. Any unpublished draft edits
        are discarded.


        The response always includes `edit_target`, `edited_pal_id`,
        `live_pal_id`, `draft_pal_id`, and `routing_message` so you can confirm
        which row was written. Draft-routed responses also include
        `publish_url`. See [Draft vs live
        PALs](/sections/conversational-video-interface/pal/draft-and-live) for
        the full model.


        ### `layers.conferencing` is live-owned


        `layers.conferencing` (the conferencing/Google Meet integration) is
        deployment config that lives on the live row so meeting invitations
        continue to work while a draft is open. Regardless of `?target`, any
        patch that touches `layers.conferencing` (or removes `layers`) is
        applied to the live PAL and then synced into the open draft, so the
        draft never carries a stale conferencing config. Consequences:


        - `?target=draft` with a conferencing op returns `400`.

        - A single request cannot mix conferencing ops with edits to other
        fields — split the request in two.

        - Publishing a stale draft never wipes deployed conferencing config;
        live conferencing is preserved.
      operationId: patchPal
      parameters:
        - name: target
          in: query
          required: false
          description: >
            Which row to write to when the PAL has an active PAL Builder draft.


            - Omitted (default): writes to the **draft** if one exists,
            otherwise to live. Live traffic is unchanged until you publish.

            - `draft`: same as the default. Rejected with `400` if the patch
            touches `layers.conferencing`.

            - `live`: writes directly to the live PAL and resets the draft to
            match, so live becomes the single source of truth. Any unpublished
            draft edits are discarded.


            For `layers.conferencing`, omit `target` or pass `target=live`.
            Explicit `target=draft` is rejected because conferencing is
            live-owned.
          schema:
            type: string
            enum:
              - draft
              - live
          example: live
      requestBody:
        content:
          application/json:
            schema:
              type: array
              items:
                type: object
                properties:
                  op:
                    type: string
                    description: >-
                      The operation to perform. Must be one of: add, remove,
                      replace, copy, move, test
                    enum:
                      - add
                      - remove
                      - replace
                      - copy
                      - move
                      - test
                    example: add
                  path:
                    type: string
                    description: >
                      JSON Pointer (RFC 6901) to a location in the PAL document.
                      Paths must match the **current** document shape-compare
                      the response from [Get PAL](/api-reference/pals/get-pal)
                      (`GET /v2/pals/{pal_id}`) before patching.
                    example: /layers/llm/model
                  value:
                    type: string
                    description: >-
                      The value to be used within the operation. **This field is
                      not required for the `remove` operation**.
                    example: tavus-llama-4
                required:
                  - op
                  - path
                  - value
            examples:
              Replace PAL System Prompt:
                summary: Edit the Builder draft (default when a draft exists)
                value:
                  - op: replace
                    path: /system_prompt
                    value: >-
                      As a Life Coach, you are a dedicated professional who
                      specializes in...
              Remove STT Hotwords:
                summary: Remove a value; also draft-routed when a draft exists
                value:
                  - op: remove
                    path: /layers/stt/hotwords
              Update conferencing (always live):
                summary: layers.conferencing is live-owned; sent without ?target
                value:
                  - op: replace
                    path: /layers/conferencing/username
                    value: acme-anna
      responses:
        '200':
          description: >
            The patched PAL body. In addition to the usual PAL fields, the
            response includes routing metadata so you can confirm which row was
            written.
          content:
            application/json:
              schema:
                type: object
                properties:
                  pal_id:
                    type: string
                    description: >
                      The PAL id you called the endpoint with — always echoed
                      back unchanged, even when the patch was routed to the
                      draft or to live. Safe to persist on the client.
                    example: pcb7a34da5fe
                  edited_pal_id:
                    type: string
                    description: >
                      The id of the row that was actually written. Equals
                      `live_pal_id` when the patch went to live and
                      `draft_pal_id` when it went to the draft.
                    example: p5f1e8d2a934
                  edit_target:
                    type: string
                    enum:
                      - draft
                      - live
                    description: >
                      Which row this PATCH wrote to. `draft` when the request
                      landed on an active PAL Builder draft (the default when
                      one exists); `live` when it landed on the live PAL —
                      either because no draft exists, `?target=live` was passed,
                      or the patch touched `layers.conferencing`.
                    example: draft
                  live_pal_id:
                    type: string
                    description: >-
                      The id of the live PAL. Same as `pal_id` when you called
                      this endpoint with the live id.
                    example: pcb7a34da5fe
                  draft_pal_id:
                    type: string
                    nullable: true
                    description: >-
                      The id of the active draft row, or `null` when no draft
                      exists.
                    example: p5f1e8d2a934
                  publish_url:
                    type: string
                    description: >-
                      Present when the patch was routed to a draft. POST to this
                      path to make the draft live.
                    example: /v2/pals/pcb7a34da5fe/publish
                  routing_message:
                    type: string
                    description: >
                      Human-readable summary of where the edit went and how
                      live/draft are related after the patch. Useful to surface
                      in logs when auditing writes.
                    example: >-
                      Edited the Builder draft (p5f1e8d2a934). The live PAL
                      (pcb7a34da5fe) is unchanged and will not reflect these
                      edits until you publish. To edit the live PAL directly,
                      re-send with ?target=live (this discards unpublished draft
                      edits and resyncs the draft from live).
        '304':
          description: No changes were made to the PAL
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    description: The error message.
                    example: No changes were made to the PAL
        '400':
          description: >
            Bad Request. Common draft-routing causes:

            - `target` is not `draft` or `live`.

            - `?target=draft` was passed with a patch op that touches
            `layers.conferencing` (conferencing is live-owned).

            - A single request mixes `layers.conferencing` ops with edits to
            other fields — split into two requests.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: The error message.
                    example: >-
                      layers.conferencing is live-owned deployment config; patch
                      it with target=live
        '422':
          description: Invalid JSON patch format
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    description: The error message.
                    example: Invalid JSON patch format
      security:
        - apiKey: []
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: x-api-key

````