Skip to content

API reference

odos_py

odos-py: a modern Python client for the Odos DEX Aggregator API.

AsyncOdosClient

Async counterpart of :class:~odos_py.client.OdosClient.

Same configuration and behaviour, backed by httpx.AsyncClient. The core flow is identical: :meth:quote returns a path_id, :meth:assemble turns it into signable calldata, and :meth:swap chains both.

Use it as an async context manager so the connection pool is closed::

async with AsyncOdosClient(api_key="...") as client:
    quote = await client.quote(request)
Example

async with AsyncOdosClient() as client: ... chains = await client.get_chains()

quote_and_assemble = swap class-attribute instance-attribute

Alias for :meth:swap: quote then assemble in one awaited call.

__init__(*, base_url=DEFAULT_BASE_URL, api_key=None, api_key_header=DEFAULT_API_KEY_HEADER, max_retries=DEFAULT_MAX_RETRIES, backoff_base=DEFAULT_BACKOFF_BASE, timeout=DEFAULT_TIMEOUT, transport=None)

Create an async client.

Parameters:

Name Type Description Default
base_url str

Base URL of the Odos API. Override to target a proxy or a self-hosted gateway.

DEFAULT_BASE_URL
api_key Optional[str]

Optional API key. Strongly recommended: the keyless tier is heavily rate limited.

None
api_key_header str

Header name the api_key is sent under. The real header name is undocumented, so it is configurable (e.g. "Authorization").

DEFAULT_API_KEY_HEADER
max_retries int

Maximum number of automatic retries on HTTP 429.

DEFAULT_MAX_RETRIES
backoff_base float

Base delay (seconds) for exponential backoff between 429 retries.

DEFAULT_BACKOFF_BASE
timeout float

Per-request timeout in seconds.

DEFAULT_TIMEOUT
transport Optional[AsyncBaseTransport]

Optional custom httpx async transport, primarily for testing (e.g. a MockTransport).

None

aclose() async

Close the underlying async HTTP connection pool.

Safe to await multiple times. Called automatically when the client is used as an async context manager.

quote(request) async

Request a swap quote (POST /sor/quote/v2).

Prices the swap described by request and returns the best path, including the path_id needed by :meth:assemble.

Parameters:

Name Type Description Default
request QuoteRequest

The swap to price.

required

Returns:

Type Description
QuoteResponse

The parsed quote, whose path_id feeds :meth:assemble.

Raises:

Type Description
OdosRateLimitError

If rate limited (HTTP 429) past max_retries.

OdosAPIError

For any other non-success HTTP status.

assemble(*, user_addr, path_id, simulate=False) async

Assemble a quoted path into a signable transaction (POST /sor/assemble).

Parameters:

Name Type Description Default
user_addr str

Address that will execute the swap. Must match the user_addr used for the originating quote.

required
path_id str

The path_id returned by a prior :meth:quote.

required
simulate bool

If True, ask Odos to simulate the transaction and include the result in the response.

False

Returns:

Type Description
AssembleResponse

The assembled response; transaction holds the ready-to-sign

AssembleResponse

EVM transaction.

Raises:

Type Description
OdosRateLimitError

If rate limited (HTTP 429) past max_retries.

OdosAPIError

For any other non-success HTTP status.

execute(*, user_addr, path_id) async

Request assisted execution of a quoted path (POST /sor/execute).

Parameters:

Name Type Description Default
user_addr str

Address that will execute the swap.

required
path_id str

The path_id returned by a prior :meth:quote.

required

Returns:

Type Description
Any

The raw decoded JSON payload from the API (shape not modelled).

Raises:

Type Description
OdosRateLimitError

If rate limited (HTTP 429) past max_retries.

OdosAPIError

For any other non-success HTTP status.

swap(request, *, simulate=False) async

Quote then assemble a swap in a single awaited call.

Convenience helper that runs :meth:quote, threads the resulting path_id into :meth:assemble, and returns both.

Parameters:

Name Type Description Default
request QuoteRequest

The swap to quote and assemble.

required
simulate bool

Forwarded to :meth:assemble; if True, Odos simulates the transaction.

False

Returns:

Type Description
QuoteResponse

A (quote, assembled) tuple: the :class:QuoteResponse and the

AssembleResponse

class:AssembleResponse whose transaction is ready to sign.

Raises:

Type Description
OdosAPIError

If the quote returned no path_id, or on any non-success HTTP status.

OdosRateLimitError

If rate limited (HTTP 429) past max_retries.

Example

async with AsyncOdosClient() as client: ... quote, assembled = await client.swap(request) ... assembled.transaction.to # router contract address

get_chains() async

List supported chains (GET /info/chains).

Returns:

Type Description
Any

Decoded JSON of the form {"chains": [<chain_id>, ...]} listing

