API reference
relay_link
relay-link-py: a Python client for the Relay Protocol API (relay.link).
Quickstart
from relay_link import RelayClient, TradeType client = RelayClient() chains = client.get_chains()
AsyncRelayClient
Bases: _BaseRelayClient
Asynchronous client for the Relay Protocol API.
Use it as an async context manager so the underlying HTTP connection is closed automatically:
async with AsyncRelayClient() as client: ... chains = await client.get_chains()
It mirrors :class:RelayClient exactly, with every method returning an
awaitable. The same retry and error-handling behavior applies.
__init__(base_url=DEFAULT_BASE_URL, api_key=None, api_key_header='x-api-key', timeout=30.0, max_retries=DEFAULT_MAX_RETRIES, backoff_base=DEFAULT_BACKOFF_BASE, http_client=None)
Create an asynchronous client.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base_url
|
str
|
Base URL of the Relay API. A trailing slash is stripped. |
DEFAULT_BASE_URL
|
api_key
|
Optional[str]
|
Optional API key sent on every request. |
None
|
api_key_header
|
str
|
Header name to send |
'x-api-key'
|
timeout
|
float
|
Per-request timeout in seconds (used only when this client creates its own HTTP client). |
30.0
|
max_retries
|
int
|
Maximum retries for 429 and transient 5xx responses. |
DEFAULT_MAX_RETRIES
|
backoff_base
|
float
|
Base delay in seconds for exponential backoff. |
DEFAULT_BACKOFF_BASE
|
http_client
|
Optional[AsyncClient]
|
An existing :class: |
None
|
__aenter__()
async
Enter the async context manager, returning this client.
__aexit__(exc_type, exc, tb)
async
Exit the async context manager, closing the client.
aclose()
async
Close the underlying async HTTP client if this instance created it.
A no-op when an http_client was supplied to the constructor.
get_chains(include_chains=None)
async
List the chains supported by Relay (GET /chains).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
include_chains
|
Optional[str]
|
Optional comma-separated chain IDs to restrict the
response to (e.g. |
None
|
Returns:
| Type | Description |
|---|---|
list[Chain]
|
The list of supported :class: |
Raises:
| Type | Description |
|---|---|
RelayAPIError
|
The API returned a non-2xx response. |
RelayConnectionError
|
The API could not be reached. |
RelayTimeoutError
|
The request timed out. |
get_quote(*, user, origin_chain_id, destination_chain_id, origin_currency, destination_currency, amount, trade_type, **extra)
async
Get an executable quote for a bridge/swap/call (POST /quote/v2).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user
|
str
|
Address depositing funds and submitting transactions. |
required |
origin_chain_id
|
int
|
Chain ID to bridge/swap from. |
required |
destination_chain_id
|
int
|
Chain ID to bridge/swap to. |
required |
origin_currency
|
str
|
Origin token address (zero = native). |
required |
destination_currency
|
str
|
Destination token address (zero = native). |
required |
amount
|
str
|
Amount in the currency's smallest unit (e.g. wei), as a string. |
required |
trade_type
|
Union[str, Any]
|
A :class: |
required |
**extra
|
Any
|
Any additional :class: |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
Quote
|
class: |
Quote
|
breakdown. |
Raises:
| Type | Description |
|---|---|
RelayAPIError
|
The API rejected the request (e.g. an invalid route). |
RelayRateLimitError
|
Rate limited after retries were exhausted. |
RelayConnectionError
|
The API could not be reached. |
RelayTimeoutError
|
The request timed out. |
Example
async with AsyncRelayClient() as client: ... quote = await client.get_quote( ... user="0x03508bb71268bba25ecacc8f620e01866650532c", ... origin_chain_id=8453, ... destination_chain_id=10, ... origin_currency="0x0000000000000000000000000000000000000000", ... destination_currency="0x0000000000000000000000000000000000000000", ... amount="1000000000000000000", ... trade_type=TradeType.EXACT_INPUT, ... )
get_price(*, origin_chain_id, destination_chain_id, origin_currency, destination_currency, amount, trade_type, user=None, **extra)
async
Get a non-executable price estimate (POST /price).
Like :meth:get_quote but returns only fees and swap details, with no
executable steps.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
origin_chain_id
|
int
|
Chain ID to bridge/swap from. |
required |
destination_chain_id
|
int
|
Chain ID to bridge/swap to. |
required |
origin_currency
|
str
|
Origin token address (zero = native). |
required |
destination_currency
|
str
|
Destination token address (zero = native). |
required |
amount
|
str
|
Amount in the currency's smallest unit, as a string. |
required |
trade_type
|
Union[str, Any]
|
A :class: |
required |
user
|
Optional[str]
|
Optional depositing address; not required for a price-only call. |
None
|
**extra
|
Any
|
Any additional :class: |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
Price
|
class: |
Price
|
swap details. |
Raises:
| Type | Description |
|---|---|
RelayAPIError
|
The API rejected the request. |
RelayRateLimitError
|
Rate limited after retries were exhausted. |
RelayConnectionError
|
The API could not be reached. |
RelayTimeoutError
|
The request timed out. |
get_status(*, request_id)
async
Get the execution status of a request (GET /intents/status/v3).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request_id
|
str
|
The request identifier from a quote step's
|
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
TransactionStatus
|
class: |
Raises:
| Type | Description |
|---|---|
RelayAPIError
|
The API returned a non-2xx response. |
RelayConnectionError
|
The API could not be reached. |
RelayTimeoutError
|
The request timed out. |
get_requests(*, user=None, hash=None, origin_chain_id=None, destination_chain_id=None, limit=None, continuation=None)
async
List relay requests (GET /requests).
All filters are optional; omitted ones are not sent. Page through
results by passing the previous response's continuation back in.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user
|
Optional[str]
|
Filter to requests initiated by this address. |
None
|
hash
|
Optional[str]
|
Filter to a specific transaction hash. |
None
|
origin_chain_id
|
Optional[int]
|
Filter by origin chain ID. |
None
|
destination_chain_id
|
Optional[int]
|
Filter by destination chain ID. |
None
|
limit
|
Optional[int]
|
Maximum number of records to return. |
None
|
continuation
|
Optional[str]
|
Pagination cursor from a previous response. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
RequestsResponse
|
class: |
RequestsResponse
|
next |
Raises:
| Type | Description |
|---|---|
RelayAPIError
|
The API returned a non-2xx response. |
RelayConnectionError
|
The API could not be reached. |
RelayTimeoutError
|
The request timed out. |
get_token_price(*, address, chain_id)
async
Get a token's USD price (GET /currencies/token/price).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
address
|
str
|
Token contract address. |
required |
chain_id
|
int
|
Chain ID the token lives on. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
TokenPrice
|
class: |
Raises:
| Type | Description |
|---|---|
RelayAPIError
|
The API returned a non-2xx response. |
RelayConnectionError
|
The API could not be reached. |
RelayTimeoutError
|
The request timed out. |
poll_status(*, request_id, interval=2.0, timeout=120.0)
async
Poll :meth:get_status until the request reaches a terminal state.
Repeatedly calls :meth:get_status, awaiting interval seconds
between polls, until status is one of
:data:~relay_link.TERMINAL_STATUSES (success, failure or
refund).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request_id
|
str
|
The request identifier to poll. |
required |
interval
|
float
|
Seconds to wait between polls. |
2.0
|
timeout
|
float
|
Maximum total seconds to poll before giving up. |
120.0
|
Returns:
| Type | Description |
|---|---|
TransactionStatus
|
The terminal :class: |
Raises:
| Type | Description |
|---|---|
RelayError
|
The timeout elapsed before reaching a terminal state. |
RelayAPIError
|
A status request returned a non-2xx response. |
RelayConnectionError
|
The API could not be reached. |
RelayTimeoutError
|
A status request timed out. |
RelayClient
Bases: _BaseRelayClient
Synchronous client for the Relay Protocol API.
Use it as a context manager so the underlying HTTP connection is closed automatically:
with RelayClient() as client: ... chains = client.get_chains()
All methods raise a :class:RelayError subclass on failure (see the
module's exception hierarchy). 429 and transient 5xx responses are retried
transparently with exponential backoff.
__init__(base_url=DEFAULT_BASE_URL, api_key=None, api_key_header='x-api-key', timeout=30.0, max_retries=DEFAULT_MAX_RETRIES, backoff_base=DEFAULT_BACKOFF_BASE, http_client=None)
Create a synchronous client.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base_url
|
str
|
Base URL of the Relay API. A trailing slash is stripped. |
DEFAULT_BASE_URL
|
api_key
|
Optional[str]
|
Optional API key sent on every request. Quotes are public and need no key. |
None
|
api_key_header
|
str
|
Header name to send |
'x-api-key'
|
timeout
|
float
|
Per-request timeout in seconds (used only when this client creates its own HTTP client). |
30.0
|
max_retries
|
int
|
Maximum retries for 429 and transient 5xx responses. |
DEFAULT_MAX_RETRIES
|
backoff_base
|
float
|
Base delay in seconds for exponential backoff between retries. |
DEFAULT_BACKOFF_BASE
|
http_client
|
Optional[Client]
|
An existing :class: |
None
|
__enter__()
Enter the context manager, returning this client.
__exit__(exc_type, exc, tb)
Exit the context manager, closing the client.
close()
Close the underlying HTTP client if this instance created it.
A no-op when an http_client was supplied to the constructor, since
the caller owns that client's lifecycle.
get_chains(include_chains=None)
List the chains supported by Relay (GET /chains).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
include_chains
|
Optional[str]
|
Optional comma-separated chain IDs to restrict the
response to (e.g. |
None
|
Returns:
| Type | Description |
|---|---|
list[Chain]
|
The list of supported :class: |
Raises:
| Type | Description |
|---|---|
RelayAPIError
|
The API returned a non-2xx response. |
RelayConnectionError
|
The API could not be reached. |
RelayTimeoutError
|
The request timed out. |
get_quote(*, user, origin_chain_id, destination_chain_id, origin_currency, destination_currency, amount, trade_type, **extra)
Get an executable quote for a bridge/swap/call (POST /quote/v2).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user
|
str
|
Address depositing funds and submitting transactions. |
required |
origin_chain_id
|
int
|
Chain ID to bridge/swap from. |
required |
destination_chain_id
|
int
|
Chain ID to bridge/swap to. |
required |
origin_currency
|
str
|
Origin token address (the zero address for the native gas currency). |
required |
destination_currency
|
str
|
Destination token address (zero = native). |
required |
amount
|
str
|
Amount in the currency's smallest unit (e.g. wei), as a string. |
required |
trade_type
|
Union[str, Any]
|
A :class: |
required |
**extra
|
Any
|
Any additional :class: |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
Quote
|
class: |
Quote
|
breakdown. |
Raises:
| Type | Description |
|---|---|
RelayAPIError
|
The API rejected the request (e.g. an invalid route). |
RelayRateLimitError
|
Rate limited after retries were exhausted. |
RelayConnectionError
|
The API could not be reached. |
RelayTimeoutError
|
The request timed out. |
Example
with RelayClient() as client: ... quote = client.get_quote( ... user="0x03508bb71268bba25ecacc8f620e01866650532c", ... origin_chain_id=8453, ... destination_chain_id=10, ... origin_currency="0x0000000000000000000000000000000000000000", ... destination_currency="0x0000000000000000000000000000000000000000", ... amount="1000000000000000000", # 1 ETH in wei ... trade_type=TradeType.EXACT_INPUT, ... ) for step in quote.steps: ... print(step.kind, step.id)
get_price(*, origin_chain_id, destination_chain_id, origin_currency, destination_currency, amount, trade_type, user=None, **extra)
Get a non-executable price estimate (POST /price).
Like :meth:get_quote but returns only fees and swap details, with no
executable steps — useful for display and comparison.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
origin_chain_id
|
int
|
Chain ID to bridge/swap from. |
required |
destination_chain_id
|
int
|
Chain ID to bridge/swap to. |
required |
origin_currency
|
str
|
Origin token address (zero = native). |
required |
destination_currency
|
str
|
Destination token address (zero = native). |
required |
amount
|
str
|
Amount in the currency's smallest unit, as a string. |
required |
trade_type
|
Union[str, Any]
|
A :class: |
required |
user
|
Optional[str]
|
Optional depositing address; not required for a price-only call. |
None
|
**extra
|
Any
|
Any additional :class: |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
Price
|
class: |
Price
|
swap details. |
Raises:
| Type | Description |
|---|---|
RelayAPIError
|
The API rejected the request. |
RelayRateLimitError
|
Rate limited after retries were exhausted. |
RelayConnectionError
|
The API could not be reached. |
RelayTimeoutError
|
The request timed out. |
get_status(*, request_id)
Get the execution status of a request (GET /intents/status/v3).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request_id
|
str
|
The request identifier from a quote step's
|
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
TransactionStatus
|
class: |
Raises:
| Type | Description |
|---|---|
RelayAPIError
|
The API returned a non-2xx response. |
RelayConnectionError
|
The API could not be reached. |
RelayTimeoutError
|
The request timed out. |
get_requests(*, user=None, hash=None, origin_chain_id=None, destination_chain_id=None, limit=None, continuation=None)
List relay requests (GET /requests).
All filters are optional; omitted ones are not sent. Page through
results by passing the previous response's continuation back in.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user
|
Optional[str]
|
Filter to requests initiated by this address. |
None
|
hash
|
Optional[str]
|
Filter to a specific transaction hash. |
None
|
origin_chain_id
|
Optional[int]
|
Filter by origin chain ID. |
None
|
destination_chain_id
|
Optional[int]
|
Filter by destination chain ID. |
None
|
limit
|
Optional[int]
|
Maximum number of records to return. |
None
|
continuation
|
Optional[str]
|
Pagination cursor from a previous response. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
RequestsResponse
|
class: |
RequestsResponse
|
next |
Raises:
| Type | Description |
|---|---|
RelayAPIError
|
The API returned a non-2xx response. |
RelayConnectionError
|
The API could not be reached. |
RelayTimeoutError
|
The request timed out. |
get_token_price(*, address, chain_id)
Get a token's USD price (GET /currencies/token/price).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
address
|
str
|
Token contract address. |
required |
chain_id
|
int
|
Chain ID the token lives on. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
TokenPrice
|
class: |
Raises:
| Type | Description |
|---|---|
RelayAPIError
|
The API returned a non-2xx response. |
RelayConnectionError
|
The API could not be reached. |
RelayTimeoutError
|
The request timed out. |
poll_status(*, request_id, interval=2.0, timeout=120.0)
Poll :meth:get_status until the request reaches a terminal state.
Repeatedly calls :meth:get_status, sleeping interval seconds
between polls, until status is one of
:data:~relay_link.TERMINAL_STATUSES (success, failure or
refund).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request_id
|
str
|
The request identifier to poll. |
required |
interval
|
float
|
Seconds to wait between polls. |
2.0
|
timeout
|
float
|
Maximum total seconds to poll before giving up. |
120.0
|
Returns:
| Type | Description |
|---|---|
TransactionStatus
|
The terminal :class: |
Raises:
| Type | Description |
|---|---|
RelayError
|
The timeout elapsed before reaching a terminal state. |
RelayAPIError
|
A status request returned a non-2xx response. |
RelayConnectionError
|
The API could not be reached. |
RelayTimeoutError
|
A status request timed out. |
RelayAPIError
Bases: RelayError
Raised when the Relay API returns a non-2xx response.
Attributes:
| Name | Type | Description |
|---|---|---|
status_code |
The HTTP status code of the response. |
|
message |
A human-readable message, extracted from the response body
when possible (the |
|
body |
The parsed JSON body, or |
__init__(status_code, message, body=None)
Build an API error.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
status_code
|
int
|
HTTP status code of the failing response. |
required |
message
|
str
|
Human-readable error message. |
required |
body
|
Optional[Any]
|
Parsed response body, if any. |
None
|
from_response(response)
classmethod
Construct an error from an httpx response.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
response
|
Response
|
The non-2xx response to wrap. |
required |
Returns:
| Type | Description |
|---|---|
RelayAPIError
|
An instance of |
RelayAPIError
|
|
RelayAPIError
|
phrase. |
RelayAPIError
|
not valid JSON. |
RelayConnectionError
Bases: RelayError
Raised when the request fails to reach the API.
Wraps a non-timeout :class:httpx.TransportError (e.g. a refused or reset
connection, or DNS failure). The original exception is available via
__cause__.
RelayError
Bases: Exception
Base class for every error raised by this library.
Catch this to handle any failure — API errors, rate limiting, connection failures and timeouts all subclass it.
RelayRateLimitError
Bases: RelayAPIError
Raised on HTTP 429 once retries are exhausted.
A subclass of :class:RelayAPIError, so status_code (always 429),
message and body are available too.
Attributes:
| Name | Type | Description |
|---|---|---|
retry_after |
The server-advised wait in seconds parsed from the
|
__init__(status_code, message, body=None, retry_after=None)
Build a rate-limit error.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
status_code
|
int
|
HTTP status code (429). |
required |
message
|
str
|
Human-readable error message. |
required |
body
|
Optional[Any]
|
Parsed response body, if any. |
None
|
retry_after
|
Optional[float]
|
Server-advised wait in seconds, if available. |
None
|
RelayTimeoutError
Bases: RelayError
Raised when the request to the API times out.
Wraps an :class:httpx.TimeoutException (connect, read, write or pool
timeout). The original exception is available via __cause__.
Chain
Bases: RelayModel
A chain supported by Relay (GET /chains).
Only id is guaranteed present; everything else is optional because the
API tailors the payload to the chain and request.
ChainCurrency
Bases: RelayModel
The native currency of a :class:Chain.
ChainsResponse
Bases: RelayModel
Wrapper for the GET /chains response body.
Currency
Bases: RelayModel
A token on a specific chain, as returned inside fees and quote details.
CurrencyMetadata
Bases: RelayModel
Display and classification metadata for a :class:Currency.
Fee
Bases: RelayModel
A single fee bucket: the currency charged plus its amounts.
amount is the raw value in the currency's smallest unit;
amount_formatted is the same value scaled by decimals; and
amount_usd is the USD equivalent. Some buckets (e.g. relayer_service)
can be negative, representing a network reward rather than a charge.
FeeBreakdown
Bases: RelayModel
The set of fee buckets returned with a :class:Quote or :class:Price.
Every bucket is optional; the API only populates the ones relevant to the
route. relayer is the sum of relayer_gas and relayer_service.
Price
Bases: RelayModel
A non-executable price estimate (POST /price).
Returned by :meth:relay_link.RelayClient.get_price. Unlike :class:Quote
it contains no executable steps — only the fee breakdown and swap details.
Quote
Bases: RelayModel
An executable quote: the steps to run plus the fee breakdown.
Returned by :meth:relay_link.RelayClient.get_quote. details,
fee_sponsorship and protocol are intentionally loose dicts — they
are large, optional, and evolve frequently, so they are passed through
verbatim rather than modeled exhaustively.
RelayRequest
Bases: RelayModel
A single relay request record (GET /requests).
RequestsResponse
Bases: RelayModel
Paginated response for GET /requests.
Returned by :meth:relay_link.RelayClient.get_requests. Pass
continuation back into the next call to page through results.
Step
Bases: RelayModel
One step (signature or transaction) required to execute a quote.
StepItem
Bases: RelayModel
A single signature or transaction within a :class:Step.
A step may bundle several items of the same kind that can be executed
together. data holds the kind-specific payload to sign or submit.
TokenPrice
Bases: RelayModel
Token price in USD (GET /currencies/token/price).
Returned by :meth:relay_link.RelayClient.get_token_price.
TradeType
Bases: str, Enum
Whether amount is the input or the desired output of the swap.
TransactionStatus
Bases: RelayModel
Execution status of a relay request (GET /intents/status/v3).
Returned by :meth:relay_link.RelayClient.get_status. status reaches a
terminal value of success, failure or refund (see
:data:relay_link.TERMINAL_STATUSES); intermediate values include
waiting, pending, depositing and submitted.
PriceRequest
Bases: _RequestBase
Body for POST /price (non-executable price estimate).
Like :class:QuoteRequest but user is optional, and the response
contains no executable steps. Usually built for you by
:meth:relay_link.RelayClient.get_price.
QuoteRequest
Bases: _RequestBase
Body for POST /quote/v2 (and the deprecated POST /quote).
The first seven fields are required; the rest are optional tuning knobs that
are only sent when set. Usually built for you by
:meth:relay_link.RelayClient.get_quote, but exposed for callers that want
to construct and reuse a request explicitly.