{
  "openapi": "3.1.0",
  "info": {
    "title": "LemonSlice",
    "description": "An API for real-time, interactive LemonSlice avatar sessions.",
    "license": {
      "name": "MIT",
      "identifier": "MIT"
    },
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://lemonslice.com/api"
    }
  ],
  "security": [
    {
      "apiKeyAuth": []
    }
  ],
  "paths": {
    "/liveai/rooms": {
      "get": {
        "summary": "List hosted sessions",
        "description": "Returns paginated hosted sessions for the authenticated account.",
        "operationId": "listRooms",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed).",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Number of rooms per page.",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Rooms retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "rooms": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "agent_id": { "type": "string" },
                          "session_id": { "type": "string" },
                          "created_at": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "session_status": { "type": "string" },
                          "credits_used": {
                            "type": ["number", "null"]
                          }
                        },
                        "required": ["agent_id", "session_id", "created_at", "session_status"]
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": { "type": "integer" },
                        "limit": { "type": "integer" },
                        "total": { "type": "integer" },
                        "total_pages": { "type": "integer" },
                        "has_more": { "type": "boolean" }
                      },
                      "required": ["page", "limit", "total", "total_pages", "has_more"]
                    }
                  },
                  "required": ["rooms", "pagination"]
                },
                "example": {
                  "rooms": [
                    {
                      "agent_id": "agent_abc123",
                      "session_id": "3f7c2b91-9e1f-4a6a-8e9d-2c7c3e7d9b5a",
                      "created_at": "2026-04-29T20:34:56.000Z",
                      "session_status": "COMPLETED",
                      "credits_used": 10.5
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 25,
                    "total": 1,
                    "total_pages": 1,
                    "has_more": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid pagination request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Requested page is too deep. Maximum offset is 1000."
                }
              }
            }
          },
          "401": {
            "description": "Authentication denied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Invalid API key"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerError"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create hosted session",
        "description": "Creates a hosted session for the specified LemonSlice avatar.",
        "operationId": "createRoom",
        "requestBody": {
          "description": "The LemonSlice avatar to use in the session.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentInfo"
              },
              "example": {
                "agent_id": "agent_abc123"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Room created successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Room"
                },
                "example": {
                  "room_url": "https://lemonslice.daily.co/abc123",
                  "token": "eyJhbGciOiJIUzI1NiIsInR5a...",
                  "image_url": "https://cdn.lemonslice.com/agents/agent_abc123.png",
                  "session_id": "3f7c2b91-9e1f-4a6a-8e9d-2c7c3e7d9b5a"
                }
              }
            }
          },
          "400": {
            "description": "Invalid arguments",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Missing required fields"
                }
              }
            }
          },
          "401": {
            "description": "Authentication denied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Invalid API key"
                }
              }
            }
          },
          "402": {
            "description": "Agent owner has insufficient funds",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Agent agent_123abc owner has insufficient funds"
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Agent not found"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerError"
                }
              }
            }
          }
        }
      }
    },
    "/liveai/sessions": {
      "get": {
        "summary": "List sessions",
        "description": "Returns paginated sessions for the authenticated account.",
        "operationId": "listSessions",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number (1-indexed).",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Number of sessions per page.",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sessions retrieved successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "sessions": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "session_id": { "type": "string" },
                          "created_at": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "session_status": { "type": "string" },
                          "credits_used": {
                            "type": ["number", "null"]
                          },
                          "provider": {
                            "type": ["string", "null"]
                          }
                        },
                        "required": ["session_id", "created_at", "session_status"]
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": { "type": "integer" },
                        "limit": { "type": "integer" },
                        "total": { "type": "integer" },
                        "total_pages": { "type": "integer" },
                        "has_more": { "type": "boolean" }
                      },
                      "required": ["page", "limit", "total", "total_pages", "has_more"]
                    }
                  },
                  "required": ["sessions", "pagination"]
                },
                "example": {
                  "sessions": [
                    {
                      "session_id": "3f7c2b91-9e1f-4a6a-8e9d-2c7c3e7d9b5a",
                      "created_at": "2026-04-29T20:34:56.000Z",
                      "session_status": "COMPLETED",
                      "credits_used": 10.5,
                      "provider": "LIVEKIT"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "limit": 25,
                    "total": 1,
                    "total_pages": 1,
                    "has_more": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid pagination request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Requested page is too deep. Maximum offset is 1000."
                }
              }
            }
          },
          "401": {
            "description": "Authentication denied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Invalid API key"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerError"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create session",
        "description": "Creates a new LemonSlice session that takes in avatar audio and publishes synchronized video/audio to the specified transport.",
        "operationId": "createSession",
        "x-mint": {
          "content": "<Warning>\n**Do not call this endpoint directly with the `livekit` or `daily` transport.** Use the official [LiveKit](/livekit) or [Pipecat](/pipecat) SDK instead to ensure proper session lifecycle management.\n</Warning>\n\n<Tip>\nTo upload an avatar image file directly, switch the request body content type to `multipart/form-data` below.\n</Tip>"
        },
        "requestBody": {
          "description": "The properties used to create a session. Use `application/json` to reference an agent_id or agent_image_url, or `multipart/form-data` to upload an image file directly.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SessionInput"
              },
              "examples": {
                "by_agent_image_url": {
                  "summary": "Create a session using an agent_image_url",
                  "value": {
                    "agent_image_url": "https://cdn.lemonslice.com/avatars/avatar.png",
                    "agent_prompt": "a person talking",
                    "transport_type": "livekit",
                    "properties": {
                      "livekit_url": "wss://lemonslice-pb123.livekit.cloud",
                      "livekit_token": "eyJhbGciOiJIUzI1NiIsInR5a..."
                    }
                  }
                },
                "by_agent_id": {
                  "summary": "Create a session using an agent_id",
                  "value": {
                    "agent_id": "agent_abc123",
                    "transport_type": "livekit",
                    "properties": {
                      "livekit_url": "wss://lemonslice-pb123.livekit.cloud",
                      "livekit_token": "eyJhbGciOiJIUzI1NiIsInR5a..."
                    }
                  }
                },
                "daily_transport": {
                  "summary": "Create a session using Daily transport",
                  "value": {
                    "agent_id": "agent_abc123",
                    "transport_type": "daily",
                    "properties": {
                      "daily_url": "https://your-domain.daily.co/your-room",
                      "daily_token": "eyJhbGciOiJIUzI1NiIsInR5a..."
                    }
                  }
                },
                "websocket_livekit": {
                  "summary": "Create a WebSocket session with LiveKit egress",
                  "value": {
                    "agent_image_url": "https://cdn.lemonslice.com/avatars/avatar.png",
                    "transport_type": "websocket-livekit",
                    "livekit_properties": {
                      "livekit_url": "wss://lemonslice-pb123.livekit.cloud",
                      "livekit_token": "eyJhbGciOiJIUzI1NiIsInR5a..."
                    }
                  }
                },
                "websocket_daily": {
                  "summary": "Create a WebSocket session with Daily egress",
                  "value": {
                    "agent_id": "agent_abc123",
                    "transport_type": "websocket-daily",
                    "daily_properties": {
                      "daily_url": "https://your-domain.daily.co/your-room",
                      "daily_token": "eyJhbGciOiJIUzI1NiIsInR5a..."
                    }
                  }
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": ["image", "payload"],
                "properties": {
                  "image": {
                    "description": "The avatar image file. The image should be 368x560 pixels with a maximum size of 4 MB. LemonSlice will automatically center-crop to the target aspect ratio if the dimensions do not match.",
                    "type": "string",
                    "format": "binary"
                  },
                  "payload": {
                    "$ref": "#/components/schemas/SessionFormDataPayload"
                  }
                }
              },
              "encoding": {
                "payload": {
                  "contentType": "application/json"
                }
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Session created successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Session"
                },
                "examples": {
                  "livekit": {
                    "summary": "LiveKit SDK session",
                    "value": {
                      "session_id": "3f7c2b91-9e1f-4a6a-8e9d-2c7c3e7d9b5a",
                      "control_url": "https://.../control/3f7c2b91"
                    }
                  },
                  "daily": {
                    "summary": "Pipecat SDK session",
                    "value": {
                      "session_id": "3f7c2b91-9e1f-4a6a-8e9d-2c7c3e7d9b5a",
                      "control_url": "https://.../control/3f7c2b91",
                      "room_url": "https://your-domain.daily.co/your-room"
                    }
                  },
                  "websocket": {
                    "summary": "WebSocket session (LiveKit or Daily egress)",
                    "value": {
                      "session_id": "3f7c2b91-9e1f-4a6a-8e9d-2c7c3e7d9b5a",
                      "control_url": "https://.../control/3f7c2b91",
                      "websocket_address": "wss://.../tunnel"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid arguments",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Missing required fields"
                }
              }
            }
          },
          "401": {
            "description": "Authentication denied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Invalid API key"
                }
              }
            }
          },
          "402": {
            "description": "Agent owner has insufficient funds",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Agent agent_123abc owner has insufficient funds"
                }
              }
            }
          },
          "403": {
            "description": "Agent not owned",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Agent agent_123abc is not owned by the authenticated user"
                }
              }
            }
          },
          "404": {
            "description": "Agent not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Agent not found"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerError"
                }
              }
            }
          }
        }
      }
    },
    "/liveai/sessions/{session_id}": {
      "get": {
        "summary": "Get session",
        "description": "Retrieves the current status of a session. Returns additional metadata if the session has ended.",
        "operationId": "getSession",
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "description": "The ID of the session to retrieve.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Session status retrieved successfully. Returns basic status for all states. When completed, includes the total cost in credits.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "session_status": {
                      "type": "string",
                      "enum": ["QUEUED", "ACTIVE", "COMPLETED", "TIMED_OUT", "FAILED"],
                      "description": "Current status of the session:\n\n- **QUEUED**: session is waiting for a GPU container. Typically completes in seconds when warm containers are available. If all warm containers are in use, a cold start is required which may take up to 2.5 minutes.\n- **ACTIVE**: agent is live.\n- **COMPLETED**: session ended successfully.\n- **TIMED_OUT**: GPU container timed out.\n- **FAILED**: session ended with an error."
                    },
                    "cost": {
                      "type": "number",
                      "description": "Number of credits used for this session. Only returned when session_status is COMPLETED."
                    }
                  },
                  "required": ["session_status"]
                },
                "examples": {
                  "queued": {
                    "summary": "Session is queued",
                    "value": {
                      "session_status": "QUEUED"
                    }
                  },
                  "active": {
                    "summary": "Session is active",
                    "value": {
                      "session_status": "ACTIVE"
                    }
                  },
                  "completed": {
                    "summary": "Session completed",
                    "value": {
                      "session_status": "COMPLETED",
                      "cost": 10.5
                    }
                  },
                  "timed_out": {
                    "summary": "Session timed out",
                    "value": {
                      "session_status": "TIMED_OUT"
                    }
                  },
                  "failed": {
                    "summary": "Session failed",
                    "value": {
                      "session_status": "FAILED"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Authentication denied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Invalid API key"
                }
              }
            }
          },
          "403": {
            "description": "Session not owned",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Session does not belong to this account"
                }
              }
            }
          },
          "404": {
            "description": "Session not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Session not found"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerError"
                }
              }
            }
          }
        }
      }
    },
    "/liveai/sessions/{session_id}/control": {
      "post": {
        "summary": "Control session",
        "description": "Send a control event to an active session.",
        "operationId": "controlSession",
        "security": [],
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "description": "The ID of the session to control.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  { 
                    "$ref": "#/components/schemas/TerminateEvent", 
                    "title": "Terminate",
                    "description": "Immediately shuts down the LemonSlice avatar and removes it from the WebRTC room."
                  },
                  { 
                    "$ref": "#/components/schemas/UpdateImageEvent", 
                    "title": "Update Image",
                    "description": "Update the avatar's reference image. When possible, send this event while the avatar is not speaking (any audio currently playing will be cut off). The image change takes <1 second. See our [Real-time Updates guide](/reference/realtime-updates) for more details."
                  },
                  {
                    "$ref": "#/components/schemas/UpdateAgentPromptEvent",
                    "title": "Update Agent Prompt",
                    "description": "A high-level system prompt that subtly influences the avatar's expressions while speaking. This prompt is best used to suggest general demeanor (for example, 'feel excited' or 'look sad') rather than precise or deterministic actions."
                  },
                  {
                    "$ref": "#/components/schemas/UpdateIdlePromptEvent",
                    "title": "Update Idle Prompt",
                    "description": "A high-level system prompt that subtly influences the avatar's expressions during the idle state."
                  },
                  {
                    "$ref": "#/components/schemas/ActionEvent",
                    "title": "Action",
                    "description": "Trigger a specific whole-body action on a CWM-1 avatar. See the [CWM-1 guide](/reference/cwm-1) for available action names and when to use the control endpoint versus LiveKit data messages."
                  },
                  {
                    "$ref": "#/components/schemas/ResetIdleTimeoutEvent",
                    "title": "Reset Idle Timeout",
                    "description": "Resets the idle timeout timer on the session. Useful to keep the session alive when the user is still engaged but the avatar is not currently speaking."
                  }
                ],
                "discriminator": {
                  "propertyName": "event",
                  "mapping": {
                    "update-image": "#/components/schemas/UpdateImageEvent",
                    "terminate": "#/components/schemas/TerminateEvent",
                    "update-agent-prompt": "#/components/schemas/UpdateAgentPromptEvent",
                    "update-idle-prompt": "#/components/schemas/UpdateIdlePromptEvent",
                    "action": "#/components/schemas/ActionEvent",
                    "reset-idle-timeout": "#/components/schemas/ResetIdleTimeoutEvent"
                  }
                }
              },
              "examples": {
                "terminate": {
                  "summary": "Terminate session",
                  "value": {
                    "event": "terminate"
                  }
                },
                "update_image": {
                  "summary": "Change the avatar image (URL)",
                  "description": "Update the avatar's reference image with an image hosted at a public URL.",
                  "value": {
                    "event": "update-image",
                    "image_url": "https://example.com/avatar.jpg"
                  }
                },
                "update_image_base64": {
                  "summary": "Change the avatar image (inline base64)",
                  "description": "Update the avatar's reference image by sending the new image bytes inline as base64. The decoded image must be under 900 KB.",
                  "value": {
                    "event": "update-image",
                    "image_base64": "iVBORw0KGgoAAAANSUhEUgAA..."
                  }
                },
                "update_agent_prompt": {
                  "summary": "Update the agent prompt (for speaking periods)",
                  "description": "Replace the agent prompt used when the avatar is speaking.",
                  "value": {
                    "event": "update-agent-prompt",
                    "agent_prompt": "a person talking"
                  }
                },
                "update_idle_prompt": {
                  "summary": "Update the idle prompt (for idle periods)",
                  "description": "Replace the idle prompt used when the avatar is idle.",
                  "value": {
                    "event": "update-idle-prompt",
                    "idle_prompt": "a serious person"
                  }
                },
                "action": {
                  "summary": "Trigger an action",
                  "description": "Trigger a CWM-1 action by name. See the [CWM-1 guide](/reference/cwm-1#available-actions) for the full list.",
                  "value": {
                    "event": "action",
                    "action": "wave"
                  }
                },
                "reset_idle_timeout": {
                  "summary": "Reset the idle timeout",
                  "description": "Reset the idle timeout timer to keep the session alive.",
                  "value": {
                    "event": "reset-idle-timeout"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Control event accepted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  }
                },
                "example": {
                  "success": true
                }
              }
            }
          },
          "400": {
            "description": "Invalid event or missing required fields",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "image_url or image_base64 required for update-image event"
                }
              }
            }
          },
          "404": {
            "description": "Session not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Session not found"
                }
              }
            }
          },
          "413": {
            "description": "Inline image too large. The decoded `image_base64` payload must be under 900 KB; host larger images and pass `image_url` instead.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "image_base64 decodes to 1048576 bytes; inline images must be under 921600 bytes. Host larger images and pass image_url instead."
                }
              }
            }
          },
          "500": {
            "description": "Unexpected error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerError"
                }
              }
            }
          }
        }
      }
    },
    "/liveai/sessions/{session_id}/join-meeting": {
      "post": {
        "summary": "Join third party meeting platform",
        "description": "Have your LemonSlice avatar join a third party meeting platform (Zoom, Google Meet, Microsoft Teams, or Webex)\n\n<Tip>\n  This feature works only with LiveKit-based sessions. We recommend using our [LiveKit plugin](/livekit) rather than calling this endpoint directly.\n</Tip>\n\n<Note>\n  This endpoint should only be used to join third party meeting platforms. Do not use it for regular LiveKit sessions.\n</Note>",
        "operationId": "joinMeeting",
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "description": "The ID of the active LemonSlice session whose avatar should join the third party meeting platform.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JoinMeetingInput"
              },
              "example": {
                "meeting_url": "https://meet.google.com/abc-defg-hij",
                "livekit_url": "wss://lemonslice-pb123.livekit.cloud",
                "broadcast_token": "<LIVEKIT_BROADCAST_TOKEN>",
                "bot_name": "LemonSlice Avatar"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Avatar is joining the third party meeting platform.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JoinMeetingResponse"
                },
                "example": {
                  "meeting_bot_id": "meeting-bot-abc123",
                  "websocket_url": "wss://example.com/agent-audio/session-id?token=..."
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (e.g. unrecognized meeting URL or invalid LiveKit token)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Unrecognized meeting link — paste a Zoom, Google Meet, Microsoft Teams, or Webex URL."
                }
              }
            }
          },
          "401": {
            "description": "Authentication denied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Invalid API key"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerError"
                },
                "example": {
                  "detail": "Failed to join meeting"
                }
              }
            }
          },
          "502": {
            "description": "Could not join the meeting",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Could not join the meeting — check the meeting link and try again."
                }
              }
            }
          },
          "503": {
            "description": "Meeting service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Meeting audio tunnel failed to start"
                }
              }
            }
          },
          "504": {
            "description": "Request timed out",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Request timed out"
                }
              }
            }
          }
        }
      }
    },
    "/liveai/sessions/{session_id}/leave-meeting": {
      "post": {
        "summary": "Leave third party meeting platform",
        "description": "Remove your LemonSlice avatar from a third party meeting platform (Zoom, Google Meet, Microsoft Teams, or Webex)\n\n<Tip>\n  This feature works only with LiveKit-based sessions. We recommend using our [LiveKit plugin](/livekit) rather than calling this endpoint directly.\n</Tip>\n\n<Note>\n  This endpoint should only be used to leave third party meeting platforms. Do not use it for regular LiveKit sessions.\n</Note>",
        "operationId": "leaveMeeting",
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "description": "The ID of the LemonSlice session associated with the third party meeting platform.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeaveMeetingInput"
              },
              "example": {
                "meeting_bot_id": "meeting-bot-abc123"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Avatar removed from the third party meeting platform.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeaveMeetingResponse"
                },
                "example": {
                  "status": "left"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (e.g. missing meeting_bot_id)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "meeting_bot_id is required"
                }
              }
            }
          },
          "401": {
            "description": "Authentication denied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Invalid API key"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerError"
                },
                "example": {
                  "detail": "Failed to leave meeting"
                }
              }
            }
          },
          "502": {
            "description": "Could not leave the meeting",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Could not leave the meeting."
                }
              }
            }
          },
          "503": {
            "description": "Meeting service unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Meeting service is not configured"
                }
              }
            }
          },
          "504": {
            "description": "Request timed out",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Request timed out"
                }
              }
            }
          }
        }
      }
    },
    "/liveai/agora/session/start": {
      "post": {
        "summary": "Create Agora session",
        "description": "Starts a LemonSlice avatar session for Agora Conversational AI Engine. Agora's generic avatar vendor calls this endpoint when you start an agent with LemonSlice configured as the avatar provider.",
        "operationId": "createAgoraSession",
        "x-mint": {
          "content": "<Warning>\n**Do not call this endpoint directly from your app.** Configure LemonSlice in Agora's `join` request via the [Agora integration](/agora) (`vendor: \"generic\"`). Agora's backend calls this endpoint to open the avatar session.\n</Warning>"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgoraSessionInput"
              },
              "example": {
                "avatar_id": "lemonslice",
                "agent_image_url": "https://cdn.lemonslice.com/avatars/avatar.png",
                "video_encoding": "H264",
                "activity_idle_timeout": 120,
                "agora_settings": {
                  "app_id": "<agora_app_id>",
                  "token": "<avatar_rtc_token>",
                  "channel": "demo-room",
                  "uid": "3000",
                  "enable_string_uid": false
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Session started successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgoraSessionStartResponse"
                },
                "example": {
                  "session_id": "3f7c2b91-9e1f-4a6a-8e9d-2c7c3e7d9b5a",
                  "websocket_address": "wss://example.modal.host/tunnel",
                  "session_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgoraError"
                },
                "example": {
                  "error": "Invalid request",
                  "message": "Missing required field: video_encoding",
                  "code": "VALIDATION_ERROR"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgoraError"
                },
                "example": {
                  "error": "Unauthorized",
                  "message": "Invalid API key",
                  "code": "INVALID_API_KEY"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient funds",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgoraError"
                },
                "example": {
                  "error": "Unauthorized",
                  "message": "User has insufficient funds",
                  "code": "INSUFFICIENT_FUNDS"
                }
              }
            }
          },
          "403": {
            "description": "Missing API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgoraError"
                },
                "example": {
                  "error": "Forbidden",
                  "message": "API key header missing",
                  "code": "MISSING_API_KEY"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgoraError"
                },
                "example": {
                  "error": "Internal Server Error",
                  "message": "Failed to join session",
                  "code": "INTERNAL_ERROR"
                }
              }
            }
          },
          "504": {
            "description": "Timed out waiting for the WebSocket tunnel",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgoraError"
                },
                "example": {
                  "error": "Gateway Timeout",
                  "message": "Timed out waiting for tunnel to become ready",
                  "code": "TUNNEL_TIMEOUT"
                }
              }
            }
          }
        }
      }
    },
    "/liveai/agora/session/stop": {
      "delete": {
        "summary": "Stop Agora session",
        "description": "Terminates an active LemonSlice Agora session. Agora's Conversational AI Engine calls this when the agent leaves the channel.",
        "operationId": "stopAgoraSession",
        "x-mint": {
          "content": "<Warning>\n**Do not call this endpoint directly from your app.** Stop the Agora Conversational AI agent with Agora's `/leave` API; Agora tears down the LemonSlice session. See the [Agora integration](/agora).\n</Warning>"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgoraSessionStopInput"
              },
              "example": {
                "session_id": "3f7c2b91-9e1f-4a6a-8e9d-2c7c3e7d9b5a",
                "session_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Session terminated successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgoraSessionStopResponse"
                },
                "example": {
                  "status": "success",
                  "message": "Session terminated successfully"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgoraError"
                },
                "example": {
                  "error": "Invalid request",
                  "message": "Missing required field: session_id",
                  "code": "VALIDATION_ERROR"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgoraError"
                },
                "example": {
                  "error": "Unauthorized",
                  "message": "Invalid API key",
                  "code": "INVALID_API_KEY"
                }
              }
            }
          },
          "403": {
            "description": "Missing API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgoraError"
                },
                "example": {
                  "error": "Forbidden",
                  "message": "API key header missing",
                  "code": "MISSING_API_KEY"
                }
              }
            }
          },
          "404": {
            "description": "Session not found or already terminated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgoraError"
                },
                "example": {
                  "error": "Not found",
                  "message": "Session not found or already terminated",
                  "code": "SESSION_NOT_FOUND"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AgoraError"
                },
                "example": {
                  "error": "Internal server error",
                  "message": "Internal server error",
                  "code": "INTERNAL_ERROR"
                }
              }
            }
          }
        }
      }
    },
    "/liveai/rooms/{session_id}": {
      "get": {
        "summary": "Get hosted session",
        "description": "Retrieves the current status of a hosted session. Includes additional metadata when the session is completed.",
        "operationId": "getRoomStatus",
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "description": "The session identifier returned upon creation.",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns basic status of session. When completed, includes additional metadata such as cost, timestamps, end reason, and conversation messages.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "session_status": {
                      "type": "string",
                      "enum": ["QUEUED", "ACTIVE", "COMPLETED", "TIMED_OUT", "FAILED"],
                      "description": "Current status of the session:\n\n- **QUEUED**: session is waiting for a GPU container. Typically completes in seconds when warm containers are available. If all warm containers are in use, a cold start is required which may take up to 2.5 minutes.\n- **ACTIVE**: agent is live.\n- **COMPLETED**: session ended successfully.\n- **TIMED_OUT**: GPU container timed out.\n- **FAILED**: session ended with an error."
                    },
                    "cost": {
                      "type": "number",
                      "description": "Number of credits used for this session. Only returned when session_status is COMPLETED."
                    },
                    "llm_ended_reason": {
                      "type": "string",
                      "description": "Reason the LLM session ended. Only returned when session_status is COMPLETED."
                    },
                    "llm_started_at": {
                      "type": "integer",
                      "description": "Unix timestamp when the LLM session started. Only returned when session_status is COMPLETED."
                    },
                    "llm_ended_at": {
                      "type": "integer",
                      "description": "Unix timestamp when the LLM session ended. Only returned when session_status is COMPLETED."
                    },
                    "messages": {
                      "type": "array",
                      "description": "Array of messages exchanged during the session. Only returned when session_status is COMPLETED.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "role": {
                            "type": "string",
                            "enum": ["user", "agent"],
                            "description": "Role of the message sender."
                          },
                          "message": {
                            "type": "string",
                            "description": "Content of the message."
                          },
                          "seconds_from_start": {
                            "type": "integer",
                            "description": "Number of seconds from the start of the session when this message was sent."
                          }
                        },
                        "required": ["role", "message", "seconds_from_start"]
                      }
                    }
                  },
                  "required": ["session_status"]
                },
                "examples": {
                  "queued": {
                    "summary": "Session is queued",
                    "value": {
                      "session_status": "QUEUED"
                    }
                  },
                  "active": {
                    "summary": "Session is active",
                    "value": {
                      "session_status": "ACTIVE"
                    }
                  },
                  "completed": {
                    "summary": "Session completed with full details",
                    "value": {
                      "session_status": "COMPLETED",
                      "cost": 10.5,
                      "llm_ended_reason": "Client disconnected: 1000",
                      "llm_started_at": 1772746376,
                      "llm_ended_at": 1772746535,
                      "messages": [
                        {
                          "role": "user",
                          "message": "hello",
                          "seconds_from_start": 0
                        },
                        {
                          "role": "agent",
                          "message": "Hello! How can I assist you today?",
                          "seconds_from_start": 10
                        }
                      ]
                    }
                  },
                  "timed_out": {
                    "summary": "Session timed out",
                    "value": {
                      "session_status": "TIMED_OUT"
                    }
                  },
                  "failed": {
                    "summary": "Session failed",
                    "value": {
                      "session_status": "FAILED"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Authentication denied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Invalid API key"
                }
              }
            }
          },
          "403": {
            "description": "Room does not belong to this account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Room does not belong to this account"
                }
              }
            }
          },
          "404": {
            "description": "Room not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Room not found"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerError"
                }
              }
            }
          }
        }
      }
    },
    "/liveai/avatar-variants": {
      "post": {
        "summary": "Create avatar variants",
        "description": "Generate optimized avatar images from a source photo. Each requested variant reframes the character into a pose and crop that works well as a LemonSlice avatar reference image. Use the returned URL when creating a session.",
        "operationId": "createAvatarVariants",
        "requestBody": {
          "required": true,
          "description": "Provide `variant_ids` and exactly one image source: `image_url` or `image_base64`.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AvatarVariantsInput"
              },
              "examples": {
                "by_image_url": {
                  "summary": "Optimize from a public image URL",
                  "value": {
                    "image_url": "https://cdn.lemonslice.com/avatars/avatar.png",
                    "variant_ids": ["standing"]
                  }
                },
                "by_image_base64": {
                  "summary": "Optimize from inline base64",
                  "value": {
                    "image_base64": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ...",
                    "variant_ids": ["sitting"]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successfully generated variants. Keys are the requested variant ids; values are hosted image URLs. Variants that fail to generate are omitted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AvatarVariantsResponse"
                },
                "example": {
                  "standing": "https://cdn.lemonslice.com/variants/standing.jpg"
                }
              }
            }
          },
          "400": {
            "description": "Invalid arguments. Typically missing an image source, providing both `image_url` and `image_base64`, or sending an empty or unknown `variant_ids` list.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Provide exactly one of image_url or image_base64"
                }
              }
            }
          },
          "401": {
            "description": "Authentication denied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Invalid API key"
                }
              }
            }
          },
          "403": {
            "description": "This workspace is not enabled for Avatar Optimization.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Endpoint is not enabled for this workspace."
                }
              }
            }
          },
          "422": {
            "description": "The source image was rejected by the content policy.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "content_policy_violation"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerError"
                }
              }
            }
          },
          "502": {
            "description": "Variant generation failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "detail": "Variant generation failed"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "AgentInfo": {
        "type": "object",
        "required": ["agent_id"],
        "properties": {
          "agent_id": {
            "description": "The ID of the LemonSlice avatar.",
            "type": "string",
            "example": "agent_abc123"
          }
        }
      },
      "Room": {
        "type": "object",
        "required": ["room_url", "token", "image_url", "session_id"],
        "properties": {
          "room_url": {
            "description": "The Daily room URL.",
            "type": "string",
            "format": "uri",
            "example": "https://your-subdomain.daily.co/abc123"
          },
          "token": {
            "description": "The Daily user token.",
            "type": "string"
          },
          "image_url": {
            "description": "The placeholder avatar image.",
            "type": "string",
            "format": "uri",
            "example": "https://cdn.lemonslice.com/agents/agent_abc123.png"
          },
          "session_id": {
            "description": "A unique identifier for the room's session.",
            "type": "string",
            "format": "string",
            "example": "3f7c2b91-9e1f-4a6a-8e9d-2c7c3e7d9b5a"
          }
        }
      },
      "SessionInput": {
        "oneOf": [
          { "$ref": "#/components/schemas/LiveKitSDKSessionInput", "title": "LiveKit SDK" },
          { "$ref": "#/components/schemas/PipecatSDKSessionInput", "title": "Pipecat SDK" },
          { "$ref": "#/components/schemas/WebSocketLiveKitSessionInput", "title": "WebSocket + LiveKit" },
          { "$ref": "#/components/schemas/WebSocketDailySessionInput", "title": "WebSocket + Daily" }
        ]
      },
      "SessionCommonParameters": {
        "type": "object",
        "properties": {
          "agent_prompt": {
            "description": "A high-level system prompt that subtly influences the avatar's movements, expressions, and emotional demeanor. This prompt is best used to suggest general affect or demeanor (for example, 'feel excited' or 'look sad') rather than precise or deterministic actions.",
            "type": "string",
            "default": "a person talking"
          },
          "agent_idle_prompt": {
            "description": "A high-level system prompt that influences the avatar's movements, expressions, and emotional demeanor during the idle state.",
            "type": "string",
            "default": "a serious person"
          },
          "idle_timeout": {
            "description": "Idle timeout in seconds. If a negative number is provided, the session will have no idle timeout. We **strongly** discourage disabling the idle timeout during development to avoid excessive credit usage.",
            "type": "integer",
            "default": 60
          },
          "response_done_timeout": {
            "description": "Time in seconds to wait without receiving new audio bytes before marking the response as complete. Some TTS models do not send an end response event, or do not send it in a timely manner. This parameter enables detection of response completion when such events are missing or delayed. This parameter can also be used to ensure proper conversation flow with multi-message LLMs (e.g. `gpt-realtime-2`).",
            "type": ["number", "null"],
            "default": null,
            "x-mint": {
              "post": ["default: null"]
            }
          },
          "aspect_ratio": {
            "description": "Output aspect ratio for the avatar video.",
            "type": "string",
            "enum": ["2x3", "9x16", "1x1"],
            "default": "2x3"
          },
          "model": {
            "description": "Model variant. Leave `null` to use the normal flagship model.",
            "type": ["string", "null"],
            "enum": ["cwm-1", "cwm-1-lite", "cartoon", "flash", "pro", null],
            "default": null,
            "x-mint": {
              "post": ["default: null"]
            }
          },
          "edit_image": {
            "description": "Boolean. If True, the source image is reframed before the session starts. Defaults to True for accounts created after September 22, 2026. See [Avatar image tips](/prompting-guide/avatar-image-tips#how-to-get-the-best-quality-avatars).",
            "type": ["boolean", "null"]
          },
          "edit_image_variant": {
            "description": "Framing to generate when `edit_image` runs: `standing` (default), `bust` (default when actions are enabled), `sitting`, or `portrait`.",
            "type": ["string", "null"],
            "enum": ["standing", "bust", "sitting", "portrait", null]
          }
        }
      },
      "SessionImageParameters": {
        "type": "object",
        "properties": {
          "agent_image_url": {
            "description": "A URL to an avatar image to use. The image should be 368x560 pixels. LemonSlice automatically center-crops images that do not match the expected dimensions. Provide either `agent_image_url` or `agent_id`, but not both.",
            "type": "string",
            "format": "uri",
            "example": "https://cdn.lemonslice.com/avatars/avatar.png"
          },
          "agent_id": {
            "description": "The ID of a LemonSlice avatar. Provide either `agent_id` or `agent_image_url`, but not both. If provided, avatar-configured settings are used as defaults for `agent_prompt`, `agent_idle_prompt`, and `idle_timeout`.",
            "type": "string",
            "example": "agent_abc123"
          }
        }
      },
      "SessionInputCommon": {
        "allOf": [
          { "$ref": "#/components/schemas/SessionImageParameters" },
          { "$ref": "#/components/schemas/SessionCommonParameters" }
        ]
      },
      "LiveKitSDKTransportParameters": {
        "type": "object",
        "required": ["transport_type", "properties"],
        "properties": {
          "transport_type": {
            "description": "Using the LiveKit SDK publishes avatar A/V to a LiveKit room.",
            "type": "string",
            "const": "livekit"
          },
          "properties": {
            "description": "LiveKit room credentials LemonSlice uses to join and publish avatar A/V.",
            "$ref": "#/components/schemas/LiveKitTransportProperties"
          },
          "simulcast": {
            "description": "LiveKit only. Enable WebRTC simulcast, which publishes multiple resolutions of the avatar video so subscribers receive the best quality their bandwidth allows.",
            "type": "boolean",
            "default": false
          },
          "video_codec": {
            "description": "LiveKit only. Video codec for the published avatar track.",
            "type": "string",
            "enum": ["vp8", "h264", "vp9", "av1", "h265"],
            "default": "vp8"
          },
          "scalability_mode": {
            "description": "LiveKit only. SVC scalability mode. Applied only when `video_codec` is `vp9` or `av1`; ignored otherwise.",
            "type": ["string", "null"],
            "enum": ["L1T1", "L1T2", "L1T3", "L2T1", "L2T2", "L2T3", "L2T1_KEY", "L2T2_KEY", "L2T3_KEY", "L3T1", "L3T2", "L3T3", "L3T1_KEY", "L3T2_KEY", "L3T3_KEY", null],
            "default": null,
            "x-mint": {
              "post": ["default: null"]
            }
          }
        }
      },
      "PipecatSDKTransportParameters": {
        "type": "object",
        "required": ["transport_type"],
        "properties": {
          "transport_type": {
            "description": "Using the Pipecat SDK publishes avatar A/V to a Daily room.",
            "type": "string",
            "const": "daily"
          },
          "properties": {
            "description": "Daily room credentials LemonSlice uses to join and publish avatar A/V. If not provided, LemonSlice will create a new room at an additional cost of 0.51 credits per participant minute.",
            "$ref": "#/components/schemas/DailyTransportProperties"
          }
        }
      },
      "WebSocketLiveKitTransportParameters": {
        "type": "object",
        "required": ["transport_type", "livekit_properties"],
        "properties": {
          "transport_type": {
            "description": "Send audio over WebSocket and publish avatar A/V to LiveKit.",
            "type": "string",
            "const": "websocket-livekit"
          },
          "livekit_properties": {
            "description": "LiveKit room credentials LemonSlice uses to join and publish avatar A/V.",
            "$ref": "#/components/schemas/WebSocketLiveKitProperties"
          }
        }
      },
      "WebSocketDailyTransportParameters": {
        "type": "object",
        "required": ["transport_type", "daily_properties"],
        "properties": {
          "transport_type": {
            "description": "Send audio over WebSocket and publish avatar A/V to Daily.",
            "type": "string",
            "const": "websocket-daily"
          },
          "daily_properties": {
            "description": "Daily room credentials LemonSlice uses to join and publish avatar A/V.",
            "$ref": "#/components/schemas/WebSocketDailyProperties"
          }
        }
      },
      "LiveKitSDKSessionInput": {
        "allOf": [
          { "$ref": "#/components/schemas/SessionInputCommon" },
          { "$ref": "#/components/schemas/LiveKitSDKTransportParameters" }
        ],
        "unevaluatedProperties": false,
        "example": {
          "agent_image_url": "https://cdn.lemonslice.com/avatars/avatar.png",
          "agent_prompt": "a person talking",
          "transport_type": "livekit",
          "properties": {
            "livekit_url": "wss://lemonslice-pb123.livekit.cloud",
            "livekit_token": "eyJhbGciOiJIUzI1NiIsInR5a..."
          }
        }
      },
      "PipecatSDKSessionInput": {
        "allOf": [
          { "$ref": "#/components/schemas/SessionInputCommon" },
          { "$ref": "#/components/schemas/PipecatSDKTransportParameters" }
        ],
        "unevaluatedProperties": false
      },
      "WebSocketLiveKitSessionInput": {
        "allOf": [
          { "$ref": "#/components/schemas/SessionInputCommon" },
          { "$ref": "#/components/schemas/WebSocketLiveKitTransportParameters" }
        ],
        "unevaluatedProperties": false
      },
      "WebSocketDailySessionInput": {
        "allOf": [
          { "$ref": "#/components/schemas/SessionInputCommon" },
          { "$ref": "#/components/schemas/WebSocketDailyTransportParameters" }
        ],
        "unevaluatedProperties": false
      },
      "SessionFormDataPayload": {
        "description": "Session parameters used alongside an uploaded avatar image. Select an integration to see its complete payload. Send the request as `application/json` to specify an agent_id or agent_image_url.",
        "oneOf": [
          { "$ref": "#/components/schemas/LiveKitSDKFormDataPayload", "title": "LiveKit SDK" },
          { "$ref": "#/components/schemas/PipecatSDKFormDataPayload", "title": "Pipecat SDK" },
          { "$ref": "#/components/schemas/WebSocketLiveKitFormDataPayload", "title": "WebSocket + LiveKit" },
          { "$ref": "#/components/schemas/WebSocketDailyFormDataPayload", "title": "WebSocket + Daily" }
        ]
      },
      "LiveKitSDKFormDataPayload": {
        "allOf": [
          { "$ref": "#/components/schemas/SessionCommonParameters" },
          { "$ref": "#/components/schemas/LiveKitSDKTransportParameters" }
        ],
        "unevaluatedProperties": false
      },
      "PipecatSDKFormDataPayload": {
        "allOf": [
          { "$ref": "#/components/schemas/SessionCommonParameters" },
          { "$ref": "#/components/schemas/PipecatSDKTransportParameters" }
        ],
        "unevaluatedProperties": false
      },
      "WebSocketLiveKitFormDataPayload": {
        "allOf": [
          { "$ref": "#/components/schemas/SessionCommonParameters" },
          { "$ref": "#/components/schemas/WebSocketLiveKitTransportParameters" }
        ],
        "unevaluatedProperties": false
      },
      "WebSocketDailyFormDataPayload": {
        "allOf": [
          { "$ref": "#/components/schemas/SessionCommonParameters" },
          { "$ref": "#/components/schemas/WebSocketDailyTransportParameters" }
        ],
        "unevaluatedProperties": false
      },
      "LiveKitTransportProperties": {
        "type": "object",
        "required": ["livekit_url", "livekit_token"],
        "properties": {
          "livekit_url": {
            "type": "string",
            "format": "uri",
            "example": "wss://lemonslice-pb123.livekit.cloud"
          },
          "livekit_token": {
            "type": "string",
            "example": "eyJhbGciOiJIUzI1NiIsInR5a..."
          }
        },
        "additionalProperties": true,
        "example": {
          "livekit_url": "wss://lemonslice-pb123.livekit.cloud",
          "livekit_token": "eyJhbGciOiJIUzI1NiIsInR5a..."
        }
      },
      "DailyTransportProperties": {
        "type": "object",
        "properties": {
          "daily_url": {
            "description": "Daily room URL to use.",
            "type": "string",
            "format": "uri",
            "example": "https://your-domain.daily.co/your-room"
          },
          "daily_token": {
            "description": "Daily token for authenticating with the room.",
            "type": "string",
            "example": "eyJhbGciOiJIUzI1NiIsInR5a..."
          },
          "enable_recording": {
            "description": "Enable Daily call recording. If set, recordings_bucket must also be provided. Enabling recording incurs an additional charge of 0.378 credits per minute.",
            "type": "string",
            "enum": ["cloud", "cloud-audio-only", "local", "raw-tracks"]
          },
          "recordings_bucket": {
            "description": "The S3 bucket configuration where recordings will be saved. Follows the Daily recording bucket specification.",
            "type": "object",
            "properties": {
              "bucket_name": {
                "description": "The name of the S3 bucket.",
                "type": "string"
              },
              "bucket_region": {
                "description": "The AWS region of the S3 bucket.",
                "type": "string"
              },
              "assume_role_arn": {
                "description": "The ARN of the IAM role for Daily to assume for storage.",
                "type": "string"
              },
              "allow_api_access": {
                "description": "Whether Daily's recording access link API should allow downloading the recording.",
                "type": "boolean"
              }
            },
            "required": ["bucket_name", "bucket_region", "assume_role_arn"]
          }
        },
        "dependentRequired": {
          "enable_recording": ["recordings_bucket"]
        },
        "additionalProperties": true,
        "example": {
          "daily_url": "https://your-domain.daily.co/your-room",
          "daily_token": "eyJhbGciOiJIUzI1NiIsInR5a..."
        }
      },
      "WebSocketLiveKitProperties": {
        "description": "LiveKit egress room credentials for the `websocket-livekit` transport.",
        "type": "object",
        "required": ["livekit_url", "livekit_token"],
        "properties": {
          "livekit_url": {
            "description": "LiveKit server URL of the room LemonSlice should join and publish avatar A/V into.",
            "type": "string",
            "format": "uri",
            "example": "wss://your-project.livekit.cloud"
          },
          "livekit_token": {
            "description": "LiveKit access token with publish permission that LemonSlice uses to join the room.",
            "type": "string",
            "example": "eyJhbGciOiJIUzI1NiIsInR5a..."
          },
          "simulcast": {
            "description": "Enable WebRTC simulcast, which publishes multiple resolutions of the avatar video so subscribers receive the best quality their bandwidth allows. LiveKit only.",
            "type": "boolean",
            "default": false
          },
          "video_codec": {
            "description": "Video codec for the published avatar track. LiveKit only.",
            "type": "string",
            "enum": ["vp8", "h264", "vp9", "av1", "h265"],
            "default": "vp8"
          },
          "scalability_mode": {
            "description": "SVC scalability mode. Applied only when `video_codec` is `vp9` or `av1`; ignored otherwise. LiveKit only.",
            "type": ["string", "null"],
            "enum": ["L1T1", "L1T2", "L1T3", "L2T1", "L2T2", "L2T3", "L2T1_KEY", "L2T2_KEY", "L2T3_KEY", "L3T1", "L3T2", "L3T3", "L3T1_KEY", "L3T2_KEY", "L3T3_KEY", null],
            "default": null,
            "x-mint": {
              "post": ["default: null"]
            }
          }
        },
        "additionalProperties": false,
        "example": {
          "livekit_url": "wss://your-project.livekit.cloud",
          "livekit_token": "eyJhbGciOiJIUzI1NiIsInR5a..."
        }
      },
      "WebSocketDailyProperties": {
        "description": "Daily egress room credentials for the `websocket-daily` transport.",
        "type": "object",
        "required": ["daily_url", "daily_token"],
        "properties": {
          "daily_url": {
            "description": "Daily room URL LemonSlice should join and publish avatar A/V into.",
            "type": "string",
            "format": "uri",
            "example": "https://your-domain.daily.co/room-name"
          },
          "daily_token": {
            "description": "Daily meeting token with publish permission that LemonSlice uses to join the room.",
            "type": "string",
            "example": "eyJhbGciOiJIUzI1NiIsInR5a..."
          }
        },
        "additionalProperties": false,
        "example": {
          "daily_url": "https://your-domain.daily.co/room-name",
          "daily_token": "eyJhbGciOiJIUzI1NiIsInR5a..."
        }
      },
      "Session": {
        "description": "Response fields vary by transport.",
        "oneOf": [
          {
            "title": "LiveKit SDK",
            "type": "object",
            "required": ["session_id", "control_url"],
            "properties": {
              "session_id": {
                "description": "The ID of the session.",
                "type": "string"
              },
              "control_url": {
                "description": "Endpoint for sending control events to the session.",
                "type": "string",
                "format": "uri"
              },
              "edited_image_url": {
                "description": "Public URL of the reframed image when editing produced or reused a variant. Omitted when editing is skipped or falls back to the original image.",
                "type": "string",
                "format": "uri"
              }
            },
            "additionalProperties": false
          },
          {
            "title": "Pipecat SDK",
            "type": "object",
            "required": ["session_id", "control_url", "room_url"],
            "properties": {
              "session_id": {
                "description": "The ID of the session.",
                "type": "string"
              },
              "control_url": {
                "description": "Endpoint for sending control events to the session.",
                "type": "string",
                "format": "uri"
              },
              "room_url": {
                "description": "The Daily room URL used by the session.",
                "type": "string",
                "format": "uri"
              },
              "edited_image_url": {
                "description": "Public URL of the reframed image when editing produced or reused a variant. Omitted when editing is skipped or falls back to the original image.",
                "type": "string",
                "format": "uri"
              }
            },
            "additionalProperties": false
          },
          {
            "title": "WebSocket",
            "description": "Returned for both `websocket-livekit` and `websocket-daily`. The egress provider determines where avatar A/V is published, not the response shape.",
            "type": "object",
            "required": ["session_id", "control_url", "websocket_address"],
            "properties": {
              "session_id": {
                "description": "The ID of the session.",
                "type": "string"
              },
              "control_url": {
                "description": "Endpoint for sending control events to the session.",
                "type": "string",
                "format": "uri"
              },
              "websocket_address": {
                "description": "WebSocket URL for sending audio and control events to LemonSlice.",
                "type": "string",
                "format": "uri"
              },
              "edited_image_url": {
                "description": "Public URL of the reframed image when editing produced or reused a variant. Omitted when editing is skipped or falls back to the original image.",
                "type": "string",
                "format": "uri"
              }
            },
            "additionalProperties": false
          }
        ]
      },
      "UpdateImageEvent": {
        "type": "object",
        "required": ["event"],
        "properties": {
          "event": {
            "type": "string",
            "const": "update-image",
            "default": "update-image",
            "description": "update-image"
          },
          "image_url": {
            "type": "string",
            "format": "uri",
            "description": "URL of the new avatar image. Must be publicly accessible. Provide exactly one of `image_url` or `image_base64`.",
            "example": "https://example.com/avatar.jpg"
          },
          "image_base64": {
            "type": "string",
            "description": "Base64-encoded bytes of the new avatar image. A data URL prefix (e.g. `data:image/png;base64,`) is also accepted. The decoded image must be under 900 KB — host larger images and pass `image_url` instead. Provide exactly one of `image_url` or `image_base64`.",
            "example": "iVBORw0KGgoAAAANSUhEUgAA..."
          }
        }
      },
      "TerminateEvent": {
        "type": "object",
        "required": ["event"],
        "properties": {
          "event": {
            "type": "string",
            "const": "terminate",
            "default": "terminate",
            "description": "terminate"
          }
        }
      },
      "ResetIdleTimeoutEvent": {
        "type": "object",
        "required": ["event"],
        "properties": {
          "event": {
            "type": "string",
            "const": "reset-idle-timeout",
            "default": "reset-idle-timeout",
            "description": "reset-idle-timeout"
          }
        }
      },
      "UpdateAgentPromptEvent": {
        "type": "object",
        "required": ["event", "agent_prompt"],
        "properties": {
          "event": {
            "type": "string",
            "const": "update-agent-prompt",
            "default": "update-agent-prompt",
            "description": "update-agent-prompt"
          },
          "agent_prompt": {
            "type": "string",
            "description": "A high-level system prompt that subtly influences the avatar's expressions while speaking.",
            "example": "a person talking"
          }
        }
      },
      "UpdateIdlePromptEvent": {
        "type": "object",
        "required": ["event", "idle_prompt"],
        "properties": {
          "event": {
            "type": "string",
            "const": "update-idle-prompt",
            "default": "update-idle-prompt",
            "description": "update-idle-prompt"
          },
          "idle_prompt": {
            "type": "string",
            "description": "A high-level system prompt that subtly influences the avatar's expressions during the idle state.",
            "example": "a serious person"
          }
        }
      },
      "ActionEvent": {
        "type": "object",
        "required": ["event", "action"],
        "properties": {
          "event": {
            "type": "string",
            "const": "action",
            "default": "action",
            "description": "action"
          },
          "action": {
            "type": "string",
            "description": "Name of the CWM-1 action to trigger. See the [CWM-1 guide](/reference/cwm-1#available-actions) for the full list.",
            "example": "wave"
          }
        }
      },
      "JoinMeetingInput": {
        "type": "object",
        "required": ["meeting_url", "livekit_url", "broadcast_token"],
        "properties": {
          "meeting_url": {
            "type": "string",
            "description": "HTTPS URL for the third party meeting platform. Supported platforms: Zoom, Google Meet, Microsoft Teams, and Webex. For platforms that support it (e.g. Zoom), include the meeting password in the URL.",
            "example": "https://meet.google.com/abc-defg-hij"
          },
          "livekit_url": {
            "type": "string",
            "description": "The LiveKit server URL (wss://) for the session.",
            "example": "wss://lemonslice-pb123.livekit.cloud"
          },
          "broadcast_token": {
            "type": "string",
            "description": "A LiveKit JWT with room permissions used to publish the avatar video stream to the third party meeting platform.",
            "example": "<LIVEKIT_BROADCAST_TOKEN>"
          },
          "bot_name": {
            "type": "string",
            "description": "Optional display name for the avatar in the third party meeting platform.",
            "example": "LemonSlice Avatar"
          }
        }
      },
      "JoinMeetingResponse": {
        "type": "object",
        "required": ["meeting_bot_id", "websocket_url"],
        "properties": {
          "meeting_bot_id": {
            "type": "string",
            "description": "ID for the joined third party meeting platform. Pass this to the leave-meeting endpoint when removing the avatar from the third party meeting platform.",
            "example": "meeting-bot-abc123"
          },
          "websocket_url": {
            "type": "string",
            "description": "WebSocket URL for receiving agent audio from the third party meeting platform.",
            "example": "wss://example.com/agent-audio/session-id?token=..."
          }
        }
      },
      "LeaveMeetingInput": {
        "type": "object",
        "required": ["meeting_bot_id"],
        "properties": {
          "meeting_bot_id": {
            "type": "string",
            "description": "The third party meeting platform ID returned by the join-meeting endpoint.",
            "example": "meeting-bot-abc123"
          }
        }
      },
      "LeaveMeetingResponse": {
        "type": "object",
        "required": ["status"],
        "properties": {
          "status": {
            "type": "string",
            "const": "left",
            "description": "Confirmation that the avatar has left the third party meeting platform."
          }
        }
      },
      "AgoraSettings": {
        "type": "object",
        "description": "Agora RTC connection settings for the LemonSlice avatar participant. Populated by Agora when using the generic avatar vendor.",
        "required": ["app_id", "token", "channel", "uid", "enable_string_uid"],
        "properties": {
          "app_id": {
            "type": "string",
            "description": "Agora application identifier."
          },
          "token": {
            "type": "string",
            "description": "Agora RTC token that authorizes the avatar UID to join the channel with publish permission."
          },
          "channel": {
            "type": "string",
            "description": "Name of the Agora RTC channel to join."
          },
          "uid": {
            "type": "string",
            "description": "RTC UID the LemonSlice avatar publishes under. Must be distinct from the Agora agent UID and end-user UID."
          },
          "enable_string_uid": {
            "type": "boolean",
            "description": "Whether `uid` should be treated as a string UID."
          }
        }
      },
      "AgoraSessionInput": {
        "description": "Body for starting a LemonSlice Agora session. Exactly one of `agent_id`, `agent_image_url`, or `agent_image_base64` must be provided.",
        "type": "object",
        "required": ["video_encoding", "agora_settings"],
        "properties": {
          "avatar_id": {
            "type": "string",
            "description": "Pass in `lemonslice` for this field. The avatar's appearance is taken from `agent_id`, `agent_image_url`, or `agent_image_base64`.",
            "example": "lemonslice"
          },
          "agent_id": {
            "type": "string",
            "description": "The ID of a LemonSlice avatar. Exactly one of `agent_id`, `agent_image_url`, or `agent_image_base64` is required. If provided, avatar-configured settings are used as defaults for `agent_prompt` and `agent_idle_prompt`.",
            "example": "agent_abc123"
          },
          "agent_image_url": {
            "type": "string",
            "format": "uri",
            "description": "A publicly accessible URL to the avatar image. Exactly one of `agent_id`, `agent_image_url`, or `agent_image_base64` is required.",
            "example": "https://cdn.lemonslice.com/avatars/avatar.png"
          },
          "agent_image_base64": {
            "type": "string",
            "description": "Base64-encoded avatar image bytes. Exactly one of `agent_id`, `agent_image_url`, or `agent_image_base64` is required."
          },
          "video_encoding": {
            "type": "string",
            "enum": ["H264", "VP8", "AV1"],
            "description": "Video codec used for the avatar stream. `H264` provides the widest client compatibility."
          },
          "activity_idle_timeout": {
            "type": "number",
            "default": 120,
            "description": "Seconds of inactivity before the session is automatically terminated. Set to `0` to disable the idle timeout. We **strongly** discourage disabling the idle timeout during development to avoid excessive credit usage."
          },
          "agora_settings": {
            "$ref": "#/components/schemas/AgoraSettings"
          },
          "agent_prompt": {
            "type": "string",
            "default": "a person talking",
            "description": "A high-level system prompt that subtly influences the avatar's movements, expressions, and emotional demeanor while speaking. Best used for general affect (for example, \"feel excited\" or \"look sad\") rather than precise actions."
          },
          "agent_idle_prompt": {
            "type": "string",
            "default": "a serious person",
            "description": "A high-level system prompt that influences the avatar's movements, expressions, and emotional demeanor during the idle state."
          },
          "model": {
            "type": ["string", "null"],
            "enum": ["cwm-1", "cwm-1-lite", "cartoon", "flash", "pro", null],
            "default": null,
            "description": "Model variant. Leave unset to use the normal flagship model.",
            "x-mint": {
              "post": ["default: null"]
            }
          },
          "aspect_ratio": {
            "type": "string",
            "enum": ["2x3", "9x16", "1x1"],
            "description": "Output aspect ratio for the avatar video.",
            "default": "2x3"
          },
          "response_done_timeout": {
            "type": ["number", "null"],
            "default": null,
            "description": "Time in seconds to wait without receiving new audio bytes before marking the response as complete. Some TTS models do not send an end-response event, or do not send it promptly. This parameter enables completion detection when such events are missing or delayed.",
            "x-mint": {
              "post": ["default: null"]
            }
          },
          "edit_image": {
            "description": "Boolean. If True, the source image is reframed before the session starts. Defaults to True for accounts created after September 22, 2026. See [Avatar image tips](/prompting-guide/avatar-image-tips#how-to-get-the-best-quality-avatars).",
            "type": ["boolean", "null"]
          },
          "edit_image_variant": {
            "description": "Framing to generate when `edit_image` runs: `standing` (default), `bust` (default when actions are enabled), `sitting`, or `portrait`.",
            "type": ["string", "null"],
            "enum": ["standing", "bust", "sitting", "portrait", null]
          }
        }
      },
      "AgoraSessionStartResponse": {
        "type": "object",
        "required": ["session_id", "websocket_address", "session_token"],
        "properties": {
          "session_id": {
            "type": "string",
            "description": "Unique identifier for this LemonSlice session."
          },
          "websocket_address": {
            "type": "string",
            "description": "WebSocket URL Agora uses for the avatar audio/video tunnel."
          },
          "session_token": {
            "type": "string",
            "description": "Token used to authenticate the WebSocket tunnel and session stop requests."
          },
          "edited_image_url": {
            "type": "string",
            "format": "uri",
            "description": "Public URL of the reframed image when editing produced or reused a variant. Omitted when editing is skipped or falls back to the original image."
          }
        }
      },
      "AgoraSessionStopInput": {
        "type": "object",
        "required": ["session_id"],
        "properties": {
          "session_id": {
            "type": "string",
            "description": "The session ID returned by `/liveai/agora/session/start`."
          },
          "session_token": {
            "type": "string",
            "description": "The session token returned by `/liveai/agora/session/start`."
          }
        }
      },
      "AgoraSessionStopResponse": {
        "type": "object",
        "required": ["status", "message"],
        "properties": {
          "status": {
            "type": "string",
            "const": "success",
            "description": "Termination status."
          },
          "message": {
            "type": "string",
            "description": "Human-readable confirmation message."
          }
        }
      },
      "AgoraError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "code": {
            "type": "string"
          }
        }
      },
      "AvatarVariantIds": {
        "description": "Variants to generate. See [Avatar image tips](/prompting-guide/avatar-image-tips#how-to-get-the-best-quality-avatars).",
        "type": "array",
        "minItems": 1,
        "items": {
          "type": "string",
          "enum": ["standing", "bust", "sitting", "portrait"]
        }
      },
      "AvatarVariantsUrlInput": {
        "type": "object",
        "required": ["image_url", "variant_ids"],
        "properties": {
          "image_url": {
            "description": "A publicly reachable URL of the source image.",
            "type": "string",
            "format": "uri",
            "example": "https://cdn.lemonslice.com/avatars/avatar.png"
          },
          "variant_ids": {
            "$ref": "#/components/schemas/AvatarVariantIds"
          }
        }
      },
      "AvatarVariantsBase64Input": {
        "type": "object",
        "required": ["image_base64", "variant_ids"],
        "properties": {
          "image_base64": {
            "description": "Raw image bytes, base64-encoded. A `data:` URL prefix is accepted.",
            "type": "string",
            "example": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ..."
          },
          "variant_ids": {
            "$ref": "#/components/schemas/AvatarVariantIds"
          }
        }
      },
      "AvatarVariantsInput": {
        "oneOf": [
          { "$ref": "#/components/schemas/AvatarVariantsUrlInput", "title": "Image URL" },
          { "$ref": "#/components/schemas/AvatarVariantsBase64Input", "title": "Image Bytes" }
        ]
      },
      "AvatarVariantsResponse": {
        "type": "object",
        "description": "Map of generated variant id to a hosted image URL.",
        "additionalProperties": {
          "type": "string",
          "format": "uri"
        },
        "example": {
          "standing": "https://cdn.lemonslice.com/variants/standing.jpg"
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "detail": {
            "type": "string"
          }
        }
      },
      "ServerError": {
        "type": "object",
        "properties": {
          "detail": {
            "type": "string"
          }
        }
      }
    },
    "securitySchemes": {
      "apiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Your LemonSlice API token."
      }
    }
  }
}