Skip to content

API reference

pyth_hermes

pyth-hermes: a Python client for the Pyth Network Hermes price-oracle API.

AsyncHermesClient

Asynchronous client for the Pyth Network Hermes API.

Adds :meth:stream_prices, an async iterator over the SSE price stream with automatic reconnect + backoff. Mirrors :class:~pyth_hermes.HermesClient for the request/response endpoints, and is an async context manager::

async with AsyncHermesClient() as client:
    price = await client.get_price_decimal(feed_id)

As with the sync client, transient failures (429/5xx) are retried with exponential backoff that honors Retry-After and the 60-second rate-limit window.

base_url property

The normalized API base URL in use (no trailing slash).

__init__(base_url=_BASE_URL_UNSET, *, api_key=None, api_key_header='Authorization', api_key_scheme='Bearer', timeout=30.0, max_retries=3, backoff_base=1.0, backoff_cap=60.0, client=None)

Construct an asynchronous Hermes client.

Parameters:

Name Type Description Default
base_url str

API base URL. Defaults to production (https://hermes.pyth.network). Set to the beta host or a paid provider's URL as needed. Ignored (with a UserWarning) when client is supplied.

_BASE_URL_UNSET
api_key Optional[str]

Optional API key. Optional today; mandatory for all callers from 2026-07-31. Sent on every request as a header.

None
api_key_header str

Header name to carry the API key. Defaults to "Authorization".

'Authorization'
api_key_scheme str

Auth scheme prefix for the header value. Defaults to "Bearer". Pass an empty string to send the raw key.

'Bearer'
timeout float

Per-request timeout in seconds.

30.0
max_retries int

Maximum retry attempts for transient errors, in addition to the initial attempt.

3
backoff_base float

Base seconds for exponential backoff between retries.

1.0
backoff_cap float

Maximum seconds any single backoff delay may reach.

60.0
client Optional[AsyncClient]

Optional preconfigured :class:httpx.AsyncClient. When given, set base_url on the client itself; the constructor's base_url is then ignored.

None

Raises:

Type Description
UserWarning

If both an explicit base_url and client are passed (the former cannot take effect).

aclose() async

Close the underlying async HTTP connection pool.

Called automatically when the client is used as an async context manager.

list_price_feeds(*, query=None, asset_type=None) async

List the price-feed catalog, optionally filtered.

Async counterpart of :meth:~pyth_hermes.HermesClient.list_price_feeds. Calls GET /v2/price_feeds; the search is fuzzy, so prefer :meth:get_feed_id to resolve a single canonical feed.

Parameters:

Name Type Description Default
query Optional[str]

Case-insensitive substring to filter feeds by symbol.

None
asset_type Optional[str]

Asset class filter, e.g. "crypto", "fx", "equity", "metal".

None

Returns:

Type Description
list[PriceFeed]

A list of :class:~pyth_hermes.models.PriceFeed catalog entries.

Raises:

Type Description
HTTPStatusError

If the API returns a non-2xx status after retries are exhausted.

get_feed_id(symbol) async

Resolve a canonical feed id by EXACT attributes.symbol match.

Async counterpart of :meth:~pyth_hermes.HermesClient.get_feed_id. The catalog search returns deprecated/variant feeds (MBTC, XBTC, ...) and matches substrings, so this filters on exact symbol equality.

Parameters:

Name Type Description Default
symbol str

The canonical symbol to match exactly, e.g. "Crypto.BTC/USD".

required

Returns:

Type Description
Optional[str]

The 32-byte hex feed id, or None if no feed matches exactly.

Raises:

Type Description
HTTPStatusError

If the underlying catalog request fails after retries are exhausted.

get_latest_price(ids, *, parsed=True, encoding='hex') async

Fetch the latest price update for one or more feed ids.

Async counterpart of :meth:~pyth_hermes.HermesClient.get_latest_price. Calls GET /v2/updates/price/latest.

Parameters:

Name Type Description Default
ids list[str]

One or more 32-byte hex feed ids (sent as repeatable ids[]).

required
parsed bool

Whether to include decoded per-feed updates. When False, only the binary payload is returned and parsed is None.

True
encoding str

Encoding for the binary payload: "hex" or "base64".

'hex'

Returns:

Name Type Description
A PriceUpdateResponse

class:~pyth_hermes.models.PriceUpdateResponse.

Raises:

Type Description
HTTPStatusError

If the API returns a non-2xx status after retries are exhausted.

get_price_at(publish_time, ids, *, parsed=True, encoding='hex') async

Fetch a historical price update at or just after a timestamp.

Async counterpart of :meth:~pyth_hermes.HermesClient.get_price_at. Calls GET /v2/updates/price/{publish_time}; the API returns the first update with a publish time at or after the requested timestamp.

Parameters:

Name Type Description Default
publish_time int

Unix timestamp (seconds) to look up.

required
ids list[str]

One or more 32-byte hex feed ids (sent as repeatable ids[]).

required
parsed bool

Whether to include decoded per-feed updates.

True
encoding str

Encoding for the binary payload: "hex" or "base64".

'hex'

Returns:

Name Type Description
A PriceUpdateResponse

class:~pyth_hermes.models.PriceUpdateResponse for that instant.

Raises:

Type Description
HTTPStatusError

If the API returns a non-2xx status after retries are exhausted.

get_price_decimal(feed_id) async

Return the latest human-readable spot price for one feed id.

Async counterpart of :meth:~pyth_hermes.HermesClient.get_price_decimal.

Parameters:

Name Type Description Default
feed_id str

A single 32-byte hex feed id.

required

Returns:

Type Description
Decimal

The latest spot price as an exact :class:~decimal.Decimal.

Raises:

Type Description
ValueError

If the API returns no parsed price for feed_id.

HTTPStatusError

If the API returns a non-2xx status after retries are exhausted.

stream_prices(ids, *, parsed=True, reconnect=True) async

Stream live price updates over Server-Sent Events (SSE).

Opens GET /v2/updates/price/stream and yields one :class:~pyth_hermes.models.PriceUpdateResponse per event. With reconnect=True (the default) the stream transparently re-opens after a disconnect or transient error, applying exponential backoff between attempts (the backoff counter resets after each successful connect). With reconnect=False the iterator stops when the server closes the stream and re-raises transport/HTTP errors.

Parameters:

Name Type Description Default
ids list[str]

One or more 32-byte hex feed ids to subscribe to (sent as repeatable ids[]).

required
parsed bool

Whether each event should include decoded per-feed updates.

True
reconnect bool

Whether to automatically reconnect with backoff after a disconnect or transient error. Defaults to True.

True

Yields:

Name Type Description
A AsyncIterator[PriceUpdateResponse]

class:~pyth_hermes.models.PriceUpdateResponse for each SSE event.

Raises:

Type Description
HTTPStatusError

On a non-2xx stream response when reconnect=False.

TransportError

On a connection failure when reconnect=False.

Example

btc = "e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43" async with AsyncHermesClient() as client: ... async for update in client.stream_prices([btc]): ... if update.parsed: ... print(update.parsed[0].to_decimal()) ... break # stop after the first tick

HermesClient

Synchronous client for the Pyth Network Hermes API.

Get a BTC/USD price in a few lines::

from pyth_hermes import HermesClient
client = HermesClient()
feed_id = client.get_feed_id("Crypto.BTC/USD")
print(client.get_price_decimal(feed_id))

An api_key and custom base_url may be supplied for paid providers and for the mandatory-key requirement landing 2026-07-31. The client is also a context manager, which closes the underlying HTTP connection on exit::

with HermesClient() as client:
    ...

Transient failures (HTTP 429 and 5xx) are retried automatically with exponential backoff that honors any Retry-After header and respects the 60-second rate-limit window.

base_url property

The normalized API base URL in use (no trailing slash).

__init__(base_url=_BASE_URL_UNSET, *, api_key=None, api_key_header='Authorization', api_key_scheme='Bearer', timeout=30.0, max_retries=3, backoff_base=1.0, backoff_cap=60.0, client=None)

Construct a synchronous Hermes client.

Parameters:

Name Type Description Default
base_url str

API base URL. Defaults to production (https://hermes.pyth.network). Set to the beta host or a paid provider's URL as needed. Ignored (with a UserWarning) when client is supplied, since the request host then comes from the injected client.

_BASE_URL_UNSET
api_key Optional[str]

Optional API key. Optional today; mandatory for all callers from 2026-07-31. Sent on every request as a header.

None
api_key_header str

Header name to carry the API key. Defaults to "Authorization".

'Authorization'
api_key_scheme str

Auth scheme prefix for the header value. Defaults to "Bearer" (producing Authorization: Bearer <key>). Pass an empty string to send the raw key with no prefix.

'Bearer'
timeout float

Per-request timeout in seconds.

30.0
max_retries int

Maximum retry attempts for transient errors (429/5xx and transport errors), in addition to the initial attempt.

3
backoff_base float

Base seconds for exponential backoff between retries.

1.0
backoff_cap float

Maximum seconds any single backoff delay may reach.

60.0
client Optional[Client]

Optional preconfigured :class:httpx.Client (custom transport, proxy, pool, ...). When given, set base_url on the client itself; the constructor's base_url is then ignored.

None

Raises:

Type Description
UserWarning

If both an explicit base_url and client are passed (the former cannot take effect).

close()

Close the underlying HTTP connection pool.

Called automatically when the client is used as a context manager.

list_price_feeds(*, query=None, asset_type=None)

List the price-feed catalog, optionally filtered.

Calls GET /v2/price_feeds. Note the search is fuzzy and returns deprecated/variant feeds; for resolving a single canonical feed prefer :meth:get_feed_id, which matches on exact symbol.

Parameters:

Name Type Description Default
query Optional[str]

Case-insensitive substring to filter feeds by symbol.

None
asset_type Optional[str]

Asset class filter, e.g. "crypto", "fx", "equity", "metal".

None

Returns:

Type Description
list[PriceFeed]

A list of :class:~pyth_hermes.models.PriceFeed catalog entries.

Raises:

Type Description
HTTPStatusError

If the API returns a non-2xx status after retries are exhausted.

get_feed_id(symbol)

Resolve a canonical feed id by EXACT attributes.symbol match.

GET /v2/price_feeds?query=... returns deprecated/variant feeds (MBTC, XBTC, ...) first and matches substrings, so this filters on exact symbol equality to avoid picking the wrong feed.

Parameters:

Name Type Description Default
symbol str

The canonical symbol to match exactly, e.g. "Crypto.BTC/USD".

required

Returns:

Type Description
Optional[str]

The 32-byte hex feed id, or None if no feed matches exactly.

Raises:

Type Description
HTTPStatusError

If the underlying catalog request fails after retries are exhausted.

Example

client.get_feed_id("Crypto.BTC/USD") 'e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43'

get_latest_price(ids, *, parsed=True, encoding='hex')

Fetch the latest price update for one or more feed ids.

Calls GET /v2/updates/price/latest.

Parameters:

Name Type Description Default
ids list[str]

One or more 32-byte hex feed ids (sent as repeatable ids[]).

required
parsed bool

Whether to include decoded per-feed updates. When False, only the binary payload is returned and parsed is None.

True
encoding str

Encoding for the binary payload: "hex" or "base64".

'hex'

Returns:

Name Type Description
A PriceUpdateResponse

class:~pyth_hermes.models.PriceUpdateResponse with the binary

PriceUpdateResponse

payload and (when parsed) the decoded updates.

Raises:

Type Description
HTTPStatusError

If the API returns a non-2xx status after retries are exhausted.

Example

btc = "e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43" resp = client.get_latest_price([btc]) resp.parsed[0].to_decimal() Decimal('63952.82153102')

get_price_at(publish_time, ids, *, parsed=True, encoding='hex')

Fetch a historical price update at or just after a timestamp.

Calls GET /v2/updates/price/{publish_time}; the API returns the first update with a publish time greater than or equal to the requested timestamp.

Parameters:

Name Type Description Default
publish_time int

Unix timestamp (seconds) to look up.

required
ids list[str]

One or more 32-byte hex feed ids (sent as repeatable ids[]).

required
parsed bool

Whether to include decoded per-feed updates.

True
encoding str

Encoding for the binary payload: "hex" or "base64".

'hex'

Returns:

Name Type Description
A PriceUpdateResponse

class:~pyth_hermes.models.PriceUpdateResponse for that instant.

Raises:

Type Description
HTTPStatusError

If the API returns a non-2xx status after retries are exhausted.

get_price_decimal(feed_id)

Return the latest human-readable spot price for one feed id.

Convenience wrapper over :meth:get_latest_price that returns just the spot price as a :class:~decimal.Decimal.

Parameters:

Name Type Description Default
feed_id str

A single 32-byte hex feed id.

required

Returns:

Type Description
Decimal

The latest spot price as an exact Decimal.

Raises:

Type Description
ValueError

If the API returns no parsed price for feed_id.

HTTPStatusError

If the API returns a non-2xx status after retries are exhausted.

BinaryUpdate

Bases: BaseModel

The encoded binary VAA/update payload.

This is the on-chain-submittable blob; data is a list of encoded strings whose representation is given by encoding.

FeedAttributes

Bases: BaseModel

Attributes block of a price feed catalog entry.

The Hermes attributes object is an open string map; the well-known keys are surfaced as typed fields and any extra keys are preserved (accessible via :attr:pydantic.BaseModel.model_extra).

ParsedPriceUpdate

Bases: BaseModel

A single parsed price update for one feed id.

Carries both the spot price and the exponentially-weighted moving average ema_price. Call :meth:to_decimal for the human-readable spot price.

to_decimal()

Return the human-readable spot price as a :class:~decimal.Decimal.

Shortcut for self.price.to_decimal().

PriceFeed

Bases: BaseModel

A single price feed catalog entry from GET /v2/price_feeds.

symbol property

Shortcut to attributes.symbol (e.g. "Crypto.BTC/USD").

Returns:

Type Description
Optional[str]

The canonical symbol, or None if absent.

PriceFeedMetadata

Bases: BaseModel

Metadata attached to a parsed price update.

All fields are optional; Hermes may omit any of them depending on the endpoint and whether proof data is available.

PriceUpdateResponse

Bases: BaseModel

Response from the latest / historical price update endpoints.

Returned by GET /v2/updates/price/latest and GET /v2/updates/price/{publish_time}, and by each SSE stream event. parsed is None when the request was made with parsed=False.

RpcPrice

Bases: BaseModel

A single price reading with its exponent and publish time.

Used for both the spot price and the ema_price of a parsed update. The price/conf fields are raw integers; apply expo (or call :meth:to_decimal / :meth:conf_to_decimal) to get human-readable values.

to_decimal()

Return the human-readable price as a :class:~decimal.Decimal.

Returns:

Type Description
Decimal

price * 10 ** expo as an exact Decimal.

conf_to_decimal()

Return the confidence interval as a :class:~decimal.Decimal.

Uses the same exponent as the price.

Returns:

Type Description
Decimal

conf * 10 ** expo as an exact Decimal.

price_to_decimal(price, expo)

Convert a raw Pyth price + exponent into a real Decimal value.

Pyth reports prices as a large integer plus a (usually negative) base-10 exponent. The human-readable value is price * 10 ** expo, computed here with :class:~decimal.Decimal to avoid binary float imprecision.

Parameters:

Name Type Description Default
price Union[int, str]

The raw integer price, as an int or its string form (Hermes returns it as a JSON string).

required
expo int

The base-10 exponent to apply (e.g. -8).

required

Returns:

Type Description
Decimal

The exact human-readable price as a :class:~decimal.Decimal.

Example

price_to_decimal(6395282153102, -8) Decimal('63952.82153102')