***

title: on_swml_request
slug: /reference/python/agents/agent-base/on-swml-request
description: Override hook for customizing the SWML document on a per-request basis.
max-toc-depth: 3
---------------------

For a complete index of all SignalWire documentation pages, fetch https://signalwire.com/docs/llms.txt

[set-dynamic-config-callback]: /docs/server-sdks/reference/python/agents/agent-base/set-dynamic-config-callback

[on-request-swml]: /docs/server-sdks/reference/python/agents/swml-service/on-request

Customization point called during SWML rendering, before the document is
returned to the caller. Override this method in a subclass to inspect request
data and return modifications to apply to the SWML document.

The default implementation checks for a
[`set_dynamic_config_callback()`][set-dynamic-config-callback]
and, if one is registered, returns an internal marker that triggers ephemeral
agent cloning. For most per-request customization,
[`set_dynamic_config_callback()`][set-dynamic-config-callback]
is the simpler approach.

<Info>
  This method is called during SWML rendering by the internal request handler. It
  is not an override of `SWMLService.on_request()` -- it is a separate hook that
  adds support for dynamic configuration and ephemeral agent copies.
</Info>

## **Parameters**

<ParamField path="request_data" type="Optional[dict[str, Any]]" default="None" toc={true}>
  Parsed POST body from the incoming request, if available.
</ParamField>

<ParamField path="callback_path" type="Optional[str]" default="None" toc={true}>
  The path segment that triggered this request.
</ParamField>

<ParamField path="request" type="Optional[Request]" default="None" toc={true}>
  The FastAPI `Request` object, providing access to query parameters, headers,
  and other HTTP metadata.
</ParamField>

## **Returns**

`Optional[dict]` -- A dictionary of modifications to apply to the SWML document,
or `None` for no modifications. The keys and structure depend on the rendering
pipeline.

## **Example**

```python {10-16}
from signalwire import AgentBase

class MultiTenantAgent(AgentBase):
    def __init__(self):
        super().__init__(name="multi-tenant", route="/agent")
        self.set_prompt_text("You are a helpful assistant.")

    def on_swml_request(self, request_data=None, callback_path=None, request=None):
        """Inject tenant context into global_data based on a request header."""
        tenant = None
        if request:
            tenant = request.headers.get("X-Tenant-ID")
        if tenant:
            # Return modifications — "global_data" keys are merged into ai.params.global_data
            return {"global_data": {"tenant_id": tenant, "tier": "premium" if tenant == "acme" else "standard"}}
        return super().on_swml_request(request_data, callback_path, request)

agent = MultiTenantAgent()
agent.run()
```

<Tip>
  For most per-request customization scenarios, prefer
  [`set_dynamic_config_callback()`][set-dynamic-config-callback]
  which provides a higher-level interface with access to query params, body, headers,
  and the agent instance.
</Tip>