Any

the EVM chain ids Odos supports.

Raises:

Type Description
OdosAPIError

On any non-success HTTP status.

get_tokens(chain_id) async

List tokens for a chain (GET /info/tokens/{chainId}).

Parameters:

Name Type Description Default
chain_id int

EVM chain id to list tokens for.

required

Returns:

Type Description
Any

Decoded JSON of the form ``{"tokenMap": {

: {"symbol":

Any

..., "decimals": ..., "name": ...}, ...}}`` keyed by token address.

Raises:

Type Description
OdosAPIError

On any non-success HTTP status.

get_router(chain_id) async

Get the router contract address for a chain (GET /info/router/v2/{chainId}).

Parameters:

Name Type Description Default
chain_id int

EVM chain id to look up.

required

Returns:

Type Description
Any

Decoded JSON containing the router contract address for the

Any

chain.

Raises:

Type Description
OdosAPIError

On any non-success HTTP status.

get_contract_info(chain_id) async

Get router contract metadata for a chain (GET /info/contract-info/v2/{chainId}).

Parameters:

Name Type Description Default
chain_id int

EVM chain id to look up.

required

Returns:

Type Description
Any

Decoded JSON with contract metadata (address and related details)

Any

for the chain.

Raises:

Type Description
OdosAPIError

On any non-success HTTP status.

get_token_price(chain_id, token_address) async

Get the price of a token (GET /pricing/token/{chainId}/{tokenAddress}).

Parameters:

Name Type Description Default
chain_id int

EVM chain id the token lives on.

required
token_address str

ERC-20 contract address of the token.

required

Returns:

Type Description
Any

Decoded JSON of the form {"price": <float>, ...} giving the

Any

token's USD price.

Raises:

Type Description
OdosAPIError

On any non-success HTTP status.

OdosClient

A synchronous client for the Odos DEX Aggregator API.

The core flow is two steps: :meth:quote returns a path_id, then :meth:assemble turns that path_id into ready-to-sign transaction calldata. :meth:swap chains both in one call.

The free keyless tier is heavily rate limited; pass api_key to raise limits. api_key_header is configurable because the exact header name is not publicly documented.

The client may be used as a context manager to ensure the underlying connection pool is closed::

with OdosClient(api_key="...") as client:
    chains = client.get_chains()
Example

client = OdosClient(api_key="YOUR_KEY") quote = client.quote(request) client.close()

quote_and_assemble = swap class-attribute instance-attribute

Alias for :meth:swap: quote then assemble in one call.

__init__(*, base_url=DEFAULT_BASE_URL, api_key=None, api_key_header=DEFAULT_API_KEY_HEADER, max_retries=DEFAULT_MAX_RETRIES, backoff_base=DEFAULT_BACKOFF_BASE, timeout=DEFAULT_TIMEOUT, transport=None)

Create a client.

Parameters:

Name Type Description Default
base_url str

Base URL of the Odos API. Override to target a proxy or a self-hosted gateway.

DEFAULT_BASE_URL
api_key Optional[str]

Optional API key. Strongly recommended: the keyless tier is heavily rate limited.

None
api_key_header str

Header name the api_key is sent under. The real header name is undocumented, so it is configurable (e.g. "Authorization").

DEFAULT_API_KEY_HEADER
max_retries int

Maximum number of automatic retries on HTTP 429.

DEFAULT_MAX_RETRIES
backoff_base float

Base delay (seconds) for exponential backoff between 429 retries.

DEFAULT_BACKOFF_BASE
timeout float

Per-request timeout in seconds.

DEFAULT_TIMEOUT
transport Optional[BaseTransport]

Optional custom httpx transport, primarily for testing (e.g. a MockTransport).

None

close()

Close the underlying HTTP connection pool.

Safe to call multiple times. Called automatically when the client is used as a context manager.

quote(request)

Request a swap quote (POST /sor/quote/v2).

Prices the swap described by request and returns the best path, including the path_id needed by :meth:assemble.

Parameters:

Name Type Description Default
request QuoteRequest

The swap to price.

required

Returns:

Type Description
QuoteResponse

The parsed quote, whose path_id feeds :meth:assemble.

Raises:

Type Description
OdosRateLimitError

If rate limited (HTTP 429) past max_retries.

OdosAPIError

For any other non-success HTTP status.

assemble(*, user_addr, path_id, simulate=False)

Assemble a quoted path into a signable transaction (POST /sor/assemble).

Parameters:

Name Type Description Default
user_addr str

Address that will execute the swap. Must match the user_addr used for the originating quote.

required
path_id str

The path_id returned by a prior :meth:quote.

required
simulate bool

If True, ask Odos to simulate the transaction and include the result in the response.

False

Returns:

