> 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. # RequestOptions > Timeout, retry, and cancellation settings for REST requests. [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 **`timeout`** `float | None` — default: None Maximum wall-clock seconds per attempt. Exceeding it raises `SignalWireRestTransportError`. Built-in default is `30.0`. --- **`retries`** `int | None` — default: None Number of retry attempts after the first failure, so total attempts equal `retries + 1`. Built-in default is `0`. --- **`retry_on_status`** `frozenset[int] | None` — default: None HTTP statuses that trigger a retry for an idempotent method. Built-in default is `{429, 500, 502, 503, 504}`. --- **`retry_backoff`** `float | None` — default: None 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`. --- **`abort_signal`** `object | None` — default: None 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"]) ``` > Timeout, retry, and cancellation settings for REST requests.