diff --git a/.claude/rules/mdx-reference-pages.md b/.claude/rules/mdx-reference-pages.md index 124da2ae5d..2d1c542a7a 100644 --- a/.claude/rules/mdx-reference-pages.md +++ b/.claude/rules/mdx-reference-pages.md @@ -8,9 +8,9 @@ paths: Applies wherever an interface is documented: SWML methods, SDK reference, Call Flow Builder nodes, cXML verbs, param-bearing snippets. - One page per symbol, terse and lookup-oriented (~50–80 lines): intro sentence → optional `Note`/`Warning` → params → returns/variables → examples. -- Section names are bolded verbatim: `## **Parameters**` (functions/methods), `## **Properties**` (data objects), `## **Returns**`, `## **Variables**` (SWML methods that set any), `## **Examples**`. +- Section names are plain headings, verbatim: `## Parameters` (functions/methods), `## Properties` (data objects), `## Returns`, `## Variables` (SWML methods that set any), `## Examples`. Don't bold them — Fern renders headings identically either way, and most existing pages still carry the old `## **Parameters**` form; leave those as they are unless you're already rewriting the page. - One `` per element, in source order. `path` = bare name for function args, dot-notation for object keys (`answer.max_duration`); nest children in `` (blank lines inside). Types in the language's own terms (`str` for Python, `string` for SWML/JSON). -- XML elements (cXML verbs): the heading is `## Attributes` — unbolded, the one exception — with the bare attribute name as `path`. Callbacks/events: `## **Parameters**` with the handler as the param, its payload fields documented inline beneath it. +- XML elements (cXML verbs): the heading is `## Attributes`, with the bare attribute name as `path`. Callbacks/events: `## Parameters` with the handler as the param, its payload fields documented inline beneath it. - `required={true}` only on required params — never `required={false}`. `default` only when the source defines one. `toc={true}` on reference params. - SWML method pages: every example in both YAML and JSON inside ``. - Server SDK reference: mirror the SDK's own naming and types per language — verify against source, and sync any edit across every language variant of the page. diff --git a/fern/docs.yml b/fern/docs.yml index a402165d14..ba8ce4c29e 100644 --- a/fern/docs.yml +++ b/fern/docs.yml @@ -502,6 +502,14 @@ redirects: - source: /docs/server-sdks/reference/typescript/agents/swml-service/on-request destination: /docs/server-sdks/reference/typescript/agents/swml-service/set-on-request-callback + # The Python SDK removed its Twilio-compatibility REST namespace + # (`client.compat`, signalwire-python 3d08c96); the pages that documented it + # are gone. Send old URLs to the Python REST overview. + - source: /docs/server-sdks/reference/python/rest/compat + destination: /docs/server-sdks/reference/python/rest + - source: /docs/server-sdks/reference/python/rest/compat/:slug* + destination: /docs/server-sdks/reference/python/rest + # The prompt writing techniques guide duplicated the prompt engineering # overview; the additive parts were merged into it and the page removed. - source: /docs/platform/ai/prompt-engineering/best-practices diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/builtin-skills.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/builtin-skills.mdx index b09439ab89..7beca450a9 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/builtin-skills.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/builtin-skills.mdx @@ -418,8 +418,8 @@ Search SignalWire DataSphere documents. | Parameter | Type | Description | Default | |-----------|------|-------------|---------| | `space_name` | string | DataSphere space name | Required | -| `project_id` | string | Project ID (falls back to `SIGNALWIRE_PROJECT_ID`) | Required | -| `token` | string | API token (falls back to `SIGNALWIRE_TOKEN`) | Required | +| `project_id` | string | Project ID | Required | +| `token` | string | API token | Required | | `document_id` | string | Document ID to search within | Required | | `tool_name` | string | Custom function name | "search_knowledge" | | `count` | integer | Results to return (1-10) | 1 | diff --git a/fern/products/server-sdks/pages/guides/build-ai-agents/results-actions.mdx b/fern/products/server-sdks/pages/guides/build-ai-agents/results-actions.mdx index 99aa96584f..287d71151c 100644 --- a/fern/products/server-sdks/pages/guides/build-ai-agents/results-actions.mdx +++ b/fern/products/server-sdks/pages/guides/build-ai-agents/results-actions.mdx @@ -116,7 +116,7 @@ FunctionResult CheckOrder(Dictionary args, Dictionary @@ -62,7 +62,7 @@ const agents = await client.fabric.aiAgents.list(); console.log(agents); // Search for available phone numbers -const available = await client.phoneNumbers.search({ areaCode: '512' }); +const available = await client.phoneNumbers.search({ areacode: '512' }); console.log(available); ``` @@ -106,7 +106,7 @@ client = RestClient.new( agents = client.fabric.ai_agents.list puts agents -available = client.phone_numbers.search(area_code: '512') +available = client.phone_numbers.search(areacode: '512') puts available ``` @@ -144,7 +144,7 @@ my $client = SignalWire::Agents::RestClient->new( my $agents = $client->fabric->ai_agents->list; print $agents; -my $available = $client->phone_numbers->search(area_code => '512'); +my $available = $client->phone_numbers->search(areacode => '512'); print $available; ``` @@ -177,7 +177,7 @@ $agents = $client->fabric->aiAgents->list(); print_r($agents); // Search for available phone numbers -$available = $client->phoneNumbers->search(['area_code' => '512']); +$available = $client->phoneNumbers->search(['areacode' => '512']); print_r($available); ``` @@ -210,7 +210,7 @@ Console.WriteLine(available); | Language | Syntax | |----------|--------| -| Python | `SignalWireClient(project="...", token="...", host="...")` | +| Python | `RestClient(project="...", token="...", host="...")` | | TypeScript | `new RestClient({ project: '...', token: '...', host: '...' })` | {/* @@ -225,7 +225,7 @@ Console.WriteLine(available); */} ```python -client = SignalWireClient( +client = RestClient( project="your-project-id", token="your-api-token", host="your-space.signalwire.com", @@ -244,7 +244,7 @@ All credentials can be provided via environment variables: ```python # With env vars set, no arguments needed -client = SignalWireClient() +client = RestClient() ``` ### Namespaced Resources @@ -257,7 +257,8 @@ client.calling # REST-based call control (37 commands) client.phone_numbers # Search, purchase, manage numbers client.video # Rooms, sessions, recordings, conferences client.datasphere # Document management and semantic search -client.compat # Twilio-compatible LAML API +client.messages # Send SMS/MMS, redact sent messages +client.projects # Subprojects and signing keys client.logs # Message, voice, fax, conference logs client.registry # 10DLC brand/campaign management client.queues # Call queue management @@ -276,7 +277,7 @@ Most resources follow a standard CRUD pattern: | Operation | Python | |-----------|--------| | List | `client.phone_numbers.list()` | -| Create | `client.fabric.ai_agents.create(name="x")` | +| Create | `client.fabric.ai_agents.create(name="x", prompt=...)` | | Get | `client.fabric.ai_agents.get("id")` | | Update | `client.fabric.ai_agents.update("id", name="y")` | | Delete | `client.fabric.ai_agents.delete("id")` | @@ -295,7 +296,9 @@ Most resources follow a standard CRUD pattern: result = client.phone_numbers.list(page_size=10) # Create a resource -new = client.fabric.ai_agents.create(name="my-agent", type="ai_agent") +new = client.fabric.ai_agents.create( + name="my-agent", prompt={"text": "You are a helpful assistant."} +) # Get a single resource agent = client.fabric.ai_agents.get("resource-id") @@ -314,7 +317,9 @@ Manage SignalWire Fabric resources -- AI agents, SWML scripts, [subscribers](/do ```python # AI agents agents = client.fabric.ai_agents.list() -agent = client.fabric.ai_agents.create(name="support-bot", type="ai_agent") +agent = client.fabric.ai_agents.create( + name="support-bot", prompt={"text": "You are a support agent."} +) # SWML scripts scripts = client.fabric.swml_scripts.list() @@ -327,16 +332,18 @@ subs = client.fabric.subscribers.list() # Subscriber SIP endpoints endpoints = client.fabric.subscribers.list_sip_endpoints("subscriber-id") -client.fabric.subscribers.create_sip_endpoint("subscriber-id", username="ext100") +client.fabric.subscribers.create_sip_endpoint( + "subscriber-id", username="ext100", password="a-strong-password" +) # Call flows with versioning flows = client.fabric.call_flows.list() versions = client.fabric.call_flows.list_versions("flow-id") -client.fabric.call_flows.deploy_version("flow-id", version_id="v2") +client.fabric.call_flows.deploy_version("flow-id", {"call_flow_version_id": "v2"}) # Tokens (subscriber, guest, invite, embed) -token = client.fabric.tokens.create_subscriber_token(subscriber_id="sub-id") -guest = client.fabric.tokens.create_guest_token(name="Guest User") +token = client.fabric.tokens.create_subscriber_token(reference="sub-id") +guest = client.fabric.tokens.create_guest_token(allowed_addresses=["address-id"]) ``` ### Phone Numbers @@ -346,8 +353,8 @@ Search, purchase, and manage phone numbers: ```python # Search for available numbers available = client.phone_numbers.search( - area_code="512", - quantity=5, + areacode="512", + max_results=5, ) # List your numbers @@ -367,8 +374,8 @@ REST-based call control with 37+ commands. All commands are dispatched via POST: ```python # Initiate a call result = client.calling.dial( - call_id="call-id", - devices=[[{"type": "phone", "params": {"to_number": "+15559876543"}}]], + from_="+15559876543", + to="+15551234567", ) # Play audio on a call @@ -377,7 +384,7 @@ client.calling.play(call_id="call-id", play=[ ]) # Record a call -client.calling.record(call_id="call-id", record={"audio": {}}) +client.calling.record(call_id="call-id", audio={}) # Control playback client.calling.play_pause(call_id="call-id", control_id="ctrl-id") @@ -399,7 +406,7 @@ Manage video rooms, conferences, sessions, and recordings: ```python # Create a video room -room = client.video.rooms.create(name="standup", max_participants=10) +room = client.video.rooms.create(name="standup", max_members=10) # List room sessions sessions = client.video.room_sessions.list() @@ -485,28 +492,24 @@ order = client.registry.campaigns.create_order( ) ``` -### Compatibility (LAML) Namespace +### Messages -Twilio-compatible REST API for migrating existing applications: +Send an SMS or MMS and redact a sent message's body: ```python -# List calls -calls = client.compat.calls.list() - -# Send an SMS -msg = client.compat.messages.create( - To="+15559876543", - From="+15551234567", - Body="Hello from SignalWire!", +# Send a message +msg = client.messages.create( + to="+15559876543", + from_="+15551234567", + body="Your table is ready.", ) -# Manage phone numbers -numbers = client.compat.phone_numbers.list() - -# Start call recording -client.compat.calls.start_recording("call-sid") +# Redact the body after delivery +client.messages.update(msg["id"], body="") ``` +To query message history, use `client.logs.messages` instead. + ### Other Resources ```python @@ -523,11 +526,11 @@ info = client.lookup.phone_number("+15551234567") # Multi-factor authentication client.mfa.sms(to="+15551234567", from_="+15550000000", message="Your code: {code}") -client.mfa.verify(request_id="req-id", token="123456") +client.mfa.verify("req-id", token="123456") # SIP profile profile = client.sip_profile.get() -client.sip_profile.update(username="my-sip-user") +client.sip_profile.update(domain_identifier="my-sip-domain") # Verified caller IDs callers = client.verified_callers.list() @@ -535,36 +538,45 @@ callers = client.verified_callers.list() ### Pagination -For endpoints that return paginated results, use `PaginatedIterator`: +`list()` returns a single page. Most list resources also expose `paginate()`, +which follows `links.next` and yields every item across all pages: ```python -from signalwire.rest._pagination import PaginatedIterator - # Iterate all phone numbers across pages -for number in PaginatedIterator( - client._http, - "/api/relay/rest/phone_numbers", - data_key="data", -): +for number in client.phone_numbers.paginate(): print(number["name"], number["number"]) ``` -The iterator automatically follows `links.next` URLs to fetch subsequent pages. +### Timeouts and retries + +Pass a `RequestOptions` to the client for a default timeout and retry policy, or +to any method for a one-off override: + +```python +from signalwire.rest import RestClient, RequestOptions + +client = RestClient(request_options=RequestOptions(timeout=10.0, retries=3)) +numbers = client.phone_numbers.list(request_options=RequestOptions(timeout=60.0)) +``` ### Error Handling -REST errors raise `SignalWireRestError`: +REST errors raise `SignalWireRestError`. A request that never reaches the server +raises `SignalWireRestTransportError`, a subclass with `status_code` set to +`None`, so one `except` covers both. The error carries the platform +`request_id` for support correlation. ```python -from signalwire.rest import SignalWireClient, SignalWireRestError +from signalwire.rest import RestClient, SignalWireRestError -client = SignalWireClient() +client = RestClient() try: client.phone_numbers.get("nonexistent-id") except SignalWireRestError as e: print(f"HTTP {e.status_code}: {e.body}") print(f"URL: {e.method} {e.url}") + print(f"Request ID: {e.request_id}") ``` ### Practical Example: Provision and Configure @@ -573,12 +585,12 @@ except SignalWireRestError as e: #!/usr/bin/env python3 """Provision a phone number and assign it to an AI agent.""" -from signalwire.rest import SignalWireClient, SignalWireRestError +from signalwire.rest import RestClient, SignalWireRestError -client = SignalWireClient() +client = RestClient() # Search for a local number -available = client.phone_numbers.search(area_code="512", quantity=1) +available = client.phone_numbers.search(areacode="512", max_results=1) numbers = available.get("data", []) if not numbers: diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/add-answer-verb.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/add-answer-verb.mdx index da12f10b04..ed9a8ccf3a 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-base/add-answer-verb.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/add-answer-verb.mdx @@ -12,7 +12,7 @@ behavior such as setting a maximum call duration. ## **Parameters** - + Answer verb configuration (e.g., `{"max_duration": 3600}`). diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/add-function-include.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/add-function-include.mdx index a804b80a98..85df8f56cf 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-base/add-function-include.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/add-function-include.mdx @@ -28,7 +28,7 @@ See the [SWML SWAIG includes reference][swml-swaig-includes-reference] for detai List of function names to include from the remote server. - + Optional metadata dictionary passed along with the function include. Can be used to provide authentication tokens or context to the remote server. diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/add-language.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/add-language.mdx index f5713e0afe..df6f5e54de 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-base/add-language.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/add-language.mdx @@ -43,26 +43,26 @@ engine that can change. `"en-US-Neural2-F"` — is resolved against a default engine, and that default can change. - + Filler phrases used during natural speech pauses (e.g., `["Um...", "Let me see..."]`). - + Filler phrases spoken while executing SWAIG functions (e.g., `["One moment please...", "Looking that up..."]`). - + Explicit TTS engine name (e.g., `"elevenlabs"`, `"rime"`). Overrides the combined string format if provided. - + Explicit TTS model name (e.g., `"eleven_turbo_v2_5"`, `"coda"`). Overrides the combined string format if provided. - + Per-language params dict for engine-specific tuning and voice settings. Emitted as the language object's `params` key in SWML, and only included when non-empty (e.g., `{"stability": 0.5, "similarity_boost": 0.75}`). diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/add-mcp-server.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/add-mcp-server.mdx index 1ef2c789b4..563acb4c6c 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-base/add-mcp-server.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/add-mcp-server.mdx @@ -28,7 +28,7 @@ agent's own tools **as** an MCP server, use MCP server HTTP endpoint URL. - + Optional HTTP headers sent with every request to the MCP server (e.g., `{"Authorization": "Bearer sk-xxx"}`). @@ -37,7 +37,7 @@ agent's own tools **as** an MCP server, use Whether to fetch the server's resources into the agent's `global_data`. - + Variables for URI template substitution when fetching resources. Supports SignalWire call variables such as `${caller_id_number}`. diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/add-per-call-config.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/add-per-call-config.mdx new file mode 100644 index 0000000000..f437520db7 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/add-per-call-config.mdx @@ -0,0 +1,54 @@ +--- +title: "add_per_call_config" +slug: /reference/python/agents/agent-base/add-per-call-config +description: Register a per-request configuration callback without replacing callbacks already set. +max-toc-depth: 3 +--- + +[ref-agentbase]: /docs/server-sdks/reference/python/agents/agent-base +[set-dynamic-config-callback]: /docs/server-sdks/reference/python/agents/agent-base/set-dynamic-config-callback + +Register a per-request configuration callback, keeping any already registered. +Same signature and contract as +[`set_dynamic_config_callback()`][set-dynamic-config-callback], except that +callbacks accumulate instead of overwriting. They run in registration order +against the same ephemeral agent, so a later callback sees what an earlier one +configured and can build on or override it. + +Prefer this form when composing. A base class and a subclass, or an agent and a +mixin, can each register what they own without knowing about the other. With +`set_dynamic_config_callback()` the second registration silently drops the +first. + +## Parameters + + + A function with the signature `(query_params, body_params, headers, agent)`. + `agent` is the ephemeral per-request copy. Configure that object, never + `self`, or the configuration leaks across callers. + + +## Returns + +[`AgentBase`][ref-agentbase] -- Returns self for method chaining. + +## Example + +```python {6-14} +from signalwire import AgentBase + +agent = AgentBase(name="dispatch", route="/dispatch") +agent.set_prompt_text("You are Ada, the dispatcher for Bayview Taxi.") + +def pick_language(query_params, body_params, headers, agent): + if query_params.get("lang") == "es": + agent.add_language("Spanish", "es-MX", "rime.marsh") + +def tag_tenant(query_params, body_params, headers, agent): + agent.set_global_data({"tenant": query_params.get("tenant", "default")}) + +agent.add_per_call_config(pick_language) +agent.add_per_call_config(tag_tenant) + +agent.serve() +``` diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/add-skill.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/add-skill.mdx index 1c5911bc58..b2573e43bb 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-base/add-skill.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/add-skill.mdx @@ -25,7 +25,7 @@ Raises `ValueError` if the skill is not found or fails to load. Use Registered skill name (e.g., `"datetime"`, `"web_search"`, `"math"`). - + Skill-specific configuration parameters. Each skill documents its own supported parameters. diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/as-router.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/as-router.mdx index fc365d1817..f582c3dee7 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-base/as-router.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/as-router.mdx @@ -22,8 +22,9 @@ None. ## **Returns** -`APIRouter` -- A FastAPI router with all agent endpoints (SWML delivery, SWAIG -function handling, post-prompt, debug events, etc.). +`HostAppRouter` -- A FastAPI `APIRouter` subclass with all agent endpoints (SWML +delivery, SWAIG function handling, post-prompt, debug events, etc.). It adds no +behavior; the subclass exists to give the return type a stable name. ## **Example** diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/define-contexts.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/define-contexts.mdx index c90e1c4eb9..c8233d88fb 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-base/define-contexts.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/define-contexts.mdx @@ -24,7 +24,7 @@ sections and raw text cannot be mixed in the main prompt. ## **Parameters** - + Context configuration. Pass a dictionary or `ContextBuilder` to set contexts directly. Omit to receive a `ContextBuilder` for fluent definition. diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/define-tool.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/define-tool.mdx index 6148f9f2be..3785effd3f 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-base/define-tool.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/define-tool.mdx @@ -54,16 +54,16 @@ comes from external configuration. Whether to require token validation on tool calls. Recommended for production. - + Language-specific filler phrases spoken while the function executes. Format: `{"en-US": ["Looking that up...", "One moment..."]}`. - + External URL to forward the tool call to instead of executing locally. - + List of required parameter names from the JSON Schema. diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/get-app.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/get-app.mdx index f38075bc6a..324699635f 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-base/get-app.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/get-app.mdx @@ -12,6 +12,13 @@ and security headers -- the same configuration that `serve()` would create. This is primarily used with deployment adapters like Mangum (AWS Lambda) or when embedding the agent in a larger FastAPI application. + +To add routers or static files to the agent's own app, use +[`mount()`](/docs/server-sdks/reference/python/agents/agent-base/mount) rather +than `get_app().include_router(...)`. Routes added by hand land behind the +agent's catch-all route and never run. + + ## **Parameters** None. diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/get-language-params.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/get-language-params.mdx index c5a92dd537..bb0cca44dd 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-base/get-language-params.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/get-language-params.mdx @@ -26,7 +26,7 @@ See the [SWML languages reference][swml-languages-reference] for the full specif ## **Returns** -`Optional[dict[str, Any]]` -- The params dict if set, or `None` otherwise (including when +`dict[str, Any] | None` -- The params dict if set, or `None` otherwise (including when the code is unknown). ## **Example** diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/get-post-prompt.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/get-post-prompt.mdx index 6c24311b2f..48bec6e5f9 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-base/get-post-prompt.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/get-post-prompt.mdx @@ -13,7 +13,7 @@ None. ## **Returns** -`Optional[str]` -- The post-prompt text, or `None` if not set. +`str | None` -- The post-prompt text, or `None` if not set. ## **Example** diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/handle-request.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/handle-request.mdx new file mode 100644 index 0000000000..b3288573d8 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/handle-request.mdx @@ -0,0 +1,72 @@ +--- +title: "handle_request" +slug: /reference/python/agents/agent-base/handle-request +description: Dispatch one HTTP request to the agent without a web framework. +max-toc-depth: 3 +--- + +[on-swml-request]: /docs/server-sdks/reference/python/agents/agent-base/on-swml-request +[register-routing-callback]: /docs/server-sdks/reference/python/agents/agent-base/register-routing-callback +[serverless]: /docs/server-sdks/reference/python/agents/agent-base/serverless + +Dispatch a request over plain values instead of FastAPI objects. Performs proxy +detection, basic auth, the [routing callback][register-routing-callback] check, +and [`on_swml_request()`][on-swml-request] modification, then renders the SWML +document, mirroring the response the FastAPI routes produce for the same +request. Basic auth is always on: pass `basic_auth` to the constructor and send +a matching `Authorization` header, or the call returns `401`. + +Use it to serve an agent from a framework the SDK has no adapter for. For the +supported serverless platforms, use +[`handle_serverless_request()`][serverless]. + +## Parameters + + + HTTP method, such as `"GET"` or `"POST"`. + + + + The full request URL. Used for proxy detection and to match a registered + routing callback path. + + + + Request headers as a plain dictionary. + + + + The already-parsed JSON body for `POST` requests. + + +## Returns + +`tuple[int, dict[str, Any], str]` -- `(status_code, response_headers, body)`. + +- `200` with the SWML document as a JSON string. +- `307` with a `Location` header and an empty body when a routing callback + returned a destination. +- `401` with `WWW-Authenticate: Basic` and a JSON error when basic auth fails. + +## Example + +```python {9-17} +import base64 +import json +from signalwire import AgentBase + +agent = AgentBase(name="dispatch", route="/dispatch", basic_auth=("dispatch", "s3cret")) +agent.set_prompt_text("You are Ada, the dispatcher for Bayview Taxi.") + +credentials = base64.b64encode(b"dispatch:s3cret").decode() +status, headers, body = agent.handle_request( + "POST", + "https://bayview-taxi.example.com/dispatch", + { + "content-type": "application/json", + "authorization": f"Basic {credentials}", + }, + {"call": {"call_id": "abc-123"}}, +) +print(status, json.loads(body)["sections"]["main"][0]) +``` diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/index.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/index.mdx index 9bea49c054..47d0731c28 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-base/index.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/index.mdx @@ -129,7 +129,7 @@ supported parameters and behaviors. Unique identifier for this agent instance. Auto-generated as a UUID if not provided. - + The Prompt Object Model instance used for structured prompt building. `None` when `use_pom=False`. @@ -146,7 +146,7 @@ supported parameters and behaviors. instead of calling `prompt_add_section()` in the constructor. - + Explicit `(username, password)` for HTTP Basic Auth on all endpoints. If not set, credentials are read from `SWML_BASIC_AUTH_USER` / `SWML_BASIC_AUTH_PASSWORD` env vars, or auto-generated on startup. @@ -177,7 +177,7 @@ supported parameters and behaviors. Record in stereo (separate channels for each party) when `True`. - + Base URL for SWAIG function webhooks. If not set, the SDK auto-detects from the incoming request or uses `SWML_PROXY_URL_BASE`. @@ -194,18 +194,18 @@ supported parameters and behaviors. Allow dynamic per-request override of input checking behavior. - + Path to a JSON config file. If not provided, the SDK searches default paths. See [`ConfigLoader`][configloader]. - + List of native SWAIG function names to enable at construction time (e.g., `["check_time", "wait_for_user"]`). Can also be set later via [`set_native_functions()`][set-native-functions]. - + Path to a custom SWML schema file for validation. If not provided, the SDK searches default paths automatically. @@ -215,7 +215,7 @@ supported parameters and behaviors. env var. - + SignalWire Signing Key (Dashboard → API Credentials). When set, webhook signature validation is enforced on the `POST /`, `/swaig`, and `/post_prompt` endpoints, and unsigned or invalidly-signed requests receive an HTTP `403`. Falls back to the @@ -229,6 +229,16 @@ supported parameters and behaviors. because proxy headers are spoofable; opt in only when you control the proxy chain. + + Secret used to sign this agent's per-call SWAIG function tokens. Falls back to + the `SIGNALWIRE_SWAIG_SECRET` environment variable. When neither is set, a + random secret is generated per process, so tokens issued before a restart stop + verifying and callers mid-call see "the security token for this function is + invalid or expired" on their next tool call. Set it in production and whenever + more than one replica serves the same agent. Distinct from `signing_key`, which + validates inbound webhooks. + + When `signing_key` is set, the `POST /`, `/swaig`, and `/post_prompt` endpoints are signature-validated. The `X-SignalWire-Signature` request header carries the signature, @@ -262,16 +272,16 @@ JSON Schema from Python type hints on the function signature. #### Parameters - + Function name exposed to the AI. Defaults to the decorated function's `__name__`. - + What the function does. The AI reads this to decide when to call it. Defaults to the function's docstring, or `"Function {name}"` as a fallback. - + Explicit JSON Schema for function parameters. If omitted, the schema is automatically inferred from Python type hints on the decorated function. @@ -280,15 +290,15 @@ JSON Schema from Python type hints on the function signature. Require token validation on tool calls. - + Filler phrases by language code, spoken while the function runs. - + External webhook URL. If set, SignalWire calls this URL instead of executing locally. - + Required parameter names. Auto-inferred from type hints when not specified. @@ -424,6 +434,9 @@ agent.run() Add a speech recognition hint with pattern matching and replacement. + + Register an additional per-request configuration callback. + Add a SWML verb to run after the AI conversation ends. @@ -502,6 +515,9 @@ agent.run() Retrieve the current prompt configured on the agent. + + Dispatch one HTTP request without a web framework. + Check whether a specific skill is currently loaded on the agent. @@ -511,9 +527,15 @@ agent.run() Manually set the proxy URL base for webhook callbacks. + + Attach a router or ASGI app to the agent's web app. + Enable built-in native functions that execute directly on the SignalWire platform. + + Run a handler with the call log when a call ends. + Register a callback for debug events received at the /debug_events endpoint. @@ -580,6 +602,9 @@ agent.run() Replace all language configurations at once with a list of raw language dictionaries. + + Let the caller switch languages mid-call with one configuration object. + Set a single AI parameter by key. diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/mount.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/mount.mdx new file mode 100644 index 0000000000..296b4df301 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/mount.mdx @@ -0,0 +1,63 @@ +--- +title: "mount" +slug: /reference/python/agents/agent-base/mount +description: Attach an extra router or ASGI app to the agent's web app without shadowing its routes. +max-toc-depth: 3 +--- + +[ref-agentbase]: /docs/server-sdks/reference/python/agents/agent-base +[get-app]: /docs/server-sdks/reference/python/agents/agent-base/get-app +[chat-gateway]: /docs/server-sdks/reference/python/agents/chat-gateway + +Mount an extra router or ASGI app alongside this agent's own routes. Use it +instead of [`get_app()`][get-app] followed by `include_router()` or `mount()` +by hand, which fails silently in three ways: + +- Anything mounted after `serve()` starts is lost, because `serve()` builds a + fresh app when none exists. This method materializes the app first so a later + `serve()` reuses it. +- The agent registers a catch-all route, and FastAPI matches routes in + registration order, so any route added afterwards is shadowed and never runs. + This method moves the catch-all back to the end. +- The app that `get_app()` builds answers the agent's bare route (no trailing + slash) with `204` instead of SWML. This method re-registers that route, so the + URL the platform fetches keeps working. + +## Parameters + + + A FastAPI `APIRouter`, included at `prefix`, or any other ASGI app such as + `StaticFiles`, mounted at `prefix`. + + + + Path prefix, without a trailing slash. Keyword-only. + + + + Mount name. Used only for ASGI apps. Keyword-only. + + +## Returns + +[`AgentBase`][ref-agentbase] -- Returns self for method chaining. + +## Example + +```python {11-12} +from fastapi.staticfiles import StaticFiles +from signalwire import AgentBase +from signalwire.ai_chat import ChatGateway + +agent = AgentBase(name="dispatch", route="/dispatch") +gateway = ChatGateway( + config_url="https://bayview-taxi.example.com/dispatch", + key="pk_your_publishable_key", +) + +agent.mount(gateway.router(), prefix="/chat") +agent.mount(StaticFiles(directory="web", html=True), prefix="/demo") +agent.serve() +``` + +See [`ChatGateway`][chat-gateway] for what the mounted router serves. diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/on-call-end.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/on-call-end.mdx new file mode 100644 index 0000000000..33f9ddd15c --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/on-call-end.mdx @@ -0,0 +1,59 @@ +--- +title: "on_call_end" +slug: /reference/python/agents/agent-base/on-call-end +description: Register a handler that receives the conversation transcript when a call ends. +max-toc-depth: 3 +--- + +[on-summary]: /docs/server-sdks/reference/python/agents/agent-base/on-summary +[post-prompt]: /docs/server-sdks/reference/python/core/post-prompt/normalize-post-prompt + +Register a handler that runs when the call ends, with the transcript. Usable as +a decorator or called directly. Handlers run in registration order. + +Under the hood this registers the platform's reserved `hangup_hook` function, +which fires on hangup and is never offered to the model, so it can't be called +early or skipped. Registering a handler also turns on the +`swaig_post_conversation` parameter. Without it the hook still fires but +carries no transcript, and the handler would receive an empty list forever +with nothing to indicate why. If you have explicitly set that parameter to +`False`, the SDK leaves it alone and logs a warning. + +The handler's return value is ignored, since the call is over. Exceptions are +caught and logged rather than raised, so a failing handler doesn't turn into a +failed hangup. For the post-prompt summary, see [`on_summary()`][on-summary]. + +## Parameters + + + Called as `handler(call_log, raw_data)`. + + - `call_log` -- the conversation as the platform recorded it, already resolved + from whichever field carried it. + - `raw_data` -- the complete SWAIG request, including `global_data` and + `call_id`. + + +## Returns + +The handler, unchanged, so the method works as a decorator. + +## Example + +```python {6-10} +from signalwire import AgentBase + +agent = AgentBase(name="dispatch", route="/dispatch") +agent.set_prompt_text("You are Ada, the dispatcher for Bayview Taxi.") + +@agent.on_call_end +def archive(call_log, raw_data): + conversation_id = raw_data.get("global_data", {}).get("conversation_id") + # Write the transcript to your system of record. + print(conversation_id, len(call_log), "turns") + +agent.serve() +``` + +To handle voice and chat transcripts with one shape, pass `raw_data` through +[`normalize_post_prompt()`][post-prompt]. diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/on-function-call.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/on-function-call.mdx index c4bf7dbf3d..b82cb5ca48 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-base/on-function-call.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/on-function-call.mdx @@ -37,7 +37,7 @@ This method **is** the tool dispatch mechanism. If you override it without calli Arguments passed by the AI, conforming to the function's parameter schema. - + The complete raw POST data from the SWAIG request, including metadata such as `call_id`, `caller_id_number`, and `global_data`. diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/on-summary.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/on-summary.mdx index 92fd0ce41e..fccb5de0ea 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-base/on-summary.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/on-summary.mdx @@ -16,6 +16,11 @@ A post-prompt must be configured via [`set_post_prompt()`][set-post-prompt] for summaries to be generated. +For the full transcript at hangup rather than the summary, register +[`on_call_end()`](/docs/server-sdks/reference/python/agents/agent-base/on-call-end). +To read voice and chat post-prompt bodies with one shape, see +[`normalize_post_prompt()`](/docs/server-sdks/reference/python/core/post-prompt/normalize-post-prompt). + The default implementation does nothing. You must override it in a subclass or set a [`set_post_prompt_url()`][set-post-prompt-url] @@ -24,12 +29,12 @@ to receive summaries at an external endpoint. ## **Parameters** - + The summary object generated by the AI based on your post-prompt instructions. `None` if no summary could be extracted from the response. - + The complete raw POST data from the post-prompt request, including metadata like `call_id` and the full AI response. diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/on-swml-request.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/on-swml-request.mdx index 55f4afb300..abd8d569de 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-base/on-swml-request.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/on-swml-request.mdx @@ -27,22 +27,22 @@ adds support for dynamic configuration and ephemeral agent copies. ## **Parameters** - + Parsed POST body from the incoming request, if available. - + The path segment that triggered this request. - + The FastAPI `Request` object, providing access to query parameters, headers, and other HTTP metadata. ## **Returns** -`Optional[dict]` -- A dictionary of modifications to apply to the SWML document, +`dict | None` -- A dictionary of modifications to apply to the SWML document, or `None` for no modifications. The keys and structure depend on the rendering pipeline. diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/prompt-add-section.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/prompt-add-section.mdx index f89ae4c154..0db8507819 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-base/prompt-add-section.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/prompt-add-section.mdx @@ -26,7 +26,7 @@ approach or the other. Section body text. - + List of bullet point strings. @@ -38,7 +38,7 @@ approach or the other. Whether bullet points should be numbered instead of bulleted. - + List of subsection dictionaries, each with `title`, `body`, and optional `bullets`. diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/prompt-add-subsection.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/prompt-add-subsection.mdx index 52a04bb4fe..32b2576929 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-base/prompt-add-subsection.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/prompt-add-subsection.mdx @@ -24,7 +24,7 @@ created automatically. Subsection body text. - + Subsection bullet points. diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/prompt-add-to-section.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/prompt-add-to-section.mdx index 5cbcc2caa6..94674a6e4f 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-base/prompt-add-to-section.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/prompt-add-to-section.mdx @@ -16,15 +16,15 @@ automatically. Title of the section to update (or create). - + Text to append to the section body. - + A single bullet point to add. - + Multiple bullet points to add. diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/register-routing-callback.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/register-routing-callback.mdx index b216a10a78..2e22b1fbda 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-base/register-routing-callback.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/register-routing-callback.mdx @@ -24,10 +24,11 @@ callbacks before starting the server. ## **Parameters** - - A function that receives a FastAPI `Request` and the parsed JSON body as a `dict`. - Return a route string to redirect the request (using HTTP 307 to preserve the POST - method and body), or return `None` to continue with normal SWML document serving. + + A function that receives the parsed JSON body and the request headers, both as a + `dict` — `callback_fn(body, headers)`. Return a route string to redirect the request + (using HTTP 307 to preserve the POST method and body), or return `None` to continue + with normal SWML document serving. @@ -48,7 +49,7 @@ from signalwire.core.swml_service import SWMLService agent = AgentBase(name="router", route="/") agent.set_prompt_text("You are a helpful assistant.") -def route_sip_call(request, body): +def route_sip_call(body, headers): username = SWMLService.extract_sip_username(body) if username == "sales": return "/agents/sales" diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/run.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/run.mdx index 12d2d501e4..bae41b2a83 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-base/run.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/run.mdx @@ -21,16 +21,16 @@ development, Docker, and serverless deployments without changes. ## **Parameters** - + Serverless event object. Pass the Lambda event, Cloud Functions request, or Azure Functions HttpRequest here. - + Serverless context object (Lambda context, etc.). - + Override automatic environment detection. Valid values: - `"server"` -- Force web server mode - `"lambda"` -- Force AWS Lambda mode @@ -39,18 +39,19 @@ development, Docker, and serverless deployments without changes. - `"azure_function"` -- Force Azure Functions mode - + Host override for server mode. - + Port override for server mode. ## **Returns** -`Optional[dict]` -- In serverless modes, returns the platform-specific response object. -In server mode, blocks until shutdown and returns `None`. +`str | dict[str, Any] | None` -- In serverless modes, returns the platform-specific +response object: a `str` in CGI mode, a `dict` otherwise. In server mode, blocks +until shutdown and returns `None`. ## **Examples** diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/serve.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/serve.mdx index 34dd40951e..3cfb55f61d 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-base/serve.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/serve.mdx @@ -28,11 +28,11 @@ The server automatically includes: ## **Parameters** - + Host override. Defaults to the value set in the constructor. - + Port override. Defaults to the value set in the constructor. diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/serverless.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/serverless.mdx index 8f8c1bd1bc..461d5de16a 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-base/serverless.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/serverless.mdx @@ -29,7 +29,7 @@ Azure Functions (HttpRequest/HttpResponse), and CGI. ## **Parameters** - + Platform-specific event or request object: - **Lambda**: The event dictionary from the Lambda handler - **Google Cloud Functions**: The Flask `request` object @@ -37,11 +37,11 @@ Azure Functions (HttpRequest/HttpResponse), and CGI. - **CGI**: Not used (reads from `stdin` and environment variables) - + Platform-specific context object (Lambda context, etc.). - + Override the auto-detected execution mode. - `"cgi"` -- CGI gateway interface diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/set-dynamic-config-callback.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/set-dynamic-config-callback.mdx index 8661b934ea..7d383b574d 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-base/set-dynamic-config-callback.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/set-dynamic-config-callback.mdx @@ -6,6 +6,7 @@ max-toc-depth: 3 --- [ref-agentbase]: /docs/server-sdks/reference/python/agents/agent-base +[add-per-call-config]: /docs/server-sdks/reference/python/agents/agent-base/add-per-call-config Set a callback function that runs on every incoming request, receiving an ephemeral copy of the agent so you can dynamically configure **any** aspect of it -- skills, @@ -14,6 +15,13 @@ query parameters, body, or headers. This is the primary mechanism for multi-tenant or per-caller customization. + +A second call replaces the first without warning: the agent still renders valid +SWML, but whatever the discarded callback configured is absent. To register +several callbacks that run in order, use +[`add_per_call_config()`][add-per-call-config]. + + The `agent` argument passed to the callback is an **ephemeral copy** of the original agent. Changes made inside the callback apply only to the current request and do not diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/set-languages.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/set-languages.mdx index 439d9eafdd..a5e8a039ed 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-base/set-languages.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/set-languages.mdx @@ -8,6 +8,9 @@ max-toc-depth: 3 [ref-agentbase]: /docs/server-sdks/reference/python/agents/agent-base Replace all language configurations at once with a list of raw language dictionaries. +To let the caller switch languages mid-call instead, use +[`set_multilingual()`](/docs/server-sdks/reference/python/agents/agent-base/set-multilingual); +the two are mutually exclusive. ## **Parameters** diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/set-multilingual.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/set-multilingual.mdx new file mode 100644 index 0000000000..298f716dca --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/set-multilingual.mdx @@ -0,0 +1,51 @@ +--- +title: "set_multilingual" +slug: /reference/python/agents/agent-base/set-multilingual +description: Let the caller switch languages mid-call by configuring recognizer-driven multilingual mode. +max-toc-depth: 3 +--- + +[ref-agentbase]: /docs/server-sdks/reference/python/agents/agent-base +[set-languages]: /docs/server-sdks/reference/python/agents/agent-base/set-languages +[add-language]: /docs/server-sdks/reference/python/agents/agent-base/add-language +[swml-multilingual]: /docs/swml/reference/calling/ai/multilingual + +Configure recognizer-driven multilingual mode. The speech recognizer runs in +code-switching mode and the agent answers in whichever language the caller +actually spoke; the model doesn't pick the language. The SDK emits the object +as the top-level `multilingual` key of the AI verb. + +This is mutually exclusive with [`set_languages()`][set-languages] and +[`add_language()`][add-language]. If both are set, the platform uses +`multilingual` and ignores `languages`. + +## Parameters + + + The multilingual configuration object, passed through unchanged. See the + [SWML `multilingual` reference][swml-multilingual] for its keys, including + the language list, the starting language, and switching thresholds. + + +## Returns + +[`AgentBase`][ref-agentbase] -- Returns self for method chaining. + +## Example + +```python {5-13} +from signalwire import AgentBase + +agent = AgentBase(name="dispatch", route="/dispatch") +agent.set_prompt_text("You are Ada, the dispatcher for Bayview Taxi.") +agent.set_multilingual({ + "start_language": "en", + "allowed": ["en", "es", "fr"], + "languages": [ + {"language": "default", "voice": "elevenlabs.rachel"}, + {"language": "es", "voice": "elevenlabs.maria"}, + {"language": "fr", "voice": "gcloud.fr-FR-Neural2-B"}, + ], +}) +agent.serve() +``` diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-base/set-prompt-pom.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-base/set-prompt-pom.mdx index 912d447f6c..f4cd02cfb9 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-base/set-prompt-pom.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-base/set-prompt-pom.mdx @@ -21,8 +21,10 @@ more reliably than flat text. ## **Parameters** - - POM dictionary structure. Each item in the list is a section with keys: + + POM structure. A list of section dictionaries is converted to a + `PromptObjectModel` before it is stored; an existing `PromptObjectModel` is + accepted as-is. Each section dictionary has keys: - `title` (str) -- Section heading - `body` (str) -- Section body text - `bullets` (list[str]) -- Optional bullet points diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-server/register.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-server/register.mdx index 54817da84a..dc8ba4eaf4 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-server/register.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-server/register.mdx @@ -22,7 +22,7 @@ Registering a duplicate route raises `ValueError`. Each route can only host one subclass. - + URL path prefix for this agent (e.g., `"/sales"`). If omitted, the agent's own `route` property is used. Leading slashes are added and trailing slashes are stripped automatically. diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-server/routing-callback.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-server/routing-callback.mdx index 3445874bee..ff76950576 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-server/routing-callback.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-server/routing-callback.mdx @@ -17,10 +17,10 @@ for example, routing based on HTTP headers, query parameters, or request body co ## **Parameters** - - A function that receives a FastAPI `Request` object and the parsed request body `dict`. - Return a route string (e.g., `"/sales"`) to redirect, or `None` to let the current - agent handle the request. + + A function that receives the parsed request body and the request headers, both as a + `dict` — `callback_fn(body, headers)`. Return a route string (e.g., `"/sales"`) to + redirect, or `None` to let the current agent handle the request. @@ -38,9 +38,9 @@ for example, routing based on HTTP headers, query parameters, or request body co from signalwire import AgentServer from signalwire import AgentBase -def route_by_language(request, body): +def route_by_language(body, headers): """Route to different agents based on Accept-Language header.""" - lang = request.headers.get("Accept-Language", "en") + lang = headers.get("Accept-Language", "en") if lang.startswith("es"): return "/spanish-agent" elif lang.startswith("fr"): diff --git a/fern/products/server-sdks/pages/reference/python/agents/agent-server/run.mdx b/fern/products/server-sdks/pages/reference/python/agents/agent-server/run.mdx index c068760d9f..5dc6ebb0d1 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/agent-server/run.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/agent-server/run.mdx @@ -16,21 +16,21 @@ another ASGI server, use `server.app` directly instead of calling `run()`. ## **Parameters** - + Serverless event object (AWS Lambda, Google Cloud Functions). Pass the Lambda handler's `event` parameter here. Ignored in server mode. - + Serverless context object (AWS Lambda, Google Cloud Functions). Pass the Lambda handler's `context` parameter here. Ignored in server mode. - + Override the host set in the constructor. Only applies in server mode. - + Override the port set in the constructor. Only applies in server mode. diff --git a/fern/products/server-sdks/pages/reference/python/agents/ai-chat-client/chat.mdx b/fern/products/server-sdks/pages/reference/python/agents/ai-chat-client/chat.mdx index ee7b9716a6..2f698a7338 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/ai-chat-client/chat.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/ai-chat-client/chat.mdx @@ -27,16 +27,16 @@ agent makes along the way, so expect seconds rather than milliseconds. said. - + Creates the conversation if it does not exist yet. Saves a call, at the cost of never receiving `initial_message`, so the agent does not speak first. - + Applies only when this call creates the conversation. - + Applies only when this call creates the conversation. diff --git a/fern/products/server-sdks/pages/reference/python/agents/ai-chat-client/create-conversation.mdx b/fern/products/server-sdks/pages/reference/python/agents/ai-chat-client/create-conversation.mdx index 37ec6faadc..6c26ac1f1b 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/ai-chat-client/create-conversation.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/ai-chat-client/create-conversation.mdx @@ -22,16 +22,16 @@ already exists returns that conversation untouched. from the public internet. - + An opening message from the user, sent as part of creating the conversation. - + Idle seconds before the conversation ends. Sent as `conversation_timeout`; the service default is 3600. - + Arbitrary data about the user, echoed back on this conversation's webhooks. Sent as `user_meta_data`. diff --git a/fern/products/server-sdks/pages/reference/python/agents/ai-chat-client/index.mdx b/fern/products/server-sdks/pages/reference/python/agents/ai-chat-client/index.mdx index d604dfe592..0de8ee67bd 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/ai-chat-client/index.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/ai-chat-client/index.mdx @@ -35,23 +35,26 @@ pip install signalwire-sdk ## **Parameters** - + Your project ID. Falls back to `SIGNALWIRE_PROJECT_ID`. Raises `ValueError` when neither is set. - + An API token with the `chat` scope. Falls back to `SIGNALWIRE_API_TOKEN`. - - Your Space name, used to build the service URL. Falls back to `SIGNALWIRE_SPACE`. + + Your space name, `your-space` rather than `your-space.signalwire.com`, used to build + the service URL. Falls back to `SIGNALWIRE_SPACE`. `RestClient` reads that variable + as a full hostname, so a value set for REST builds a wrong URL here; pass `space` or + `url` explicitly in that case. - + The service URL, used verbatim. Overrides `space`. Raises `ValueError` when neither is available. - + An existing session to send requests on. When omitted, the client creates and owns one, and `close()` closes it. Pass your own to control connection pooling or timeouts. diff --git a/fern/products/server-sdks/pages/reference/python/agents/ai-chat-client/summarize.mdx b/fern/products/server-sdks/pages/reference/python/agents/ai-chat-client/summarize.mdx index c1f212186c..3c08d0ad84 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/ai-chat-client/summarize.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/ai-chat-client/summarize.mdx @@ -17,7 +17,7 @@ conversation. The conversation to summarize. - + How to summarize. Overrides the [`post_prompt`][post-prompt] text in your SWML for this call only. diff --git a/fern/products/server-sdks/pages/reference/python/agents/chat-gateway/index.mdx b/fern/products/server-sdks/pages/reference/python/agents/chat-gateway/index.mdx index 37818571d2..c2cfc100fc 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/chat-gateway/index.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/chat-gateway/index.mdx @@ -13,6 +13,8 @@ max-toc-depth: 3 [visiblemessages]: /docs/server-sdks/reference/python/agents/chat-gateway/visible-messages [lastactivity]: /docs/server-sdks/reference/python/agents/chat-gateway/last-activity [close]: /docs/server-sdks/reference/python/agents/chat-gateway/close +[handoffrouter]: /docs/server-sdks/reference/python/agents/handoff-router +[mount]: /docs/server-sdks/reference/python/agents/agent-base/mount A chat widget in a page cannot hold a SignalWire API token: the token carries the whole project, and every visitor could read it. `ChatGateway` mounts inside a web application you already run, holds the @@ -35,7 +37,13 @@ app.include_router(gateway.router(), prefix="/chat") ``` It mounts on any FastAPI app. An agent already serves one, so this costs no new infrastructure: -`agent.get_app().include_router(gateway.router(), prefix="/chat")`. +`agent.mount(gateway.router(), prefix="/chat")` (see [`mount()`][mount]). + + +The SignalWire address widget also calls `/handoff`, `/escalate`, and `/say` at the same URL to +move a conversation between chat and a phone call. [`HandoffRouter`][handoffrouter] serves those +three routes; mount it at the same prefix as the gateway. + ## **Parameters** @@ -46,7 +54,7 @@ Keyword-only. whoever holds a key cannot choose which agent runs. - + The publishable key the widget carries. Falls back to `SIGNALWIRE_CHAT_GATEWAY_KEY`, then to a generated `pk_` value, which is useful only for a process that also serves the page and can embed it. @@ -57,11 +65,11 @@ Keyword-only. unconfigured; anything else must be listed, so nothing ships open by accident. - + The [`AIChatClient`][aichatclient] to forward on. Built from the environment when omitted. - + HMAC key for signing handles. Falls back to `SIGNALWIRE_CHAT_GATEWAY_SECRET`, then to a random per-process value. @@ -71,7 +79,7 @@ Keyword-only. left open overnight expires. - + Idle seconds before the service ends a conversation, passed on every create. `None` leaves it to the service default of 3600. Set here rather than in the page, because the JSON-RPC result exposes neither the deadline nor the server's clock, so a browser cannot discover it and two places holding diff --git a/fern/products/server-sdks/pages/reference/python/agents/chat-gateway/mint-handle.mdx b/fern/products/server-sdks/pages/reference/python/agents/chat-gateway/mint-handle.mdx index bce760e40a..007b04cf87 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/chat-gateway/mint-handle.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/chat-gateway/mint-handle.mdx @@ -20,7 +20,7 @@ conversation your server already started. ## **Parameters** - + The conversation to bind the handle to. Generates a random id when omitted. diff --git a/fern/products/server-sdks/pages/reference/python/agents/chat-gateway/router.mdx b/fern/products/server-sdks/pages/reference/python/agents/chat-gateway/router.mdx index 9834c3bb07..c33b500667 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/chat-gateway/router.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/chat-gateway/router.mdx @@ -6,6 +6,8 @@ max-toc-depth: 3 --- [ref-chatgateway]: /docs/server-sdks/reference/python/agents/chat-gateway +[mount]: /docs/server-sdks/reference/python/agents/agent-base/mount +[handoffrouter]: /docs/server-sdks/reference/python/agents/handoff-router Return an `APIRouter` exposing this gateway, ready to hand to `include_router`. It serves `POST /` for the four browser methods and `OPTIONS /` for the CORS preflight. @@ -43,9 +45,10 @@ gateway = ChatGateway( app.include_router(gateway.router(), prefix="/chat") ``` -An agent already serves a FastAPI app, so it can host the gateway too: +An agent already serves a FastAPI app, so it can host the gateway too. Use +[`mount()`][mount], which keeps the new routes ahead of the agent's catch-all: -```python {4} +```python {9} import os agent = MyAgent() @@ -54,6 +57,9 @@ gateway = ChatGateway( secret=os.environ["SIGNALWIRE_CHAT_GATEWAY_SECRET"], ) -agent.get_app().include_router(gateway.router(), prefix="/chat") +agent.mount(gateway.router(), prefix="/chat") agent.run() ``` + +To let the widget move a conversation to a phone call and back, mount a +[`HandoffRouter`][handoffrouter] at the same prefix. diff --git a/fern/products/server-sdks/pages/reference/python/agents/cli/sw-agent-dokku.mdx b/fern/products/server-sdks/pages/reference/python/agents/cli/sw-agent-dokku.mdx index 1abfd9c4d0..d573200e6c 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/cli/sw-agent-dokku.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/cli/sw-agent-dokku.mdx @@ -194,7 +194,7 @@ sw-agent-dokku config set \ SWML_BASIC_AUTH_PASSWORD=secure-password \ SIGNALWIRE_SPACE_NAME=my-space \ SIGNALWIRE_PROJECT_ID=my-project-id \ - SIGNALWIRE_TOKEN=my-token + SIGNALWIRE_API_TOKEN=my-token # 3. Deploy sw-agent-dokku deploy @@ -202,3 +202,7 @@ sw-agent-dokku deploy # 4. Monitor sw-agent-dokku logs -t ``` + +`SIGNALWIRE_SPACE_NAME` configures the CLI and the deployed app's dashboard links. +If the agent also uses `RestClient` or `RelayClient`, set `SIGNALWIRE_SPACE` to the +full hostname, `my-space.signalwire.com`, in the same `config set` call. diff --git a/fern/products/server-sdks/pages/reference/python/agents/cli/sw-agent-init.mdx b/fern/products/server-sdks/pages/reference/python/agents/cli/sw-agent-init.mdx index afeb56c1bd..5ea56fc4cb 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/cli/sw-agent-init.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/cli/sw-agent-init.mdx @@ -120,11 +120,15 @@ The generated project auto-detects SignalWire credentials from environment varia |----------|-------------| | `SIGNALWIRE_SPACE_NAME` | Your SignalWire space | | `SIGNALWIRE_PROJECT_ID` | Project identifier | -| `SIGNALWIRE_TOKEN` | API token | +| `SIGNALWIRE_API_TOKEN` | API token | If these are set when running `sw-agent-init`, they are written into the generated `.env` file. +Only the CLI reads `SIGNALWIRE_SPACE_NAME`. `RestClient` and `RelayClient` read +`SIGNALWIRE_SPACE`, the full hostname `your-space.signalwire.com`, so add it to +the generated `.env` if the agent uses either client. + ## Examples ### Basic Local Agent diff --git a/fern/products/server-sdks/pages/reference/python/agents/cli/sw-search.mdx b/fern/products/server-sdks/pages/reference/python/agents/cli/sw-search.mdx index 7e516b31e3..52c8dd2f60 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/cli/sw-search.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/cli/sw-search.mdx @@ -102,7 +102,7 @@ sw-search ./docs ./examples README.md --file-types md,txt,py NLP backend for document processing. Valid values: - `"nltk"` -- Fast, good quality (default) - - `"spacy"` -- Better quality, slower. Requires `[search-nlp]` extras. + - `"spacy"` -- Slower; also expands content with WordNet synonyms, and the expansion is written into the index. The effect depends on your corpus, so measure it before choosing. Requires `[search-nlp]` extras. @@ -139,7 +139,14 @@ sw-search ./docs ./examples README.md --file-types md,txt,py - Chunk size in words. Used with `sliding` strategy. + Chunk size in words. Used with `sliding` strategy. The `markdown` strategy + also uses it as its split threshold, applied as `chunk_size * 6` characters. + + + + Minimum words a section needs before a heading starts a new chunk. Shorter + sections merge into the next one instead of being emitted alone. `0` splits + at every heading. Used with `markdown` strategy. @@ -191,7 +198,11 @@ sw-search search knowledge.swsearch "API reference" --count 3 --verbose NLP backend for query processing. - `"nltk"` -- Fast, good quality (default) - - `"spacy"` -- Better quality, slower. Requires `[search-nlp]` extras. + - `"spacy"` -- Slower; expands the query with WordNet synonyms. The effect depends on your corpus, so measure it rather than assuming it helps. Requires `[search-nlp]` extras. + + + + Manual keyword weight (0.0-1.0). Overrides automatic weight detection. diff --git a/fern/products/server-sdks/pages/reference/python/agents/cli/swaig-test.mdx b/fern/products/server-sdks/pages/reference/python/agents/cli/swaig-test.mdx index ac4c3fdbe0..c64db8290e 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/cli/swaig-test.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/cli/swaig-test.mdx @@ -168,6 +168,12 @@ Run `swaig-test agent.py --help-platforms` for the full list. Key options per pl Show comprehensive usage examples covering all features. + + Validate the invocation's arguments and exit without loading the agent or + touching the network. Prints `parse OK` on success and exits non-zero on + invalid arguments. Useful for checking documented commands in CI. + + ## Examples ### List Tools and Generate SWML diff --git a/fern/products/server-sdks/pages/reference/python/agents/configuration/config-loader/find-config-file.mdx b/fern/products/server-sdks/pages/reference/python/agents/configuration/config-loader/find-config-file.mdx index 70fc34be60..17227514ad 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/configuration/config-loader/find-config-file.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/configuration/config-loader/find-config-file.mdx @@ -9,7 +9,7 @@ max-toc-depth: 3 ### find_config_file (static) -**[ConfigLoader][ref-configloader].find_config_file**(`service_name=None`, `additional_paths=None`) -> `Optional[str]` +**[ConfigLoader][ref-configloader].find_config_file**(`service_name=None`, `additional_paths=None`) -> `str | None` Static method to locate a config file without loading it. @@ -26,7 +26,7 @@ Static method to locate a config file without loading it. ## **Returns** -`Optional[str]` -- Path to the first config file found, or `None`. +`str | None` -- Path to the first config file found, or `None`. ## **Example** diff --git a/fern/products/server-sdks/pages/reference/python/agents/configuration/config-loader/get-config-file.mdx b/fern/products/server-sdks/pages/reference/python/agents/configuration/config-loader/get-config-file.mdx index 8608afd3b5..a7034b7dca 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/configuration/config-loader/get-config-file.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/configuration/config-loader/get-config-file.mdx @@ -9,7 +9,7 @@ Get the path of the loaded config file. ## **Returns** -`Optional[str]` -- The file path, or `None` if no config was loaded. +`str | None` -- The file path, or `None` if no config was loaded. ## **Example** diff --git a/fern/products/server-sdks/pages/reference/python/agents/configuration/environment-variables.mdx b/fern/products/server-sdks/pages/reference/python/agents/configuration/environment-variables.mdx index d106f54792..7bdccebdbe 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/configuration/environment-variables.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/configuration/environment-variables.mdx @@ -50,6 +50,26 @@ passwords change on every restart, which will break SignalWire webhook callbacks until you update the credentials in your SignalWire dashboard. + + Your SignalWire Signing Key. When set, the agent validates the signature on + `POST /`, `/swaig`, and `/post_prompt` requests and rejects unsigned or + invalidly signed requests with `403`. The `signing_key` constructor argument + takes precedence. + + + + Secret used to sign the agent's per-call SWAIG function tokens. When unset, a + random secret is generated per process, so tokens stop verifying after a + restart or when a tool call lands on a different replica. Set it in + production. The `swaig_secret` constructor argument takes precedence. + + + + In CGI mode, accept a request authenticated by the web server (`REMOTE_USER`) + when no `HTTP_AUTHORIZATION` header is present. Accepts `"1"`, `"true"`, or + `"yes"`. + + --- ## SSL / TLS @@ -91,6 +111,12 @@ until you update the credentials in your SignalWire dashboard. Enable proxy request debug logging. + + Trust `X-Forwarded-Host` and `X-Forwarded-Proto` headers when detecting the + public URL for webhook generation. Accepts `1`, `true`, or `yes`. Enable only + behind a reverse proxy you control. Setting `SWML_PROXY_URL_BASE` implies it. + + Setting `SWML_PROXY_URL_BASE` (or `APP_URL`) overrides SSL configuration and port settings for webhook URL generation. @@ -137,6 +163,26 @@ settings for webhook URL generation. HSTS `max-age` directive in seconds. Default is 1 year. + + Let URL validation accept hosts that resolve to private, loopback, or + link-local addresses. Accepts `"1"`, `"true"`, or `"yes"`. Leave unset in + production; it disables the SDK's protection against server-side request + forgery. + + +## AI chat gateway + + + Publishable key a `ChatGateway` accepts from the browser when no `key` is + passed to its constructor. A random `pk_` value is generated if neither is set. + + + + HMAC secret a `ChatGateway` uses to sign handles when no `secret` is passed. + A random per-process value is generated if neither is set, which invalidates + outstanding handles on restart. + + ## Logging @@ -174,7 +220,9 @@ settings for webhook URL generation. ## Relay and REST Client -These variables are shared between the Relay WebSocket client and the REST HTTP client. +`RelayClient`, `RestClient`, and `AIChatClient` read these variables. The +three clients agree on the credential variables but not on `SIGNALWIRE_SPACE`, +so read that entry before setting it in a process that uses more than one client. SignalWire project ID for authentication. @@ -188,8 +236,40 @@ These variables are shared between the Relay WebSocket client and the REST HTTP JWT token for Relay authentication. Alternative to project ID + API token. - - Space hostname used for Relay WebSocket connections and as the REST API base URL. + +The SDK reads `SIGNALWIRE_API_TOKEN` only. Older examples that used +`SIGNALWIRE_TOKEN` need to be updated; that name is not read anywhere. + + + + Your space hostname, for example `your-space.signalwire.com`. `RestClient` uses + it as the REST API host and raises `ValueError` when neither this variable nor + the `host` argument is set. `AIChatClient` reads the same variable but expects + the bare space name, `your-space`, and appends `.signalwire.com` itself. + + + +`RelayClient` connects to `relay.signalwire.com` by default and needs no space +setting. When `SIGNALWIRE_SPACE` is set, it connects to that host instead. If +the same process uses REST and Relay, pass `host="relay.signalwire.com"` to +`RelayClient` so the REST setting does not redirect the WebSocket connection. + + + +`sw-agent-init` and `sw-agent-dokku` read and write a different variable, +`SIGNALWIRE_SPACE_NAME`, holding the bare space name. No client reads it, so a +scaffolded project still needs `SIGNALWIRE_SPACE` before `RestClient()` can +start from the environment. + + + + Path to a CA bundle the REST client trusts for TLS verification. Unset uses + the default trust store. + + + + Path to a CA bundle the Relay WebSocket client trusts for TLS verification. + Unset uses the system trust store. @@ -277,6 +357,15 @@ You typically do not set these manually -- they are provided by the platform run CGI script path. + + Request path following the script name. Used to route the request to the + matching agent. + + + + Size of the POST body in bytes, read from stdin for SWAIG function calls. + + ## Example .env File ```bash @@ -286,6 +375,8 @@ PORT=3000 # Authentication SWML_BASIC_AUTH_USER=agent_user SWML_BASIC_AUTH_PASSWORD=secret_password_123 +SIGNALWIRE_SIGNING_KEY=your-signing-key +SIGNALWIRE_SWAIG_SECRET=a-stable-secret-across-replicas # SSL Configuration SWML_SSL_ENABLED=true @@ -305,6 +396,7 @@ SIGNALWIRE_LOG_LEVEL=info # Relay / REST SIGNALWIRE_PROJECT_ID=your-project-id SIGNALWIRE_API_TOKEN=your-api-token +# REST host. RelayClient reads it too; pass host="relay.signalwire.com" there. SIGNALWIRE_SPACE=your-space.signalwire.com # Custom Skills diff --git a/fern/products/server-sdks/pages/reference/python/agents/configuration/security-config/index.mdx b/fern/products/server-sdks/pages/reference/python/agents/configuration/security-config/index.mdx index 59eb6d7887..1c908b80ff 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/configuration/security-config/index.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/configuration/security-config/index.mdx @@ -34,15 +34,15 @@ service-specific config files. Whether HTTPS is enabled. - + Path to the SSL certificate file. Required when `ssl_enabled` is `True`. - + Path to the SSL private key file. Required when `ssl_enabled` is `True`. - + Domain name for SSL certificates and URL generation. @@ -78,11 +78,11 @@ service-specific config files. HSTS `max-age` in seconds (default 1 year). - + Basic auth username. Defaults to `"signalwire"` when accessed via `get_basic_auth()`. - + Basic auth password. Auto-generated if not set when accessed via `get_basic_auth()`. diff --git a/fern/products/server-sdks/pages/reference/python/agents/configuration/security-config/validate-ssl-config.mdx b/fern/products/server-sdks/pages/reference/python/agents/configuration/security-config/validate-ssl-config.mdx index 75bfe10ad3..787aae2af6 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/configuration/security-config/validate-ssl-config.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/configuration/security-config/validate-ssl-config.mdx @@ -9,7 +9,7 @@ Validate that SSL configuration is complete and the certificate files exist. ## **Returns** -`tuple[bool, Optional[str]]` -- A tuple of `(is_valid, error_message)`. +`tuple[bool, str | None]` -- A tuple of `(is_valid, error_message)`. Returns `(True, None)` when SSL is disabled or when all required files exist. ## **Example** diff --git a/fern/products/server-sdks/pages/reference/python/agents/context-builder/context/index.mdx b/fern/products/server-sdks/pages/reference/python/agents/context-builder/context/index.mdx index 371820335f..7bbbf36c7f 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/context-builder/context/index.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/context-builder/context/index.mdx @@ -90,6 +90,9 @@ You obtain a Context by calling `add_context()` on a ContextBuilder or by callin Set whether to completely replace the system prompt when entering this context. + + Set the default history visibility mode for every step in this context. + Set which step the context starts on when entered. diff --git a/fern/products/server-sdks/pages/reference/python/agents/context-builder/context/set-history.mdx b/fern/products/server-sdks/pages/reference/python/agents/context-builder/context/set-history.mdx new file mode 100644 index 0000000000..57e14aafc9 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/agents/context-builder/context/set-history.mdx @@ -0,0 +1,42 @@ +--- +title: "set_history" +slug: /reference/python/agents/context-builder/context/set-history +description: Set the default history visibility mode for every step in this context. +max-toc-depth: 3 +--- + +[ref-context]: /docs/server-sdks/reference/python/agents/context-builder/context +[ref-step-set-history]: /docs/server-sdks/reference/python/agents/context-builder/step/set-history + +Set the default visibility mode for every step in this context. A step's own +[`set_history()`][ref-step-set-history] overrides it. See that page for what +each mode does. + +## Parameters + + + One of `"keep"`, `"default"`, or `"hide"`. + + +## Returns + +[`Context`][ref-context] -- Self for method chaining. + +## Raises + +`ValueError` if `history` is not one of the three modes. + +## Example + +```python {6} +from signalwire import AgentBase + +agent = AgentBase(name="my-agent", route="/agent") + +contexts = agent.define_contexts() +ctx = contexts.add_context("default").set_history("hide") +ctx.add_step("greet").set_text("Greet the caller.") +ctx.add_step("help").set_text("Previously: ${step_history.prev.summary}. Help them.") + +agent.serve() +``` diff --git a/fern/products/server-sdks/pages/reference/python/agents/context-builder/step/add-gather-question.mdx b/fern/products/server-sdks/pages/reference/python/agents/context-builder/step/add-gather-question.mdx index 00e5cd599a..ea38e91fee 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/context-builder/step/add-gather-question.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/context-builder/step/add-gather-question.mdx @@ -36,14 +36,20 @@ must be called before this method. When `True`, the AI must confirm the answer with the caller before accepting it. - + Extra instruction text appended for this specific question. - + Additional function names to make visible while asking this question. + + Override the gather's `isolated` default for this one question. `True` hides + the sibling questions and answers while this question is asked; `False` keeps + them visible even in an isolated gather. `None` inherits the gather's setting. + + ## **Returns** [`Step`][ref-step] -- Self for method chaining. Raises `ValueError` if `set_gather_info()` diff --git a/fern/products/server-sdks/pages/reference/python/agents/context-builder/step/index.mdx b/fern/products/server-sdks/pages/reference/python/agents/context-builder/step/index.mdx index 735c6077c3..52c8f3e46e 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/context-builder/step/index.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/context-builder/step/index.mdx @@ -62,6 +62,9 @@ return `self` for fluent method chaining. Enable structured info gathering for this step. + + Control what the model still sees from earlier steps when this step is entered. + Set whether to consolidate conversation history on context switch. diff --git a/fern/products/server-sdks/pages/reference/python/agents/context-builder/step/set-gather-info.mdx b/fern/products/server-sdks/pages/reference/python/agents/context-builder/step/set-gather-info.mdx index edb492289c..9944fdf740 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/context-builder/step/set-gather-info.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/context-builder/step/set-gather-info.mdx @@ -19,12 +19,12 @@ LLM-visible history. ## **Parameters** - + Key in `global_data` to store collected answers under. When `None`, answers are stored at the top level of `global_data`. - + Where to go when all questions are answered. - `"next_step"` -- auto-advance to the next sequential step @@ -32,11 +32,18 @@ LLM-visible history. - `None` -- return to normal step mode after gathering - + Preamble text injected once when entering the gather step, giving the AI personality and context for asking the questions. + + Default for every question in this gather. When `True`, each question is + asked with the sibling questions and answers hidden from the model, so it + must ask rather than derive the answer from an earlier one. A question's own + `isolated` overrides this. Hidden turns stay in the call log. + + ## **Returns** [`Step`][ref-step] -- Self for method chaining. diff --git a/fern/products/server-sdks/pages/reference/python/agents/context-builder/step/set-history.mdx b/fern/products/server-sdks/pages/reference/python/agents/context-builder/step/set-history.mdx new file mode 100644 index 0000000000..4f71cc9bd5 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/agents/context-builder/step/set-history.mdx @@ -0,0 +1,56 @@ +--- +title: "set_history" +slug: /reference/python/agents/context-builder/step/set-history +description: Control what the model still sees from earlier steps when this step is entered. +max-toc-depth: 3 +--- + +[ref-step]: /docs/server-sdks/reference/python/agents/context-builder/step +[ref-context-set-history]: /docs/server-sdks/reference/python/agents/context-builder/context/set-history + +Control what the model still sees when this step is entered. The mode applies at +the moment of entry and governs everything that came before, including the turn +that triggered the transition. It doesn't affect this step's own turns, which +accumulate fresh. Nothing is deleted: the call log keeps every message. + +Overrides the context-level default set with +[`Context.set_history()`][ref-context-set-history]. + +## Parameters + + + One of three modes. + + - `"keep"` -- clear nothing. Every prior step's instructions and dialogue stay + visible to the model. + - `"default"` -- hide the prior step instructions, keep the user and assistant + dialogue. This is the behavior when unset. + - `"hide"` -- hide the prior instructions and pull the prior dialogue out of the + model's context. Pair it with a `${step_history.*}` reference in this step's + text to choose exactly what comes back. + + +## Returns + +[`Step`][ref-step] -- Self for method chaining. + +## Raises + +`ValueError` if `history` is not one of the three modes. + +## Example + +```python {8-10} +from signalwire import AgentBase + +agent = AgentBase(name="my-agent", route="/agent") + +contexts = agent.define_contexts() +ctx = contexts.add_context("default") +ctx.add_step("collect_trip").set_text("Ask where the caller is going and when.") +ctx.add_step("confirm_trip").set_history("hide").set_text( + "Previously: ${step_history.prev.summary}\n\nConfirm the booking details." +) + +agent.serve() +``` diff --git a/fern/products/server-sdks/pages/reference/python/agents/context-builder/validate.mdx b/fern/products/server-sdks/pages/reference/python/agents/context-builder/validate.mdx index 501e34f57b..282ff9d596 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/context-builder/validate.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/context-builder/validate.mdx @@ -19,8 +19,15 @@ Checks performed: exist in the builder. - All `valid_contexts` references at the step level point to contexts that exist in the builder. +- Every context's `initial_step`, when set, names a step in that context. - All `gather_info` configurations have at least one question, no duplicate keys, and valid `completion_action` targets. +- When the builder is attached to an agent, no user-defined tool shares a name + with a reserved native tool (`next_step`, `change_context`, `gather_submit`). +- When the builder is attached to an agent, every name a step passes to + `set_functions([...])` is a registered SWAIG tool or a reserved native tool. + A name that matches neither would render a dangling function reference. + `"none"` and `[]` mean "disable all" and are never treated as references. ## **Returns** diff --git a/fern/products/server-sdks/pages/reference/python/agents/function-result/connect.mdx b/fern/products/server-sdks/pages/reference/python/agents/function-result/connect.mdx index dc7e467753..921ea6c76a 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/function-result/connect.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/function-result/connect.mdx @@ -28,7 +28,7 @@ When `final=True` (the default), the call permanently leaves the agent. When - `False` — call returns to the agent when the far end hangs up - + Caller ID override. Phone number or SIP address to show as the caller. When `None`, the current call's originating address is used. diff --git a/fern/products/server-sdks/pages/reference/python/agents/function-result/create-payment-prompt.mdx b/fern/products/server-sdks/pages/reference/python/agents/function-result/create-payment-prompt.mdx index 54e4b4220f..b043de3e5d 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/function-result/create-payment-prompt.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/function-result/create-payment-prompt.mdx @@ -26,11 +26,11 @@ payment collection. to build each entry. - + Space-separated card types this prompt applies to (e.g., `"visa mastercard"`). - + Space-separated error types this prompt handles. diff --git a/fern/products/server-sdks/pages/reference/python/agents/function-result/execute-rpc.mdx b/fern/products/server-sdks/pages/reference/python/agents/function-result/execute-rpc.mdx index c633864b8d..4f688c42e1 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/function-result/execute-rpc.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/function-result/execute-rpc.mdx @@ -22,15 +22,15 @@ cross-call communication. For common operations, prefer the specific helpers RPC method name (e.g., `"dial"`, `"ai_message"`, `"ai_unhold"`). - + Parameters for the RPC method. - + Target call ID for the RPC command. - + Target node ID for the RPC command. diff --git a/fern/products/server-sdks/pages/reference/python/agents/function-result/hold.mdx b/fern/products/server-sdks/pages/reference/python/agents/function-result/hold.mdx index bad6ea8b71..49a421932a 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/function-result/hold.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/function-result/hold.mdx @@ -1,28 +1,61 @@ --- title: "hold" slug: /reference/python/agents/function-result/hold -description: Put the call on hold with an optional timeout. +description: Put the call on hold, announce it first, and route where the call resumes. max-toc-depth: 3 --- [functionresult]: /docs/server-sdks/reference/python/agents/function-result +[settoolresponse]: /docs/server-sdks/reference/python/agents/function-result/set-tool-response +[swmlchangestep]: /docs/server-sdks/reference/python/agents/function-result/swml-change-step -Put the call on hold. The caller hears hold music until the hold is released -or the timeout expires. +Put the call on hold. The caller hears hold music until the hold is released or +the timeout expires. During hold, speech detection is paused and the agent +doesn't respond, so anything the caller needs to hear must be said before the +hold takes effect. Pass `prompt` and the method arranges that for you. -## **Parameters** +## Parameters + + + Instruction for the model to deliver before the hold starts, in the second + person. Sets the response to + `{"tool_result": "status: on hold", "tool_prompt": prompt}` via + [`set_tool_response()`][settoolresponse] and turns on `post_process`, so the + model speaks once more before the hold executes. An `int` in this position is + treated as `timeout`, so `hold(120)` still works. + - Maximum hold duration in seconds. Clamped to the range 0--900 (15 minutes max). + Maximum hold duration in seconds. Clamped to the range 0 to 900. + + + + Step to move to when the call is taken off hold. Without it the caller + resumes in the step they left. + + + + Step to move to when the hold times out. Without it the caller resumes in + place. -## **Returns** + +`step` and `timeout_step` are deferred: the transition fires when the hold ends. +[`swml_change_step()`][swmlchangestep] applies immediately, so returning both a +hold and a change step in one result moves the caller before the hold begins. +When neither routing argument is given, the action is emitted as a bare integer +timeout, so existing output is unchanged. + + +## Returns [`FunctionResult`][functionresult] — self, for chaining. -## **Example** +## Examples + +### Announce the hold -```python {7,11} +```python {9-11} from signalwire import AgentBase from signalwire import FunctionResult @@ -31,10 +64,22 @@ agent.set_prompt_text("You are a helpful assistant.") @agent.tool(name="hold_for_agent", description="Place the caller on hold") def hold_for_agent(args, raw_data): - return ( - FunctionResult("Please hold while I find an available agent.") - .hold(timeout=60) + return FunctionResult().hold( + "Tell the caller you are placing them on hold while you find an agent.", 120 ) agent.serve() ``` + +### Route the caller when the hold ends + +```python +@agent.tool(name="check_availability", description="Check whether the agent is free") +def check_availability(args, raw_data): + return FunctionResult().hold( + "Tell the caller you are checking if the dispatcher is available.", + 300, + step="back_with_agent", # released early + timeout_step="take_a_message", # nobody picked up + ) +``` diff --git a/fern/products/server-sdks/pages/reference/python/agents/function-result/index.mdx b/fern/products/server-sdks/pages/reference/python/agents/function-result/index.mdx index a8aa614b2e..6b4b258e26 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/function-result/index.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/function-result/index.mdx @@ -59,11 +59,13 @@ max-toc-depth: 3 [rpcdial]: /docs/server-sdks/reference/python/agents/function-result/rpc-dial [rpcaimessage]: /docs/server-sdks/reference/python/agents/function-result/rpc-ai-message [rpcaiunhold]: /docs/server-sdks/reference/python/agents/function-result/rpc-ai-unhold +[settoolresponse]: /docs/server-sdks/reference/python/agents/function-result/set-tool-response +[rpcaiglobaldata]: /docs/server-sdks/reference/python/agents/function-result/rpc-ai-global-data `FunctionResult` is the return type for all SWAIG tool functions. It wraps a response -message (text for the AI to speak) and an ordered list of actions (transfers, SMS, -data updates, context switches, and more). Every method returns `self`, so you can -chain calls into a single fluent expression. +(a prompt the AI reads, not text it speaks verbatim) and an ordered list of actions +(transfers, SMS, data updates, context switches, and more). Every method returns +`self`, so you can chain calls into a single fluent expression. Returned from functions defined with the [`@tool()`][tool] decorator or [`define_tool()`][define-tool] on @@ -75,10 +77,41 @@ See the [SWML SWAIG functions reference][swml-swaig-functions-reference] for the full response format specification. -## **Properties** +## Parameters - - Text the AI speaks back to the caller after the function executes. + + A prompt injected into the model's context after the function executes. The + model reads it and decides what to say, so write it as an instruction in the + second person: `"Tell the caller their order shipped Tuesday."` rather than + `"Your order shipped Tuesday."`. A first-person script usually still works + because the model tends to repeat it, but it is interpreted, not spoken, and + can drift or be merged with other context. + + + + Let the AI take one more turn before executing actions. Set it whenever the + caller must hear something before an action that ends or suspends the AI's + turn: `hold` pauses speech detection, `connect` and `transfer` replace the + leg, and `hangup` ends the call. + + + + Factual outcome of the call, such as `"status: on hold"`. When given, the + response takes the structured form described under + [`set_tool_response()`][settoolresponse]. + + + + Instruction for what the model should say next, in the second person. Pairs + with `tool_result`. + + +## Properties + + + The prompt injected into the model's context. Either a plain string or a + `{"tool_result": ..., "tool_prompt": ...}` object built by + [`set_tool_response()`][settoolresponse]. @@ -87,12 +120,12 @@ full response format specification. - When `True`, the AI speaks the response and takes one more conversational turn - with the user before executing actions. When `False` (default), actions execute - immediately after the response. + When `True`, the AI responds to the prompt and takes one more conversational + turn with the user before executing actions. When `False` (default), actions + execute immediately after the response. -## **Example** +## Example ```python {10} from signalwire import AgentBase @@ -105,7 +138,7 @@ agent.set_prompt_text("You are a helpful assistant.") def transfer_to_billing(args, raw_data): return ( FunctionResult( - "I'll transfer you to billing. Anything else first?", + "Tell the caller you are transferring them to billing and ask if they need anything else first.", post_process=True ) .update_global_data({"transferred": True}) @@ -120,7 +153,7 @@ def transfer_to_billing(args, raw_data): agent.serve() ``` -## **Fluent Chaining Pattern** +## Fluent Chaining Pattern Every method on `FunctionResult` returns `self`, so you build complex responses in a single expression. Actions execute in the order they are added. @@ -142,7 +175,7 @@ agent.set_prompt_text("You are a helpful assistant.") def transfer_call(args, raw_data): # Data update + SMS execute before the terminal transfer return ( - FunctionResult("Transferring you now.") + FunctionResult("Tell the caller you are transferring them now.") .update_global_data({"transferred": True}) .send_sms( to_number="+15551234567", @@ -155,13 +188,16 @@ def transfer_call(args, raw_data): agent.serve() ``` -## **Methods** +## Methods ### Core - Set or replace the response text on a FunctionResult. + Set or replace the response prompt on a FunctionResult. + + + Split the response into a factual result and a speaking instruction. Enable or disable post-processing on a FunctionResult. @@ -187,7 +223,7 @@ agent.serve() End the call immediately. - Put the call on hold with an optional timeout. + Put the call on hold, announce it first, and route where it resumes. Transfer the call to a SWML endpoint with a return message. @@ -372,7 +408,10 @@ agent.serve() Dial out to a phone number with a destination SWML URL via RPC. - Inject a message into the AI agent running on another call. + Inject a message or global data into the AI agent running on another call. + + + Merge data into another call's global_data without a conversation turn. Release another call from hold via RPC. diff --git a/fern/products/server-sdks/pages/reference/python/agents/function-result/join-conference.mdx b/fern/products/server-sdks/pages/reference/python/agents/function-result/join-conference.mdx index 749735a45e..507e166ca2 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/function-result/join-conference.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/function-result/join-conference.mdx @@ -46,7 +46,7 @@ used internally. Passing any non-default parameter triggers the full object form Whether the conference ends for all participants when this participant leaves. - + SWML URL for hold music played while waiting for the conference to start. When `None`, default hold music is used. @@ -62,7 +62,7 @@ used internally. Passing any non-default parameter triggers the full object form - `"record-from-start"` -- begin recording as soon as the conference starts - + Conference region for geographic optimization. @@ -73,12 +73,12 @@ used internally. Passing any non-default parameter triggers the full object form - `"do-not-trim"` -- keep silence in the recording as-is - + SWML Call ID or CXML CallSid of a participant who can coach (whisper to) this participant without other participants hearing. - + Space-separated list of events to report. - `"start"` -- conference has started @@ -92,7 +92,7 @@ used internally. Passing any non-default parameter triggers the full object form - `"announcement"` -- an announcement was played - + URL to receive conference status event webhooks. @@ -103,7 +103,7 @@ used internally. Passing any non-default parameter triggers the full object form - `"POST"` -- send status callbacks as POST requests - + URL to receive recording status event webhooks. @@ -122,7 +122,7 @@ used internally. Passing any non-default parameter triggers the full object form - `"absent"` -- no recording was produced - + Result handling configuration. Pass an object `{}` for `return_value`-based switching, or an array `[]` for conditional switching. diff --git a/fern/products/server-sdks/pages/reference/python/agents/function-result/pay.mdx b/fern/products/server-sdks/pages/reference/python/agents/function-result/pay.mdx index efae26777f..c7163b96de 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/function-result/pay.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/function-result/pay.mdx @@ -10,8 +10,8 @@ max-toc-depth: 3 [functionresult]: /docs/server-sdks/reference/python/agents/function-result Collect and process a credit card payment during the call. Generates a SWML -`pay` verb that walks the caller through entering card details via DTMF or -voice, then submits to your payment connector endpoint. +`pay` verb that walks the caller through entering card details by DTMF, then +submits to your payment connector endpoint. ## **Parameters** @@ -21,13 +21,11 @@ voice, then submits to your payment connector endpoint. - How the caller provides card details. - - - `"dtmf"` -- caller enters digits on the keypad - - `"voice"` -- caller speaks the numbers + How the caller provides card details. The SWML `pay` verb accepts only + `"dtmf"`: the caller enters digits on the keypad. - + URL to receive payment status change webhook notifications. @@ -63,7 +61,7 @@ voice, then submits to your payment connector endpoint. - `"reusable"` -- token can be charged again later - + Amount to charge as a decimal string (e.g., `"49.99"`). @@ -79,7 +77,7 @@ voice, then submits to your payment connector endpoint. TTS voice for payment prompts (e.g., `"woman"`, `"man"`). - + Custom description for the payment transaction. @@ -87,17 +85,17 @@ voice, then submits to your payment connector endpoint. Space-separated list of accepted card types. - + Additional name/value pairs to send to the payment connector. Use [`create_payment_parameter()`][create-payment-parameter] to build entries. - + Custom prompt configurations to override default payment prompts. Use [`create_payment_prompt()`][create-payment-prompt] to build entries. - + AI response template after payment completes. The `${pay_result}` variable is substituted with the payment outcome. Set to `None` to disable. diff --git a/fern/products/server-sdks/pages/reference/python/agents/function-result/record-call.mdx b/fern/products/server-sdks/pages/reference/python/agents/function-result/record-call.mdx index e116f72104..ad43dd8c5f 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/function-result/record-call.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/function-result/record-call.mdx @@ -11,7 +11,7 @@ max-toc-depth: 3 Start recording the call in the background. The conversation continues while recording is active. -Raises `ValueError` if `format` is not `"wav"` or `"mp3"`, or if `direction` +Raises `ValueError` if `format` is not `"wav"`, `"mp3"`, or `"mp4"`, or if `direction` is not `"speak"`, `"listen"`, or `"both"`. @@ -22,7 +22,7 @@ silence. Use [`stop_record_call()`][stop-record-call] to end continuous recordin ## **Parameters** - + Identifier for this recording. Pass the same ID to `stop_record_call()` to stop this specific recording. @@ -31,14 +31,15 @@ silence. Use [`stop_record_call()`][stop-record-call] to end continuous recordin Record in stereo (`True`) or mono (`False`). - + Recording file format. - `"wav"` -- uncompressed WAV audio - `"mp3"` -- compressed MP3 audio + - `"mp4"` -- MP4 container - + Audio direction to record. - `"speak"` -- what the agent says @@ -46,7 +47,7 @@ silence. Use [`stop_record_call()`][stop-record-call] to end continuous recordin - `"both"` -- both sides of the conversation - + DTMF digits that stop recording when pressed (e.g., `"#"`). @@ -58,21 +59,21 @@ silence. Use [`stop_record_call()`][stop-record-call] to end continuous recordin Input sensitivity level for the recording. - + Seconds to wait for speech to begin before auto-stopping. Used for voicemail-style recordings. - + Seconds of silence after speech to wait before auto-stopping. Used for voicemail-style recordings. - + Maximum recording duration in seconds. - + URL to receive recording status webhook events. diff --git a/fern/products/server-sdks/pages/reference/python/agents/function-result/rpc-ai-global-data.mdx b/fern/products/server-sdks/pages/reference/python/agents/function-result/rpc-ai-global-data.mdx new file mode 100644 index 0000000000..bf48e7f9f7 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/agents/function-result/rpc-ai-global-data.mdx @@ -0,0 +1,50 @@ +--- +title: "rpc_ai_global_data" +slug: /reference/python/agents/function-result/rpc-ai-global-data +description: Merge data into another call's global_data without adding a conversation turn. +max-toc-depth: 3 +--- + +[functionresult]: /docs/server-sdks/reference/python/agents/function-result +[rpcaimessage]: /docs/server-sdks/reference/python/agents/function-result/rpc-ai-message + +Merge data into another call's `global_data` without injecting a conversation +turn. A thin wrapper over [`rpc_ai_message()`][rpcaimessage] with only +`global_data` set. Use it when the other call needs a value rather than an +instruction; the destination prompt reads it back with `${global_data.key}`. + +## Parameters + + + Call ID of the target call. + + + + Object merged into that call's `global_data`. Existing keys not in `data` + are left in place. + + +## Returns + +[`FunctionResult`][functionresult] — self, for chaining. + +## Example + +```python {11-13} +from signalwire import AgentBase +from signalwire import FunctionResult + +agent = AgentBase(name="my-agent", route="/agent") +agent.set_prompt_text("You are a helpful assistant.") + +@agent.tool(name="share_eta", description="Send the ETA to the waiting caller") +def share_eta(args, raw_data): + waiting_call_id = args["waiting_call_id"] + return ( + FunctionResult("Tell the driver the passenger has been updated.") + .rpc_ai_global_data(waiting_call_id, {"eta_minutes": args["eta_minutes"]}) + .rpc_ai_unhold(waiting_call_id) + ) + +agent.serve() +``` diff --git a/fern/products/server-sdks/pages/reference/python/agents/function-result/rpc-ai-message.mdx b/fern/products/server-sdks/pages/reference/python/agents/function-result/rpc-ai-message.mdx index d8a368cc04..b6ebd3363e 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/function-result/rpc-ai-message.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/function-result/rpc-ai-message.mdx @@ -6,30 +6,49 @@ max-toc-depth: 3 --- [functionresult]: /docs/server-sdks/reference/python/agents/function-result +[rpcaiglobaldata]: /docs/server-sdks/reference/python/agents/function-result/rpc-ai-global-data -Inject a message into the AI agent running on another call. Useful for -cross-call coordination, such as notifying a held caller's agent about a -status change or instructing it to relay information. +Send a message, global data, or both to the AI agent running on another call. +Useful for cross-call coordination, such as notifying a held caller's agent +about a status change or handing it a value to speak later. -## **Parameters** +A message lands as a turn in the other agent's conversation, where it competes +with everything else arriving that moment. Global data is merged silently into +the other call's `global_data` and stays there until a prompt expands it with +`${global_data.key}`, which makes it the more reliable channel for content a +later step needs to say. + +## Parameters Call ID of the target call whose AI agent should receive the message. - + The message text to inject into the target AI's conversation. - Role for the injected message. Typically `"system"` for instructions. + Role for the injected message. Typically `"system"` for instructions. Sent + only when `message_text` is given. + + + + Object merged into the target call's `global_data`. See also + [`rpc_ai_global_data()`][rpcaiglobaldata]. -## **Returns** +## Raises + +`ValueError` when neither `message_text` nor `global_data` is given. + +## Returns [`FunctionResult`][functionresult] — self, for chaining. -## **Example** +## Examples + +### Inject a message ```python {12} from signalwire import AgentBase @@ -42,7 +61,7 @@ agent.set_prompt_text("You are a helpful assistant.") def notify_caller(args, raw_data): caller_call_id = args.get("original_call_id") return ( - FunctionResult("I'll let them know.") + FunctionResult("Tell the caller you have passed the message along.") .rpc_ai_message( call_id=caller_call_id, message_text="The person you're trying to reach is unavailable. Please leave a message." @@ -51,3 +70,17 @@ def notify_caller(args, raw_data): agent.serve() ``` + +### Hand the other call a value to speak + +```python +# Sender: set the value, then release the held call. +return ( + FunctionResult("Tell the caller you have passed the message along.") + .rpc_ai_message(call_id, global_data={"decline_message": args["message"]}) + .rpc_ai_unhold(call_id) +) + +# Destination step, on the other call: +# step.set_text("Tell the caller: ${global_data.decline_message}") +``` diff --git a/fern/products/server-sdks/pages/reference/python/agents/function-result/send-sms.mdx b/fern/products/server-sdks/pages/reference/python/agents/function-result/send-sms.mdx index f7cb55cb03..adbf5f65d3 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/function-result/send-sms.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/function-result/send-sms.mdx @@ -22,20 +22,20 @@ Raises `ValueError` if neither `body` nor `media` is provided. Sender phone number in E.164 format. Must be a number in your SignalWire project. - + Text body of the message. - + List of media URLs to include as MMS attachments. - + Tags to associate with the message for searching and filtering in the SignalWire dashboard. - + Region to originate the message from. diff --git a/fern/products/server-sdks/pages/reference/python/agents/function-result/set-response.mdx b/fern/products/server-sdks/pages/reference/python/agents/function-result/set-response.mdx index 64ebb2ad2c..b483ba075e 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/function-result/set-response.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/function-result/set-response.mdx @@ -6,14 +6,18 @@ max-toc-depth: 3 --- [functionresult]: /docs/server-sdks/reference/python/agents/function-result +[settoolresponse]: /docs/server-sdks/reference/python/agents/function-result/set-tool-response -Set or replace the response text after construction. The response is the text -the AI speaks back to the caller after the function executes. +Set or replace the response after construction. The response is a prompt +injected into the model's context, not text spoken verbatim, so write it as an +instruction in the second person. To separate a factual outcome from the +speaking instruction, use [`set_tool_response()`][settoolresponse] instead. ## **Parameters** - Text for the AI to speak to the caller. + Instruction for the model, such as `"Tell the caller their order shipped + yesterday."` ## **Returns** @@ -34,9 +38,9 @@ def check_order(args, raw_data): order_id = args.get("order_id") result = FunctionResult() if order_id: - result.set_response(f"Your order {order_id} shipped yesterday.") + result.set_response(f"Tell the caller order {order_id} shipped yesterday.") else: - result.set_response("I couldn't find that order number.") + result.set_response("Tell the caller you couldn't find that order number.") return result agent.serve() diff --git a/fern/products/server-sdks/pages/reference/python/agents/function-result/set-tool-response.mdx b/fern/products/server-sdks/pages/reference/python/agents/function-result/set-tool-response.mdx new file mode 100644 index 0000000000..af360cd15e --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/agents/function-result/set-tool-response.mdx @@ -0,0 +1,60 @@ +--- +title: "set_tool_response" +slug: /reference/python/agents/function-result/set-tool-response +description: Split the response into a factual result and a speaking instruction. +max-toc-depth: 3 +--- + +[functionresult]: /docs/server-sdks/reference/python/agents/function-result +[setresponse]: /docs/server-sdks/reference/python/agents/function-result/set-response + +Set the structured form of the response, separating what the tool did from what +the model should say next. The response becomes an object with up to two keys: + +```json +{ + "tool_result": "status: on hold", + "tool_prompt": "Tell the caller you are placing them on hold." +} +``` + +Splitting them keeps the model from reading a status line aloud, and keeps the +spoken instruction from being mistaken for data. For a single instruction +string, use [`set_response()`][setresponse]. + +## Parameters + + + What the tool did: a factual status line for the model to reason from, such + as `"payment declined"` or `"3 seats left"`. Omit it when there is nothing + to report beyond the instruction. + + + + What the model should now say, as an instruction in the second person. Omit + it for a silent, status-only result. + + +## Returns + +[`FunctionResult`][functionresult] — self, for chaining. + +## Example + +```python {10-13} +from signalwire import AgentBase +from signalwire import FunctionResult + +agent = AgentBase(name="my-agent", route="/agent") +agent.set_prompt_text("You are a helpful assistant.") + +@agent.tool(name="check_seats", description="Check remaining seats for a showing") +def check_seats(args, raw_data): + seats = 3 # look this up in your booking system + return FunctionResult().set_tool_response( + tool_result=f"seats remaining: {seats}", + tool_prompt="Tell the caller how many seats are left and ask how many they want.", + ) + +agent.serve() +``` diff --git a/fern/products/server-sdks/pages/reference/python/agents/function-result/stop-record-call.mdx b/fern/products/server-sdks/pages/reference/python/agents/function-result/stop-record-call.mdx index c8d3a06637..18c81f5c5d 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/function-result/stop-record-call.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/function-result/stop-record-call.mdx @@ -11,7 +11,7 @@ Stop an active background call recording. ## **Parameters** - + Identifier of the recording to stop. If not provided, the most recent recording is stopped. diff --git a/fern/products/server-sdks/pages/reference/python/agents/function-result/stop-tap.mdx b/fern/products/server-sdks/pages/reference/python/agents/function-result/stop-tap.mdx index b8615c3f85..3e3ca0daf6 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/function-result/stop-tap.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/function-result/stop-tap.mdx @@ -11,7 +11,7 @@ Stop an active media tap stream. ## **Parameters** - + Identifier of the tap to stop. If not provided, the most recently started tap is stopped. diff --git a/fern/products/server-sdks/pages/reference/python/agents/function-result/switch-context.mdx b/fern/products/server-sdks/pages/reference/python/agents/function-result/switch-context.mdx index 3049377b0b..4b7a083e02 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/function-result/switch-context.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/function-result/switch-context.mdx @@ -19,11 +19,11 @@ object-based context switch with fine-grained control. ## **Parameters** - + New system prompt to replace the current one. - + A user message to inject into the conversation after the context switch. diff --git a/fern/products/server-sdks/pages/reference/python/agents/function-result/tap.mdx b/fern/products/server-sdks/pages/reference/python/agents/function-result/tap.mdx index fa7977a1a4..1704259175 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/function-result/tap.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/function-result/tap.mdx @@ -22,20 +22,20 @@ if `codec` is not `"PCMU"` or `"PCMA"`, or if `rtp_ptime` is not a positive inte - `"wss://example.com"` — Secure WebSocket stream - + Identifier for this tap. Pass the same ID to `stop_tap()` to end this specific tap. If omitted, a default ID is generated. - + Audio direction to tap. - `"speak"` -- what the party says - - `"hear"` -- what the party hears + - `"listen"` -- what the party hears - `"both"` -- both directions - + Audio codec for the stream. - `"PCMU"` -- G.711 mu-law @@ -46,7 +46,7 @@ if `codec` is not `"PCMU"` or `"PCMA"`, or if `rtp_ptime` is not a positive inte Packetization time in milliseconds for RTP streams. Must be a positive integer. - + URL to receive tap status change webhooks. diff --git a/fern/products/server-sdks/pages/reference/python/agents/function-result/wait-for-user.mdx b/fern/products/server-sdks/pages/reference/python/agents/function-result/wait-for-user.mdx index e980da0cca..3e0bc0e438 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/function-result/wait-for-user.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/function-result/wait-for-user.mdx @@ -14,11 +14,11 @@ timeout. ## **Parameters** - + Explicitly enable (`True`) or disable (`False`) waiting for user input. - + Number of seconds to wait for the user to speak before the agent continues. diff --git a/fern/products/server-sdks/pages/reference/python/agents/handoff-router/escalate.mdx b/fern/products/server-sdks/pages/reference/python/agents/handoff-router/escalate.mdx new file mode 100644 index 0000000000..c214be9b2d --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/agents/handoff-router/escalate.mdx @@ -0,0 +1,36 @@ +--- +title: "escalate" +slug: /reference/python/agents/handoff-router/escalate +description: End a chat leg and wait for its record before a phone call is placed. +max-toc-depth: 3 +--- + +[ref-handoffrouter]: /docs/server-sdks/reference/python/agents/handoff-router +[read-handle]: /docs/server-sdks/reference/python/agents/chat-gateway/read-handle + +End a chat leg and wait for `capture_leg` to confirm its record. The browser calls `POST /escalate` +and waits on it before dialing, so the voice leg that follows is guaranteed to find the text leg +already recorded. The handle is verified with the gateway's [`read_handle()`][read-handle]. + +## Parameters + + + The chat handle the browser holds. + + +## Returns + +`bool` -- `True` when the handle was valid and the capture attempt has finished, +`False` for an invalid or expired handle. `True` doesn't confirm a record was +written: if `capture_leg` is unset, times out after `capture_timeout`, or raises, +the failure is logged and this still returns `True`. + +## Example + +```python +if not await handoff.escalate(handle): + return {"error": "not found"}, 404 +return {"ok": True} +``` + +See [`HandoffRouter`][ref-handoffrouter] for the route this backs. diff --git a/fern/products/server-sdks/pages/reference/python/agents/handoff-router/index.mdx b/fern/products/server-sdks/pages/reference/python/agents/handoff-router/index.mdx new file mode 100644 index 0000000000..de6b8d1b9b --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/agents/handoff-router/index.mdx @@ -0,0 +1,196 @@ +--- +title: "HandoffRouter" +slug: /reference/python/agents/handoff-router +description: The three routes a browser chat widget calls to move a conversation between text and a phone call. +max-toc-depth: 3 +--- + +[chatgateway]: /docs/server-sdks/reference/python/agents/chat-gateway +[mount]: /docs/server-sdks/reference/python/agents/agent-base/mount +[capabilities]: /docs/server-sdks/reference/python/core/capabilities +[register]: /docs/server-sdks/reference/python/agents/handoff-router/register +[redeem]: /docs/server-sdks/reference/python/agents/handoff-router/redeem +[escalate]: /docs/server-sdks/reference/python/agents/handoff-router/escalate +[say]: /docs/server-sdks/reference/python/agents/handoff-router/say +[router]: /docs/server-sdks/reference/python/agents/handoff-router/router +[read-handle]: /docs/server-sdks/reference/python/agents/chat-gateway/read-handle + +[`ChatGateway`][chatgateway] lets a browser hold a text conversation. `HandoffRouter` is the other +half the SignalWire address widget expects: three routes, served at the same URL prefix as the +gateway, that move that conversation to a phone call and back, and let a visitor type into a live +call. + +| Route | Body | Effect | +|---|---|---| +| `POST {prefix}/handoff` | `{"nonce"}` | End the call, wait for its record, return a chat handle for the next leg | +| `POST {prefix}/escalate` | `{"handle"}` | End the chat leg and wait for its record before a call is placed | +| `POST {prefix}/say` | `{"nonce", "text"}` | Deliver typed text into the live call | + +Every route checks the request origin against the gateway's allowlist. Unknown, expired, and +already-redeemed nonces all answer `404`, so a caller can't probe whether a given call is live. + +```python +from signalwire.ai_chat import ChatGateway, HandoffRouter + +gateway = ChatGateway(config_url="https://bayview-taxi.example.com/dispatch") +handoff = HandoffRouter(gateway=gateway, capture_leg=save_leg, end_call=hang_up) + +agent.mount(gateway.router(), prefix="/chat") +agent.mount(handoff.router(), prefix="/chat") +``` + +## How the nonce works + +A browser can't be trusted to name a call, since a page-supplied call ID would let anyone inject +speech into a stranger's call. Instead the browser proves which call it is on. Your application puts +a random `handoff_nonce` in the user variables of one dial, [registers][register] it against that +call's IDs from the dynamic-config callback, and the browser presents it later. The same dial +carries the `chat_handle`, so the callback recovers the conversation ID with +[`read_handle()`][read-handle]. +Redemption for a handle is single use. Typing is repeatable for the life of the call, bounded by +`max_messages_per_call`. + +A new medium never starts until the one it replaces has finished and your `capture_leg` callback has +confirmed its record is durable. Without that wait the new leg's config fetch races a record that is +still being written and opens knowing nothing. + + +Like the gateway's rate-limit counters, the registry lives in the serving process. A redemption must +reach the replica that served the dial. Run one replica, use sticky routing, or pass a shared +`registry`. + + +## Parameters + +Keyword-only. + + + The gateway that owns the conversations. Used to issue handles and to check origins, so both + halves of the URL enforce the same origin policy. + + + + Called as `capture_leg(conversation_id, medium)` to end a leg and write its record. Return a truthy + value only once that record is durable. Sync or async. When omitted, no wait happens and the + ordering guarantee isn't provided. + + + + Called as `end_call(call_id)` to hang the call up server-side so its teardown hooks fire + immediately. + + + + Called as `send_message(call_id, text)` for `/say`. Omit to leave typing disabled; the route then + answers `404`. + + + + Called as `next_conversation_id(conversation_id)` to produce the ID for the new leg. An ended + conversation can't be reopened, so a fresh ID is required. Defaults to appending `.1`, or + incrementing an existing `.N` suffix. + + + + Seconds a nonce stays redeemable. + + + + Ceiling on typed messages for one call. Each is a billable turn, so this is a spend guard as much + as an abuse guard. + + + + Seconds to wait for `capture_leg`. A ceiling, not a budget; capture is normally sub-second. On + timeout the next medium starts without this leg's record and a warning is logged. + + + + Shared mapping for the nonce table. Supply one backed by shared storage to run more than one + replica. + + +## Properties + + + What a nonce is a capability for. Importable from `signalwire.ai_chat`. + + + + + The conversation the nonce belongs to. + + + + The call it was registered against. + + + + Monotonic timestamp used for expiry. + + + + Typed messages delivered so far. + + + +## Methods + + + + Record what a nonce is a capability for. + + + Exchange a nonce for a chat handle. Single use. + + + End a chat leg and wait for its record. + + + Deliver typed text into a live call. + + + The APIRouter to mount beside the gateway's. + + + +## Example + +Register the nonce from the dynamic-config callback of the dial that carried it, reading the call ID +from the platform's request rather than from anything the browser sent. The +[`capabilities`][capabilities] helpers read the same user variables. + +```python {20-27,30-31} +from signalwire import AgentBase +from signalwire.ai_chat import ChatGateway, HandoffRouter +from signalwire.core.capabilities import user_variables + +agent = AgentBase(name="dispatch", route="/dispatch") +agent.set_prompt_text("You are Ada, the dispatcher for Bayview Taxi.") + +gateway = ChatGateway( + config_url="https://bayview-taxi.example.com/dispatch", + key="pk_your_publishable_key", + allowed_origins=["https://bayviewtaxi.example.com"], +) +handoff = HandoffRouter( + gateway=gateway, + capture_leg=save_leg, # your function: write the leg's transcript, return True when durable + end_call=hang_up, # your function: end the call server-side + send_message=inject_text, # your function: speak typed text into the call +) + +def remember_nonce(query_params, body_params, headers, ephemeral_agent): + variables = user_variables(body_params) + nonce = variables.get("handoff_nonce") + chat_handle = variables.get("chat_handle") + if nonce and chat_handle: + conversation_id = gateway.read_handle(chat_handle) + call_id = body_params.get("call", {}).get("call_id") + handoff.register(nonce, conversation_id=conversation_id, call_id=call_id) + +agent.add_per_call_config(remember_nonce) +agent.mount(gateway.router(), prefix="/chat") +agent.mount(handoff.router(), prefix="/chat") +agent.serve() +``` diff --git a/fern/products/server-sdks/pages/reference/python/agents/handoff-router/redeem.mdx b/fern/products/server-sdks/pages/reference/python/agents/handoff-router/redeem.mdx new file mode 100644 index 0000000000..3e0817cf83 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/agents/handoff-router/redeem.mdx @@ -0,0 +1,36 @@ +--- +title: "redeem" +slug: /reference/python/agents/handoff-router/redeem +description: Exchange a handoff nonce for a chat handle, ending the call first. +max-toc-depth: 3 +--- + +[ref-handoffrouter]: /docs/server-sdks/reference/python/agents/handoff-router +[mint-handle]: /docs/server-sdks/reference/python/agents/chat-gateway/mint-handle + +Exchange a nonce for a chat handle. Single use: the nonce is consumed even if a later step fails. +Ends the call through `end_call` when the nonce was registered with a call ID and `end_call` is +configured, waits for `capture_leg` to confirm the voice leg's record, and only then issues a handle for a new leg of the same conversation via the gateway's +[`mint_handle()`][mint-handle]. This is what `POST /handoff` calls. + +## Parameters + + + The nonce the browser presented. + + +## Returns + +`str | None` -- The signed handle, or `None` for an unknown, expired, or already-redeemed nonce. +The three cases are deliberately indistinguishable. + +## Example + +```python +handle = await handoff.redeem(nonce) +if handle is None: + return {"error": "not found"}, 404 +return {"handle": handle} +``` + +See [`HandoffRouter`][ref-handoffrouter] for the route this backs. diff --git a/fern/products/server-sdks/pages/reference/python/agents/handoff-router/register.mdx b/fern/products/server-sdks/pages/reference/python/agents/handoff-router/register.mdx new file mode 100644 index 0000000000..cc60737c93 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/agents/handoff-router/register.mdx @@ -0,0 +1,48 @@ +--- +title: "register" +slug: /reference/python/agents/handoff-router/register +description: Record which conversation and call a handoff nonce stands for. +max-toc-depth: 3 +--- + +[ref-handoffrouter]: /docs/server-sdks/reference/python/agents/handoff-router +[user-variables]: /docs/server-sdks/reference/python/core/capabilities/user-variables + +Record what a nonce is a capability for. Call it from the dynamic-config callback of the dial that +carried the nonce, reading `call_id` from the request the platform sent and never from anything the +browser supplied. Expired entries are pruned on every call. A nonce that isn't a non-empty string is +ignored. + +## Parameters + + + The random value your application placed in the dial's `handoff_nonce` user variable. Read it with + [`user_variables()`][user-variables]. + + + + The conversation this call continues. Keyword-only. + + + + The platform call ID. Required for `/handoff` to end the call and for `/say` to deliver text. + Keyword-only. + + +## Returns + +`None` + +## Example + +```python {3-7} +def remember_nonce(query_params, body_params, headers, ephemeral_agent): + variables = user_variables(body_params) + handoff.register( + variables["handoff_nonce"], + conversation_id=gateway.read_handle(variables["chat_handle"]), + call_id=body_params.get("call", {}).get("call_id"), + ) +``` + +See [`HandoffRouter`][ref-handoffrouter] for the full flow. diff --git a/fern/products/server-sdks/pages/reference/python/agents/handoff-router/router.mdx b/fern/products/server-sdks/pages/reference/python/agents/handoff-router/router.mdx new file mode 100644 index 0000000000..0af69797ce --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/agents/handoff-router/router.mdx @@ -0,0 +1,39 @@ +--- +title: "router" +slug: /reference/python/agents/handoff-router/router +description: Build the APIRouter serving the handoff, escalate, and say routes. +max-toc-depth: 3 +--- + +[ref-handoffrouter]: /docs/server-sdks/reference/python/agents/handoff-router +[mount]: /docs/server-sdks/reference/python/agents/agent-base/mount +[gateway-router]: /docs/server-sdks/reference/python/agents/chat-gateway/router + +Return an `APIRouter` serving `POST /handoff`, `POST /escalate`, and `POST /say`. Mount it at the +same prefix as the [gateway's router][gateway-router]: the browser derives all three paths from the +one URL it was configured with, so they must be siblings of the gateway's endpoint. + +Each route checks the `Origin` header against the gateway's allowlist and answers `403` when it +isn't allowed. A malformed or unknown nonce answers `404`; a missing handle on `/escalate` answers +`400`. + +## Parameters + +None. + +## Returns + +`fastapi.APIRouter` + +## Example + +```python {4-5} +gateway = ChatGateway(config_url="https://bayview-taxi.example.com/dispatch") +handoff = HandoffRouter(gateway=gateway, capture_leg=save_leg, end_call=hang_up) + +agent.mount(gateway.router(), prefix="/chat") +agent.mount(handoff.router(), prefix="/chat") +``` + +Use [`mount()`][mount] rather than `get_app().include_router()`, so the new routes aren't shadowed +by the agent's catch-all. See [`HandoffRouter`][ref-handoffrouter] for the full flow. diff --git a/fern/products/server-sdks/pages/reference/python/agents/handoff-router/say.mdx b/fern/products/server-sdks/pages/reference/python/agents/handoff-router/say.mdx new file mode 100644 index 0000000000..bd41f7362e --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/agents/handoff-router/say.mdx @@ -0,0 +1,39 @@ +--- +title: "say" +slug: /reference/python/agents/handoff-router/say +description: Deliver typed text into the live call a nonce names. +max-toc-depth: 3 +--- + +[ref-handoffrouter]: /docs/server-sdks/reference/python/agents/handoff-router + +Deliver typed text into the live call the nonce names, through your `send_message` callback. Doesn't +consume the nonce, since typing is repeatable for the life of the call, but stops once +`max_messages_per_call` is reached. Only the text is forwarded; no other request field reaches the +call. This is what `POST /say` calls. + +## Parameters + + + The nonce registered for the call. + + + + The text to deliver. Leading and trailing whitespace is stripped; empty text is rejected. + + +## Returns + +`bool` -- `True` when `send_message` ran without raising. `False` when `send_message` isn't +configured, the nonce is unknown or has no call ID, the text is empty, the message cap is reached, +or the callback raised. + +## Example + +```python +if not await handoff.say(nonce, "I'm at the north entrance."): + return {"error": "not found"}, 404 +return {"ok": True} +``` + +See [`HandoffRouter`][ref-handoffrouter] for the route this backs. diff --git a/fern/products/server-sdks/pages/reference/python/agents/helpers.mdx b/fern/products/server-sdks/pages/reference/python/agents/helpers.mdx index b2c2cd2bb0..1b19d476e0 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/helpers.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/helpers.mdx @@ -20,6 +20,7 @@ from signalwire import ( create_simple_context, create_simple_api_tool, create_expression_tool, + list_skills, list_skills_with_params, register_skill, add_skill_directory, @@ -198,6 +199,31 @@ need multiple patterns against the same test value. --- +## list_skills + +**list_skills**() -> `list[dict[str, Any]]` + +Return one summary dictionary per available skill. The lighter counterpart of +[`list_skills_with_params()`](#list_skills_with_params), drawn from the same +skill registry. + +#### Returns + +`list[dict[str, Any]]` -- One entry per skill with its name, description, +version, required packages and environment variables, and whether it supports +multiple instances. + +#### Example + +```python +from signalwire import list_skills + +for skill in list_skills(): + print(skill["name"], "-", skill["description"]) +``` + +--- + ## list_skills_with_params **list_skills_with_params**() -> `dict[str, dict[str, Any]]` diff --git a/fern/products/server-sdks/pages/reference/python/agents/livewire/agent-server/index.mdx b/fern/products/server-sdks/pages/reference/python/agents/livewire/agent-server/index.mdx index ebec07d0fa..205b9e1c8e 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/livewire/agent-server/index.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/livewire/agent-server/index.mdx @@ -36,7 +36,7 @@ run_app(server) ## **Properties** - + A setup function called before the entrypoint. Receives a [`JobProcess`][jobprocess] instance. Assign directly to register. diff --git a/fern/products/server-sdks/pages/reference/python/agents/livewire/agent-server/rtc-session.mdx b/fern/products/server-sdks/pages/reference/python/agents/livewire/agent-server/rtc-session.mdx index a602c81181..3114d8c212 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/livewire/agent-server/rtc-session.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/livewire/agent-server/rtc-session.mdx @@ -18,7 +18,7 @@ calling `session.start()`. ## **Parameters** - + The entrypoint function. When used as `@server.rtc_session()` with parentheses, `func` is `None` and the decorator returns a wrapper. When used as `@server.rtc_session` without parentheses, the function is passed directly. diff --git a/fern/products/server-sdks/pages/reference/python/agents/livewire/agent-session/generate-reply.mdx b/fern/products/server-sdks/pages/reference/python/agents/livewire/agent-session/generate-reply.mdx index 609788c7d2..05a8ee0ead 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/livewire/agent-session/generate-reply.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/livewire/agent-session/generate-reply.mdx @@ -11,7 +11,7 @@ additional text to speak. ## **Parameters** - + Optional instructions to include in the reply. diff --git a/fern/products/server-sdks/pages/reference/python/agents/livewire/agent-session/index.mdx b/fern/products/server-sdks/pages/reference/python/agents/livewire/agent-session/index.mdx index f2cc24c1eb..a9e494e929 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/livewire/agent-session/index.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/livewire/agent-session/index.mdx @@ -30,9 +30,9 @@ session = AgentSession() await session.start(agent) ``` -## **Constructor Parameters** +## Parameters - + Additional tools to register alongside the agent's tools. @@ -74,7 +74,7 @@ handles the full media pipeline automatically. MCP servers are not yet supported in LiveWire. -## **Properties** +## Properties Arbitrary data attached to the session. Accessible from tool handlers via @@ -86,7 +86,7 @@ in LiveWire. Conversation history as a list of `{"role": ..., "content": ...}` dicts. -## **Methods** +## Methods diff --git a/fern/products/server-sdks/pages/reference/python/agents/livewire/agent/index.mdx b/fern/products/server-sdks/pages/reference/python/agents/livewire/agent/index.mdx index c664f4dc4f..01c9f541bf 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/livewire/agent/index.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/livewire/agent/index.mdx @@ -41,7 +41,7 @@ agent = Agent( The system prompt text for the agent. - + The [`AgentSession`][agentsession] this agent is bound to. Set automatically when `session.start(agent)` is called. diff --git a/fern/products/server-sdks/pages/reference/python/agents/livewire/function-tool.mdx b/fern/products/server-sdks/pages/reference/python/agents/livewire/function-tool.mdx index 51a65ca278..081e5ac173 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/livewire/function-tool.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/livewire/function-tool.mdx @@ -29,16 +29,16 @@ are automatically excluded from the generated JSON schema and injected at call t #### Parameters - + The function to decorate. When `@function_tool` is used without parentheses, the decorated function is passed here directly. - + Override the tool name. Defaults to the function's `__name__`. - + Override the tool description. Defaults to the function's docstring. diff --git a/fern/products/server-sdks/pages/reference/python/agents/livewire/job-context.mdx b/fern/products/server-sdks/pages/reference/python/agents/livewire/job-context.mdx index 27dd27ce36..dd66dfa856 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/livewire/job-context.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/livewire/job-context.mdx @@ -54,14 +54,14 @@ agent connects when the platform invokes the SWML endpoint. #### wait_for_participant -**wait_for_participant**(`identity=None`) -> `None` +**wait_for_participant**(`*, identity=None`) -> `None` No-op. SignalWire handles participant management automatically. - - Participant identity to wait for. Accepted for API compatibility. + + Participant identity to wait for. Accepted for API compatibility. Keyword-only. --- diff --git a/fern/products/server-sdks/pages/reference/python/agents/livewire/run-context.mdx b/fern/products/server-sdks/pages/reference/python/agents/livewire/run-context.mdx index dd2ab7324c..887159824b 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/livewire/run-context.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/livewire/run-context.mdx @@ -32,7 +32,7 @@ when the tool is called by the LLM. ## **Properties** - + The [`AgentSession`][agentsession] that owns this context. May be `None` if the tool is invoked outside a session. diff --git a/fern/products/server-sdks/pages/reference/python/agents/mcp-gateway/session-manager/create-session.mdx b/fern/products/server-sdks/pages/reference/python/agents/mcp-gateway/session-manager/create-session.mdx index 14fe045c4e..322f46b7d0 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/mcp-gateway/session-manager/create-session.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/mcp-gateway/session-manager/create-session.mdx @@ -25,11 +25,11 @@ or the per-service session limit is exceeded. The MCP client process to associate with this session. - + Session timeout in seconds. Defaults to the manager's `default_timeout` (300). - + Arbitrary metadata to attach to the session. diff --git a/fern/products/server-sdks/pages/reference/python/agents/overview.mdx b/fern/products/server-sdks/pages/reference/python/agents/overview.mdx index 90e6930a52..00374fb5be 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/overview.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/overview.mdx @@ -84,6 +84,12 @@ if __name__ == "__main__": > Browser-facing gateway that keeps AI chat credentials and agent configuration on your server. + + Routes that move a chat conversation to a phone call and back, beside a ChatGateway. + - + List of bullet points for this section. @@ -31,7 +31,7 @@ Add a new top-level section to the POM. Whether to number bullet points instead of using bullet markers. - + List of subsection objects, each with `"title"`, optional `"body"`, and optional `"bullets"` keys. diff --git a/fern/products/server-sdks/pages/reference/python/agents/pom-builder/add-subsection.mdx b/fern/products/server-sdks/pages/reference/python/agents/pom-builder/add-subsection.mdx index e323728801..d78107034b 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/pom-builder/add-subsection.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/pom-builder/add-subsection.mdx @@ -24,7 +24,7 @@ it is created automatically. Subsection body text. - + Bullet points for the subsection. diff --git a/fern/products/server-sdks/pages/reference/python/agents/pom-builder/add-to-section.mdx b/fern/products/server-sdks/pages/reference/python/agents/pom-builder/add-to-section.mdx index f7071c3402..3922ce5dda 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/pom-builder/add-to-section.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/pom-builder/add-to-section.mdx @@ -16,15 +16,15 @@ automatically (auto-vivification). Section title to add content to. - + Text to append to the section body. Appended with a double newline separator. - + Single bullet point to add. - + Multiple bullet points to add. diff --git a/fern/products/server-sdks/pages/reference/python/agents/pom-builder/has-section.mdx b/fern/products/server-sdks/pages/reference/python/agents/pom-builder/has-section.mdx index 196e4125bb..53cf6a779b 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/pom-builder/has-section.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/pom-builder/has-section.mdx @@ -33,7 +33,7 @@ Get a section by title for direct manipulation. ### **Returns** -`Optional[Section]` -- The POM Section object, or `None` if not found. +`Section | None` -- The POM Section object, or `None` if not found. ## **Example** diff --git a/fern/products/server-sdks/pages/reference/python/agents/search/document-processor/index.mdx b/fern/products/server-sdks/pages/reference/python/agents/search/document-processor/index.mdx index e6e43e9224..107636a297 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/search/document-processor/index.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/search/document-processor/index.mdx @@ -32,14 +32,24 @@ Full document processing requires additional dependencies. Install with - Word count per chunk when using the `sliding` strategy. + Word count per chunk for the `sliding` strategy. The `markdown` strategy + also uses it as its split threshold, applied as `chunk_size * 6` + characters. Word overlap between chunks when using the `sliding` strategy. - + + For the `markdown` strategy, the minimum words a section needs before a + heading is allowed to start a new chunk. Shorter sections merge forward + into the next one rather than being emitted alone, which keeps a densely + headed document from producing chunks too thin to retrieve on. `0` splits + at every heading. + + + Number of consecutive newlines that trigger a split before sentence tokenization in the `sentence` strategy. `None` when not explicitly set. diff --git a/fern/products/server-sdks/pages/reference/python/agents/search/helpers.mdx b/fern/products/server-sdks/pages/reference/python/agents/search/helpers.mdx index 58c59a3c44..057f533f96 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/search/helpers.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/search/helpers.mdx @@ -53,7 +53,7 @@ also be called directly for custom search pipelines. Language code (e.g., `"en"`, `"es"`, `"fr"`) or `"auto"` for automatic detection. - + POS tags to expand with synonyms. Defaults to `["NOUN", "VERB", "ADJ"]`. @@ -73,10 +73,10 @@ also be called directly for custom search pipelines. NLP backend for query processing. Valid values: - `"nltk"` -- fast, lightweight (default) - - `"spacy"` -- better quality, requires spaCy models + - `"spacy"` -- slower; expands the query with WordNet synonyms. The effect depends on your corpus, so measure it rather than assuming it helps. Requires spaCy models. - + Sentence transformer model name for vectorization. Must match the model used to build the index being searched. If not specified, uses the default model. @@ -138,7 +138,9 @@ index construction. - NLP backend for processing. `"nltk"` or `"spacy"`. + NLP backend for document processing. + - `"nltk"` -- fast, the default. + - `"spacy"` -- slower; also expands content with WordNet synonyms, and the expansion is written into the index. The effect depends on your corpus, so measure it before choosing. Requires spaCy models. #### Returns diff --git a/fern/products/server-sdks/pages/reference/python/agents/search/index-builder/build-index-from-sources.mdx b/fern/products/server-sdks/pages/reference/python/agents/search/index-builder/build-index-from-sources.mdx index a8b60b0632..c4891c4098 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/search/index-builder/build-index-from-sources.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/search/index-builder/build-index-from-sources.mdx @@ -23,15 +23,15 @@ text extraction, chunking, embedding generation, and storage. File extensions to include when scanning directories (e.g., `["md", "txt", "py"]`). - + Glob patterns for files to exclude (e.g., `["**/node_modules/**"]`). - + List of language codes to support. Defaults to `["en"]`. - + Global tags to add to every chunk in the index. diff --git a/fern/products/server-sdks/pages/reference/python/agents/search/index-builder/build-index.mdx b/fern/products/server-sdks/pages/reference/python/agents/search/index-builder/build-index.mdx index a0f6b32107..e7fe8e85c3 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/search/index-builder/build-index.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/search/index-builder/build-index.mdx @@ -25,15 +25,15 @@ for the common case of indexing one directory. File extensions to include. - + Glob patterns to exclude. - + Language codes. Defaults to `["en"]`. - + Global tags for all chunks. diff --git a/fern/products/server-sdks/pages/reference/python/agents/search/index-builder/index.mdx b/fern/products/server-sdks/pages/reference/python/agents/search/index-builder/index.mdx index a3b72e8b34..925d853379 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/search/index-builder/index.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/search/index-builder/index.mdx @@ -36,6 +36,13 @@ for full document processing support. Active chunking strategy passed to the internal `DocumentProcessor`. + + For the `markdown` strategy, the minimum words a section needs before a + heading is allowed to start a new chunk. Shorter sections merge forward + into the next one instead of being emitted alone. `0` splits at every + heading. Recorded in the index metadata. + + Storage backend. Either `"sqlite"` or `"pgvector"`. @@ -45,7 +52,7 @@ for full document processing support. instance used for chunking. - + The loaded sentence transformer model. `None` until the first call to `build_index()` or `build_index_from_sources()`. diff --git a/fern/products/server-sdks/pages/reference/python/agents/search/search-engine/index.mdx b/fern/products/server-sdks/pages/reference/python/agents/search/search-engine/index.mdx index ddeabe9480..0fd89993dd 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/search/search-engine/index.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/search/search-engine/index.mdx @@ -39,7 +39,7 @@ Requires search dependencies. Install with `pip install signalwire-sdk[search]`. Dimensionality of the embedding vectors in the index. Defaults to `768`. - + Optional sentence transformer model instance passed at construction time. diff --git a/fern/products/server-sdks/pages/reference/python/agents/search/search-engine/search.mdx b/fern/products/server-sdks/pages/reference/python/agents/search/search-engine/search.mdx index eb4e699f98..8ee3f907e0 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/search/search-engine/search.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/search/search-engine/search.mdx @@ -37,16 +37,17 @@ The search pipeline works in three stages: threshold are filtered out. - + Filter results to only those containing at least one of the specified tags. - - Manual weight for keyword vs. vector scoring. When not set, the engine - uses its internal max-signal-wins scoring. + + Accepted for API compatibility and currently ignored. Scoring is always + max-signal-wins with an agreement boost, so setting this has no effect on + the results. - + The original unprocessed query string. Used for exact-match boosting. diff --git a/fern/products/server-sdks/pages/reference/python/agents/search/search-service/index.mdx b/fern/products/server-sdks/pages/reference/python/agents/search/search-service/index.mdx index f4904c63ca..ab9e9ba1b9 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/search/search-service/index.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/search/search-service/index.mdx @@ -25,7 +25,7 @@ Requires FastAPI and uvicorn in addition to search dependencies: ## **Properties** - + The FastAPI application instance. `None` if FastAPI is not installed. diff --git a/fern/products/server-sdks/pages/reference/python/agents/search/search-service/search-direct.mdx b/fern/products/server-sdks/pages/reference/python/agents/search/search-service/search-direct.mdx index 8d3f93b20e..e0ce7a3d6b 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/search/search-service/search-direct.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/search/search-service/search-direct.mdx @@ -27,11 +27,11 @@ the full preprocessing pipeline but do not need network overhead. Minimum similarity threshold for results. - + Filter results by tags. - + Language code for query processing, or `None` for auto-detection. diff --git a/fern/products/server-sdks/pages/reference/python/agents/search/search-service/start.mdx b/fern/products/server-sdks/pages/reference/python/agents/search/search-service/start.mdx index 8a191e7a5a..db81d83476 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/search/search-service/start.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/search/search-service/start.mdx @@ -15,15 +15,15 @@ reload endpoints. Host address to bind to. - + Port to bind to. Defaults to the port set in the constructor. - + Path to an SSL certificate file for HTTPS. Overrides environment settings. - + Path to an SSL key file for HTTPS. Overrides environment settings. diff --git a/fern/products/server-sdks/pages/reference/python/agents/swaig-function/execute.mdx b/fern/products/server-sdks/pages/reference/python/agents/swaig-function/execute.mdx index f7b3cddcfb..082be3557b 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/swaig-function/execute.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/swaig-function/execute.mdx @@ -16,7 +16,7 @@ the return value into a FunctionResult dictionary. Parsed arguments for the function, matching the parameter schema. - + Full raw request data including `global_data`, `call_id`, `caller_id_number`, `meta_data`, and `ai_session_id`. diff --git a/fern/products/server-sdks/pages/reference/python/agents/swaig-function/index.mdx b/fern/products/server-sdks/pages/reference/python/agents/swaig-function/index.mdx index 18fded6d1d..63e9c6e6eb 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/swaig-function/index.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/swaig-function/index.mdx @@ -62,20 +62,20 @@ full specification. Whether token authentication is required. - + Filler phrases by language code to speak while the function executes (e.g., `{"en-US": ["Let me check on that..."]}`). - + URL of an audio file to play while the function executes. Preferred over `fillers`. - + Number of times to loop `wait_file`. Defaults to playing once. - + External webhook URL. When set, the function call is forwarded to this URL instead of being handled locally. diff --git a/fern/products/server-sdks/pages/reference/python/agents/swaig-function/to-swaig.mdx b/fern/products/server-sdks/pages/reference/python/agents/swaig-function/to-swaig.mdx index 9e34c1aae2..09cfaca9ba 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/swaig-function/to-swaig.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/swaig-function/to-swaig.mdx @@ -14,11 +14,11 @@ document. Called internally during SWML rendering. Base URL for the webhook endpoint. - + Auth token to include in the webhook URL. - + Call ID for session tracking. diff --git a/fern/products/server-sdks/pages/reference/python/agents/swml-builder/ai.mdx b/fern/products/server-sdks/pages/reference/python/agents/swml-builder/ai.mdx index e8f0d0cf4c..46ce061512 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/swml-builder/ai.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/swml-builder/ai.mdx @@ -14,25 +14,25 @@ set the AI system prompt, but not both. ## **Parameters** - + Plain text system prompt for the AI. Mutually exclusive with `prompt_pom`. - + Prompt Object Model (POM) structure for the AI prompt. A list of section dictionaries with keys like `"section"`, `"body"`, and `"bullets"`. Mutually exclusive with `prompt_text`. - + Instructions for summarizing the call after the AI conversation ends. - + URL where the post-prompt summary is sent via webhook. - + SWAIG (SignalWire AI Gateway) configuration with tool function definitions and defaults. Structure: `{"defaults": {"web_hook_url": "..."}, "functions": [...]}`. diff --git a/fern/products/server-sdks/pages/reference/python/agents/swml-builder/answer.mdx b/fern/products/server-sdks/pages/reference/python/agents/swml-builder/answer.mdx index 866025132a..8e92f82124 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/swml-builder/answer.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/swml-builder/answer.mdx @@ -9,12 +9,12 @@ Add an `answer` verb to the main section. Answers an incoming call. ## **Parameters** - + Maximum call duration in seconds. The call is automatically hung up after this duration elapses. - + Comma-separated list of audio codecs to use for the call. Valid values include: `PCMU`, `PCMA`, `G722`, `G729`, `AMR-WB`, `OPUS`, `VP8`, `H264`. diff --git a/fern/products/server-sdks/pages/reference/python/agents/swml-builder/hangup.mdx b/fern/products/server-sdks/pages/reference/python/agents/swml-builder/hangup.mdx index ef1b302836..a034243d45 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/swml-builder/hangup.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/swml-builder/hangup.mdx @@ -9,7 +9,7 @@ Add a `hangup` verb to the main section. Ends the current call. ## **Parameters** - + Reason for the hangup. Valid values: `"hangup"`, `"busy"`, `"decline"`. diff --git a/fern/products/server-sdks/pages/reference/python/agents/swml-builder/play.mdx b/fern/products/server-sdks/pages/reference/python/agents/swml-builder/play.mdx index 34d4a0e6ae..c4093eef2d 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/swml-builder/play.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/swml-builder/play.mdx @@ -14,32 +14,32 @@ raises a `ValueError`. ## **Parameters** - + Single URL to play. Supports audio file URLs and the `say:` prefix for text-to-speech (e.g., `"say:Hello world"`). Mutually exclusive with `urls`. - + List of URLs to play in sequence. Mutually exclusive with `url`. - + Volume adjustment level, from `-40` to `40` dB. - + Voice name for text-to-speech playback. - + Language code for text-to-speech (e.g., `"en-US"`). - + Gender for text-to-speech voice selection. - + Whether to automatically answer the call before playing audio. diff --git a/fern/products/server-sdks/pages/reference/python/agents/swml-builder/say.mdx b/fern/products/server-sdks/pages/reference/python/agents/swml-builder/say.mdx index c798eb1d74..686fef994a 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/swml-builder/say.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/swml-builder/say.mdx @@ -17,19 +17,19 @@ constructs the `say:` URL automatically. The text to speak. - + Voice name for text-to-speech. - + Language code (e.g., `"en-US"`). - + Gender for voice selection. - + Volume adjustment level, from `-40` to `40` dB. diff --git a/fern/products/server-sdks/pages/reference/python/agents/swml-service/add-verb-to-section.mdx b/fern/products/server-sdks/pages/reference/python/agents/swml-service/add-verb-to-section.mdx index fa52e0380d..094faa61a7 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/swml-service/add-verb-to-section.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/swml-service/add-verb-to-section.mdx @@ -9,6 +9,11 @@ Add a verb to a specific named section of the SWML document. If the section does exist, it is created automatically before the verb is appended. Raises `SchemaValidationError` if validation is enabled and the verb config is invalid. +For verbs with a registered handler, such as `ai`, the handler validates the +verb's shape and the top-level keys are then checked against the schema, so a +misspelled or unknown top-level key raises. Nested shapes such as `ai.params` +are left to the handler. + ## **Parameters** diff --git a/fern/products/server-sdks/pages/reference/python/agents/swml-service/add-verb.mdx b/fern/products/server-sdks/pages/reference/python/agents/swml-service/add-verb.mdx index 3bd6197484..7a0d7058a1 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/swml-service/add-verb.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/swml-service/add-verb.mdx @@ -11,6 +11,11 @@ Add a verb to the `main` section of the current SWML document. The verb is valid against the SWML schema (or a registered custom handler) before being appended. Raises `SchemaValidationError` if validation is enabled and the verb config is invalid. +For verbs with a registered handler, such as `ai`, the handler validates the +verb's shape and the top-level keys are then checked against the schema, so a +misspelled or unknown top-level key raises. Nested shapes such as `ai.params` +are left to the handler. + [SWMLService][ref-swmlservice] also auto-generates convenience methods for every verb defined in the SWML schema (e.g., `service.play(url=...)`, `service.connect(to=...)`). These call `add_verb` diff --git a/fern/products/server-sdks/pages/reference/python/agents/swml-service/as-router.mdx b/fern/products/server-sdks/pages/reference/python/agents/swml-service/as-router.mdx index c0a545885b..6d79754f49 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/swml-service/as-router.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/swml-service/as-router.mdx @@ -27,7 +27,8 @@ via [`AgentServer`][agentserver]. ## **Returns** -`APIRouter` — A FastAPI router with all endpoints registered. +`HostAppRouter` — A FastAPI `APIRouter` subclass with all endpoints registered. +It adds no behavior; the subclass exists to give the return type a stable name. ## **Example** diff --git a/fern/products/server-sdks/pages/reference/python/agents/swml-service/handle-request.mdx b/fern/products/server-sdks/pages/reference/python/agents/swml-service/handle-request.mdx new file mode 100644 index 0000000000..569b93a913 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/agents/swml-service/handle-request.mdx @@ -0,0 +1,64 @@ +--- +title: "handle_request" +slug: /reference/python/agents/swml-service/handle-request +description: Dispatch one HTTP request to the service without a web framework. +max-toc-depth: 3 +--- + +[on-request]: /docs/server-sdks/reference/python/agents/swml-service/on-request +[register-routing-callback]: /docs/server-sdks/reference/python/agents/swml-service/register-routing-callback + +Dispatch a request over plain values instead of FastAPI objects. Performs proxy +detection, basic auth, the [routing callback][register-routing-callback] check, +and [`on_request()`][on-request] modification, then renders the document. The +FastAPI routes delegate to the same logic, so both paths return identical +responses. Basic auth is always on: pass `basic_auth` to the constructor and +send a matching `Authorization` header, or the call returns `401`. + +## Parameters + + + HTTP method, such as `"GET"` or `"POST"`. + + + + The full request URL. Used for proxy detection and to match a registered + routing callback path. + + + + Request headers as a plain dictionary. + + + + The already-parsed JSON body for `POST` requests. + + +## Returns + +`tuple[int, dict[str, str], str]` -- `(status_code, response_headers, body)`. + +- `200` with the SWML document as a JSON string. +- `307` with a `Location` header and an empty body when a routing callback + returned a destination. +- `401` with `WWW-Authenticate: Basic` and a JSON error when basic auth fails. + +## Example + +```python {10-15} +import base64 +import json +from signalwire import SWMLService + +service = SWMLService(name="greeting", route="/greeting", basic_auth=("greeting", "s3cret")) +service.add_verb("answer", {}) +service.add_verb("play", {"url": "say:Welcome to Bayview Taxi."}) + +credentials = base64.b64encode(b"greeting:s3cret").decode() +status, headers, body = service.handle_request( + "GET", + "https://bayview-taxi.example.com/greeting", + {"authorization": f"Basic {credentials}"}, +) +print(status, json.loads(body)["sections"]["main"]) +``` diff --git a/fern/products/server-sdks/pages/reference/python/agents/swml-service/index.mdx b/fern/products/server-sdks/pages/reference/python/agents/swml-service/index.mdx index 85b923908b..e28bb558a7 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/swml-service/index.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/swml-service/index.mdx @@ -131,21 +131,24 @@ and `full_validation_enabled` to check validation status. Create a FastAPI APIRouter for mounting the service into an existing application. + + Static utility to extract the SIP username from request body data. + Retrieve the HTTP Basic Auth credentials for the service. Get the current SWML document as a Python dictionary. + + Dispatch one HTTP request without a web framework. + Manually set the proxy URL base for webhook callback generation. Request handling hook for customizing SWML output per request. - - Static utility to extract the SIP username from request body data. - Register routing callbacks for dynamic request handling and SIP routing. diff --git a/fern/products/server-sdks/pages/reference/python/agents/swml-service/on-request.mdx b/fern/products/server-sdks/pages/reference/python/agents/swml-service/on-request.mdx index dfb2342d38..2577cb3824 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/swml-service/on-request.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/swml-service/on-request.mdx @@ -25,12 +25,12 @@ SignalWire. ## **Parameters** - + The parsed POST body as a dictionary, or an empty dict for GET requests. Typically contains call metadata from SignalWire (e.g., `call.to`, `call.from`, `call.headers`). - + The routing callback path that matched this request, if any. This is set when the request came through a path registered via [`register_routing_callback()`][register-routing-callback]. @@ -39,7 +39,7 @@ SignalWire. ## **Returns** -`Optional[dict]` — Return `None` to serve the document unchanged. Return a dictionary +`dict | None` — Return `None` to serve the document unchanged. Return a dictionary to merge modifications into the top-level SWML document (keys in the returned dict replace corresponding keys in the document). diff --git a/fern/products/server-sdks/pages/reference/python/agents/swml-service/register-routing-callback.mdx b/fern/products/server-sdks/pages/reference/python/agents/swml-service/register-routing-callback.mdx index 2796ebc164..bf79b995e2 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/swml-service/register-routing-callback.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/swml-service/register-routing-callback.mdx @@ -14,8 +14,8 @@ the request to a different endpoint or let normal processing continue. This is p used for SIP-based routing where the destination depends on the incoming SIP URI. An HTTP endpoint is automatically created at the specified path when the service starts. -The callback receives the raw FastAPI `Request` object and the parsed request body as -a dictionary. +The callback receives the parsed request body and the request headers, both as a +dictionary — `callback_fn(body, headers)`. This is also how you receive an [`ai_sidecar`](/docs/swml/reference/calling/ai-sidecar) verb's webhook @@ -33,10 +33,11 @@ starting the server. ## **Parameters** - - A function that receives a FastAPI `Request` and the parsed JSON body as a `dict`. - Return a route string to redirect the request (using HTTP 307 to preserve the POST - method and body), or return `None` to continue with normal SWML document serving. + + A function that receives the parsed JSON body and the request headers, both as a + `dict` — `callback_fn(body, headers)`. Return a route string to redirect the request + (using HTTP 307 to preserve the POST method and body), or return `None` to continue + with normal SWML document serving. @@ -65,7 +66,7 @@ the `call.to` field. ### **Returns** -`Optional[str]` — The extracted username or phone number, or `None` if the `call.to` +`str | None` — The extracted username or phone number, or `None` if the `call.to` field is missing or cannot be parsed. ### **Example** @@ -77,7 +78,7 @@ from signalwire import SWMLService service = SWMLService(name="sip-router", route="/") -def route_sip_call(request, body): +def route_sip_call(body, headers): """Route calls based on the SIP username in the request.""" username = SWMLService.extract_sip_username(body) if username == "sales": diff --git a/fern/products/server-sdks/pages/reference/python/agents/swml-service/serve.mdx b/fern/products/server-sdks/pages/reference/python/agents/swml-service/serve.mdx index b1083d68b9..d29dab8712 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/swml-service/serve.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/swml-service/serve.mdx @@ -21,32 +21,32 @@ console. If routing callbacks are registered, their endpoint URLs are also displ ## **Parameters** - + Host to bind to. Overrides the value set in the constructor. When `None`, uses the constructor's `host` value. - + Port to bind to. Overrides the value set in the constructor. When `None`, uses the constructor's `port` value. - + Path to an SSL certificate file. Overrides the `SWML_SSL_CERT_PATH` environment variable. - + Path to an SSL private key file. Overrides the `SWML_SSL_KEY_PATH` environment variable. - + Explicitly enable or disable SSL. Overrides the `SWML_SSL_ENABLED` environment variable. - + Domain name for the SSL certificate. Used for URL generation when SSL is enabled. diff --git a/fern/products/server-sdks/pages/reference/python/agents/web-service/index.mdx b/fern/products/server-sdks/pages/reference/python/agents/web-service/index.mdx index b57c83b16c..53f02771d4 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/web-service/index.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/web-service/index.mdx @@ -56,12 +56,12 @@ web.start() Whether CORS middleware is enabled. - + If set, only files with these extensions are served (e.g., `[".html", ".css"]`). When `None`, all extensions except those in `blocked_extensions` are allowed. - + File extensions and names that are never served. Defaults to `.env`, `.git`, `.gitignore`, `.key`, `.pem`, `.crt`, `.pyc`, `__pycache__`, `.DS_Store`, `.swp`. @@ -73,8 +73,8 @@ web.start() -The constructor also accepts `basic_auth` (`Optional[tuple[str, str]]`) and -`config_file` (`Optional[str]`) parameters. These are not exposed as public +The constructor also accepts `basic_auth` (`tuple[str, str] | None`) and +`config_file` (`str | None`) parameters. These are not exposed as public instance attributes after initialization. diff --git a/fern/products/server-sdks/pages/reference/python/agents/web-service/start.mdx b/fern/products/server-sdks/pages/reference/python/agents/web-service/start.mdx index 4da7ed3d50..a6e48dcdfd 100644 --- a/fern/products/server-sdks/pages/reference/python/agents/web-service/start.mdx +++ b/fern/products/server-sdks/pages/reference/python/agents/web-service/start.mdx @@ -21,16 +21,16 @@ environment variables. Host address to bind to. - + Port to bind to. Defaults to the `port` set in the constructor. - + Path to an SSL certificate file. Overrides environment-based SSL configuration. - + Path to an SSL key file. Overrides environment-based SSL configuration. diff --git a/fern/products/server-sdks/pages/reference/python/core/capabilities/declared-capabilities.mdx b/fern/products/server-sdks/pages/reference/python/core/capabilities/declared-capabilities.mdx new file mode 100644 index 0000000000..67314a0de3 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/core/capabilities/declared-capabilities.mdx @@ -0,0 +1,38 @@ +--- +title: "declared_capabilities" +slug: /reference/python/core/capabilities/declared-capabilities +description: Return the set of capability names a client declared as truthy. +max-toc-depth: 3 +--- + +[ref-capabilities]: /docs/server-sdks/reference/python/core/capabilities + +Return the capability names the client declared as truthy. Accepts either a full SWML request body +or an already-extracted user variables dict, so it works from a dynamic-config callback and from a +SWAIG handler without the caller tracking which one it holds. + +## Parameters + + + A SWML request body, or a user variables dict. + + +## Returns + +`frozenset[str]` -- Names whose declared value is truthy. Empty when nothing was declared, the +payload was malformed, or the client isn't a browser at all. + +## Example + +```python {4} +from signalwire.core.capabilities import declared_capabilities + +def configure(query_params, body_params, headers, ephemeral_agent): + caps = declared_capabilities(body_params) + if "display_content" in caps: + ephemeral_agent.prompt_add_section("Screen", body="The caller can see a screen.") + if "chat_handoff" in caps: + ephemeral_agent.prompt_add_section("Chat", body="Offer to continue by text if asked.") +``` + +Part of the [client capabilities][ref-capabilities] module. diff --git a/fern/products/server-sdks/pages/reference/python/core/capabilities/has-capability.mdx b/fern/products/server-sdks/pages/reference/python/core/capabilities/has-capability.mdx new file mode 100644 index 0000000000..e6e43c5d3e --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/core/capabilities/has-capability.mdx @@ -0,0 +1,38 @@ +--- +title: "has_capability" +slug: /reference/python/core/capabilities/has-capability +description: Whether a client explicitly declared one named capability. +max-toc-depth: 3 +--- + +[ref-capabilities]: /docs/server-sdks/reference/python/core/capabilities +[declared-capabilities]: /docs/server-sdks/reference/python/core/capabilities/declared-capabilities + +Whether the client declared `name`. A convenience over +[`declared_capabilities()`][declared-capabilities] for a single check. + +## Parameters + + + A SWML request body, or a user variables dict. + + + + Capability name, such as `"display_content"`. + + +## Returns + +`bool` -- `True` only when the capability was explicitly declared truthy. + +## Example + +```python {4} +from signalwire.core.capabilities import has_capability + +def configure(query_params, body_params, headers, ephemeral_agent): + if has_capability(body_params, "transcript"): + ephemeral_agent.set_global_data({"show_transcript": True}) +``` + +Part of the [client capabilities][ref-capabilities] module. diff --git a/fern/products/server-sdks/pages/reference/python/core/capabilities/index.mdx b/fern/products/server-sdks/pages/reference/python/core/capabilities/index.mdx new file mode 100644 index 0000000000..c2b50507ce --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/core/capabilities/index.mdx @@ -0,0 +1,82 @@ +--- +title: "Client capabilities" +slug: /reference/python/core/capabilities +description: Read the rendering capabilities a browser client declares in its user variables at dial time. +max-toc-depth: 3 +--- + +[user-variables]: /docs/server-sdks/reference/python/core/capabilities/user-variables +[declared-capabilities]: /docs/server-sdks/reference/python/core/capabilities/declared-capabilities +[has-capability]: /docs/server-sdks/reference/python/core/capabilities/has-capability +[handoff-router]: /docs/server-sdks/reference/python/agents/handoff-router + +A browser client such as the SignalWire address widget declares what it can render in the user +variables it sends at dial time. The `signalwire.core.capabilities` module reads those +declarations so an agent can decide what to offer: whether to push content to a screen, whether to +advertise a text-handoff tool. + +```json +{ + "vars": { + "userVariables": { + "capabilities": { + "display_content": true, + "transcript": true, + "chat_handoff": false + } + } + } +} +``` + + +A capability says what the client can render. It is never permission to do anything privileged, +because a caller controls its own user variables. Use these values as hints for what to offer. + + +Absence means no. Every function resolves errors and missing data to "not declared", because +offering a caller something they can't reach is worse than never mentioning it: a phone caller has no +screen. There is no fixed list of capability names; a client can declare a name this SDK has never +seen and your application can act on it. + +```python +from signalwire.core.capabilities import declared_capabilities, has_capability, user_variables +``` + +## Functions + + + + Return the user variables from a SWML request body. + + + Return the capability names the client declared as truthy. + + + Whether the client declared one named capability. + + + +## Example + +Offer a screen-only tool to callers who can render it: + +```python {8-12} +from signalwire import AgentBase +from signalwire.core.capabilities import has_capability + +agent = AgentBase(name="dispatch", route="/dispatch") +agent.set_prompt_text("You are Ada, the dispatcher for Bayview Taxi.") + +def configure(query_params, body_params, headers, ephemeral_agent): + if has_capability(body_params, "display_content"): + ephemeral_agent.prompt_add_section( + "Screen", + body="The caller can see a screen. Offer to show the fare breakdown there.", + ) + +agent.add_per_call_config(configure) +agent.serve() +``` + +For moving a conversation between chat and a call, see [`HandoffRouter`][handoff-router]. diff --git a/fern/products/server-sdks/pages/reference/python/core/capabilities/user-variables.mdx b/fern/products/server-sdks/pages/reference/python/core/capabilities/user-variables.mdx new file mode 100644 index 0000000000..bf27519ee4 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/core/capabilities/user-variables.mdx @@ -0,0 +1,34 @@ +--- +title: "user_variables" +slug: /reference/python/core/capabilities/user-variables +description: Return the user variables nested inside a SWML request body. +max-toc-depth: 3 +--- + +[ref-capabilities]: /docs/server-sdks/reference/python/core/capabilities + +Return the user variables from a SWML request body. They are nested two levels down, at +`vars.userVariables`, which is easy to get wrong silently: a missing level yields an empty dict and +every downstream check quietly reports "not declared". + +## Parameters + + + The SWML request body, as passed to a dynamic-config callback or SWAIG handler. + + +## Returns + +`dict[str, Any]` -- The user variables, or `{}` when absent or malformed. Never raises. + +## Example + +```python {4} +from signalwire.core.capabilities import user_variables + +def configure(query_params, body_params, headers, ephemeral_agent): + variables = user_variables(body_params) + nonce = variables.get("handoff_nonce") +``` + +Part of the [client capabilities][ref-capabilities] module. diff --git a/fern/products/server-sdks/pages/reference/python/core/post-prompt/dialogue-turns.mdx b/fern/products/server-sdks/pages/reference/python/core/post-prompt/dialogue-turns.mdx new file mode 100644 index 0000000000..fd9ab61ca0 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/core/post-prompt/dialogue-turns.mdx @@ -0,0 +1,52 @@ +--- +title: "dialogue_turns" +slug: /reference/python/core/post-prompt/dialogue-turns +description: Extract the user and assistant turns from a call log, dropping tool traffic and the summary echo. +max-toc-depth: 3 +--- + +[ref-post-prompt]: /docs/server-sdks/reference/python/core/post-prompt + +Extract the real dialogue from a call log. Drops everything that is machinery rather than speech: +entries whose role isn't in `roles`, entries carrying `tool_calls`, and empty content. The +`system`, `system-log`, `tool`, and `assistant-manual` roles are all excluded by default. + +`drop_echo` handles one engine behavior. The chat engine appends its own post-prompt output to +`call_log` as a bare `role: assistant` entry, indistinguishable by role from real speech. Replayed +into another medium, the agent would narrate a summary of itself. It is identifiable only by +content, being identical to `post_prompt_data.raw`, which is what this parameter compares against. + +## Parameters + + + The log, as delivered in `call_log`, `raw_call_log`, or `raw_messages`. A non-list value yields + `[]`. + + + + Roles to keep. Keyword-only. The default is exported as `DIALOGUE_ROLES`. + + + + Exact content to treat as the summary echo and drop. Keyword-only. + + +## Returns + +`list[dict[str, str]]` -- `{"role", "content"}` pairs in order. + +## Example + +```python {4-7} +from signalwire.core.post_prompt import dialogue_turns + +raw_summary = raw_body.get("post_prompt_data", {}).get("raw") +turns = dialogue_turns( + raw_body.get("call_log", []), + drop_echo=raw_summary, +) +for turn in turns: + print(turn["role"], turn["content"]) +``` + +Part of the [post-prompt normalization][ref-post-prompt] module. diff --git a/fern/products/server-sdks/pages/reference/python/core/post-prompt/index.mdx b/fern/products/server-sdks/pages/reference/python/core/post-prompt/index.mdx new file mode 100644 index 0000000000..2d38bc2356 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/core/post-prompt/index.mdx @@ -0,0 +1,111 @@ +--- +title: "Post-prompt normalization" +slug: /reference/python/core/post-prompt +description: Read voice and chat post-prompt bodies as one shape, with the summary parsed and the dialogue extracted. +max-toc-depth: 3 +--- + +[normalize]: /docs/server-sdks/reference/python/core/post-prompt/normalize-post-prompt +[parse]: /docs/server-sdks/reference/python/core/post-prompt/parse-post-prompt-data +[dialogue]: /docs/server-sdks/reference/python/core/post-prompt/dialogue-turns +[strip]: /docs/server-sdks/reference/python/core/post-prompt/strip-json-fence +[on-summary]: /docs/server-sdks/reference/python/agents/agent-base/on-summary +[on-call-end]: /docs/server-sdks/reference/python/agents/agent-base/on-call-end + +One conversation can run over voice and over text chat, and both produce a post-prompt body, but not +the same shape. The `signalwire.core.post_prompt` module absorbs that divergence so your +application sees one artifact regardless of which engine finished the conversation. + +| Field | Voice | Chat | +|---|---|---| +| `app_name` | `"swml app"` | `"ai_chat"` | +| `conversation_id` | absent | present at top level | +| Full log | `raw_call_log` | `raw_messages` | +| Summary arrives as | a `summarize_conversation` tool call | a bare `role: assistant` turn inside `call_log` | +| `post_prompt_data` | parsed object | `{"raw": ""}` | + +`conversation_type` is a reliable top-level discriminator on both. The voice engine can also +deliver `post_prompt_data` as `{"parsed": [ {...} ], "raw": "..."}`, an object wrapped in a +list, which passes structural checks and misses every field lookup. The parser unwraps it. + +The module doesn't decide what a summary should contain. The schema is whatever your post-prompt +text asked the model to produce, so parsing is schema-agnostic and returns the dict as found. +Nothing here raises: the conversation that produced the body is already over. + +```python +from signalwire.core.post_prompt import NormalizedPostPrompt, normalize_post_prompt +``` + +## Properties + +`NormalizedPostPrompt` is a frozen dataclass, one finished conversation leg in a shape that doesn't +vary by engine. + + + `conversation_type` as reported, such as `"voice"` or `"chat"`. Empty when the engine didn't say. + + + + Present on chat, absent on voice. When `None`, fall back to your own key from `global_data` or + `call_id` rather than treating this as authoritative. + + + + The parsed `post_prompt_data`, with whatever keys your post-prompt asked for. `{}` when there was + none or it couldn't be parsed. A model that answered in prose instead of JSON yields + `{"summary": ""}`. + + + + `user` and `assistant` turns only, as `{"role", "content"}` pairs, with tool calls and the chat + engine's summary echo removed. + + + + The platform call ID, when present. + + + + The complete request body, untouched. + + +## Functions + + + + Normalize a post-prompt body from either engine. + + + Return post_prompt_data as a plain dict, whichever shape it arrived in. + + + Extract the user and assistant turns from a call log. + + + Unwrap a fenced JSON code block. + + + +## Example + +Store every finished leg the same way, whether it came from +[`on_summary()`][on-summary] or [`on_call_end()`][on-call-end]: + +```python {11-14} +from signalwire import AgentBase +from signalwire.core.post_prompt import normalize_post_prompt + +class DispatchAgent(AgentBase): + def __init__(self): + super().__init__(name="dispatch", route="/dispatch") + self.set_prompt_text("You are Ada, the dispatcher for Bayview Taxi.") + self.set_post_prompt("Summarize the call as JSON with keys intent and resolved.") + + def on_summary(self, summary, raw_data=None): + leg = normalize_post_prompt(raw_data) + if leg.dialogue: + # Write to your system of record. + print(leg.medium, leg.conversation_id or leg.call_id, leg.summary) + +DispatchAgent().serve() +``` diff --git a/fern/products/server-sdks/pages/reference/python/core/post-prompt/normalize-post-prompt.mdx b/fern/products/server-sdks/pages/reference/python/core/post-prompt/normalize-post-prompt.mdx new file mode 100644 index 0000000000..829172b6fa --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/core/post-prompt/normalize-post-prompt.mdx @@ -0,0 +1,36 @@ +--- +title: "normalize_post_prompt" +slug: /reference/python/core/post-prompt/normalize-post-prompt +description: Normalize a post-prompt body from the voice or chat engine into one shape. +max-toc-depth: 3 +--- + +[ref-post-prompt]: /docs/server-sdks/reference/python/core/post-prompt +[parse]: /docs/server-sdks/reference/python/core/post-prompt/parse-post-prompt-data +[dialogue]: /docs/server-sdks/reference/python/core/post-prompt/dialogue-turns + +Normalize a post-prompt body from either engine. Parses `post_prompt_data` with +[`parse_post_prompt_data()`][parse], reads the log from `call_log`, `raw_call_log`, or +`raw_messages`, and extracts the dialogue with [`dialogue_turns()`][dialogue], dropping the chat +engine's summary echo by comparing against the raw summary string. + +## Parameters + + + The complete post-prompt request body. + + +## Returns + +[`NormalizedPostPrompt`][ref-post-prompt] -- Never raises. A body the function can't make sense of +yields one with empty fields. + +## Example + +```python {3} +from signalwire.core.post_prompt import normalize_post_prompt + +leg = normalize_post_prompt(raw_body) +if leg.dialogue: + store(leg.conversation_id, leg.medium, leg.summary, leg.dialogue) +``` diff --git a/fern/products/server-sdks/pages/reference/python/core/post-prompt/parse-post-prompt-data.mdx b/fern/products/server-sdks/pages/reference/python/core/post-prompt/parse-post-prompt-data.mdx new file mode 100644 index 0000000000..87f7c9b28b --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/core/post-prompt/parse-post-prompt-data.mdx @@ -0,0 +1,40 @@ +--- +title: "parse_post_prompt_data" +slug: /reference/python/core/post-prompt/parse-post-prompt-data +description: Return post_prompt_data as a plain dict, whichever of its three shapes arrived. +max-toc-depth: 3 +--- + +[ref-post-prompt]: /docs/server-sdks/reference/python/core/post-prompt +[strip]: /docs/server-sdks/reference/python/core/post-prompt/strip-json-fence + +Return `post_prompt_data` as a plain dict, whichever shape it arrived in: + +- A `{"parsed": {...}}` or `{"parsed": [ {...} ]}` wrapper is unwrapped first. +- A flat object with real keys is returned as-is, minus `raw` and `parsed`. +- A `{"raw": "..."}` string is unfenced with [`strip_json_fence()`][strip] and parsed as JSON. + Prose that isn't JSON becomes `{"summary": ""}`. + +Never raises. A malformed summary degrades to `{}` rather than failing the request that +delivered it. + +## Parameters + + + The `post_prompt_data` value from a post-prompt body. + + +## Returns + +`dict[str, Any]` -- The summary object, or `{}` when there is nothing usable. + +## Example + +```python {3} +from signalwire.core.post_prompt import parse_post_prompt_data + +summary = parse_post_prompt_data(raw_body.get("post_prompt_data")) +print(summary.get("intent")) +``` + +Part of the [post-prompt normalization][ref-post-prompt] module. diff --git a/fern/products/server-sdks/pages/reference/python/core/post-prompt/strip-json-fence.mdx b/fern/products/server-sdks/pages/reference/python/core/post-prompt/strip-json-fence.mdx new file mode 100644 index 0000000000..0ff26a96ec --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/core/post-prompt/strip-json-fence.mdx @@ -0,0 +1,33 @@ +--- +title: "strip_json_fence" +slug: /reference/python/core/post-prompt/strip-json-fence +description: Unwrap a fenced JSON code block returned verbatim by the chat engine. +max-toc-depth: 3 +--- + +[ref-post-prompt]: /docs/server-sdks/reference/python/core/post-prompt + +Unwrap ```` ```json ... ``` ```` fencing. The chat engine hands the model's answer back verbatim, +fence and all, where the voice engine parses it first. Text without a fence is returned trimmed. + +## Parameters + + + The raw string, fenced or not. + + +## Returns + +`str` -- The content with any opening and closing fence removed and whitespace trimmed. + +## Example + +```python {4} +import json +from signalwire.core.post_prompt import strip_json_fence + +summary = json.loads(strip_json_fence('```json\n{"intent": "booking"}\n```')) +print(summary["intent"]) # booking +``` + +Part of the [post-prompt normalization][ref-post-prompt] module. diff --git a/fern/products/server-sdks/pages/reference/python/relay/actions/collect-action/index.mdx b/fern/products/server-sdks/pages/reference/python/relay/actions/collect-action/index.mdx index 0750b6b0a4..e1761539be 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/actions/collect-action/index.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/actions/collect-action/index.mdx @@ -8,6 +8,8 @@ max-toc-depth: 3 [call-play-and-collect]: /docs/server-sdks/reference/python/relay/call/play-and-collect [base-action-interface]: /docs/server-sdks/reference/python/relay/actions [stop]: /docs/server-sdks/reference/python/relay/actions/collect-action/stop +[pause]: /docs/server-sdks/reference/python/relay/actions/collect-action/pause +[resume]: /docs/server-sdks/reference/python/relay/actions/collect-action/resume [volume]: /docs/server-sdks/reference/python/relay/actions/collect-action/volume [startinputtimers]: /docs/server-sdks/reference/python/relay/actions/collect-action/start-input-timers @@ -36,6 +38,12 @@ No additional properties beyond the [base Action interface][base-action-interfac Stop the play-and-collect operation. + + Pause the play-and-collect operation. + + + Resume a paused play-and-collect operation. + Adjust the prompt playback volume during a play-and-collect operation. diff --git a/fern/products/server-sdks/pages/reference/python/relay/actions/collect-action/pause.mdx b/fern/products/server-sdks/pages/reference/python/relay/actions/collect-action/pause.mdx new file mode 100644 index 0000000000..861538d7b2 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/relay/actions/collect-action/pause.mdx @@ -0,0 +1,47 @@ +--- +title: "pause" +slug: /reference/python/relay/actions/collect-action/pause +description: Pause an active play-and-collect operation. +max-toc-depth: 3 +--- + +Pause the play-and-collect operation. + +## Parameters + + + Optional pause behavior. Controls what happens to the audio stream while paused + (e.g., silence insertion). + + +## Returns + +`dict` -- Server acknowledgment. + +## Example + +```python {19} +from signalwire.relay import RelayClient + +client = RelayClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", + contexts=["default"], +) + +@client.on_call +async def handle_call(call): + await call.answer() + action = await call.play_and_collect( + media=[{"type": "tts", "params": {"text": "Press 1 for sales, 2 for support."}}], + collect={"digits": {"max": 1, "digit_timeout": 5.0}}, + ) + + # Pause during an interruption + await action.pause() + # ... interruption handled ... + await action.resume() + +client.run() +``` diff --git a/fern/products/server-sdks/pages/reference/python/relay/actions/collect-action/resume.mdx b/fern/products/server-sdks/pages/reference/python/relay/actions/collect-action/resume.mdx new file mode 100644 index 0000000000..d76cb2bbfc --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/relay/actions/collect-action/resume.mdx @@ -0,0 +1,43 @@ +--- +title: "resume" +slug: /reference/python/relay/actions/collect-action/resume +description: Resume a paused play-and-collect operation. +max-toc-depth: 3 +--- + +Resume a paused play-and-collect operation. + +## Returns + +`dict` -- Server acknowledgment. + +## Example + +```python {20} +from signalwire.relay import RelayClient + +client = RelayClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", + contexts=["default"], +) + +@client.on_call +async def handle_call(call): + await call.answer() + action = await call.play_and_collect( + media=[{"type": "tts", "params": {"text": "Press 1 for sales, 2 for support."}}], + collect={"digits": {"max": 1, "digit_timeout": 5.0}}, + ) + + await action.pause() + # ... interruption handled ... + await action.resume() + + event = await action.wait() + result = event.params.get("result", {}) + print(f"User pressed: {result.get('digits', '')}") + +client.run() +``` diff --git a/fern/products/server-sdks/pages/reference/python/relay/actions/index.mdx b/fern/products/server-sdks/pages/reference/python/relay/actions/index.mdx index 2a23ec9366..9b54a5220e 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/actions/index.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/actions/index.mdx @@ -78,7 +78,7 @@ All action classes share these properties and methods. `True` once the action has finished and the terminal event has been processed. - + The terminal [`RelayEvent`][relayevent] for this action, or `None` if the action has not yet completed. @@ -91,7 +91,7 @@ All action classes share these properties and methods. Block until the action completes and return the terminal event. - + Maximum seconds to wait. `None` waits indefinitely. Raises `asyncio.TimeoutError` if exceeded. @@ -115,7 +115,7 @@ Block until the action completes and return the terminal event. title="CollectAction" href="/docs/server-sdks/reference/python/relay/actions/collect-action" > - Tracks play-and-collect. Supports stop, volume, and input timers. + Tracks play-and-collect. Supports stop, pause, resume, volume, and input timers. + Optional pause behavior. Controls what happens to the audio stream while paused (e.g., silence insertion). diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/ai-hold.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/ai-hold.mdx index 9705f51719..4358f0376a 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/ai-hold.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/ai-hold.mdx @@ -17,11 +17,11 @@ Use [`ai_unhold()`][ai-unhold] to resume the AI session. ## **Parameters** - + Maximum hold duration. The AI session automatically resumes after this timeout. - + A prompt for the AI to speak before going on hold (e.g., "Please hold while I check on that."). diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/ai-message.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/ai-message.mdx index 7fdeab665d..1bfe43f66d 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/ai-message.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/ai-message.mdx @@ -18,23 +18,23 @@ an active session has no effect. ## **Parameters** - + The message text to send to the AI agent. - + The role of the message sender. Valid values: - `"user"` -- simulate user input - `"system"` -- send a system-level instruction - `"assistant"` -- inject an assistant response - + Reset configuration. Allows resetting AI state such as the conversation history or functions. - + Update the global data accessible to the AI and SWAIG functions. diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/ai-unhold.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/ai-unhold.mdx index 0fc7cd4451..54725bf87b 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/ai-unhold.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/ai-unhold.mdx @@ -10,7 +10,7 @@ conversation. ## **Parameters** - + A prompt for the AI to speak upon resuming (e.g., "Thank you for holding. I have your information now."). diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/ai.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/ai.mdx index 30dd1a7a1d..972872b02c 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/ai.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/ai.mdx @@ -34,16 +34,16 @@ parameters and behaviors. ## **Parameters** - + Custom control ID. Auto-generated if not provided. - + Fabric agent resource ID. When set, the AI uses a pre-configured agent from SignalWire Fabric instead of inline configuration. - + The main prompt configuration. @@ -61,7 +61,7 @@ parameters and behaviors. - + Post-prompt configuration for summarization or analysis after the conversation ends. @@ -72,45 +72,45 @@ parameters and behaviors. - + URL to receive the post-prompt result via webhook. - + Username for basic auth on the post-prompt webhook. - + Password for basic auth on the post-prompt webhook. - + Data accessible to the AI agent and SWAIG functions throughout the session. - + Pronunciation rules for words or phrases the TTS engine should handle specially. - + Speech recognition hints to improve accuracy for domain-specific terms. - + Language configurations for multilingual support. - + SWAIG (SignalWire AI Gateway) configuration for tool/function definitions. - + Additional AI parameters such as `barge_confidence`, `end_of_speech_timeout`, `attention_timeout`, and other LLM tuning settings. - + Callback invoked when the AI session ends. diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/amazon-bedrock.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/amazon-bedrock.mdx index bf8b6a0ce6..5b4e59d014 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/amazon-bedrock.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/amazon-bedrock.mdx @@ -13,27 +13,27 @@ the LLM backend. ## **Parameters** - + The prompt configuration for the Bedrock agent. - + SWAIG configuration for tool/function definitions. - + AI parameters for the Bedrock session. - + Data accessible to the AI and SWAIG functions. - + Post-prompt configuration. - + URL to receive the post-prompt result. diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/bind-digit.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/bind-digit.mdx index 98bd548eed..efdb8b46d7 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/bind-digit.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/bind-digit.mdx @@ -26,16 +26,16 @@ Use [`clear_digit_bindings()`][clear-digit-bindings] to remove bindings. (e.g., `"calling.transfer"`, `"calling.play"`). - + Parameters to pass to the bound method when triggered. - + A namespace for grouping digit bindings. Useful for selectively clearing bindings by realm. - + Maximum number of times this binding can be triggered. After reaching the limit, the binding is automatically removed. diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/clear-digit-bindings.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/clear-digit-bindings.mdx index 82c1867cc8..2a4d8af791 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/clear-digit-bindings.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/clear-digit-bindings.mdx @@ -9,7 +9,7 @@ Clear all digit bindings, optionally filtered by realm. ## **Parameters** - + If provided, only clear bindings in this realm. If omitted, all bindings are cleared. diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/collect.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/collect.mdx index 629c698b01..2afce59a17 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/collect.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/collect.mdx @@ -21,7 +21,7 @@ This method emits [`calling.call.collect`][calling-call-collect] events. See [Ca ## **Parameters** - + DTMF digit collection settings. @@ -39,7 +39,7 @@ This method emits [`calling.call.collect`][calling-call-collect] events. See [Ca - + Speech recognition settings. @@ -61,32 +61,32 @@ This method emits [`calling.call.collect`][calling-call-collect] events. See [Ca - + Seconds to wait for the first input before ending with `no_input`. - + Enable partial speech recognition results. - + Keep collecting after each result instead of stopping. - + Send an event when input is first detected. - + Start input timers immediately. If `False`, call `action.start_input_timers()` to start them manually. - + Custom control ID. Auto-generated if not provided. - + Callback invoked when collection completes. diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/connect.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/connect.mdx index 7109c2679a..e39ec5710f 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/connect.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/connect.mdx @@ -36,24 +36,24 @@ This method corresponds to the SWML [`connect`][connect] verb. See the - `"params"` -- Type-specific parameters (`to_number`, `from_number`, etc.) - + Media items to play to the caller while the destination is ringing. Same format as [`play()`][play] media items. - + Correlation tag for the connected call. - + Maximum duration of the connected call in seconds. - + Maximum price per minute for the connected call. - + URL to receive connection status webhooks. diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/detect-answering-machine.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/detect-answering-machine.mdx new file mode 100644 index 0000000000..7055ae9651 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/relay/call/detect-answering-machine.mdx @@ -0,0 +1,79 @@ +--- +title: "detect_answering_machine" +slug: /reference/python/relay/call/detect-answering-machine +description: "Detect whether a human or an answering machine answered a call." +max-toc-depth: 3 +--- + +[detect]: /docs/server-sdks/reference/python/relay/call/detect + +Detect a human versus an answering machine. A typed convenience over +[`detect()`][detect] that builds the `{"type": "machine", "params": {...}}` +configuration for you. All parameters are keyword-only, and only the ones you +set are sent. + +## Parameters + + + Seconds to wait for initial voice before deciding. + + + + Seconds of silence that end the greeting. + + + + Seconds of continuous voice above which the greeting is treated as a machine. + + + + Word count above which the greeting is treated as a machine. + + + + When `True`, detect the caller interrupting during the machine greeting + playback. + + + + Whether to keep listening for the end of a machine's message, so you can + leave one after the beep. + + + + Maximum seconds to run the detector before stopping. Keyword-only. + + + + Callback invoked when the operation reaches a terminal state. Can be a regular + function or async coroutine. Keyword-only. + + +## Returns + +[`DetectAction`](/docs/server-sdks/reference/python/relay/actions) -- An action handle with `stop()` and `wait()` methods. It resolves on the first detection result. + +## Example + +```python {13-16} +from signalwire.relay import RelayClient + +client = RelayClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", + contexts=["default"], +) + +@client.on_call +async def handle_call(call): + await call.answer() + action = await call.detect_answering_machine( + detect_message_end=True, + timeout=30, + ) + event = await action.wait() + print("Detect result:", event.params) + +client.run() +``` diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/detect-digit.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/detect-digit.mdx new file mode 100644 index 0000000000..7c6e57988d --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/relay/call/detect-digit.mdx @@ -0,0 +1,54 @@ +--- +title: "detect_digit" +slug: /reference/python/relay/call/detect-digit +description: "Detect DTMF digits on a call." +max-toc-depth: 3 +--- + +[detect]: /docs/server-sdks/reference/python/relay/call/detect + +Detect DTMF digits. A typed convenience over [`detect()`][detect] that builds the +`{"type": "digit", "params": {...}}` configuration for you. All parameters are +keyword-only. + +## Parameters + + + The digits to listen for, such as `"1234567890*#"`. Omit to detect any digit. + Keyword-only. + + + + Maximum seconds to run the detector before stopping. Keyword-only. + + + + Callback invoked when the operation reaches a terminal state. Can be a regular + function or async coroutine. Keyword-only. + + +## Returns + +[`DetectAction`](/docs/server-sdks/reference/python/relay/actions) -- An action handle with `stop()` and `wait()` methods. It resolves on the first detection result. + +## Example + +```python {13-15} +from signalwire.relay import RelayClient + +client = RelayClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", + contexts=["default"], +) + +@client.on_call +async def handle_call(call): + await call.answer() + action = await call.detect_digit(digits="0123456789", timeout=15) + event = await action.wait() + print("Detect result:", event.params) + +client.run() +``` diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/detect-fax.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/detect-fax.mdx new file mode 100644 index 0000000000..852d81408a --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/relay/call/detect-fax.mdx @@ -0,0 +1,53 @@ +--- +title: "detect_fax" +slug: /reference/python/relay/call/detect-fax +description: "Detect a fax tone on a call." +max-toc-depth: 3 +--- + +[detect]: /docs/server-sdks/reference/python/relay/call/detect + +Detect a fax tone. A typed convenience over [`detect()`][detect] that builds the +`{"type": "fax", "params": {...}}` configuration for you. All parameters are +keyword-only. + +## Parameters + + + Which tone to detect: `"CED"` (called station) or `"CNG"` (calling station). + Omit to default to `"CED"`. Keyword-only. + + + + Maximum seconds to run the detector before stopping. Keyword-only. + + + + Callback invoked when the operation reaches a terminal state. Can be a regular + function or async coroutine. Keyword-only. + + +## Returns + +[`DetectAction`](/docs/server-sdks/reference/python/relay/actions) -- An action handle with `stop()` and `wait()` methods. It resolves on the first detection result. + +## Example + +```python {13-14} +from signalwire.relay import RelayClient + +client = RelayClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", + contexts=["default"], +) + +@client.on_call +async def handle_call(call): + await call.answer() + action = await call.detect_fax(tone="CED", timeout=20) + event = await action.wait() + +client.run() +``` diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/detect.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/detect.mdx index 253a1def63..6f32de8736 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/detect.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/detect.mdx @@ -42,15 +42,15 @@ This method emits [`calling.call.detect`][calling-call-detect] events. See [Call - + Maximum seconds to run the detector before stopping. - + Custom control ID. Auto-generated if not provided. - + Callback invoked when detection completes. diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/echo.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/echo.mdx index 0fe4b8e42e..aaa32b80e4 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/echo.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/echo.mdx @@ -18,12 +18,12 @@ This method emits [`calling.call.echo`][calling-call-echo] events. See [Call Eve ## **Parameters** - + Maximum duration of the echo in seconds. The echo stops automatically after this timeout. - + URL to receive echo status webhooks. diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/index.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/index.mdx index b2f76985e1..f969be9140 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/index.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/index.mdx @@ -119,6 +119,15 @@ objects that let you stop, pause, or wait for the operation to complete. Wait for a specific event on a call. + + Wait until the call is ringing. + + + Wait until the call is answered. + + + Wait until the call is ending. + Wait for a call to reach the ended state. @@ -149,18 +158,45 @@ objects that let you stop, pause, or wait for the operation to complete. Play audio content on a call. + + Play text-to-speech. + + + Play an audio file from a URL. + + + Play silence for a number of seconds. + + + Play a named ringtone. + Record audio from a call. Play audio and collect DTMF or speech input. + + Play text-to-speech, then collect input. + + + Play an audio file, then collect input. + Collect DTMF or speech input without playing media. Detect answering machines, fax tones, or digits on a call. + + Detect DTMF digits. + + + Detect a human versus an answering machine. + + + Detect a fax tone. + Start an AI agent session on a call. diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/join-conference.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/join-conference.mdx index f879d04380..277eb17933 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/join-conference.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/join-conference.mdx @@ -26,11 +26,11 @@ This method emits [`calling.conference`][calling-conference] events. See [Call E Conference name. All calls joining the same name are in the same conference. - + Join the conference muted. - + Play a beep when joining or leaving. - `"true"` -- beep on both enter and exit @@ -39,75 +39,75 @@ This method emits [`calling.conference`][calling-conference] events. See [Call E - `"onExit"` -- beep only when a participant leaves - + Start the conference when this participant enters. If `False`, the conference waits until a participant with `start_on_enter=True` joins. - + End the conference when this participant leaves. - + URL of audio to play while waiting for the conference to start. - + Maximum number of participants in the conference. - + Recording mode. - `"record-from-start"` -- begin recording when the conference starts - `"do-not-record"` -- do not record the conference - + Region for the conference media server. - + Whether to trim silence from the conference recording. - + Call ID of a participant who can hear but not be heard (coaching mode). - + URL to receive conference status webhooks. - + Events that trigger status callbacks. - + Content type for status callback requests. - + HTTP method for status callbacks (e.g., `"POST"`, `"GET"`). - + URL to receive recording status webhooks. - + Events that trigger recording status callbacks. - + Content type for recording status callback requests. - + HTTP method for recording status callbacks. - + Attach a bidirectional WebSocket stream to the conference audio, enabling real-time audio processing, transcription, or AI agents that listen to the conference. Uses the same stream schema as the `stream` device type in `connect`. @@ -119,31 +119,31 @@ This method emits [`calling.conference`][calling-conference] events. See [Call E Secure WebSocket URL (`wss://`) to stream the conference audio to. Plain `ws://` is not supported. - + A friendly name to identify the stream at the WebSocket endpoint. - + Audio codec for the streamed audio (e.g., `"PCMU"`, `"PCMA"`, `"G722"`, `"L16"`). - + HTTP or HTTPS URL to receive stream status webhooks. - + HTTP method for the status webhook (`"GET"` or `"POST"`). - + When `True`, enables bidirectional audio so your endpoint can stream audio back into the conference (not just receive it). - + Bearer token sent in the `Authorization` header when the WebSocket connection is opened, so your endpoint can authenticate the request. - + Custom key-value pairs delivered to your WebSocket endpoint when the stream connects. Use them to pass context such as a session or customer ID. diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/join-room.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/join-room.mdx index e75dc546a7..45d398075d 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/join-room.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/join-room.mdx @@ -20,7 +20,7 @@ Use [`leave_room()`][leave-room] to leave the room. Room name to join. - + URL to receive room status webhooks. diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/live-translate.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/live-translate.mdx index 79ee270981..1b8bff10f5 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/live-translate.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/live-translate.mdx @@ -31,7 +31,7 @@ another language in real-time. - + URL to receive translation results via webhook. diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/pay.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/pay.mdx index f48b2c209c..c372c8af94 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/pay.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/pay.mdx @@ -24,88 +24,88 @@ This method emits [`calling.call.pay`][calling-call-pay] events. See [Call Event URL of the payment connector service that processes the payment. - + Custom control ID. Auto-generated if not provided. - + How the caller provides payment info. - `"dtmf"` -- caller enters digits on the keypad - `"speech"` -- caller speaks the payment information - + URL to receive payment status webhooks. - + Payment method type. Valid values: `"credit-card"`. - + Timeout for the payment session. - + Maximum number of input attempts before failing. - + Whether to collect CVV. - `"true"` -- prompt the caller for the security code - `"false"` -- skip security code collection - + Whether to collect postal code. - `"true"` -- prompt the caller for the postal code - `"false"` -- skip postal code collection - + Minimum length for the postal code. - + Tokenization type for the payment data. - + Amount to charge (e.g., `"29.99"`). - + Currency code (e.g., `"USD"`, `"EUR"`). - + Language for payment prompts (e.g., `"en"`). - + Voice for TTS prompts during the payment flow. - + Description of the payment/charge. - + Comma-separated list of accepted card types (e.g., `"visa,mastercard,amex"`). - + Additional parameters to pass to the payment connector. - + Custom prompts for the payment flow. - + Callback invoked when the payment operation completes. diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/play-and-collect.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/play-and-collect.mdx index 9ac7ec3483..6eb285bde4 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/play-and-collect.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/play-and-collect.mdx @@ -78,22 +78,22 @@ This method emits [`calling.call.collect`][calling-call-collect] events. See [Ca - + Volume adjustment in dB for the prompt audio. - + Custom control ID. Auto-generated if not provided. - + Callback invoked when collection completes. ## **Returns** [`CollectAction`][collectaction] -- An action handle with -`stop()`, `volume()`, `start_input_timers()`, and `wait()` methods. +`stop()`, `pause()`, `resume()`, `volume()`, `start_input_timers()`, and `wait()` methods. ## **Example** diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/play-audio.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/play-audio.mdx new file mode 100644 index 0000000000..2c64eda10d --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/relay/call/play-audio.mdx @@ -0,0 +1,51 @@ +--- +title: "play_audio" +slug: /reference/python/relay/call/play-audio +description: "Play an audio file from a URL on a call." +max-toc-depth: 3 +--- + +[play]: /docs/server-sdks/reference/python/relay/call/play + +Play an audio file from a URL. A typed convenience over [`play()`][play] that +builds the `{"type": "audio", "params": {"url": ...}}` media item for you. + +## Parameters + + + URL of the audio file to play. + + + + Volume adjustment in dB, from `-40.0` to `40.0`. Keyword-only. + + + + Callback invoked when the operation reaches a terminal state. Can be a regular + function or async coroutine. Keyword-only. + + +## Returns + +[`PlayAction`](/docs/server-sdks/reference/python/relay/actions) -- An action handle with `stop()`, `pause()`, `resume()`, `volume()`, and `wait()` methods. + +## Example + +```python {13} +from signalwire.relay import RelayClient + +client = RelayClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", + contexts=["default"], +) + +@client.on_call +async def handle_call(call): + await call.answer() + action = await call.play_audio("https://example.com/hold-music.mp3", volume=-6.0) + await action.wait() + +client.run() +``` diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/play-ringtone.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/play-ringtone.mdx new file mode 100644 index 0000000000..7572ad274b --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/relay/call/play-ringtone.mdx @@ -0,0 +1,55 @@ +--- +title: "play_ringtone" +slug: /reference/python/relay/call/play-ringtone +description: "Play a named ringtone on a call." +max-toc-depth: 3 +--- + +[play]: /docs/server-sdks/reference/python/relay/call/play + +Play a named ringtone by country code. A typed convenience over [`play()`][play] +that builds the `{"type": "ringtone", "params": {...}}` media item for you. + +## Parameters + + + Ringtone name, a country code such as `"us"`. + + + + Seconds to play the ringtone. Keyword-only. + + + + Volume adjustment in dB, from `-40.0` to `40.0`. Keyword-only. + + + + Callback invoked when the operation reaches a terminal state. Can be a regular + function or async coroutine. Keyword-only. + + +## Returns + +[`PlayAction`](/docs/server-sdks/reference/python/relay/actions) -- An action handle with `stop()`, `pause()`, `resume()`, `volume()`, and `wait()` methods. + +## Example + +```python {13} +from signalwire.relay import RelayClient + +client = RelayClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", + contexts=["default"], +) + +@client.on_call +async def handle_call(call): + await call.answer() + action = await call.play_ringtone("us", duration=10) + await action.wait() + +client.run() +``` diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/play-silence.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/play-silence.mdx new file mode 100644 index 0000000000..7634031528 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/relay/call/play-silence.mdx @@ -0,0 +1,48 @@ +--- +title: "play_silence" +slug: /reference/python/relay/call/play-silence +description: "Play silence on a call for a number of seconds." +max-toc-depth: 3 +--- + +[play]: /docs/server-sdks/reference/python/relay/call/play + +Play silence for `duration` seconds. A typed convenience over [`play()`][play] +that builds the `{"type": "silence", "params": {"duration": ...}}` media item for +you. + +## Parameters + + + Seconds of silence to play. + + + + Callback invoked when the operation reaches a terminal state. Can be a regular + function or async coroutine. Keyword-only. + + +## Returns + +[`PlayAction`](/docs/server-sdks/reference/python/relay/actions) -- An action handle with `stop()`, `pause()`, `resume()`, `volume()`, and `wait()` methods. + +## Example + +```python {13-14} +from signalwire.relay import RelayClient + +client = RelayClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", + contexts=["default"], +) + +@client.on_call +async def handle_call(call): + await call.answer() + await (await call.play_tts("One moment.")).wait() + await (await call.play_silence(2)).wait() + +client.run() +``` diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/play-tts.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/play-tts.mdx new file mode 100644 index 0000000000..d6afebe279 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/relay/call/play-tts.mdx @@ -0,0 +1,63 @@ +--- +title: "play_tts" +slug: /reference/python/relay/call/play-tts +description: "Play text-to-speech on a call." +max-toc-depth: 3 +--- + +[play]: /docs/server-sdks/reference/python/relay/call/play + +Play text-to-speech. A typed convenience over [`play()`][play] that builds the +`{"type": "tts", "params": {...}}` media item for you. + +## Parameters + + + The text to speak. + + + + Language code for the voice, such as `"en-US"`. Keyword-only. + + + + Voice gender, `"male"` or `"female"`. Keyword-only. + + + + Voice ID. Keyword-only. + + + + Volume adjustment in dB, from `-40.0` to `40.0`. Keyword-only. + + + + Callback invoked when the operation reaches a terminal state. Can be a regular + function or async coroutine. Keyword-only. + + +## Returns + +[`PlayAction`](/docs/server-sdks/reference/python/relay/actions) -- An action handle with `stop()`, `pause()`, `resume()`, `volume()`, and `wait()` methods. + +## Example + +```python {13} +from signalwire.relay import RelayClient + +client = RelayClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", + contexts=["default"], +) + +@client.on_call +async def handle_call(call): + await call.answer() + action = await call.play_tts("Welcome to Bayview Taxi.", language="en-US") + await action.wait() + +client.run() +``` diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/play.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/play.mdx index bd2d06b286..adad2f8283 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/play.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/play.mdx @@ -35,26 +35,26 @@ This method corresponds to the SWML [`play`][play] verb. See the - `{"type": "ringtone", "params": {"name": "us"}}` -- play a standard ringtone - + Volume adjustment in dB, from `-40.0` to `40.0`. - + Audio direction. Valid values: - `"listen"` -- play to the caller only - `"speak"` -- play to the remote party only - `"both"` -- play to both sides - + Number of times to repeat the media. `0` loops indefinitely. - + Custom control ID for this operation. Auto-generated if not provided. - + Callback invoked when playback reaches a terminal state. Can be a regular function or async coroutine. diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/prompt-audio.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/prompt-audio.mdx new file mode 100644 index 0000000000..556860f07b --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/relay/call/prompt-audio.mdx @@ -0,0 +1,59 @@ +--- +title: "prompt_audio" +slug: /reference/python/relay/call/prompt-audio +description: "Play an audio file, then collect digits or speech." +max-toc-depth: 3 +--- + +[play-and-collect]: /docs/server-sdks/reference/python/relay/call/play-and-collect + +Play an audio file as a prompt and collect input. A typed convenience over +[`play_and_collect()`][play-and-collect] that builds the audio media item for you. + +## Parameters + + + URL of the audio file to play as the prompt. + + + + Input collection configuration, in the same format as + [`play_and_collect()`][play-and-collect]. + + + + Volume adjustment in dB, from `-40.0` to `40.0`. Keyword-only. + + + + Callback invoked when the operation reaches a terminal state. Can be a regular + function or async coroutine. Keyword-only. + + +## Returns + +[`CollectAction`](/docs/server-sdks/reference/python/relay/actions) -- An action handle that resolves when input is collected, the operation times out, or an error occurs. + +## Example + +```python {13-16} +from signalwire.relay import RelayClient + +client = RelayClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", + contexts=["default"], +) + +@client.on_call +async def handle_call(call): + await call.answer() + action = await call.prompt_audio( + "https://example.com/menu.mp3", + {"digits": {"max": 1, "digit_timeout": 5}}, + ) + event = await action.wait() + +client.run() +``` diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/prompt-tts.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/prompt-tts.mdx new file mode 100644 index 0000000000..f026a4e7d1 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/relay/call/prompt-tts.mdx @@ -0,0 +1,72 @@ +--- +title: "prompt_tts" +slug: /reference/python/relay/call/prompt-tts +description: "Play text-to-speech, then collect digits or speech." +max-toc-depth: 3 +--- + +[play-and-collect]: /docs/server-sdks/reference/python/relay/call/play-and-collect + +Play text-to-speech as a prompt and collect input. A typed convenience over +[`play_and_collect()`][play-and-collect] that builds the TTS media item for you. + +## Parameters + + + The prompt to speak. + + + + Input collection configuration, in the same format as + [`play_and_collect()`][play-and-collect]. + + + + Language code for the voice, such as `"en-US"`. Keyword-only. + + + + Voice gender, `"male"` or `"female"`. Keyword-only. + + + + Voice ID. Keyword-only. + + + + Volume adjustment in dB, from `-40.0` to `40.0`. Keyword-only. + + + + Callback invoked when the operation reaches a terminal state. Can be a regular + function or async coroutine. Keyword-only. + + +## Returns + +[`CollectAction`](/docs/server-sdks/reference/python/relay/actions) -- An action handle that resolves when input is collected, the operation times out, or an error occurs. + +## Example + +```python {13-17} +from signalwire.relay import RelayClient + +client = RelayClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", + contexts=["default"], +) + +@client.on_call +async def handle_call(call): + await call.answer() + action = await call.prompt_tts( + "Press 1 to book a ride or 2 to check on a booking.", + {"digits": {"max": 1, "digit_timeout": 5}}, + ) + event = await action.wait() + print("Collect result:", event.params) + +client.run() +``` diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/queue-enter.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/queue-enter.mdx index 10a3b9a5ce..7304117c84 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/queue-enter.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/queue-enter.mdx @@ -23,11 +23,11 @@ This method emits [`calling.call.queue`][calling-call-queue] events. See [Call E Name of the queue to enter. - + Custom control ID. Auto-generated if not provided. - + URL to receive queue status webhooks (position updates, dequeue events). diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/queue-leave.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/queue-leave.mdx index 7610a510b4..dfd63ddbe4 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/queue-leave.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/queue-leave.mdx @@ -20,16 +20,16 @@ This method emits [`calling.call.queue`][calling-call-queue] events. See [Call E Name of the queue to leave. - + Custom control ID. Auto-generated if not provided. - + Specific queue ID to leave (if the call is in multiple queues with the same name). - + URL to receive queue status webhooks. diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/receive-fax.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/receive-fax.mdx index 93575d70e2..57a8bb3771 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/receive-fax.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/receive-fax.mdx @@ -19,11 +19,11 @@ This method emits [`calling.call.fax`][calling-call-fax] events. See [Call Event ## **Parameters** - + Custom control ID. Auto-generated if not provided. - + Callback invoked when the fax reception completes. The event contains the received document URL and page count. diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/record.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/record.mdx index 39f5079021..8dc7569384 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/record.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/record.mdx @@ -26,7 +26,7 @@ This method corresponds to the SWML [`record`][record] verb. See the ## **Parameters** - + Audio recording configuration object. @@ -71,11 +71,11 @@ This method corresponds to the SWML [`record`][record] verb. See the - + Custom control ID for this operation. Auto-generated if not provided. - + Callback invoked when recording reaches a terminal state (`finished` or `no_input`). The event contains the recording `url`, `duration`, and `size`. diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/refer.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/refer.mdx index 5297ae5eac..cfc4a626f5 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/refer.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/refer.mdx @@ -34,7 +34,7 @@ This method emits [`calling.call.refer`][calling-call-refer] events. See [Call E - + URL to receive REFER status webhooks. diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/send-digits.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/send-digits.mdx index 74ba401ed5..d8f0140de7 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/send-digits.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/send-digits.mdx @@ -22,7 +22,7 @@ This method emits [`calling.call.send_digits`][calling-call-send-digits] events. `A-D`, `W` (0.5s pause), `w` (1s pause). - + Custom control ID. Auto-generated if not provided. diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/send-fax.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/send-fax.mdx index edbf48ffc9..e991e69c0f 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/send-fax.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/send-fax.mdx @@ -23,19 +23,19 @@ This method emits [`calling.call.fax`][calling-call-fax] events. See [Call Event URL of the document to fax (PDF or TIFF format). - + Caller identity string (TSI) transmitted with the fax. - + Header text printed at the top of each fax page. - + Custom control ID. Auto-generated if not provided. - + Callback invoked when the fax operation completes. diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/stream.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/stream.mdx index 5c2245bff2..56d880d3ce 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/stream.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/stream.mdx @@ -23,11 +23,11 @@ This method emits [`calling.call.stream`][calling-call-stream] events. See [Call WebSocket URL to stream audio to (e.g., `"wss://example.com/stream"`). - + A name for this stream, useful for identifying multiple concurrent streams. - + Audio codec for the stream. - `"PCMU"` -- G.711 mu-law (default for North America) @@ -35,7 +35,7 @@ This method emits [`calling.call.stream`][calling-call-stream] events. See [Call - `"OPUS"` -- Opus codec (higher quality, variable bitrate) - + Which audio track to stream. - `"inbound"` -- audio received from the caller @@ -43,30 +43,30 @@ This method emits [`calling.call.stream`][calling-call-stream] events. See [Call - `"both"` -- audio in both directions - + URL to receive stream status webhooks. - + HTTP method for status webhooks. - `"GET"` -- send status updates via GET request - `"POST"` -- send status updates via POST request - + Bearer token for authenticating with the WebSocket server. - + Custom key-value pairs sent with the stream start message. - + Custom control ID. Auto-generated if not provided. - + Callback invoked when the stream ends. diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/tap.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/tap.mdx index b52df26e30..48defa7b7e 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/tap.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/tap.mdx @@ -55,11 +55,11 @@ This method emits [`calling.call.tap`][calling-call-tap] events. See [Call Event - + Custom control ID. Auto-generated if not provided. - + Callback invoked when the tap operation ends. diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/transcribe.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/transcribe.mdx index 0a951aa7c5..39c9c31a51 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/transcribe.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/transcribe.mdx @@ -26,15 +26,15 @@ This method emits [`calling.call.transcribe`][calling-call-transcribe] events. S ## **Parameters** - + Custom control ID. Auto-generated if not provided. - + URL to receive transcription status webhooks. - + Callback invoked when transcription completes. The event carries the recording's `url`, `duration`, and `size`. diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/user-event.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/user-event.mdx index b0fd5bde6b..f8e4f9bf90 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/user-event.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/user-event.mdx @@ -11,7 +11,7 @@ the same call can receive and react to these events. ## **Parameters** - + The event name or identifier. diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/wait-for-answered.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/wait-for-answered.mdx new file mode 100644 index 0000000000..f2aad9f9fc --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/relay/call/wait-for-answered.mdx @@ -0,0 +1,52 @@ +--- +title: "wait_for_answered" +slug: /reference/python/relay/call/wait-for-answered +description: "Wait until the call is answered." +max-toc-depth: 3 +--- + +[wait-for]: /docs/server-sdks/reference/python/relay/call/wait-for +[relayevent]: /docs/server-sdks/reference/python/relay/events +[answer]: /docs/server-sdks/reference/python/relay/call/answer +[dial]: /docs/server-sdks/reference/python/relay/client/dial + +Wait until the call state reaches `answered`. Returns immediately if the call +is already answered or has moved past it (ending or ended). A typed convenience over +[`wait_for()`][wait-for] on the `calling.call.state` event. + +[`answer()`][answer] returns as soon as the platform accepts the command; the call reaches +`answered` a moment later. Await `wait_for_answered()` when the next step needs the +media path up. Outbound calls from [`client.dial()`][dial] are already answered when they +return, so the method returns immediately for them. + +## Parameters + + + Maximum seconds to wait. Raises `asyncio.TimeoutError` if exceeded. `None` + waits indefinitely. + + +## Returns + +[`RelayEvent`][relayevent] -- The state event. When the call was already at or past the target, `event.params["call_state"]` holds the current state. + +## Example + +```python {12-13} +from signalwire.relay import RelayClient + +client = RelayClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", + contexts=["default"], +) + +@client.on_call +async def handle_call(call): + await call.answer() + await call.wait_for_answered(timeout=10) + await (await call.play_tts("Thanks for calling Bayview Taxi.")).wait() + +client.run() +``` diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/wait-for-ended.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/wait-for-ended.mdx index f28c91abd7..ec7ed1c22a 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/wait-for-ended.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/wait-for-ended.mdx @@ -12,7 +12,7 @@ equivalent to waiting for a `calling.call.state` event with `call_state == "ende ## **Parameters** - + Maximum seconds to wait. Raises `asyncio.TimeoutError` if exceeded. `None` waits indefinitely. diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/wait-for-ending.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/wait-for-ending.mdx new file mode 100644 index 0000000000..bbf40cc61c --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/relay/call/wait-for-ending.mdx @@ -0,0 +1,46 @@ +--- +title: "wait_for_ending" +slug: /reference/python/relay/call/wait-for-ending +description: "Wait until the call is ending." +max-toc-depth: 3 +--- + +[wait-for]: /docs/server-sdks/reference/python/relay/call/wait-for +[relayevent]: /docs/server-sdks/reference/python/relay/events + +Wait until the call state reaches `ending`. Returns immediately if the call +is already ending or has moved past it (ended). A typed convenience over +[`wait_for()`][wait-for] on the `calling.call.state` event. + +## Parameters + + + Maximum seconds to wait. Raises `asyncio.TimeoutError` if exceeded. `None` + waits indefinitely. + + +## Returns + +[`RelayEvent`][relayevent] -- The state event. When the call was already at or past the target, `event.params["call_state"]` holds the current state. + +## Example + +```python {15} +from signalwire.relay import RelayClient + +client = RelayClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", + contexts=["default"], +) + +@client.on_call +async def handle_call(call): + await call.answer() + await (await call.play_tts("Goodbye.")).wait() + await call.hangup() + await call.wait_for_ending(timeout=10) + +client.run() +``` diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/wait-for-ringing.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/wait-for-ringing.mdx new file mode 100644 index 0000000000..c01fecd70e --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/relay/call/wait-for-ringing.mdx @@ -0,0 +1,56 @@ +--- +title: "wait_for_ringing" +slug: /reference/python/relay/call/wait-for-ringing +description: "Wait until the call is ringing." +max-toc-depth: 3 +--- + +[wait-for]: /docs/server-sdks/reference/python/relay/call/wait-for +[relayevent]: /docs/server-sdks/reference/python/relay/events +[dial]: /docs/server-sdks/reference/python/relay/client/dial + +Wait until the call state reaches `ringing`. Returns immediately if the call +is already ringing or has moved past it (answered, ending, or ended). A typed convenience over +[`wait_for()`][wait-for] on the `calling.call.state` event. + +For an outbound call, this has usually already happened by the time you hold a reference +to it: [`client.dial()`][dial] returns only after the far end answers, so the method +returns at once and `event.params["call_state"]` reports where the call is, working as a +guard rather than a wait. An inbound call's initial state is `created`; for it, the method +returns once the `ringing` state event arrives, which usually precedes `answer()`. + +## Parameters + + + Maximum seconds to wait. Raises `asyncio.TimeoutError` if exceeded. `None` + waits indefinitely. + + +## Returns + +[`RelayEvent`][relayevent] -- The state event. When the call was already at or past the target, `event.params["call_state"]` holds the current state. + +## Example + +```python {13-18} +from signalwire.relay import RelayClient + +client = RelayClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", + contexts=["default"], +) + +@client.on_call +async def handle_call(call): + await call.answer() + dialed = await client.dial( + devices=[[{"type": "phone", "params": {"to_number": "+15551234567", "from_number": "+15559876543"}}]] + ) + event = await dialed.wait_for_ringing(timeout=10) + # dial() already waited for the answer, so this prints "answered". + print("State:", event.params["call_state"]) + +client.run() +``` diff --git a/fern/products/server-sdks/pages/reference/python/relay/call/wait-for.mdx b/fern/products/server-sdks/pages/reference/python/relay/call/wait-for.mdx index 6214314f36..1430a87c0c 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/call/wait-for.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/call/wait-for.mdx @@ -17,12 +17,12 @@ and then removes itself. The event type string to wait for. - + Optional filter function. If provided, the wait only resolves when the predicate returns `True` for a received event. - + Maximum seconds to wait. Raises `asyncio.TimeoutError` if exceeded. `None` waits indefinitely. diff --git a/fern/products/server-sdks/pages/reference/python/relay/client/dial.mdx b/fern/products/server-sdks/pages/reference/python/relay/client/dial.mdx index 246a68aa51..aa8b890407 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/client/dial.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/client/dial.mdx @@ -58,17 +58,17 @@ Raises `RelayError` if the dial fails or if no answer is received within the - + Client-provided correlation tag for event matching. Auto-generated as a UUID if not supplied. - + Maximum call duration in seconds. The call is automatically ended when this limit is reached. - + How long in seconds to wait for the dial to complete (answer or failure) before raising a timeout error. diff --git a/fern/products/server-sdks/pages/reference/python/relay/client/index.mdx b/fern/products/server-sdks/pages/reference/python/relay/client/index.mdx index 9f81dbaeda..ac9779aea3 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/client/index.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/client/index.mdx @@ -41,15 +41,18 @@ token. Credentials can be passed directly or read from environment variables. - SignalWire space hostname (e.g., `your-space.signalwire.com`). Set via constructor or `SIGNALWIRE_SPACE` - environment variable. Defaults to `relay.signalwire.com`. + Relay WebSocket endpoint. The default is the endpoint for SignalWire projects; you + do not set your space here. The constructor argument wins, then the `SIGNALWIRE_SPACE` + environment variable, then the default. `RestClient` reads `SIGNALWIRE_SPACE` as the + REST host, so when it is set for REST, pass `host="relay.signalwire.com"` to keep + the default. List of contexts to subscribe to for inbound call and message events. - + Maximum number of concurrent inbound calls the client will track. Calls arriving beyond this limit are dropped with a log warning. Set via constructor or `RELAY_MAX_ACTIVE_CALLS` environment variable. Constructor-only -- not diff --git a/fern/products/server-sdks/pages/reference/python/relay/client/send-message.mdx b/fern/products/server-sdks/pages/reference/python/relay/client/send-message.mdx index af990d3544..640f8c19b4 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/client/send-message.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/client/send-message.mdx @@ -29,29 +29,29 @@ with text and attached media. Sender phone number in E.164 format. Must be a number owned by your SignalWire project. - + Context for receiving state-change events for this message. Defaults to the server-assigned relay protocol string, or `"default"` if no protocol has been assigned yet. - + Text body of the message. Required for SMS. Optional for MMS if `media` is provided. - + List of publicly accessible media URLs for MMS attachments (e.g., images, audio files). - + Optional tags to attach to the message for filtering or tracking. - + Origination region for the message. - + Callback function invoked when the message reaches a terminal state (`delivered`, `undelivered`, or `failed`). Receives the terminal event as its argument. diff --git a/fern/products/server-sdks/pages/reference/python/relay/events.mdx b/fern/products/server-sdks/pages/reference/python/relay/events.mdx index 61674ebe73..d335b5d90c 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/events.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/events.mdx @@ -419,7 +419,7 @@ Handlers for this event receive a `CollectEvent` with the following properties: - `"speech"` -- speech input was collected - + Whether this is the final result. May be `None` for non-continuous collect operations. diff --git a/fern/products/server-sdks/pages/reference/python/relay/message/index.mdx b/fern/products/server-sdks/pages/reference/python/relay/message/index.mdx index 0c3ef921a0..7f22dee95c 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/message/index.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/message/index.mdx @@ -109,7 +109,7 @@ asyncio.run(send_sms()) Read-only property. - + The terminal [`RelayEvent`][relayevent] that resolved this message, or `None` if the message has not yet completed. diff --git a/fern/products/server-sdks/pages/reference/python/relay/message/wait.mdx b/fern/products/server-sdks/pages/reference/python/relay/message/wait.mdx index 9745867408..77864a810f 100644 --- a/fern/products/server-sdks/pages/reference/python/relay/message/wait.mdx +++ b/fern/products/server-sdks/pages/reference/python/relay/message/wait.mdx @@ -17,7 +17,7 @@ reach a terminal state within the given duration. ## **Parameters** - + Maximum number of seconds to wait. `None` waits indefinitely. diff --git a/fern/products/server-sdks/pages/reference/python/rest/calling/collect-start-input-timers.mdx b/fern/products/server-sdks/pages/reference/python/rest/calling/collect-start-input-timers.mdx index 36d5bdc4fc..9174dfdb81 100644 --- a/fern/products/server-sdks/pages/reference/python/rest/calling/collect-start-input-timers.mdx +++ b/fern/products/server-sdks/pages/reference/python/rest/calling/collect-start-input-timers.mdx @@ -21,7 +21,7 @@ before starting the timer countdown. ## **Example** -```python {23} +```python {25} from signalwire.rest import RestClient client = RestClient( @@ -30,12 +30,14 @@ client = RestClient( host="your-space.signalwire.com", ) -# Start collection without auto-timers, play prompt, then start timers -result = client.calling.collect( +# Start collection without auto-timers, play prompt, then start timers. +# The response never carries control_id back, so name the collection yourself +# and reuse that same value below. +client.calling.collect( call_id="call-id-xxx", + control_id="collect-1", digits={"max": 4, "terminators": "#"}, ) -control_id = result.get("control_id") # Play a prompt first client.calling.play( @@ -46,6 +48,6 @@ client.calling.play( # Now start the input timers client.calling.collect_start_input_timers( call_id="call-id-xxx", - control_id=control_id, + control_id="collect-1", ) ``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/calling/collect.mdx b/fern/products/server-sdks/pages/reference/python/rest/calling/collect.mdx index ebaaed55c1..b4fcbe615f 100644 --- a/fern/products/server-sdks/pages/reference/python/rest/calling/collect.mdx +++ b/fern/products/server-sdks/pages/reference/python/rest/calling/collect.mdx @@ -5,8 +5,15 @@ description: Collect user input (DTMF or speech) on an active call via REST. max-toc-depth: 3 --- +[collect-stop]: /docs/server-sdks/reference/python/rest/calling/collect-stop +[collect-start-input-timers]: /docs/server-sdks/reference/python/rest/calling/collect-start-input-timers + Start collecting user input on an active call. Supports DTMF digit collection -and speech recognition. Returns a `control_id` for managing the collection. +and speech recognition. Pass a `control_id` to name the collection so you can +manage it later with [`collect_stop()`][collect-stop] or +[`collect_start_input_timers()`][collect-start-input-timers]. The response never +carries `control_id` back -- omit it and you have no way to control this +collection afterward. ## **Request** @@ -29,9 +36,10 @@ client = RestClient( host="your-space.signalwire.com", ) -# Collect DTMF digits -result = client.calling.collect( +# Collect DTMF digits -- name it so it can be stopped or its timers managed later +client.calling.collect( call_id="call-id-xxx", + control_id="collect-1", digits={"max": 4, "terminators": "#", "digit_timeout": 5.0}, initial_timeout=10.0, ) diff --git a/fern/products/server-sdks/pages/reference/python/rest/calling/detect.mdx b/fern/products/server-sdks/pages/reference/python/rest/calling/detect.mdx index 0bf9ba555b..e9d3d83f4a 100644 --- a/fern/products/server-sdks/pages/reference/python/rest/calling/detect.mdx +++ b/fern/products/server-sdks/pages/reference/python/rest/calling/detect.mdx @@ -5,8 +5,13 @@ description: Start detection (answering machine, fax, DTMF) on a call via REST. max-toc-depth: 3 --- +[detect-stop]: /docs/server-sdks/reference/python/rest/calling/detect-stop + Start a detector on an active call. Detectors can identify answering machines, -fax tones, or DTMF digits. Returns a `control_id` for managing the detector. +fax tones, or DTMF digits. Pass a `control_id` to name the detector so you can +stop it later with [`detect_stop()`][detect-stop]. The response never carries +`control_id` back -- omit it and you have no way to control this detector +afterward. ## **Request** @@ -29,9 +34,10 @@ client = RestClient( host="your-space.signalwire.com", ) -# Answering machine detection -result = client.calling.detect( +# Answering machine detection -- name it so it can be stopped later +client.calling.detect( call_id="call-id-xxx", + control_id="detect-1", detect={ "type": "machine", "params": { diff --git a/fern/products/server-sdks/pages/reference/python/rest/calling/play.mdx b/fern/products/server-sdks/pages/reference/python/rest/calling/play.mdx index 2c3771d5e2..dd28fe7054 100644 --- a/fern/products/server-sdks/pages/reference/python/rest/calling/play.mdx +++ b/fern/products/server-sdks/pages/reference/python/rest/calling/play.mdx @@ -10,12 +10,13 @@ max-toc-depth: 3 [play-stop]: /docs/server-sdks/reference/python/rest/calling/play-stop [play-volume]: /docs/server-sdks/reference/python/rest/calling/play-volume -Play audio or text-to-speech on an active call. Returns a `control_id` that can be -used with [`play_pause()`][play-pause], +Play audio or text-to-speech on an active call. Pass a `control_id` to name the +operation so you can manage it later with [`play_pause()`][play-pause], [`play_resume()`][play-resume], [`play_stop()`][play-stop], and -[`play_volume()`][play-volume] to manage -the playback. +[`play_volume()`][play-volume]. +The response never carries `control_id` back -- omit it and you have no way to +control this playback afterward. ## **Request** @@ -38,12 +39,12 @@ client = RestClient( host="your-space.signalwire.com", ) -# Play TTS -result = client.calling.play( +# Play TTS -- name it so it can be paused, resumed, or stopped later +client.calling.play( call_id="call-id-xxx", + control_id="play-1", play=[{"type": "tts", "text": "Hello from the REST API!"}] ) -control_id = result.get("control_id") ``` ### Play Audio File diff --git a/fern/products/server-sdks/pages/reference/python/rest/calling/record.mdx b/fern/products/server-sdks/pages/reference/python/rest/calling/record.mdx index 91261f0c25..c5943904d2 100644 --- a/fern/products/server-sdks/pages/reference/python/rest/calling/record.mdx +++ b/fern/products/server-sdks/pages/reference/python/rest/calling/record.mdx @@ -9,10 +9,11 @@ max-toc-depth: 3 [resume]: /docs/server-sdks/reference/python/rest/calling/record-resume [stop]: /docs/server-sdks/reference/python/rest/calling/record-stop -Start recording an active call. Returns a `control_id` used to -[pause][pause], +Start recording an active call. Pass a `control_id` to name the recording so you +can [pause][pause], [resume][resume], -or [stop][stop] the recording. +or [stop][stop] it later. The response never carries `control_id` back -- omit +it and you have no way to control this recording afterward. ## **Request** @@ -33,9 +34,9 @@ client = RestClient( host="your-space.signalwire.com", ) -result = client.calling.record( +client.calling.record( call_id="call-id-xxx", + control_id="record-1", audio={"format": "mp3", "stereo": True} ) -control_id = result.get("control_id") ``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/calling/stream.mdx b/fern/products/server-sdks/pages/reference/python/rest/calling/stream.mdx index 5f069d2379..6797c5acf8 100644 --- a/fern/products/server-sdks/pages/reference/python/rest/calling/stream.mdx +++ b/fern/products/server-sdks/pages/reference/python/rest/calling/stream.mdx @@ -5,9 +5,13 @@ description: Stream call audio to a WebSocket endpoint via REST. max-toc-depth: 3 --- +[stream-stop]: /docs/server-sdks/reference/python/rest/calling/stream-stop + Start streaming audio from an active call to a WebSocket endpoint. This is -commonly used for real-time speech processing, analytics, or archival. -Returns a `control_id` for stopping the stream. +commonly used for real-time speech processing, analytics, or archival. Pass a +`control_id` to name the stream so you can stop it later with +[`stream_stop()`][stream-stop]. The response never carries `control_id` back -- +omit it and you have no way to stop this stream afterward. ## **Request** @@ -28,9 +32,9 @@ client = RestClient( host="your-space.signalwire.com", ) -result = client.calling.stream( +client.calling.stream( call_id="call-id-xxx", + control_id="stream-1", url="wss://example.com/audio-stream", ) -control_id = result.get("control_id") ``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/calling/tap.mdx b/fern/products/server-sdks/pages/reference/python/rest/calling/tap.mdx index c5228502b1..b6ae8f2353 100644 --- a/fern/products/server-sdks/pages/reference/python/rest/calling/tap.mdx +++ b/fern/products/server-sdks/pages/reference/python/rest/calling/tap.mdx @@ -5,9 +5,12 @@ description: Tap call audio to an external endpoint via REST. max-toc-depth: 3 --- +[tap-stop]: /docs/server-sdks/reference/python/rest/calling/tap-stop + Start tapping audio from an active call and sending it to an external endpoint -(e.g., a WebSocket or RTP destination). Returns a `control_id` for stopping -the tap. +(e.g., a WebSocket or RTP destination). Pass a `control_id` to name the tap so +you can stop it later with [`tap_stop()`][tap-stop]. The response never carries +`control_id` back -- omit it and you have no way to stop this tap afterward. ## **Request** @@ -28,10 +31,10 @@ client = RestClient( host="your-space.signalwire.com", ) -result = client.calling.tap( +client.calling.tap( call_id="call-id-xxx", + control_id="tap-1", tap={"type": "audio", "params": {"direction": "both"}}, device={"type": "ws", "params": {"uri": "wss://example.com/tap"}}, ) -control_id = result.get("control_id") ``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/client/index.mdx b/fern/products/server-sdks/pages/reference/python/rest/client/index.mdx index 895142cc28..75b8d75f7a 100644 --- a/fern/products/server-sdks/pages/reference/python/rest/client/index.mdx +++ b/fern/products/server-sdks/pages/reference/python/rest/client/index.mdx @@ -25,14 +25,16 @@ max-toc-depth: 3 [project]: /docs/server-sdks/reference/python/rest/project [pubsub]: /docs/server-sdks/reference/python/rest/pubsub [chat]: /docs/server-sdks/reference/python/rest/chat -[compatibility]: /docs/server-sdks/reference/python/rest/compat +[messages]: /docs/server-sdks/reference/python/rest/messages +[projects]: /docs/server-sdks/reference/python/rest/projects +[request-options]: /docs/server-sdks/reference/python/rest/request-options The `RestClient` is the entry point for all SignalWire REST API operations. It authenticates with your project credentials and exposes every API namespace as a property, giving you typed access to phone numbers, fabric resources, call control, video rooms, datasphere documents, logs, and more. -## **Constructor Parameters** +## Parameters SignalWire project ID. Falls back to the `SIGNALWIRE_PROJECT_ID` environment variable @@ -49,74 +51,80 @@ call control, video rooms, datasphere documents, logs, and more. `SIGNALWIRE_SPACE` environment variable when not provided. + + Client-wide defaults for request timeout, retries, and cancellation. Every + method also accepts its own `request_options=` argument, which overrides these + defaults for that one call. See [`RequestOptions`][request-options]. + + -All three parameters are required. If any is missing from both the constructor -arguments and environment variables, a `ValueError` is raised. +`project`, `token`, and `host` are required. If any is missing from both the +constructor arguments and environment variables, a `ValueError` is raised. -## **Namespace Properties** +## Namespace Properties AI agents, SWML scripts, [subscribers](/docs/platform/subscribers), call flows, SIP gateways, and tokens. See [`Fabric`][fabric]. - + REST-based call control with 37+ commands dispatched via POST. See [`Calling`][calling]. - + Search, purchase, and manage phone numbers. See [`Phone Numbers`][phone-numbers]. - + Manage regulatory addresses. See [`Addresses`][addresses]. - + Manage call queues and queue members. See [`Queues`][queues]. - + List, retrieve, and delete call recordings. See [`Recordings`][recordings]. - + Manage number groups and their memberships. See [`Number Groups`][number-groups]. - + Manage and verify caller IDs. See [`Verified Callers`][verified-callers]. - + Get and update the project SIP profile. See [`SIP Profile`][sip-profile]. - + Phone number carrier and CNAM lookup. See [`Lookup`][lookup]. - + Manage short codes. See [`Short Codes`][short-codes]. - + Import externally-hosted phone numbers. See [`Imported Numbers`][imported-numbers]. - + Multi-factor authentication via SMS and voice. See [`MFA`][mfa]. @@ -146,22 +154,27 @@ arguments and environment variables, a `ValueError` is raised. See [`Project`][project]. - + PubSub token generation. See [`PubSub`][pubsub]. - + Chat token generation. See [`Chat`][chat]. - - Twilio-compatible LAML API for migration. - See [`Compatibility`][compatibility]. + + Send SMS and MMS messages and redact the body of a sent message. + See [`Messages`][messages]. + + + + Create and manage subprojects and rotate a project's signing key. + See [`Projects`][projects]. -## **Examples** +## Examples ### Explicit credentials @@ -186,5 +199,5 @@ from signalwire.rest import RestClient # With SIGNALWIRE_PROJECT_ID, SIGNALWIRE_API_TOKEN, and SIGNALWIRE_SPACE set client = RestClient() -available = client.phone_numbers.search(area_code="512") +available = client.phone_numbers.search(areacode="512") ``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/accounts/create.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/accounts/create.mdx deleted file mode 100644 index 1eba2d8514..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/accounts/create.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "create" -slug: /reference/python/rest/compat/accounts/create -description: Create a new subproject (sub-account). -max-toc-depth: 3 ---- - - -Create a new subproject (sub-account). - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -sub = client.compat.accounts.create(FriendlyName="Marketing Team") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/accounts/get.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/accounts/get.mdx deleted file mode 100644 index 75ea66d5db..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/accounts/get.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "get" -slug: /reference/python/rest/compat/accounts/get -description: Retrieve a single account by SID. -max-toc-depth: 3 ---- - - -Retrieve a single account by its SID. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -account = client.compat.accounts.get("account-sid") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/accounts/index.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/accounts/index.mdx deleted file mode 100644 index 8165c363ff..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/accounts/index.mdx +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: "Accounts" -slug: /reference/python/rest/compat/accounts -description: Manage accounts and subprojects via the Compat API. -max-toc-depth: 3 ---- - -[restclient]: /docs/server-sdks/reference/python/rest/client -[list]: /docs/server-sdks/reference/python/rest/compat/accounts/list -[create]: /docs/server-sdks/reference/python/rest/compat/accounts/create -[get]: /docs/server-sdks/reference/python/rest/compat/accounts/get -[update]: /docs/server-sdks/reference/python/rest/compat/accounts/update - -Manage accounts and subprojects. The base path is -`/api/laml/2010-04-01/Accounts` (not scoped to a specific account SID). - -Access via `client.compat.accounts` on a [`RestClient`][restclient] instance. - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -accounts = client.compat.accounts.list() -``` - -## **Methods** - - - - List accounts in the project. - - - Create a new subproject (sub-account). - - - Retrieve a single account by SID. - - - Update an account. - - diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/accounts/list.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/accounts/list.mdx deleted file mode 100644 index 337bcd8a5e..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/accounts/list.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "list" -slug: /reference/python/rest/compat/accounts/list -description: List accounts in the project. -max-toc-depth: 3 ---- - - -List accounts. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -accounts = client.compat.accounts.list() -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/accounts/update.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/accounts/update.mdx deleted file mode 100644 index 11b075199f..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/accounts/update.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "update" -slug: /reference/python/rest/compat/accounts/update -description: Update an account. -max-toc-depth: 3 ---- - - -Update an account. Uses POST (Twilio convention). - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.accounts.update("account-sid", FriendlyName="Sales Team") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/applications/create.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/applications/create.mdx deleted file mode 100644 index d9136bd04f..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/applications/create.mdx +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: "create" -slug: /reference/python/rest/compat/applications/create -description: Create a new application. -max-toc-depth: 3 ---- - - -Create a new application. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -app = client.compat.applications.create( - FriendlyName="My App", - VoiceUrl="https://example.com/voice", - SmsUrl="https://example.com/sms" -) -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/applications/delete.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/applications/delete.mdx deleted file mode 100644 index 9d0291b49c..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/applications/delete.mdx +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: "delete" -slug: /reference/python/rest/compat/applications/delete -description: Delete an application. -max-toc-depth: 3 ---- - - -Delete an application. - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.applications.delete("AP...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/applications/get.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/applications/get.mdx deleted file mode 100644 index 0c06570873..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/applications/get.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "get" -slug: /reference/python/rest/compat/applications/get -description: Retrieve a single application by SID. -max-toc-depth: 3 ---- - - -Retrieve a single application by SID. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -app = client.compat.applications.get("AP...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/applications/index.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/applications/index.mdx deleted file mode 100644 index 0ba7561c39..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/applications/index.mdx +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: "Applications" -slug: /reference/python/rest/compat/applications -description: Manage applications with CRUD operations. -max-toc-depth: 3 ---- - -[restclient]: /docs/server-sdks/reference/python/rest/client -[list]: /docs/server-sdks/reference/python/rest/compat/applications/list -[create]: /docs/server-sdks/reference/python/rest/compat/applications/create -[get]: /docs/server-sdks/reference/python/rest/compat/applications/get -[update]: /docs/server-sdks/reference/python/rest/compat/applications/update -[delete]: /docs/server-sdks/reference/python/rest/compat/applications/delete - -Manage applications with CRUD operations. Applications define voice and messaging -URL endpoints for handling incoming calls and messages. - -Access via `client.compat.applications` on a [`RestClient`][restclient] instance. - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -apps = client.compat.applications.list() -``` - -## **Methods** - - - - List applications in the account. - - - Create a new application. - - - Retrieve a single application by SID. - - - Update an application. - - - Delete an application. - - diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/applications/list.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/applications/list.mdx deleted file mode 100644 index 9c222ed61d..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/applications/list.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "list" -slug: /reference/python/rest/compat/applications/list -description: List applications in the account. -max-toc-depth: 3 ---- - - -List applications in the account. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -apps = client.compat.applications.list(PageSize=20) -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/applications/update.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/applications/update.mdx deleted file mode 100644 index 29fb8eaba6..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/applications/update.mdx +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: "update" -slug: /reference/python/rest/compat/applications/update -description: Update an application. -max-toc-depth: 3 ---- - - -Update an application's configuration. Uses POST (Twilio convention). - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.applications.update( - "AP...", - VoiceUrl="https://example.com/new-voice" -) -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/calls/create.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/calls/create.mdx deleted file mode 100644 index c22daef970..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/calls/create.mdx +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: "create" -slug: /reference/python/rest/compat/calls/create -description: Initiate a new outbound call. -max-toc-depth: 3 ---- - - -Initiate a new outbound call. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -call = client.compat.calls.create( - To="+15559876543", - From="+15551234567", - Url="https://example.com/voice" -) -print(call["sid"]) -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/calls/delete.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/calls/delete.mdx deleted file mode 100644 index 4ff092ef60..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/calls/delete.mdx +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: "delete" -slug: /reference/python/rest/compat/calls/delete -description: Delete a call record. -max-toc-depth: 3 ---- - - -Delete a call record. - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.calls.delete("CA...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/calls/get.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/calls/get.mdx deleted file mode 100644 index 1a6285de5f..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/calls/get.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "get" -slug: /reference/python/rest/compat/calls/get -description: Retrieve a single call by SID. -max-toc-depth: 3 ---- - - -Retrieve a single call by SID. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -call = client.compat.calls.get("CA...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/calls/index.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/calls/index.mdx deleted file mode 100644 index 8338a68b40..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/calls/index.mdx +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: "Calls" -slug: /reference/python/rest/compat/calls -description: Manage calls with CRUD operations, in-call recording, and media streaming. -max-toc-depth: 3 ---- - -[restclient]: /docs/server-sdks/reference/python/rest/client -[list]: /docs/server-sdks/reference/python/rest/compat/calls/list -[create]: /docs/server-sdks/reference/python/rest/compat/calls/create -[get]: /docs/server-sdks/reference/python/rest/compat/calls/get -[update]: /docs/server-sdks/reference/python/rest/compat/calls/update -[delete]: /docs/server-sdks/reference/python/rest/compat/calls/delete -[startrecording]: /docs/server-sdks/reference/python/rest/compat/calls/start-recording -[updaterecording]: /docs/server-sdks/reference/python/rest/compat/calls/update-recording -[startstream]: /docs/server-sdks/reference/python/rest/compat/calls/start-stream -[stopstream]: /docs/server-sdks/reference/python/rest/compat/calls/stop-stream - -Manage calls with CRUD operations, plus sub-resources for in-call recording -and streaming. Uses POST for updates (Twilio convention). - -Access via `client.compat.calls` on a [`RestClient`][restclient] instance. - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -calls = client.compat.calls.list() -``` - -## **Methods** - -### Call CRUD - - - - List calls in the account. - - - Initiate a new outbound call. - - - Retrieve a single call by SID. - - - Update an active call. - - - Delete a call record. - - - -### Recording - - - - Start recording an active call. - - - Update a call recording (pause, resume, or stop). - - - -### Streaming - - - - Start a media stream on an active call. - - - Stop a media stream on a call. - - diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/calls/list.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/calls/list.mdx deleted file mode 100644 index 9119f627dc..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/calls/list.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "list" -slug: /reference/python/rest/compat/calls/list -description: List calls in the account. -max-toc-depth: 3 ---- - - -List calls in the account. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -calls = client.compat.calls.list(Status="completed", PageSize=20) -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/calls/start-recording.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/calls/start-recording.mdx deleted file mode 100644 index ff37a0f41a..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/calls/start-recording.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "start_recording" -slug: /reference/python/rest/compat/calls/start-recording -description: Start recording an active call. -max-toc-depth: 3 ---- - - -Start recording an active call. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -recording = client.compat.calls.start_recording("CA...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/calls/start-stream.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/calls/start-stream.mdx deleted file mode 100644 index 5d1b1df497..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/calls/start-stream.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "start_stream" -slug: /reference/python/rest/compat/calls/start-stream -description: Start a media stream on an active call. -max-toc-depth: 3 ---- - - -Start a media stream on an active call, sending real-time audio to a WebSocket URL. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -stream = client.compat.calls.start_stream("CA...", Url="wss://stream.example.com") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/calls/stop-stream.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/calls/stop-stream.mdx deleted file mode 100644 index 779e7b2961..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/calls/stop-stream.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "stop_stream" -slug: /reference/python/rest/compat/calls/stop-stream -description: Stop a media stream on a call. -max-toc-depth: 3 ---- - - -Stop a media stream on a call. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.calls.stop_stream("CA...", "ST...", Status="stopped") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/calls/update-recording.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/calls/update-recording.mdx deleted file mode 100644 index 4d73290477..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/calls/update-recording.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "update_recording" -slug: /reference/python/rest/compat/calls/update-recording -description: Update a call recording (pause, resume, or stop). -max-toc-depth: 3 ---- - - -Update a call recording (e.g., pause, resume, or stop). - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.calls.update_recording("CA...", "RE...", Status="paused") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/calls/update.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/calls/update.mdx deleted file mode 100644 index 0c075fc6c3..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/calls/update.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "update" -slug: /reference/python/rest/compat/calls/update -description: Update an active call. -max-toc-depth: 3 ---- - - -Update an active call (e.g., redirect to new LAML, end the call). Uses POST (Twilio convention). - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.calls.update("CA...", Status="completed") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/delete-recording.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/delete-recording.mdx deleted file mode 100644 index 9c3b296000..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/delete-recording.mdx +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: "delete_recording" -slug: /reference/python/rest/compat/conferences/delete-recording -description: Delete a conference recording. -max-toc-depth: 3 ---- - - -Delete a conference recording. - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.conferences.delete_recording("CF...", "RE...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/get-participant.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/get-participant.mdx deleted file mode 100644 index dcc8b864ab..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/get-participant.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "get_participant" -slug: /reference/python/rest/compat/conferences/get-participant -description: Retrieve a specific participant in a conference. -max-toc-depth: 3 ---- - - -Retrieve a specific participant in a conference. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -participant = client.compat.conferences.get_participant("CF...", "CA...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/get-recording.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/get-recording.mdx deleted file mode 100644 index 7f3cecbd3e..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/get-recording.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "get_recording" -slug: /reference/python/rest/compat/conferences/get-recording -description: Retrieve a specific conference recording. -max-toc-depth: 3 ---- - - -Retrieve a specific conference recording. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -recording = client.compat.conferences.get_recording("CF...", "RE...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/get.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/get.mdx deleted file mode 100644 index e4a1cb0f84..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/get.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "get" -slug: /reference/python/rest/compat/conferences/get -description: Retrieve a single conference by SID. -max-toc-depth: 3 ---- - - -Retrieve a single conference by SID. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -conf = client.compat.conferences.get("CF...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/index.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/index.mdx deleted file mode 100644 index feb0492d4f..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/index.mdx +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: "Conferences" -slug: /reference/python/rest/compat/conferences -description: Manage conferences with participants, recordings, and media streams. -max-toc-depth: 3 ---- - -[restclient]: /docs/server-sdks/reference/python/rest/client -[list]: /docs/server-sdks/reference/python/rest/compat/conferences/list -[get]: /docs/server-sdks/reference/python/rest/compat/conferences/get -[update]: /docs/server-sdks/reference/python/rest/compat/conferences/update -[listparticipants]: /docs/server-sdks/reference/python/rest/compat/conferences/list-participants -[getparticipant]: /docs/server-sdks/reference/python/rest/compat/conferences/get-participant -[updateparticipant]: /docs/server-sdks/reference/python/rest/compat/conferences/update-participant -[removeparticipant]: /docs/server-sdks/reference/python/rest/compat/conferences/remove-participant -[listrecordings]: /docs/server-sdks/reference/python/rest/compat/conferences/list-recordings -[getrecording]: /docs/server-sdks/reference/python/rest/compat/conferences/get-recording -[updaterecording]: /docs/server-sdks/reference/python/rest/compat/conferences/update-recording -[deleterecording]: /docs/server-sdks/reference/python/rest/compat/conferences/delete-recording -[startstream]: /docs/server-sdks/reference/python/rest/compat/conferences/start-stream -[stopstream]: /docs/server-sdks/reference/python/rest/compat/conferences/stop-stream - -Manage conferences with participants, recordings, and streams. Conferences are -list/get/update only (they are created implicitly when a participant dials in -via LAML). - -Access via `client.compat.conferences` on a [`RestClient`][restclient] instance. - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -conferences = client.compat.conferences.list() -``` - -## **Methods** - -### Conference CRUD - - - - List conferences. - - - Retrieve a single conference by SID. - - - Update a conference (e.g., end it or set an announce URL). - - - -### Participants - - - - List participants in a conference. - - - Retrieve a specific participant in a conference. - - - Update a participant in a conference (mute or hold). - - - Remove a participant from a conference. - - - -### Recordings - - - - List recordings for a conference. - - - Retrieve a specific conference recording. - - - Update a conference recording (pause, resume, or stop). - - - Delete a conference recording. - - - -### Streaming - - - - Start a media stream on a conference. - - - Stop a media stream on a conference. - - diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/list-participants.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/list-participants.mdx deleted file mode 100644 index 9bc0f1ed97..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/list-participants.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "list_participants" -slug: /reference/python/rest/compat/conferences/list-participants -description: List participants in a conference. -max-toc-depth: 3 ---- - - -List participants in a conference. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -participants = client.compat.conferences.list_participants("CF...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/list-recordings.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/list-recordings.mdx deleted file mode 100644 index c1e0cf8374..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/list-recordings.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "list_recordings" -slug: /reference/python/rest/compat/conferences/list-recordings -description: List recordings for a conference. -max-toc-depth: 3 ---- - - -List recordings for a conference. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -recordings = client.compat.conferences.list_recordings("CF...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/list.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/list.mdx deleted file mode 100644 index 9d1417b1c3..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/list.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "list" -slug: /reference/python/rest/compat/conferences/list -description: List conferences. -max-toc-depth: 3 ---- - - -List conferences. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -conferences = client.compat.conferences.list(Status="in-progress") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/remove-participant.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/remove-participant.mdx deleted file mode 100644 index 6d5336400a..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/remove-participant.mdx +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: "remove_participant" -slug: /reference/python/rest/compat/conferences/remove-participant -description: Remove a participant from a conference. -max-toc-depth: 3 ---- - - -Remove a participant from a conference, ending their call leg. - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.conferences.remove_participant("CF...", "CA...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/start-stream.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/start-stream.mdx deleted file mode 100644 index ba21f2812c..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/start-stream.mdx +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: "start_stream" -slug: /reference/python/rest/compat/conferences/start-stream -description: Start a media stream on a conference. -max-toc-depth: 3 ---- - - -Start a media stream on a conference, sending real-time audio to a WebSocket URL. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -stream = client.compat.conferences.start_stream( - "CF...", - Url="wss://stream.example.com" -) -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/stop-stream.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/stop-stream.mdx deleted file mode 100644 index 32d5059a5a..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/stop-stream.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "stop_stream" -slug: /reference/python/rest/compat/conferences/stop-stream -description: Stop a media stream on a conference. -max-toc-depth: 3 ---- - - -Stop a media stream on a conference. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.conferences.stop_stream("CF...", "ST...", Status="stopped") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/update-participant.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/update-participant.mdx deleted file mode 100644 index f5a32b2651..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/update-participant.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "update_participant" -slug: /reference/python/rest/compat/conferences/update-participant -description: Update a participant in a conference (mute or hold). -max-toc-depth: 3 ---- - - -Update a participant in a conference (e.g., mute or hold). - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.conferences.update_participant("CF...", "CA...", Muted=True) -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/update-recording.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/update-recording.mdx deleted file mode 100644 index b50cc4df50..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/update-recording.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "update_recording" -slug: /reference/python/rest/compat/conferences/update-recording -description: Update a conference recording (pause, resume, or stop). -max-toc-depth: 3 ---- - - -Update a conference recording (e.g., pause, resume, or stop). - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.conferences.update_recording("CF...", "RE...", Status="paused") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/update.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/update.mdx deleted file mode 100644 index 713258671d..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/conferences/update.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "update" -slug: /reference/python/rest/compat/conferences/update -description: Update a conference (e.g., end it or set an announce URL). -max-toc-depth: 3 ---- - - -Update a conference (e.g., end it, or set the announce URL). Uses POST (Twilio convention). - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.conferences.update("CF...", Status="completed") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/create.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/create.mdx deleted file mode 100644 index 23782821b0..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/create.mdx +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: "create" -slug: /reference/python/rest/compat/faxes/create -description: Send a new fax. -max-toc-depth: 3 ---- - - -Send a new fax. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -fax = client.compat.faxes.create( - To="+15559876543", - From="+15551234567", - MediaUrl="https://example.com/document.pdf" -) -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/delete-media.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/delete-media.mdx deleted file mode 100644 index c73d1716de..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/delete-media.mdx +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: "delete_media" -slug: /reference/python/rest/compat/faxes/delete-media -description: Delete a media item from a fax. -max-toc-depth: 3 ---- - - -Delete a media item from a fax. - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.faxes.delete_media("FX...", "ME...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/delete.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/delete.mdx deleted file mode 100644 index 90aca186f7..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/delete.mdx +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: "delete" -slug: /reference/python/rest/compat/faxes/delete -description: Delete a fax record. -max-toc-depth: 3 ---- - - -Delete a fax record. - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.faxes.delete("FX...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/get-media.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/get-media.mdx deleted file mode 100644 index 8b18f1273d..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/get-media.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "get_media" -slug: /reference/python/rest/compat/faxes/get-media -description: Retrieve a specific media item from a fax. -max-toc-depth: 3 ---- - - -Retrieve a specific media item from a fax. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -item = client.compat.faxes.get_media("FX...", "ME...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/get.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/get.mdx deleted file mode 100644 index d592133ccd..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/get.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "get" -slug: /reference/python/rest/compat/faxes/get -description: Retrieve a single fax by SID. -max-toc-depth: 3 ---- - - -Retrieve a single fax by SID. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -fax = client.compat.faxes.get("FX...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/index.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/index.mdx deleted file mode 100644 index 4c482cfda3..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/index.mdx +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: "Faxes" -slug: /reference/python/rest/compat/faxes -description: Manage faxes with CRUD operations and media sub-resources. -max-toc-depth: 3 ---- - -[messages]: /docs/server-sdks/reference/python/rest/compat/messages -[restclient]: /docs/server-sdks/reference/python/rest/client -[list]: /docs/server-sdks/reference/python/rest/compat/faxes/list -[create]: /docs/server-sdks/reference/python/rest/compat/faxes/create -[get]: /docs/server-sdks/reference/python/rest/compat/faxes/get -[update]: /docs/server-sdks/reference/python/rest/compat/faxes/update -[delete]: /docs/server-sdks/reference/python/rest/compat/faxes/delete -[listmedia]: /docs/server-sdks/reference/python/rest/compat/faxes/list-media -[getmedia]: /docs/server-sdks/reference/python/rest/compat/faxes/get-media -[deletemedia]: /docs/server-sdks/reference/python/rest/compat/faxes/delete-media - -Manage faxes with CRUD operations and media sub-resources. The media sub-resource -pattern is identical to [`messages`][messages]. - -Access via `client.compat.faxes` on a [`RestClient`][restclient] instance. - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -faxes = client.compat.faxes.list() -``` - -## **Methods** - -### Fax CRUD - - - - List faxes in the account. - - - Send a new fax. - - - Retrieve a single fax by SID. - - - Update a fax resource. - - - Delete a fax record. - - - -### Media - - - - List media items attached to a fax. - - - Retrieve a specific media item from a fax. - - - Delete a media item from a fax. - - diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/list-media.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/list-media.mdx deleted file mode 100644 index 6e6b1b47af..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/list-media.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "list_media" -slug: /reference/python/rest/compat/faxes/list-media -description: List media items attached to a fax. -max-toc-depth: 3 ---- - - -List media items attached to a fax. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -media = client.compat.faxes.list_media("FX...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/list.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/list.mdx deleted file mode 100644 index 18eed75c2e..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/list.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "list" -slug: /reference/python/rest/compat/faxes/list -description: List faxes in the account. -max-toc-depth: 3 ---- - - -List faxes in the account. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -faxes = client.compat.faxes.list() -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/update.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/update.mdx deleted file mode 100644 index 104f8190f8..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/faxes/update.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "update" -slug: /reference/python/rest/compat/faxes/update -description: Update a fax resource. -max-toc-depth: 3 ---- - - -Update a fax resource. Uses POST (Twilio convention). - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.faxes.update("FX...", Status="canceled") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/index.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/index.mdx deleted file mode 100644 index 5aca33c754..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/index.mdx +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: "Compat" -slug: /reference/python/rest/compat -description: Twilio-compatible REST API for calls, messages, faxes, conferences, phone numbers, and more. -max-toc-depth: 3 ---- - -[restclient]: /docs/server-sdks/reference/python/rest/client -[accounts]: /docs/server-sdks/reference/python/rest/compat/accounts -[calls]: /docs/server-sdks/reference/python/rest/compat/calls -[messages]: /docs/server-sdks/reference/python/rest/compat/messages -[faxes]: /docs/server-sdks/reference/python/rest/compat/faxes -[conferences]: /docs/server-sdks/reference/python/rest/compat/conferences -[phone-numbers]: /docs/server-sdks/reference/python/rest/compat/phone-numbers -[applications]: /docs/server-sdks/reference/python/rest/compat/applications -[laml-bins]: /docs/server-sdks/reference/python/rest/compat/laml-bins -[queues]: /docs/server-sdks/reference/python/rest/compat/queues -[recordings]: /docs/server-sdks/reference/python/rest/compat/recordings -[transcriptions]: /docs/server-sdks/reference/python/rest/compat/transcriptions -[tokens]: /docs/server-sdks/reference/python/rest/compat/tokens - -The `CompatNamespace` provides a Twilio-compatible LAML REST API through the -[`RestClient`][restclient]. It implements the familiar -`/2010-04-01/Accounts/{AccountSid}/` URL structure with 12 sub-resources, making it -straightforward to migrate existing Twilio integrations to SignalWire. - -Access via `client.compat` on a [`RestClient`][restclient] instance. - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -calls = client.compat.calls.list() -``` - - -The Compat namespace uses the same REST patterns as Twilio's API. If you are migrating -from Twilio, most code changes are limited to updating the client initialization to use -SignalWire credentials. Resource identifiers use SIDs (e.g., `CA...` for calls, `SM...` -for messages). - - -## **Sub-resources** - - - - Account and subproject management. - - - Call management with recording and stream sub-resources. - - - SMS/MMS messaging with media sub-resources. - - - Fax management with media sub-resources. - - - Conference management with participants, recordings, and streams. - - - Phone number management, search, and import. - - - Application configuration management. - - - LAML (cXML) script management. - - - Queue management with member operations. - - - Recording management. - - - Transcription management. - - - API token management. - - diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/laml-bins/create.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/laml-bins/create.mdx deleted file mode 100644 index 6d575d490f..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/laml-bins/create.mdx +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: "create" -slug: /reference/python/rest/compat/laml-bins/create -description: Create a new LAML bin. -max-toc-depth: 3 ---- - - -Create a new LAML bin containing a cXML/LaML script. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -laml_bin = client.compat.laml_bins.create( - Name="Greeting", - Contents=( - '' - "Hello!" - ) -) -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/laml-bins/delete.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/laml-bins/delete.mdx deleted file mode 100644 index 1c8078f0bb..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/laml-bins/delete.mdx +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: "delete" -slug: /reference/python/rest/compat/laml-bins/delete -description: Delete a LAML bin. -max-toc-depth: 3 ---- - - -Delete a LAML bin. - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.laml_bins.delete("LB...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/laml-bins/get.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/laml-bins/get.mdx deleted file mode 100644 index 7bba19d8eb..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/laml-bins/get.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "get" -slug: /reference/python/rest/compat/laml-bins/get -description: Retrieve a single LAML bin by SID. -max-toc-depth: 3 ---- - - -Retrieve a single LAML bin by SID. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -laml_bin = client.compat.laml_bins.get("LB...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/laml-bins/index.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/laml-bins/index.mdx deleted file mode 100644 index 8ebab98da3..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/laml-bins/index.mdx +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: "LAML Bins" -slug: /reference/python/rest/compat/laml-bins -description: Manage LAML bins (cXML/LaML scripts) with CRUD operations. -max-toc-depth: 3 ---- - -[restclient]: /docs/server-sdks/reference/python/rest/client -[list]: /docs/server-sdks/reference/python/rest/compat/laml-bins/list -[create]: /docs/server-sdks/reference/python/rest/compat/laml-bins/create -[get]: /docs/server-sdks/reference/python/rest/compat/laml-bins/get -[update]: /docs/server-sdks/reference/python/rest/compat/laml-bins/update -[delete]: /docs/server-sdks/reference/python/rest/compat/laml-bins/delete - -Manage LAML bins with CRUD operations. LAML bins store reusable cXML/LaML scripts -that can be referenced by URL in call and message handling. - -Access via `client.compat.laml_bins` on a [`RestClient`][restclient] instance. - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -bins = client.compat.laml_bins.list() -``` - -## **Methods** - - - - List LAML bins in the account. - - - Create a new LAML bin. - - - Retrieve a single LAML bin by SID. - - - Update a LAML bin. - - - Delete a LAML bin. - - diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/laml-bins/list.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/laml-bins/list.mdx deleted file mode 100644 index 93dfdac108..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/laml-bins/list.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "list" -slug: /reference/python/rest/compat/laml-bins/list -description: List LAML bins in the account. -max-toc-depth: 3 ---- - - -List LAML bins in the account. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -bins = client.compat.laml_bins.list(PageSize=20) -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/laml-bins/update.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/laml-bins/update.mdx deleted file mode 100644 index d4364cdf4d..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/laml-bins/update.mdx +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: "update" -slug: /reference/python/rest/compat/laml-bins/update -description: Update a LAML bin. -max-toc-depth: 3 ---- - - -Update a LAML bin's content or name. Uses POST (Twilio convention). - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.laml_bins.update( - "LB...", - Name="Greeting", - Contents=( - '' - "Goodbye!" - ) -) -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/messages/create.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/messages/create.mdx deleted file mode 100644 index 2c61969bca..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/messages/create.mdx +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: "create" -slug: /reference/python/rest/compat/messages/create -description: Send a new SMS or MMS message. -max-toc-depth: 3 ---- - - -Send a new SMS or MMS message. - - - -## **Response Example** - - - -## **Example** - -```python {10,17} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -# Send an SMS -msg = client.compat.messages.create( - To="+15559876543", - From="+15551234567", - Body="Hello from SignalWire!" -) - -# Send an MMS with an image -mms = client.compat.messages.create( - To="+15559876543", - From="+15551234567", - Body="Check this out", - MediaUrl=["https://example.com/image.jpg"] -) -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/messages/delete-media.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/messages/delete-media.mdx deleted file mode 100644 index 4f448d17dc..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/messages/delete-media.mdx +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: "delete_media" -slug: /reference/python/rest/compat/messages/delete-media -description: Delete a media item from a message. -max-toc-depth: 3 ---- - - -Delete a media item from a message. - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.messages.delete_media("SM...", "ME...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/messages/delete.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/messages/delete.mdx deleted file mode 100644 index 3c1958b716..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/messages/delete.mdx +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: "delete" -slug: /reference/python/rest/compat/messages/delete -description: Delete a message record. -max-toc-depth: 3 ---- - - -Delete a message record. - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.messages.delete("SM...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/messages/get-media.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/messages/get-media.mdx deleted file mode 100644 index b4e4413e60..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/messages/get-media.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "get_media" -slug: /reference/python/rest/compat/messages/get-media -description: Retrieve a specific media item from a message. -max-toc-depth: 3 ---- - - -Retrieve a specific media item from a message. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -item = client.compat.messages.get_media("SM...", "ME...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/messages/get.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/messages/get.mdx deleted file mode 100644 index 3f34341da5..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/messages/get.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "get" -slug: /reference/python/rest/compat/messages/get -description: Retrieve a single message by SID. -max-toc-depth: 3 ---- - - -Retrieve a single message by SID. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -message = client.compat.messages.get("SM...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/messages/index.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/messages/index.mdx deleted file mode 100644 index 623a3d3183..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/messages/index.mdx +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: "Messages" -slug: /reference/python/rest/compat/messages -description: Manage SMS and MMS messages with media sub-resources. -max-toc-depth: 3 ---- - -[restclient]: /docs/server-sdks/reference/python/rest/client -[list]: /docs/server-sdks/reference/python/rest/compat/messages/list -[create]: /docs/server-sdks/reference/python/rest/compat/messages/create -[get]: /docs/server-sdks/reference/python/rest/compat/messages/get -[update]: /docs/server-sdks/reference/python/rest/compat/messages/update -[delete]: /docs/server-sdks/reference/python/rest/compat/messages/delete -[listmedia]: /docs/server-sdks/reference/python/rest/compat/messages/list-media -[getmedia]: /docs/server-sdks/reference/python/rest/compat/messages/get-media -[deletemedia]: /docs/server-sdks/reference/python/rest/compat/messages/delete-media - -Manage SMS and MMS messages with CRUD operations and media sub-resources. - -Access via `client.compat.messages` on a [`RestClient`][restclient] instance. - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -messages = client.compat.messages.list() -``` - -## **Methods** - -### Message CRUD - - - - List messages in the account. - - - Send a new SMS or MMS message. - - - Retrieve a single message by SID. - - - Update a message (e.g., redact the body). - - - Delete a message record. - - - -### Media - - - - List media items attached to a message. - - - Retrieve a specific media item from a message. - - - Delete a media item from a message. - - diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/messages/list-media.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/messages/list-media.mdx deleted file mode 100644 index cbe28148fc..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/messages/list-media.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "list_media" -slug: /reference/python/rest/compat/messages/list-media -description: List media items attached to a message. -max-toc-depth: 3 ---- - - -List media items (images, files) attached to a message. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -media = client.compat.messages.list_media("SM...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/messages/list.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/messages/list.mdx deleted file mode 100644 index 632063a520..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/messages/list.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "list" -slug: /reference/python/rest/compat/messages/list -description: List messages in the account. -max-toc-depth: 3 ---- - - -List messages in the account. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -messages = client.compat.messages.list(PageSize=20) -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/messages/update.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/messages/update.mdx deleted file mode 100644 index 10b5ce329a..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/messages/update.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "update" -slug: /reference/python/rest/compat/messages/update -description: Update a message (e.g., redact the body). -max-toc-depth: 3 ---- - - -Update a message (e.g., redact the body of a sent message). Uses POST (Twilio convention). - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.messages.update("SM...", Body="") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/delete.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/delete.mdx deleted file mode 100644 index 6b5f9bd2d1..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/delete.mdx +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: "delete" -slug: /reference/python/rest/compat/phone-numbers/delete -description: Release a phone number. -max-toc-depth: 3 ---- - - -Release a phone number from the account. - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.phone_numbers.delete("PN...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/get.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/get.mdx deleted file mode 100644 index 7f4b4c62e9..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/get.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "get" -slug: /reference/python/rest/compat/phone-numbers/get -description: Retrieve a single phone number by SID. -max-toc-depth: 3 ---- - - -Retrieve a single phone number by SID. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -number = client.compat.phone_numbers.get("PN...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/import-number.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/import-number.mdx deleted file mode 100644 index a1def13903..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/import-number.mdx +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: "import_number" -slug: /reference/python/rest/compat/phone-numbers/import-number -description: Import an external phone number. -max-toc-depth: 3 ---- - - -Import an external phone number into the account. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -number = client.compat.phone_numbers.import_number( - number="+15559876543", - number_type="longcode", -) -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/index.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/index.mdx deleted file mode 100644 index d567eb5462..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/index.mdx +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: "Phone Numbers" -slug: /reference/python/rest/compat/phone-numbers -description: Manage phone numbers, search available inventory, and import numbers. -max-toc-depth: 3 ---- - -[restclient]: /docs/server-sdks/reference/python/rest/client -[list]: /docs/server-sdks/reference/python/rest/compat/phone-numbers/list -[purchase]: /docs/server-sdks/reference/python/rest/compat/phone-numbers/purchase -[get]: /docs/server-sdks/reference/python/rest/compat/phone-numbers/get -[update]: /docs/server-sdks/reference/python/rest/compat/phone-numbers/update -[delete]: /docs/server-sdks/reference/python/rest/compat/phone-numbers/delete -[importnumber]: /docs/server-sdks/reference/python/rest/compat/phone-numbers/import-number -[listavailablecountries]: /docs/server-sdks/reference/python/rest/compat/phone-numbers/list-available-countries -[searchlocal]: /docs/server-sdks/reference/python/rest/compat/phone-numbers/search-local -[searchtollfree]: /docs/server-sdks/reference/python/rest/compat/phone-numbers/search-toll-free - -Manage incoming phone numbers with CRUD operations, search available inventory -by country, and import external numbers. - -Access via `client.compat.phone_numbers` on a [`RestClient`][restclient] instance. - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -numbers = client.compat.phone_numbers.list() -``` - -## **Methods** - -### Phone Number CRUD - - - - List incoming phone numbers in the account. - - - Purchase a new phone number. - - - Retrieve a single phone number by SID. - - - Update a phone number's configuration. - - - Release a phone number. - - - -### Import - - - - Import an external phone number. - - - -### Available Numbers - - - - List countries with available phone numbers. - - - Search for available local numbers in a country. - - - Search for available toll-free numbers in a country. - - diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/list-available-countries.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/list-available-countries.mdx deleted file mode 100644 index 22329d7a01..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/list-available-countries.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "list_available_countries" -slug: /reference/python/rest/compat/phone-numbers/list-available-countries -description: List countries with available phone numbers. -max-toc-depth: 3 ---- - - -List countries that have phone numbers available for purchase. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -countries = client.compat.phone_numbers.list_available_countries() -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/list.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/list.mdx deleted file mode 100644 index 6343404759..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/list.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "list" -slug: /reference/python/rest/compat/phone-numbers/list -description: List incoming phone numbers in the account. -max-toc-depth: 3 ---- - - -List incoming phone numbers in the account. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -numbers = client.compat.phone_numbers.list(PageSize=20) -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/purchase.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/purchase.mdx deleted file mode 100644 index 5dd0193113..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/purchase.mdx +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: "purchase" -slug: /reference/python/rest/compat/phone-numbers/purchase -description: Purchase a new phone number. -max-toc-depth: 3 ---- - - -Purchase a new phone number for the account. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -number = client.compat.phone_numbers.purchase( - PhoneNumber="+15551234567", - FriendlyName="Main Line" -) -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/search-local.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/search-local.mdx deleted file mode 100644 index ec7be16cf7..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/search-local.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "search_local" -slug: /reference/python/rest/compat/phone-numbers/search-local -description: Search for available local numbers in a country. -max-toc-depth: 3 ---- - - -Search for available local phone numbers in a specific country. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -numbers = client.compat.phone_numbers.search_local("US", AreaCode="512") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/search-toll-free.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/search-toll-free.mdx deleted file mode 100644 index 76ee55343d..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/search-toll-free.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "search_toll_free" -slug: /reference/python/rest/compat/phone-numbers/search-toll-free -description: Search for available toll-free numbers in a country. -max-toc-depth: 3 ---- - - -Search for available toll-free phone numbers in a specific country. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -numbers = client.compat.phone_numbers.search_toll_free("US", Contains="800") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/update.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/update.mdx deleted file mode 100644 index e40ad3cb90..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/phone-numbers/update.mdx +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: "update" -slug: /reference/python/rest/compat/phone-numbers/update -description: Update a phone number's configuration. -max-toc-depth: 3 ---- - - -Update a phone number's configuration (e.g., change voice/SMS URLs). Uses POST (Twilio convention). - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.phone_numbers.update( - "PN...", - VoiceUrl="https://example.com/voice" -) -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/queues/create.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/queues/create.mdx deleted file mode 100644 index 6c5827ba48..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/queues/create.mdx +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: "create" -slug: /reference/python/rest/compat/queues/create -description: Create a new queue. -max-toc-depth: 3 ---- - - -Create a new call queue. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -queue = client.compat.queues.create( - FriendlyName="Support Queue", - MaxSize=100 -) -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/queues/delete.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/queues/delete.mdx deleted file mode 100644 index b8763bd499..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/queues/delete.mdx +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: "delete" -slug: /reference/python/rest/compat/queues/delete -description: Delete a queue. -max-toc-depth: 3 ---- - - -Delete a queue. - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.queues.delete("QU...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/queues/dequeue-member.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/queues/dequeue-member.mdx deleted file mode 100644 index 558fc6ad1f..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/queues/dequeue-member.mdx +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: "dequeue_member" -slug: /reference/python/rest/compat/queues/dequeue-member -description: Dequeue a member from a queue. -max-toc-depth: 3 ---- - - -Dequeue a member from a queue, redirecting the call to a new LAML URL. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.queues.dequeue_member( - "QU...", "CA...", - Url="https://example.com/dequeue" -) -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/queues/get-member.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/queues/get-member.mdx deleted file mode 100644 index 4d1ff3a387..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/queues/get-member.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "get_member" -slug: /reference/python/rest/compat/queues/get-member -description: Retrieve a specific queue member. -max-toc-depth: 3 ---- - - -Retrieve a specific member from a queue by call SID. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -member = client.compat.queues.get_member("QU...", "CA...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/queues/get.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/queues/get.mdx deleted file mode 100644 index 59e11c7e50..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/queues/get.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "get" -slug: /reference/python/rest/compat/queues/get -description: Retrieve a single queue by SID. -max-toc-depth: 3 ---- - - -Retrieve a single queue by SID. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -queue = client.compat.queues.get("QU...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/queues/index.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/queues/index.mdx deleted file mode 100644 index 1435e16f9b..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/queues/index.mdx +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: "Queues" -slug: /reference/python/rest/compat/queues -description: Manage call queues with CRUD operations and member management. -max-toc-depth: 3 ---- - -[restclient]: /docs/server-sdks/reference/python/rest/client -[list]: /docs/server-sdks/reference/python/rest/compat/queues/list -[create]: /docs/server-sdks/reference/python/rest/compat/queues/create -[get]: /docs/server-sdks/reference/python/rest/compat/queues/get -[update]: /docs/server-sdks/reference/python/rest/compat/queues/update -[delete]: /docs/server-sdks/reference/python/rest/compat/queues/delete -[listmembers]: /docs/server-sdks/reference/python/rest/compat/queues/list-members -[getmember]: /docs/server-sdks/reference/python/rest/compat/queues/get-member -[dequeuemember]: /docs/server-sdks/reference/python/rest/compat/queues/dequeue-member - -Manage call queues with CRUD operations and member sub-resources for dequeuing -callers. - -Access via `client.compat.queues` on a [`RestClient`][restclient] instance. - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -queues = client.compat.queues.list() -``` - -## **Methods** - -### Queue CRUD - - - - List queues in the account. - - - Create a new queue. - - - Retrieve a single queue by SID. - - - Update a queue. - - - Delete a queue. - - - -### Members - - - - List members in a queue. - - - Retrieve a specific queue member. - - - Dequeue a member from a queue. - - diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/queues/list-members.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/queues/list-members.mdx deleted file mode 100644 index b95e99ef9f..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/queues/list-members.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "list_members" -slug: /reference/python/rest/compat/queues/list-members -description: List members in a queue. -max-toc-depth: 3 ---- - - -List members currently waiting in a queue. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -members = client.compat.queues.list_members("QU...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/queues/list.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/queues/list.mdx deleted file mode 100644 index c01a703282..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/queues/list.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "list" -slug: /reference/python/rest/compat/queues/list -description: List queues in the account. -max-toc-depth: 3 ---- - - -List queues in the account. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -queues = client.compat.queues.list(PageSize=20) -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/queues/update.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/queues/update.mdx deleted file mode 100644 index 2bdc74b3ab..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/queues/update.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "update" -slug: /reference/python/rest/compat/queues/update -description: Update a queue. -max-toc-depth: 3 ---- - - -Update a queue's configuration. Uses POST (Twilio convention). - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.queues.update("QU...", FriendlyName="Support Queue", MaxSize=200) -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/recordings/delete.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/recordings/delete.mdx deleted file mode 100644 index c8bb4cc76d..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/recordings/delete.mdx +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: "delete" -slug: /reference/python/rest/compat/recordings/delete -description: Delete a recording. -max-toc-depth: 3 ---- - - -Delete a recording. - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.recordings.delete("RE...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/recordings/get.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/recordings/get.mdx deleted file mode 100644 index b2467c9c07..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/recordings/get.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "get" -slug: /reference/python/rest/compat/recordings/get -description: Retrieve a single recording by SID. -max-toc-depth: 3 ---- - - -Retrieve a single recording by SID. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -recording = client.compat.recordings.get("RE...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/recordings/index.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/recordings/index.mdx deleted file mode 100644 index e06e4a785d..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/recordings/index.mdx +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: "Recordings" -slug: /reference/python/rest/compat/recordings -description: Manage call recordings. -max-toc-depth: 3 ---- - -[restclient]: /docs/server-sdks/reference/python/rest/client -[list]: /docs/server-sdks/reference/python/rest/compat/recordings/list -[get]: /docs/server-sdks/reference/python/rest/compat/recordings/get -[delete]: /docs/server-sdks/reference/python/rest/compat/recordings/delete - -Manage call recordings with list, get, and delete operations. - -Access via `client.compat.recordings` on a [`RestClient`][restclient] instance. - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -recordings = client.compat.recordings.list() -``` - -## **Methods** - - - - List recordings in the account. - - - Retrieve a single recording by SID. - - - Delete a recording. - - diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/recordings/list.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/recordings/list.mdx deleted file mode 100644 index 924253fd27..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/recordings/list.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "list" -slug: /reference/python/rest/compat/recordings/list -description: List recordings in the account. -max-toc-depth: 3 ---- - - -List recordings in the account. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -recordings = client.compat.recordings.list(PageSize=20) -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/tokens/create.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/tokens/create.mdx deleted file mode 100644 index 33672f1733..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/tokens/create.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "create" -slug: /reference/python/rest/compat/tokens/create -description: Create a new API token. -max-toc-depth: 3 ---- - - -Create a new API token. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -token = client.compat.tokens.create(name="my-token", permissions=["voice", "messaging"]) -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/tokens/delete.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/tokens/delete.mdx deleted file mode 100644 index e0f06dba35..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/tokens/delete.mdx +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: "delete" -slug: /reference/python/rest/compat/tokens/delete -description: Delete an API token. -max-toc-depth: 3 ---- - - -Delete an API token. - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.tokens.delete("token-id") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/tokens/index.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/tokens/index.mdx deleted file mode 100644 index b2829f871d..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/tokens/index.mdx +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: "Tokens" -slug: /reference/python/rest/compat/tokens -description: Manage API tokens. -max-toc-depth: 3 ---- - -[restclient]: /docs/server-sdks/reference/python/rest/client -[create]: /docs/server-sdks/reference/python/rest/compat/tokens/create -[update]: /docs/server-sdks/reference/python/rest/compat/tokens/update -[delete]: /docs/server-sdks/reference/python/rest/compat/tokens/delete - -Manage API tokens with create, update, and delete operations. - -Access via `client.compat.tokens` on a [`RestClient`][restclient] instance. - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -token = client.compat.tokens.create() -``` - -## **Methods** - - - - Create a new API token. - - - Update an API token. - - - Delete an API token. - - diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/tokens/update.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/tokens/update.mdx deleted file mode 100644 index 0ddc3e6bdf..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/tokens/update.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "update" -slug: /reference/python/rest/compat/tokens/update -description: Update an API token. -max-toc-depth: 3 ---- - - -Update an API token. Uses PATCH. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.tokens.update("token-id", name="updated-token") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/transcriptions/delete.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/transcriptions/delete.mdx deleted file mode 100644 index f990cd12e4..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/transcriptions/delete.mdx +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: "delete" -slug: /reference/python/rest/compat/transcriptions/delete -description: Delete a transcription. -max-toc-depth: 3 ---- - - -Delete a transcription. - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -client.compat.transcriptions.delete("TR...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/transcriptions/get.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/transcriptions/get.mdx deleted file mode 100644 index 0a8df57e43..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/transcriptions/get.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "get" -slug: /reference/python/rest/compat/transcriptions/get -description: Retrieve a single transcription by SID. -max-toc-depth: 3 ---- - - -Retrieve a single transcription by SID. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -transcription = client.compat.transcriptions.get("TR...") -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/transcriptions/index.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/transcriptions/index.mdx deleted file mode 100644 index 9729ad37d0..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/transcriptions/index.mdx +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: "Transcriptions" -slug: /reference/python/rest/compat/transcriptions -description: Manage call transcriptions. -max-toc-depth: 3 ---- - -[restclient]: /docs/server-sdks/reference/python/rest/client -[list]: /docs/server-sdks/reference/python/rest/compat/transcriptions/list -[get]: /docs/server-sdks/reference/python/rest/compat/transcriptions/get -[delete]: /docs/server-sdks/reference/python/rest/compat/transcriptions/delete - -Manage call transcriptions with list, get, and delete operations. - -Access via `client.compat.transcriptions` on a [`RestClient`][restclient] instance. - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -transcriptions = client.compat.transcriptions.list() -``` - -## **Methods** - - - - List transcriptions in the account. - - - Retrieve a single transcription by SID. - - - Delete a transcription. - - diff --git a/fern/products/server-sdks/pages/reference/python/rest/compat/transcriptions/list.mdx b/fern/products/server-sdks/pages/reference/python/rest/compat/transcriptions/list.mdx deleted file mode 100644 index 82b78d8549..0000000000 --- a/fern/products/server-sdks/pages/reference/python/rest/compat/transcriptions/list.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "list" -slug: /reference/python/rest/compat/transcriptions/list -description: List transcriptions in the account. -max-toc-depth: 3 ---- - - -List transcriptions in the account. - - - -## **Response Example** - - - -## **Example** - -```python {9} -from signalwire.rest import RestClient - -client = RestClient( - project="your-project-id", - token="your-api-token", - host="your-space.signalwire.com", -) - -transcriptions = client.compat.transcriptions.list(PageSize=20) -``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/messages/create.mdx b/fern/products/server-sdks/pages/reference/python/rest/messages/create.mdx new file mode 100644 index 0000000000..23e5fe0e41 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/rest/messages/create.mdx @@ -0,0 +1,87 @@ +--- +title: "create" +slug: /reference/python/rest/messages/create +description: Send an SMS or MMS message. +max-toc-depth: 3 +--- + +### messages.create + +Send an outbound SMS or MMS message. The `from_` number determines the channel; +pass `media` or `send_as_mms=True` to send an MMS. + + + +## Parameters + +All parameters are keyword-only. + + + Destination phone number in E.164 format. + + + + Sending phone number in E.164 format. It must belong to your project. The + trailing underscore avoids Python's reserved word; the SDK sends it as `from`. + + + + Text content of the message. + + + + URLs of media attachments. Supplying media sends the message as MMS. + + + + Send as MMS even when no media is attached. + + + + URL that receives delivery status updates for this message. + + + + Your own key/value string pairs, up to 20. When `status_callback` is set, every + status callback includes them as a `custom_variables` object so you can match + it to a record in your own system. + + + + Additional request body fields merged into the payload as sent. + + + + Per-call timeout and retry overrides. See + [`RequestOptions`](/docs/server-sdks/reference/python/rest/request-options). + + +## Returns + +`Message` — the queued message, including its `id`, `status`, `direction`, and +`number_of_segments`. + +## Response Example + + + +## Example + +```python {9} +from signalwire.rest import RestClient + +client = RestClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", +) + +message = client.messages.create( + to="+15551234567", + from_="+15559876543", + body="Your order #4821 has shipped.", + media=["https://example.com/receipts/4821.png"], + status_callback="https://example.com/sms-status", +) +print(message["id"], message["status"]) +``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/messages/index.mdx b/fern/products/server-sdks/pages/reference/python/rest/messages/index.mdx new file mode 100644 index 0000000000..c687c29b02 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/rest/messages/index.mdx @@ -0,0 +1,43 @@ +--- +title: "Messages" +slug: /reference/python/rest/messages +description: "Send SMS and MMS messages and redact the body of a sent message." +max-toc-depth: 3 +--- + +[restclient]: /docs/server-sdks/reference/python/rest/client +[logs-messages]: /docs/server-sdks/reference/python/rest/logs/messages + +Send outbound SMS and MMS messages and redact the body of a message you already +sent. This resource sends and redacts; to query the history of sent and received +messages, use [message logs][logs-messages] at `client.logs.messages`. + +Access via `client.messages` on a [`RestClient`][restclient] instance. + +```python {9} +from signalwire.rest import RestClient + +client = RestClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", +) + +message = client.messages.create( + to="+15551234567", + from_="+15559876543", + body="Your table is ready.", +) +print(message["id"], message["status"]) +``` + +## Methods + + + + Send an SMS or MMS message. + + + Redact the body of a sent message. + + diff --git a/fern/products/server-sdks/pages/reference/python/rest/messages/update.mdx b/fern/products/server-sdks/pages/reference/python/rest/messages/update.mdx new file mode 100644 index 0000000000..d07704c01e --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/rest/messages/update.mdx @@ -0,0 +1,57 @@ +--- +title: "update" +slug: /reference/python/rest/messages/update +description: Redact the body of a previously sent message. +max-toc-depth: 3 +--- + +### messages.update + +Redact the body of a previously sent message. The API accepts only an empty +string for `body`; any other value is rejected. Messages still in progress +(`queued` or `initiated`) can't be redacted, and a redacted body can't be +recovered. + + + +## Parameters + + + ID of the message to redact. + + + + New body. Pass `""` to redact. Keyword-only. + + + + Additional request body fields merged into the payload as sent. + + + + Per-call timeout and retry overrides. See + [`RequestOptions`](/docs/server-sdks/reference/python/rest/request-options). + + +## Returns + +`Message` — the updated message with its body cleared. + +## Response Example + + + +## Example + +```python {9} +from signalwire.rest import RestClient + +client = RestClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", +) + +redacted = client.messages.update("message-id", body="") +print(redacted["body"]) # "" +``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/overview.mdx b/fern/products/server-sdks/pages/reference/python/rest/overview.mdx index 5a58e0fefa..ea5072d58c 100644 --- a/fern/products/server-sdks/pages/reference/python/rest/overview.mdx +++ b/fern/products/server-sdks/pages/reference/python/rest/overview.mdx @@ -16,7 +16,11 @@ position: 0 [datasphere]: /docs/server-sdks/reference/python/rest/datasphere [logs]: /docs/server-sdks/reference/python/rest/logs [registry]: /docs/server-sdks/reference/python/rest/registry -[compat]: /docs/server-sdks/reference/python/rest/compat +[messages]: /docs/server-sdks/reference/python/rest/messages +[projects]: /docs/server-sdks/reference/python/rest/projects +[paginate]: /docs/server-sdks/reference/python/rest/paginate +[request-options]: /docs/server-sdks/reference/python/rest/request-options +[transport-error]: /docs/server-sdks/reference/python/rest/rest-transport-error [mfa]: /docs/server-sdks/reference/python/rest/mfa The REST namespace provides a synchronous HTTP client for the SignalWire platform @@ -39,7 +43,7 @@ client = RestClient( ) # Search for available numbers in area code 512 -available = client.phone_numbers.search(area_code="512", quantity=3) +available = client.phone_numbers.search(areacode="512", max_results=3) for number in available.get("data", []): print(f"{number['number']} - {number.get('region')}") @@ -64,9 +68,31 @@ All three constructor arguments can also be provided via environment variables: When those are set, you can instantiate with `RestClient()` and no arguments. +## Pagination + +`list()` returns one page, the server's first response. To walk every item across +all pages, call [`paginate()`][paginate] on the same resource. It follows the +response's `links.next` until the last page. Most list resources have it; the +few that don't return a single page only. + +```python +for number in client.phone_numbers.paginate(): + print(number["number"]) +``` + +## Timeouts and retries + +Pass a [`RequestOptions`][request-options] to the constructor to set a default +timeout and retry policy for every request, or to any method's `request_options=` +argument to override it for one call. + ## Error Handling -REST errors raise `SignalWireRestError`: +REST errors raise `SignalWireRestError`. A request that never reaches the +server (connection refused, DNS failure, timeout) raises +[`SignalWireRestTransportError`][transport-error], a subclass whose +`status_code` is `None`, so one `except` clause covers both. The error carries the +response headers and the platform `request_id` for support correlation. ```python from signalwire.rest import RestClient, SignalWireRestError @@ -78,6 +104,7 @@ try: except SignalWireRestError as e: print(f"HTTP {e.status_code}: {e.body}") print(f"URL: {e.method} {e.url}") + print(f"Request ID: {e.request_id}") ``` ## Resources @@ -132,10 +159,16 @@ except SignalWireRestError as e: 10DLC brand and campaign registration. + Send SMS and MMS messages and redact sent message bodies. + + - Twilio-compatible LAML API for migration. + Create and manage subprojects and rotate signing keys. PaginatedIterator +``` + +## Parameters + + + Timeout and retry overrides applied to every page fetch. See + [`RequestOptions`][request-options]. + + + + Query parameters forwarded to the list endpoint, the same ones `list()` + accepts. Passed on the first request; later pages follow the server's link. + + +## Returns + +`PaginatedIterator` — a plain Python iterator that yields one item at a time and +fetches the next page on demand. + +## Examples + +### Walk every phone number + +```python {9} +from signalwire.rest import RestClient + +client = RestClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", +) + +for number in client.phone_numbers.paginate(): + print(number["number"]) +``` + +### Nested resources + +```python +for address in client.fabric.addresses.paginate(): + print(address["display_name"]) +``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/phone-numbers/index.mdx b/fern/products/server-sdks/pages/reference/python/rest/phone-numbers/index.mdx index 0e497db908..fa5010a870 100644 --- a/fern/products/server-sdks/pages/reference/python/rest/phone-numbers/index.mdx +++ b/fern/products/server-sdks/pages/reference/python/rest/phone-numbers/index.mdx @@ -37,7 +37,7 @@ client = RestClient( host="your-space.signalwire.com", ) -available = client.phone_numbers.search(area_code="512") +available = client.phone_numbers.search(areacode="512") for number in available.get("data", []): print(number["phone_number"]) ``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/phone-numbers/set-call-flow.mdx b/fern/products/server-sdks/pages/reference/python/rest/phone-numbers/set-call-flow.mdx index 07eee89269..28194daf47 100644 --- a/fern/products/server-sdks/pages/reference/python/rest/phone-numbers/set-call-flow.mdx +++ b/fern/products/server-sdks/pages/reference/python/rest/phone-numbers/set-call-flow.mdx @@ -22,12 +22,17 @@ This is a typed wrapper over [`update`][update] that sets `call_handler` to ID of the Call Flow to route calls to. - + Which Call Flow version to invoke. Accepts `"working_copy"` or `"current_deployed"`. Defaults to the server's current deployed version when omitted. + + Per-call timeout and retry overrides. See + [`RequestOptions`](/docs/server-sdks/reference/python/rest/request-options). + + Additional fields forwarded to `update`. diff --git a/fern/products/server-sdks/pages/reference/python/rest/phone-numbers/set-cxml-webhook.mdx b/fern/products/server-sdks/pages/reference/python/rest/phone-numbers/set-cxml-webhook.mdx index 73b228f05b..3bff8714ef 100644 --- a/fern/products/server-sdks/pages/reference/python/rest/phone-numbers/set-cxml-webhook.mdx +++ b/fern/products/server-sdks/pages/reference/python/rest/phone-numbers/set-cxml-webhook.mdx @@ -30,14 +30,19 @@ instead. Primary cXML webhook URL. - + URL invoked when the primary URL fails. - + URL that receives call-status updates. + + Per-call timeout and retry overrides. See + [`RequestOptions`](/docs/server-sdks/reference/python/rest/request-options). + + Additional fields forwarded to `update`. diff --git a/fern/products/server-sdks/pages/reference/python/rest/phone-numbers/set-relay-topic.mdx b/fern/products/server-sdks/pages/reference/python/rest/phone-numbers/set-relay-topic.mdx index 7b07c8e223..7e039ef137 100644 --- a/fern/products/server-sdks/pages/reference/python/rest/phone-numbers/set-relay-topic.mdx +++ b/fern/products/server-sdks/pages/reference/python/rest/phone-numbers/set-relay-topic.mdx @@ -23,10 +23,15 @@ This is a typed wrapper over [`update`][update] that sets `call_handler` to Relay topic name. - + URL that receives status updates for calls routed via this topic. + + Per-call timeout and retry overrides. See + [`RequestOptions`](/docs/server-sdks/reference/python/rest/request-options). + + Additional fields forwarded to `update`. diff --git a/fern/products/server-sdks/pages/reference/python/rest/projects/create.mdx b/fern/products/server-sdks/pages/reference/python/rest/projects/create.mdx new file mode 100644 index 0000000000..73276ad17f --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/rest/projects/create.mdx @@ -0,0 +1,73 @@ +--- +title: "create" +slug: /reference/python/rest/projects/create +description: Create a subproject under the authenticated root project. +max-toc-depth: 3 +--- + +### projects.create + +Create a subproject under the authenticated root project. + + + +## Parameters + +All parameters are keyword-only. + + + Display name for the subproject. + + + + Require authentication to download call recordings. + + + + Require authentication to download message media. + + + + Require authentication to download fax media. + + + + Reject webhook URLs that aren't HTTPS. + + + + Additional request body fields merged into the payload as sent. + + + + Per-call timeout and retry overrides. See + [`RequestOptions`](/docs/server-sdks/reference/python/rest/request-options). + + +## Returns + +`Project` — the new subproject. The response also carries `signing_key`, which +is returned only on creation and by `rotate_signing_key`, so store it now. + +## Response Example + + + +## Example + +```python {9} +from signalwire.rest import RestClient + +client = RestClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", +) + +sub = client.projects.create( + name="Bayview Taxi - staging", + protect_recordings=True, + force_https_requests=True, +) +print(sub["id"]) +``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/projects/delete.mdx b/fern/products/server-sdks/pages/reference/python/rest/projects/delete.mdx new file mode 100644 index 0000000000..932bfea521 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/rest/projects/delete.mdx @@ -0,0 +1,43 @@ +--- +title: "delete" +slug: /reference/python/rest/projects/delete +description: Delete a subproject. +max-toc-depth: 3 +--- + +### projects.delete + +Delete a subproject. + + + +## Parameters + + + ID of the subproject to delete. + + + + Per-call timeout and retry overrides. See + [`RequestOptions`](/docs/server-sdks/reference/python/rest/request-options). + + +## Returns + +An empty dict. The endpoint responds `204 No Content`; the SDK returns `{}` and +raises [`SignalWireRestError`](/docs/server-sdks/reference/python/rest/rest-error) +on any error status. + +## Example + +```python {9} +from signalwire.rest import RestClient + +client = RestClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", +) + +client.projects.delete("subproject-id") +``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/projects/get.mdx b/fern/products/server-sdks/pages/reference/python/rest/projects/get.mdx new file mode 100644 index 0000000000..6541788fb5 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/rest/projects/get.mdx @@ -0,0 +1,47 @@ +--- +title: "get" +slug: /reference/python/rest/projects/get +description: Retrieve a single project or subproject by ID. +max-toc-depth: 3 +--- + +### projects.get + +Retrieve a single project or subproject. An ID outside the caller's project tree +returns `404`. + + + +## Parameters + + + ID of the project or subproject to retrieve. + + + + Per-call timeout and retry overrides. See + [`RequestOptions`](/docs/server-sdks/reference/python/rest/request-options). + + +## Returns + +`Project` — the project record. + +## Response Example + + + +## Example + +```python {9} +from signalwire.rest import RestClient + +client = RestClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", +) + +project = client.projects.get("project-id") +print(project["name"], project["region_preference"]) +``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/projects/index.mdx b/fern/products/server-sdks/pages/reference/python/rest/projects/index.mdx new file mode 100644 index 0000000000..db97fc1bee --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/rest/projects/index.mdx @@ -0,0 +1,56 @@ +--- +title: "Projects" +slug: /reference/python/rest/projects +description: "Create and manage subprojects and rotate a project's signing key." +max-toc-depth: 3 +--- + +[restclient]: /docs/server-sdks/reference/python/rest/client +[project-tokens]: /docs/server-sdks/reference/python/rest/project +[paginate]: /docs/server-sdks/reference/python/rest/paginate + +List the authenticated root project and its subprojects, create and update +subprojects, and rotate a project's signing key. Every call operates only within +the caller's project tree. For API tokens on the current project, use +[`client.project.tokens`][project-tokens]. + +Access via `client.projects` on a [`RestClient`][restclient] instance. + +```python {9} +from signalwire.rest import RestClient + +client = RestClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", +) + +sub = client.projects.create(name="Bayview Taxi - staging") +print(sub["id"], sub["subproject"]) +``` + +## Methods + + + + List the root project and its subprojects. + + + Retrieve one project by ID. + + + Create a subproject. + + + Update a project's name or media protection settings. + + + Delete a subproject. + + + Issue a new signing key for a project. + + + +`client.projects` also exposes [`paginate()`][paginate] to iterate across all +pages. diff --git a/fern/products/server-sdks/pages/reference/python/rest/projects/list.mdx b/fern/products/server-sdks/pages/reference/python/rest/projects/list.mdx new file mode 100644 index 0000000000..13ccfb9122 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/rest/projects/list.mdx @@ -0,0 +1,34 @@ +--- +title: "list" +slug: /reference/python/rest/projects/list +description: List the authenticated root project and its subprojects. +max-toc-depth: 3 +--- + +### projects.list + +List the authenticated root project and its subprojects. Returns one page; use +`client.projects.paginate()` to iterate every project across pages. + + + +## Response Example + + + +## Example + +```python {9} +from signalwire.rest import RestClient + +client = RestClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", +) + +result = client.projects.list() +for project in result.get("data", []): + kind = "subproject" if project["subproject"] else "root" + print(project["name"], project["id"], kind) +``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/projects/rotate-signing-key.mdx b/fern/products/server-sdks/pages/reference/python/rest/projects/rotate-signing-key.mdx new file mode 100644 index 0000000000..a91ccb5433 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/rest/projects/rotate-signing-key.mdx @@ -0,0 +1,47 @@ +--- +title: "rotate_signing_key" +slug: /reference/python/rest/projects/rotate-signing-key +description: Issue a new signing key for a project, invalidating the old one. +max-toc-depth: 3 +--- + +### projects.rotate_signing_key + +Issue a new signing key for a project. The response is the only place the new +key is returned. + + + +## Parameters + + + ID of the project whose key to rotate. + + + + Per-call timeout and retry overrides. See + [`RequestOptions`](/docs/server-sdks/reference/python/rest/request-options). + + +## Returns + +`ProjectWithSigningKey` — the project with its new signing key. + +## Response Example + + + +## Example + +```python {9} +from signalwire.rest import RestClient + +client = RestClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", +) + +project = client.projects.rotate_signing_key("project-id") +print(project["id"]) +``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/projects/update.mdx b/fern/products/server-sdks/pages/reference/python/rest/projects/update.mdx new file mode 100644 index 0000000000..5399e731f6 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/rest/projects/update.mdx @@ -0,0 +1,71 @@ +--- +title: "update" +slug: /reference/python/rest/projects/update +description: Update a project's name or media protection settings. +max-toc-depth: 3 +--- + +### projects.update + +Update a project's name or protection settings. Only the fields you pass are +sent. + + + +## Parameters + + + ID of the project to update. Positional-only. + + + + New display name. + + + + Require authentication to download call recordings. + + + + Require authentication to download message media. + + + + Require authentication to download fax media. + + + + Reject webhook URLs that aren't HTTPS. + + + + Additional request body fields merged into the payload as sent. + + + + Per-call timeout and retry overrides. See + [`RequestOptions`](/docs/server-sdks/reference/python/rest/request-options). + + +## Returns + +`Project` — the updated project. + +## Response Example + + + +## Example + +```python {9} +from signalwire.rest import RestClient + +client = RestClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", +) + +project = client.projects.update("project-id", name="Bayview Taxi - production") +print(project["name"]) +``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/request-options.mdx b/fern/products/server-sdks/pages/reference/python/rest/request-options.mdx new file mode 100644 index 0000000000..a9caaf5963 --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/rest/request-options.mdx @@ -0,0 +1,116 @@ +--- +title: "RequestOptions" +slug: /reference/python/rest/request-options +description: Timeout, retry, and cancellation settings for REST requests. +max-toc-depth: 3 +--- + +[restclient]: /docs/server-sdks/reference/python/rest/client +[transport-error]: /docs/server-sdks/reference/python/rest/rest-transport-error + +Per-request transport settings: a timeout, an opt-in retry policy with +exponential backoff, and cooperative cancellation. `RequestOptions` is a frozen +dataclass; every field is optional and `None` means "inherit". + +```python {1} +from signalwire.rest import RequestOptions +``` + +Supply it at two levels: + +- **Client default.** Pass `request_options=` to the [`RestClient`][restclient] + constructor and it applies to every request. +- **Per-call override.** Every resource method accepts `request_options=`. Set + fields override the client default for that one call; unset fields fall back + to the client default, then to the built-in default. + +Retries are idempotency-aware. `GET`, `PUT`, and `DELETE` retry on any status in +`retry_on_status`. `POST` and `PATCH` retry only on `429` and `503`, never on +`500`, `502`, or `504`, so a request that may have partially applied is never +replayed. A transport failure retries for every method. When retries are +exhausted the request raises [`SignalWireRestTransportError`][transport-error] +or `SignalWireRestError`, whichever matches the last attempt. + +## Properties + + + Maximum wall-clock seconds per attempt. Exceeding it raises + `SignalWireRestTransportError`. Built-in default is `30.0`. + + + + Number of retry attempts after the first failure, so total attempts equal + `retries + 1`. Built-in default is `0`. + + + + HTTP statuses that trigger a retry for an idempotent method. Built-in default + is `{429, 500, 502, 503, 504}`. + + + + Base seconds for exponential backoff between retries, computed as + `retry_backoff * 2 ** (attempt - 1)`. A `Retry-After` header on the response + takes precedence. Built-in default is `0.5`. + + + + Any object with an `is_set() -> bool` method, such as a `threading.Event`. + Checked before each attempt; if set, the request raises instead of proceeding. + The check is cooperative and doesn't interrupt an attempt already in flight. + + +## Methods + +### merge + +`merge(override: RequestOptions | None) -> RequestOptions` + +Return a copy of this instance with every non-`None` field of `override` applied. +This is the shallow merge the client performs when a per-call override meets the +client default. + +## Examples + +### Client-wide retry policy + +```python {1,3-7} +from signalwire.rest import RestClient, RequestOptions + +defaults = RequestOptions( + timeout=10.0, + retries=3, + retry_backoff=1.0, +) + +client = RestClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", + request_options=defaults, +) +``` + +### Per-call override + +```python +# Inherit the client's retry policy but allow a longer timeout for this call. +result = client.phone_numbers.search( + areacode="512", + request_options=RequestOptions(timeout=60.0), +) +``` + +### Cancellation + +```python +import threading + +cancel = threading.Event() + +# Another thread can call cancel.set() to stop between retry attempts. +for project in client.projects.paginate( + request_options=RequestOptions(retries=5, abort_signal=cancel) +): + print(project["name"]) +``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/rest-error.mdx b/fern/products/server-sdks/pages/reference/python/rest/rest-error.mdx index d6cbd893ab..7d85190e4e 100644 --- a/fern/products/server-sdks/pages/reference/python/rest/rest-error.mdx +++ b/fern/products/server-sdks/pages/reference/python/rest/rest-error.mdx @@ -5,6 +5,8 @@ description: Error raised when the REST API returns a non-success response. max-toc-depth: 3 --- +[transport-error]: /docs/server-sdks/reference/python/rest/rest-transport-error + Custom exception class for REST API errors. Extends Python's built-in `Exception` class. Raised when an HTTP request to the SignalWire REST API returns a non-success status code. @@ -13,10 +15,17 @@ status code. from signalwire.rest import SignalWireRestError ``` + +A request that never produces a response raises +[`SignalWireRestTransportError`][transport-error], a subclass of this class. +Catching `SignalWireRestError` handles both. + + ## **Properties** - - HTTP status code returned by the API (e.g., `404`, `422`, `500`). + + HTTP status code returned by the API (e.g., `404`, `422`, `500`). `None` for a + transport failure that produced no response. @@ -24,13 +33,23 @@ from signalwire.rest import SignalWireRestError - The URL path that was requested. + The full URL that was requested, including the query string. The HTTP method used (`"GET"`, `"POST"`, `"PUT"`, `"PATCH"`, `"DELETE"`). + + Response headers from the API. `None` for a transport failure. + + + + The platform request ID, read from the `x-request-id`, + `x-signalwire-request-id`, `request-id`, or `x-amzn-requestid` response header. + Also appended to the exception message. Quote it when contacting support. + + ## **Example** ```python {9} @@ -47,4 +66,5 @@ try: except SignalWireRestError as e: print(f"HTTP {e.status_code}: {e.body}") print(f"Request: {e.method} {e.url}") + print(f"Request ID: {e.request_id}") ``` diff --git a/fern/products/server-sdks/pages/reference/python/rest/rest-transport-error.mdx b/fern/products/server-sdks/pages/reference/python/rest/rest-transport-error.mdx new file mode 100644 index 0000000000..01c270525f --- /dev/null +++ b/fern/products/server-sdks/pages/reference/python/rest/rest-transport-error.mdx @@ -0,0 +1,66 @@ +--- +title: "SignalWireRestTransportError" +slug: /reference/python/rest/rest-transport-error +description: Error raised when a REST request never reaches a response. +max-toc-depth: 3 +--- + +[rest-error]: /docs/server-sdks/reference/python/rest/rest-error +[request-options]: /docs/server-sdks/reference/python/rest/request-options + +Raised when a REST request fails before the server responds: connection +refused, DNS failure, connection reset, TLS error, or a +[`RequestOptions`][request-options] timeout. Subclass of +[`SignalWireRestError`][rest-error], so one `except SignalWireRestError` clause +handles both HTTP errors and transport failures. + +```python {1} +from signalwire.rest import SignalWireRestTransportError +``` + +## Properties + +Inherits every property of `SignalWireRestError` with these values: + + + Always `None`; no response was produced. + + + + The underlying transport error message. + + + + The full URL that was requested, including the query string. + + + + The HTTP method used. + + + + Always `None`. + + + + Always `None`. + + +## Example + +```python {9-14} +from signalwire.rest import RestClient, SignalWireRestError, SignalWireRestTransportError + +client = RestClient( + project="your-project-id", + token="your-api-token", + host="your-space.signalwire.com", +) + +try: + client.phone_numbers.list() +except SignalWireRestTransportError as e: + print(f"Could not reach SignalWire: {e.body}") +except SignalWireRestError as e: + print(f"HTTP {e.status_code}: {e.body}") +``` diff --git a/fern/products/server-sdks/pages/reference/typescript/agents/skills/datasphere.mdx b/fern/products/server-sdks/pages/reference/typescript/agents/skills/datasphere.mdx index ecfd898540..998aa9ee3e 100644 --- a/fern/products/server-sdks/pages/reference/typescript/agents/skills/datasphere.mdx +++ b/fern/products/server-sdks/pages/reference/typescript/agents/skills/datasphere.mdx @@ -16,7 +16,7 @@ required — `setup()` fails closed if any are missing. **Tools:** Custom per instance via `tool_name` (default `search_knowledge`) -**Env vars:** `SIGNALWIRE_PROJECT_ID`, `SIGNALWIRE_TOKEN`, `SIGNALWIRE_SPACE` +**Env vars:** `SIGNALWIRE_PROJECT_ID`, `SIGNALWIRE_API_TOKEN`, `SIGNALWIRE_SPACE` **Multi-instance:** yes @@ -35,7 +35,7 @@ required — `setup()` fails closed if any are missing. - SignalWire API token. Falls back to `SIGNALWIRE_TOKEN`. + SignalWire API token. Falls back to `SIGNALWIRE_API_TOKEN`. diff --git a/fern/products/server-sdks/sdk-source-sync.json b/fern/products/server-sdks/sdk-source-sync.json index bb3d0e55ab..61debc1672 100644 --- a/fern/products/server-sdks/sdk-source-sync.json +++ b/fern/products/server-sdks/sdk-source-sync.json @@ -5,8 +5,8 @@ "repository": "https://github.com/signalwire/signalwire-python.git", "local_path": "temp/signalwire-python", "status": "active", - "synced_commit": "295745b24a4b69b92a4b536a7e7052d5128e71c8", - "synced_at": "2026-06-03" + "synced_commit": "f7fec89e31261fd593edc116e3e5694d338e4ae6", + "synced_at": "2026-09-09" }, "typescript": { "repository": "https://github.com/signalwire/signalwire-typescript.git",