Type Description
AssembleResponse

The assembled response; transaction holds the ready-to-sign

AssembleResponse

EVM transaction.

Raises:

Type Description
OdosRateLimitError

If rate limited (HTTP 429) past max_retries.

OdosAPIError

For any other non-success HTTP status.

execute(*, user_addr, path_id)

Request assisted execution of a quoted path (POST /sor/execute).

Parameters:

Name Type Description Default
user_addr str

Address that will execute the swap.

required
path_id str

The path_id returned by a prior :meth:quote.

required

Returns:

Type Description
Any

The raw decoded JSON payload from the API (shape not modelled).

Raises:

Type Description
OdosRateLimitError

If rate limited (HTTP 429) past max_retries.

OdosAPIError

For any other non-success HTTP status.

swap(request, *, simulate=False)

Quote then assemble a swap in a single call.

Convenience helper that runs :meth:quote, threads the resulting path_id into :meth:assemble, and returns both. Use this when you want signable calldata directly from a :class:QuoteRequest.

Parameters:

Name Type Description Default
request QuoteRequest

The swap to quote and assemble.

required
simulate bool

Forwarded to :meth:assemble; if True, Odos simulates the transaction.

False

Returns:

Type Description
QuoteResponse

A (quote, assembled) tuple: the :class:QuoteResponse and the

AssembleResponse

class:AssembleResponse whose transaction is ready to sign.

Raises:

Type Description
OdosAPIError

If the quote returned no path_id, or on any non-success HTTP status.

OdosRateLimitError

If rate limited (HTTP 429) past max_retries.

Example

request = QuoteRequest( ... chain_id=1, ... input_tokens=[InputToken( ... token_address="0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", ... amount="1000000000000000000", ... )], ... output_tokens=[OutputToken( ... token_address="0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", ... proportion=1, ... )], ... user_addr="0x47E2D28169738039755586743E2dfCF3bd643f86", ... slippage_limit_percent=0.3, ... ) quote, assembled = client.swap(request) assembled.transaction.to # router contract address

get_chains()

List supported chains (GET /info/chains).

Returns:

Type Description
Any

Decoded JSON of the form {"chains": [<chain_id>, ...]} listing

Any

the EVM chain ids Odos supports.

Raises:

Type Description
OdosAPIError

On any non-success HTTP status.

get_tokens(chain_id)

List tokens for a chain (GET /info/tokens/{chainId}).

Parameters:

Name Type Description Default
chain_id int

EVM chain id to list tokens for.

required

Returns:

Type Description
Any

Decoded JSON of the form ``{"tokenMap": {

: {"symbol":

Any

..., "decimals": ..., "name": ...}, ...}}`` keyed by token address.

Raises:

Type Description
OdosAPIError

On any non-success HTTP status.

get_router(chain_id)

Get the router contract address for a chain (GET /info/router/v2/{chainId}).

Parameters:

Name Type Description Default
chain_id int

EVM chain id to look up.

required

Returns:

Type Description
Any

Decoded JSON containing the router contract address for the

Any

chain.

Raises:

Type Description
OdosAPIError

On any non-success HTTP status.

get_contract_info(chain_id)

Get router contract metadata for a chain (GET /info/contract-info/v2/{chainId}).

Parameters:

Name Type Description Default
chain_id int

EVM chain id to look up.

required

Returns:

Type Description
Any

Decoded JSON with contract metadata (address and related details)

Any

for the chain.

Raises:

Type Description
OdosAPIError

On any non-success HTTP status.

get_token_price(chain_id, token_address)

Get the price of a token (GET /pricing/token/{chainId}/{tokenAddress}).

Parameters:

Name Type Description Default
chain_id int

EVM chain id the token lives on.

required
token_address str

ERC-20 contract address of the token.

required

Returns:

Type Description
Any

Decoded JSON of the form {"price": <float>, ...} giving the

Any

token's USD price.

Raises:

Type Description
OdosAPIError

On any non-success HTTP status.

OdosAPIError

Bases: OdosError

Raised when the Odos API returns a non-success HTTP status.

Also raised for client-side protocol problems, such as a quote response that lacks a path_id during :meth:~odos_py.OdosClient.swap.

Attributes:

Name Type Description
status_code

The HTTP status code returned by the API, or None when the error did not originate from an HTTP response.

body

The parsed response body (JSON when decodable, otherwise the raw text), or None.

__init__(message, *, status_code=None, body=None)

Initialize the error.

Parameters:

Name Type Description Default
message str

Human-readable description of the failure.

required
status_code Optional[int]

HTTP status code associated with the failure, if any.

None
body Any

Parsed response body associated with the failure, if any.

None

OdosError

Bases: Exception

Base class for all errors raised by this library.

