Metadata-Version: 2.5
Name: tickerlayer
Version: 0.1.0
Summary: Python client for the TickerLayer market data API: REST and WebSocket for stocks, forex, crypto, indices, ETFs, commodities, perpetual futures and bond yields.
Project-URL: Homepage, https://tickerlayer.com
Project-URL: Documentation, https://tickerlayer.com/docs
Project-URL: API reference, https://tickerlayer.com/docs/rest
Project-URL: Pricing, https://tickerlayer.com/pricing
Author-email: TickerLayer <info@tickerlayer.com>
License-Expression: MIT
License-File: LICENSE
Keywords: bond yields,commodities,crypto,etf,financial data,forex,indices,market data,perpetual futures,real-time,stock api,stocks,tickerlayer,websocket
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Office/Business :: Financial :: Investment
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: httpx<1,>=0.24
Requires-Dist: websockets>=12
Description-Content-Type: text/markdown

# TickerLayer Python client

The Python client for the [TickerLayer](https://tickerlayer.com) market data API. One API key covers stocks, forex, crypto, indices, ETFs, commodities, perpetual futures and government bond yields, over REST and a WebSocket stream, with one symbol format and one response shape.

- Sync and async clients with the same methods, typed responses.
- Errors carry the HTTP status and the API's error code.
- Retries the per-second rate limit, a 503 and network errors with backoff; never retries the monthly quota.
- The stream reconnects and resubscribes on its own.

Get a free API key at [tickerlayer.com/signup](https://tickerlayer.com/signup).

## Install

```bash
pip install tickerlayer
```

Python 3.9 or newer.

## REST

```python
from tickerlayer import TickerLayer

tl = TickerLayer()  # reads TICKERLAYER_API_KEY, or pass TickerLayer("your key")

quote = tl.quote("stocks", "US:KO")
# {'symbol': 'US:KO', 'bid': 93.87, 'ask': 93.99, 'bid_size': 100, 'ask_size': 200, 'timestamp': 1792500685080}

btc = tl.snapshot("crypto", "BTCUSD")
print(btc["last_price"], btc["change_percent"])

bars = tl.bars("stocks", "US:KO", start="2026-10-13", end="2026-10-17", sort="asc")
for bar in bars["results"]:
    print(bar["t"], bar["c"])
```

Symbols: stocks as `COUNTRY:TICKER` (`US:KO`, `DE:BMW`), crypto and forex as pairs (`BTCUSD`, `EURUSD`), commodities like `XAUUSD`, ETFs like `US500ETF`, indices like `US500`, perpetual contracts like `XAUUSDT`, bonds as `COUNTRY:TENOR` (`US:10Y`). Timestamps are Unix milliseconds.

| Method | Route |
| --- | --- |
| `quote(asset, symbol, **params)` | `GET /{asset}/quote/{symbol}` |
| `last_trade(asset, symbol, **params)` | `GET /{asset}/trade/last/{symbol}` |
| `snapshot(asset, symbol)` | `GET /{asset}/snapshot/{symbol}` |
| `previous_bar(asset, symbol, interval=None)` | `GET /{asset}/agg/{symbol}/prev` |
| `bars(asset, symbol, start=, end=, multiplier=1, timespan="day", limit=, offset=, sort=)` | `GET /{asset}/agg/{symbol}/{multiplier}/{timespan}/{from}/{to}` |
| `symbols(asset=None, **params)` | `GET /{asset}/symbols`, or `GET /symbols` |
| `symbol_coverage(symbols)` | `POST /symbols/coverage` |
| `perpetual_mark(symbol, **params)` | `GET /perpetuals/mark/{symbol}` |
| `bond_yield(symbol)`, `bond_snapshot(symbol)` | `GET /bond/last/{symbol}`, `GET /bond/snapshot/{symbol}` |
| `market_status(**params)`, `market_status_bulk(items)` | `GET /markets/status`, `GET /markets/status/bulk` |
| `market_sessions(**params)`, `market_holidays(**params)` | `GET /markets/sessions`, `GET /markets/holidays` |
| `fundamentals(symbol)`, `fundamentals_list(**params)`, `economic_events(**params)` | `GET /fundamentals/...` |
| `overnight_symbols()`, `overnight_quote(symbol)`, `overnight_snapshot(symbols=)` | `GET /overnight/...` |
| `get(path, params)` | any other GET route |

`asset` is one of `crypto`, `forex`, `stocks`, `indices`, `etfs`, `commodities`, `perpetuals`. Route options are keyword arguments, for example `tl.quote("etfs", "US500ETF", spread="full")`. Every route and parameter is in the [REST reference](https://tickerlayer.com/docs/rest) and the [OpenAPI 3.1 spec](https://tickerlayer.com/openapi.json).

### Async

```python
import asyncio
from tickerlayer import AsyncTickerLayer

async def main():
    async with AsyncTickerLayer() as tl:
        quote, btc = await asyncio.gather(tl.quote("stocks", "US:KO"), tl.snapshot("crypto", "BTCUSD"))
        print(quote["bid"], btc["last_price"])

asyncio.run(main())
```

### Errors

A failed request raises `TickerLayerError` with `status` (0 when there was no answer), `code` (for example `REST_RATE_LIMIT_EXCEEDED`, `REST_QUOTA_EXCEEDED`), `body` and `retry_after` in seconds.

```python
from tickerlayer import TickerLayerError

try:
    tl.quote("stocks", "US:KO")
except TickerLayerError as err:
    if err.status == 404:
        print("not in the catalog")
    else:
        raise
```

Options: `TickerLayer(api_key, timeout=15.0, max_retries=2, base_url=..., http_client=...)`.

## WebSocket stream

```python
import asyncio
from tickerlayer import AsyncTickerLayer

async def main():
    tl = AsyncTickerLayer()
    async with tl.stream() as stream:
        await stream.subscribe(["stocks.quotes", "stocks.trades"], ["US:KO", "US:JPM"])
        await stream.subscribe("crypto.quotes", ["BTCUSD", "ETHUSD"])
        async for frame in stream:
            if frame["type"] == "quote":
                print(frame["symbol"], float(frame["bid"]), float(frame["ask"]), frame["ts"])

asyncio.run(main())
```

- Subscribe once: the client sends it as soon as the server is ready and again after every reconnect. More than 500 symbols are split into several messages.
- Frames are dicts as the server sends them. Quote and trade prices are strings on some channels (`"bid": "93.87"`) and numbers on others, so read them with `float()`. The [stream reference](https://tickerlayer.com/docs/websocket) lists every channel and frame.
- Subscribe options are keyword arguments: `snapshot`, `view`, `spread`, `interval` and `session` on the bar channels, and the rest of the documented options.
- Reconnects wait longer after each failed attempt, up to 30 seconds (`tl.stream(max_reconnect_delay=...)`), and start over once a connection has stayed up for a minute. After a server release the client is back within a second. A refused key ends the stream with a `TickerLayerError`. `tl.stream(reconnect=False)` turns reconnects off.
- `stream()` is available on `TickerLayer` too; the stream itself always runs in asyncio.

## Links

- [Documentation](https://tickerlayer.com/docs)
- [Pricing](https://tickerlayer.com/pricing)
- [MCP server for AI agents](https://tickerlayer.com/mcp)
- [JavaScript client](https://www.npmjs.com/package/tickerlayer)

## License

MIT
