> Fetch clean Markdown by appending `.md` to any page URL under https://signalwire.com/docs or requesting it with the HTTP header `Accept: text/markdown`. The root index at https://signalwire.com/docs/llms.txt lists the available documentation indexes. # registerRoutingCallback > Register routing callbacks for dynamic request handling and SIP routing. [ref-serve]: /docs/server-sdks/reference/typescript/agents/swml-service/serve [ref-asrouter]: /docs/server-sdks/reference/typescript/agents/swml-service/as-router [ref-extractsipusername]: /docs/server-sdks/reference/typescript/agents/swml-service/extract-sip-username [ai-sidecar-callbacks]: /docs/swml/reference/calling/ai-sidecar#webhook-callbacks Register a callback for dynamic request routing. When a request arrives at the specified path, the callback inspects the POST body and decides whether to route the request to a different endpoint (via HTTP 307 redirect) or let normal SWML serving continue. Commonly used for SIP-based routing where the destination depends on the incoming SIP URI. A Hono endpoint is registered immediately for the specified path, serving both GET and POST. > **Tip** > > This is also how you receive an [`ai_sidecar`](/docs/swml/reference/calling/ai-sidecar) verb's webhook > callbacks. Register a callback at the path your `ai_sidecar.url` points to (for example, `/events`) and > return `null` to acknowledge each one. The callback's body wraps the event under `sidecar_event` — see the > [callback catalog][ai-sidecar-callbacks] for the payload shapes. > **Note** > > Unlike the Python SDK, the TypeScript `RoutingCallback` receives only the > parsed request body -- not the underlying `Request` object. If you need access > to headers or URL, use `asRouter()` and install custom middleware on the Hono > app directly. ## **Parameters** **`callbackFn`** `RoutingCallback` — required A function that receives the parsed JSON request body. Return a route string to redirect the request (HTTP 307 preserves the POST method and body), or `null` / `undefined` to continue with normal SWML document serving. May be async. Type: `(body: Record) => string | null | undefined | Promise` --- **`path`** `string` — default: /sip The URL path where this routing endpoint is created. The path is normalized: a leading `/` is added if missing, trailing slashes are stripped. --- ## **Returns** `void` ## **Example** ### Routing callback with SIP username ```typescript {15} import { SWMLService } from '@signalwire/sdk'; const service = new SWMLService({ name: 'sip-router', route: '/' }); function routeSipCall(body: Record): string | null { const username = SWMLService.extractSipUsername(body); if (username === 'sales') return '/agents/sales'; if (username === 'support') return '/agents/support'; return null; // Default handling } service.addVerb('answer', {}); service.registerRoutingCallback(routeSipCall, '/sip'); await service.serve(); ``` See also [`extractSipUsername()`][ref-extractsipusername] and [`serve()`][ref-serve] / [`asRouter()`][ref-asrouter]. > Register routing callbacks for dynamic request handling and SIP routing.