Catch this to handle any failure originating from odos_py without distinguishing the specific subtype.

OdosRateLimitError

Bases: OdosAPIError

Raised on HTTP 429 after the client's retries are exhausted.

The client automatically retries 429 responses with exponential backoff (honouring Retry-After); this is raised only once max_retries is reached.

Attributes:

Name Type Description
retry_after

The server-advised wait in seconds parsed from the Retry-After header, or None when absent or unparseable.

__init__(message, *, status_code=None, body=None, retry_after=None)

Initialize the rate-limit error.

Parameters:

Name Type Description Default
message str

Human-readable description of the failure.

required
status_code Optional[int]

HTTP status code (typically 429).

None
body Any

Parsed response body associated with the failure, if any.

None
retry_after Optional[float]

Server-advised wait in seconds, if provided.

None

AssembleRequest

Bases: BaseModel

Body for POST /sor/assemble.

Attributes:

Name Type Description
user_addr str

Address that will execute the swap. Must match the user_addr used for the originating quote. Serialized as userAddr.

path_id str

The path_id returned by a prior quote. Serialized as pathId.

simulate bool

When True, asks Odos to simulate the transaction and return the simulation result alongside the calldata.

AssembleResponse

Bases: BaseModel

Response from POST /sor/assemble.

Any fields the API returns beyond transaction (e.g. simulation output, expected output amounts) are preserved via extra="allow" and reachable through model_extra.

Attributes:

Name Type Description
transaction Optional[Transaction]

The ready-to-sign :class:Transaction, or None if the API did not return one.

InputToken

Bases: BaseModel

A token being sold, with its amount expressed in wei (base units).

Attributes:

Name Type Description
token_address str

Checksummed ERC-20 contract address of the token being sold. Serialized as tokenAddress.

amount str

Amount to sell, as a decimal string in the token's smallest unit (wei for an 18-decimal token). A string is used to avoid precision loss on large integers.

OutputToken

Bases: BaseModel

A token being bought, with its desired proportion of the output.

Attributes:

Name Type Description
token_address str

Checksummed ERC-20 contract address of the token to receive. Serialized as tokenAddress.

proportion float

Share of the total output this token should represent, in the range 0..1. Proportions across all output tokens should sum to 1 (use 1 for a single-output swap).

QuoteRequest

Bases: BaseModel

Body for POST /sor/quote/v2.

Describes the swap to price. The response (:class:QuoteResponse) carries the path_id that :meth:~odos_py.OdosClient.assemble turns into signable calldata.

Attributes:

Name Type Description
chain_id int

EVM chain id the swap executes on (e.g. 1 for Ethereum mainnet, 137 for Polygon). Serialized as chainId.

input_tokens list[InputToken]

Tokens being sold and their amounts (in wei).

output_tokens list[OutputToken]

Tokens to receive and their output proportions.

user_addr str

Address that will execute the swap; also receives the output tokens. Serialized as userAddr.

slippage_limit_percent float

Maximum acceptable slippage as a percentage (e.g. 0.3 means 0.3%). Serialized as slippageLimitPercent.

QuoteResponse

Bases: BaseModel

Response from POST /sor/quote/v2.

Only the fields commonly needed by callers are typed explicitly; any other fields the API returns are preserved (extra="allow") and accessible via model_extra.

Attributes:

Name Type Description
path_id Optional[str]

Opaque identifier for the routed path. Pass it to :meth:~odos_py.OdosClient.assemble to build the transaction. None if the quote produced no executable path.

out_amounts list[str]

Expected output amounts (wei), parallel to the request's output_tokens.

in_amounts list[str]

Input amounts consumed (wei), parallel to input_tokens.

gas_estimate Optional[float]

Estimated gas units for the swap.

gas_estimate_value Optional[float]

Estimated gas cost expressed in USD.

price_impact Optional[float]

Estimated price impact of the swap, as a percentage (may be negative).

block_number Optional[int]

Block height the quote was computed against.

Transaction

Bases: BaseModel

The ready-to-sign transaction returned by assemble.

The fields mirror a standard EVM transaction and can be passed to a signer such as web3.py's eth.account.sign_transaction. All fields are optional because the API may omit some depending on the request.

Attributes:

Name Type Description
to Optional[str]

Router contract address the transaction calls.

data Optional[str]

ABI-encoded calldata (0x-prefixed hex).

value Optional[str]

Native-token amount to send with the call (wei, as a string).

gas Optional[int]

Gas limit.

gas_price Optional[int]

Gas price in wei. Serialized as gasPrice.

nonce Optional[int]

Sender account nonce.

chain_id Optional[int]

EVM chain id the transaction targets. Serialized as chainId.

from_ Optional[str]

Sender address. Serialized as from (renamed because from is a Python keyword).