diff --git a/deployment/pipecat-cloud/guides/session-api.mdx b/deployment/pipecat-cloud/guides/session-api.mdx new file mode 100644 index 00000000..6c194353 --- /dev/null +++ b/deployment/pipecat-cloud/guides/session-api.mdx @@ -0,0 +1,149 @@ +--- +title: Session API +description: "Send HTTP requests to your running Pipecat Cloud sessions" +--- + +The Session API lets you send HTTP requests directly to your running Pipecat Cloud agents. This enables real-time control and data exchange with active sessions, such as updating conversation context, triggering actions, or retrieving session state. + +## How It Works + +1. [Start a session](/deployment/pipecat-cloud/fundamentals/active-sessions) with your agent +2. Capture the `sessionId` header from the start response +3. Send HTTP requests to your session using the session endpoint + +## Endpoint Format + +``` +https://api.pipecat.daily.co/v1/public/{service_name}/sessions/{session_id}/{path} +``` + +| Parameter | Description | +| -------------- | --------------------------------------------- | +| `service_name` | The name of your deployed agent | +| `session_id` | The `sessionId` value from the start response | +| `path` | The endpoint path you defined in your bot | + +### Supported Methods + +- `GET` +- `POST` +- `PUT` +- `PATCH` +- `DELETE` +- `OPTIONS` +- `HEAD` + +## Authentication + +Include your Pipecat Cloud public API key in the `Authorization` header: + +```bash +Authorization: Bearer pk_... +``` + +## Setting Up Your Bot + +To handle Session API requests, define endpoints in your `bot.py` file using the `app` object from `pipecatcloud_system`: + +```python +from pipecatcloud_system import app +from pipecat.runner.types import PipecatRunnerArguments + +# Define your API endpoints +@app.get("/status") +async def get_status(): + return {"status": "active", "message": "Bot is running"} + +@app.post("/update-context") +async def update_context(data: dict): + # Handle context updates + return {"updated": True} + +# Your main bot function +async def bot(args: PipecatRunnerArguments): + # Bot implementation + pass +``` + +Requires base image version `0.1.2` or later. + +## Examples + +### Get Session Status + +Define an endpoint that returns the current session state: + +```python +from pipecatcloud_system import app + +session_data = {"messages": [], "user_name": None} + +@app.get("/status") +async def get_status(): + return { + "message_count": len(session_data["messages"]), + "user_name": session_data["user_name"] + } +``` + +Call the endpoint: + +```bash +curl -X GET \ + 'https://api.pipecat.daily.co/v1/public/my-agent/sessions/57af5437-97a2-4646-9873-a5c5935bd705/status' \ + -H 'Authorization: Bearer pk_...' +``` + +### Update Conversation Context + +Define an endpoint to inject information into the conversation: + +```python +from pipecatcloud_system import app +from pydantic import BaseModel + +class ContextUpdate(BaseModel): + user_name: str + preferences: dict + +@app.post("/context") +async def update_context(update: ContextUpdate): + # Update your bot's context with the new information + # This could modify the LLM system prompt, add to conversation history, etc. + return {"status": "context updated", "user_name": update.user_name} +``` + +Call the endpoint: + +```bash +curl -X POST \ + 'https://api.pipecat.daily.co/v1/public/my-agent/sessions/57af5437-97a2-4646-9873-a5c5935bd705/context' \ + -H 'Authorization: Bearer pk_...' \ + -H 'Content-Type: application/json' \ + -d '{"user_name": "Alice", "preferences": {"language": "Spanish"}}' +``` + +### Trigger an Action + +Define an endpoint to trigger bot behavior mid-session: + +```python +from pipecatcloud_system import app + +@app.post("/speak") +async def trigger_speech(data: dict): + message = data.get("message", "Hello!") + # Queue the message for your TTS pipeline + # Implementation depends on your bot architecture + return {"queued": True, "message": message} +``` + +## Important Notes + +- **Startup latency**: If you call the Session API before your bot finishes initializing, the request may take longer while waiting for the bot to become available. +- **Session scope**: Each endpoint call is routed to the specific session identified by `session_id`. Different sessions run independently. +- **Error handling**: If a session has ended or the session ID is invalid, you'll receive an error response. + +## Getting Help + +If you have questions about the Session API, reach out on [Discord](https://discord.gg/pipecat). diff --git a/deployment/pipecat-cloud/rest-reference/endpoint/session-proxy.mdx b/deployment/pipecat-cloud/rest-reference/endpoint/session-proxy.mdx new file mode 100644 index 00000000..69e86e46 --- /dev/null +++ b/deployment/pipecat-cloud/rest-reference/endpoint/session-proxy.mdx @@ -0,0 +1,21 @@ +--- +title: "Session API" +description: "Send HTTP requests directly to your running Pipecat Cloud agent sessions." +openapi: "GET /{serviceName}/sessions/{sessionId}/{path}" +--- + +Send HTTP requests to endpoints defined in your running bot. Supports `GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `OPTIONS`, and `HEAD` methods. + +## Request Headers + +Headers are forwarded to your bot with these exceptions: + +- `host` - Excluded +- `content-length` - Excluded +- `authorization` - Excluded (authentication is handled by the API gateway) + + + Requires base image version `0.1.2` or later. See the [Session API + guide](/deployment/pipecat-cloud/guides/session-api) for setup instructions + and examples. + diff --git a/deployment/pipecat-cloud/rest-reference/openapi-session-proxy.json b/deployment/pipecat-cloud/rest-reference/openapi-session-proxy.json new file mode 100644 index 00000000..311ba3e5 --- /dev/null +++ b/deployment/pipecat-cloud/rest-reference/openapi-session-proxy.json @@ -0,0 +1,492 @@ +{ + "openapi": "3.0.0", + "info": { + "title": "Pipecat Cloud - Session API", + "version": "1.0.0", + "description": "Send HTTP requests directly to running Pipecat Cloud agent sessions" + }, + "servers": [ + { + "url": "https://api.pipecat.daily.co/v1/public", + "description": "Public API server" + } + ], + "paths": { + "/{serviceName}/sessions/{sessionId}/{path}": { + "get": { + "summary": "Send GET request to session", + "operationId": "sessionProxyGet", + "description": "Proxies a GET request to an endpoint defined in your running bot. The response is returned directly from the bot.", + "security": [ + { + "PublicKeyAuth": [] + } + ], + "parameters": [ + { + "$ref": "#/components/parameters/ServiceName" + }, + { + "$ref": "#/components/parameters/SessionId" + }, + { + "$ref": "#/components/parameters/Path" + } + ], + "responses": { + "200": { + "description": "Successful response from the bot", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProxiedResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/ServiceNotAvailable" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + }, + "post": { + "summary": "Send POST request to session", + "operationId": "sessionProxyPost", + "description": "Proxies a POST request to an endpoint defined in your running bot. The request body and response are passed through directly.", + "security": [ + { + "PublicKeyAuth": [] + } + ], + "parameters": [ + { + "$ref": "#/components/parameters/ServiceName" + }, + { + "$ref": "#/components/parameters/SessionId" + }, + { + "$ref": "#/components/parameters/Path" + } + ], + "requestBody": { + "description": "Request body to pass to the bot endpoint", + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "description": "Arbitrary JSON data to send to your bot endpoint", + "example": { + "user_name": "Alice", + "preferences": { + "language": "Spanish" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Successful response from the bot", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProxiedResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/ServiceNotAvailable" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + }, + "put": { + "summary": "Send PUT request to session", + "operationId": "sessionProxyPut", + "description": "Proxies a PUT request to an endpoint defined in your running bot.", + "security": [ + { + "PublicKeyAuth": [] + } + ], + "parameters": [ + { + "$ref": "#/components/parameters/ServiceName" + }, + { + "$ref": "#/components/parameters/SessionId" + }, + { + "$ref": "#/components/parameters/Path" + } + ], + "requestBody": { + "description": "Request body to pass to the bot endpoint", + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "description": "Arbitrary JSON data to send to your bot endpoint" + } + } + } + }, + "responses": { + "200": { + "description": "Successful response from the bot", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProxiedResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/ServiceNotAvailable" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + }, + "patch": { + "summary": "Send PATCH request to session", + "operationId": "sessionProxyPatch", + "description": "Proxies a PATCH request to an endpoint defined in your running bot.", + "security": [ + { + "PublicKeyAuth": [] + } + ], + "parameters": [ + { + "$ref": "#/components/parameters/ServiceName" + }, + { + "$ref": "#/components/parameters/SessionId" + }, + { + "$ref": "#/components/parameters/Path" + } + ], + "requestBody": { + "description": "Request body to pass to the bot endpoint", + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "description": "Arbitrary JSON data to send to your bot endpoint" + } + } + } + }, + "responses": { + "200": { + "description": "Successful response from the bot", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProxiedResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/ServiceNotAvailable" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + }, + "delete": { + "summary": "Send DELETE request to session", + "operationId": "sessionProxyDelete", + "description": "Proxies a DELETE request to an endpoint defined in your running bot.", + "security": [ + { + "PublicKeyAuth": [] + } + ], + "parameters": [ + { + "$ref": "#/components/parameters/ServiceName" + }, + { + "$ref": "#/components/parameters/SessionId" + }, + { + "$ref": "#/components/parameters/Path" + } + ], + "responses": { + "200": { + "description": "Successful response from the bot", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProxiedResponse" + } + } + } + }, + "400": { + "$ref": "#/components/responses/ServiceNotAvailable" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + }, + "options": { + "summary": "Send OPTIONS request to session", + "operationId": "sessionProxyOptions", + "description": "Proxies an OPTIONS request to an endpoint defined in your running bot.", + "security": [ + { + "PublicKeyAuth": [] + } + ], + "parameters": [ + { + "$ref": "#/components/parameters/ServiceName" + }, + { + "$ref": "#/components/parameters/SessionId" + }, + { + "$ref": "#/components/parameters/Path" + } + ], + "responses": { + "200": { + "description": "Successful response from the bot" + }, + "400": { + "$ref": "#/components/responses/ServiceNotAvailable" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + }, + "head": { + "summary": "Send HEAD request to session", + "operationId": "sessionProxyHead", + "description": "Proxies a HEAD request to an endpoint defined in your running bot.", + "security": [ + { + "PublicKeyAuth": [] + } + ], + "parameters": [ + { + "$ref": "#/components/parameters/ServiceName" + }, + { + "$ref": "#/components/parameters/SessionId" + }, + { + "$ref": "#/components/parameters/Path" + } + ], + "responses": { + "200": { + "description": "Successful response from the bot" + }, + "400": { + "$ref": "#/components/responses/ServiceNotAvailable" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + } + } + }, + "components": { + "securitySchemes": { + "PublicKeyAuth": { + "type": "http", + "scheme": "bearer", + "description": "Authentication using a Pipecat Cloud public API key.\n\nGenerate a public API key from your Dashboard (Settings > API Keys > Public > Create key) and include it as a Bearer token in the Authorization header." + } + }, + "parameters": { + "ServiceName": { + "name": "serviceName", + "in": "path", + "required": true, + "description": "Name of the deployed agent", + "schema": { + "type": "string" + }, + "example": "my-agent" + }, + "SessionId": { + "name": "sessionId", + "in": "path", + "required": true, + "description": "Session ID returned from the start endpoint", + "schema": { + "type": "string", + "format": "uuid" + }, + "example": "57af5437-97a2-4646-9873-a5c5935bd705" + }, + "Path": { + "name": "path", + "in": "path", + "required": true, + "description": "The endpoint path defined in your bot using the `@app` decorator", + "schema": { + "type": "string" + }, + "example": "status" + } + }, + "responses": { + "ServiceNotAvailable": { + "description": "Service deployment is not available", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + }, + "example": { + "error": "Attempt to start agent when deployment is not in ready state. Is your image pull secret valid?", + "code": "PCC-1001" + } + } + } + }, + "Unauthorized": { + "description": "Invalid or missing API key", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + }, + "example": { + "error": "Unauthorized / token expired", + "code": "401" + } + } + } + }, + "NotFound": { + "description": "Service or session not found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + }, + "example": { + "error": "Service not found", + "code": "404" + } + } + } + }, + "InternalServerError": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + }, + "example": { + "error": "Internal server error. Please check logs for more information or contact support.", + "code": "500" + } + } + } + } + }, + "schemas": { + "ProxiedResponse": { + "type": "object", + "description": "Response from your bot endpoint. The schema depends on what your bot returns.", + "additionalProperties": true, + "example": { + "status": "active", + "message_count": 5, + "user_name": "Alice" + } + }, + "ErrorResponse": { + "type": "object", + "properties": { + "error": { + "type": "string", + "description": "Error message describing what went wrong" + }, + "code": { + "type": "string", + "description": "Error code for programmatic handling" + } + }, + "required": ["error", "code"] + } + } + }, + "security": [ + { + "PublicKeyAuth": [] + } + ] +} diff --git a/docs.json b/docs.json index fbf3709d..5ca66ba2 100644 --- a/docs.json +++ b/docs.json @@ -569,6 +569,7 @@ "pages": ["deployment/pipecat-cloud/guides/using-datadog"] }, "deployment/pipecat-cloud/guides/regions", + "deployment/pipecat-cloud/guides/session-api", "deployment/pipecat-cloud/guides/smart-turn", "deployment/pipecat-cloud/guides/whatsapp", { @@ -603,6 +604,7 @@ "deployment/pipecat-cloud/rest-reference/endpoint/agent-update", "deployment/pipecat-cloud/rest-reference/endpoint/start", "deployment/pipecat-cloud/rest-reference/endpoint/stop", + "deployment/pipecat-cloud/rest-reference/endpoint/session-proxy", "deployment/pipecat-cloud/rest-reference/endpoint/agent-get-logs", "deployment/pipecat-cloud/rest-reference/endpoint/agent-get-sessions", "deployment/pipecat-cloud/rest-reference/endpoint/agent-list-one",