# Architecture

How the API-key SDK layers ConnectRPC, realtime, catalogs, and services.

The SDK is a thin typed layer over two wire protocols:

- **ConnectRPC over HTTP** for unary requests (binary Protobuf by default)
- **Centrifugo over WebSocket** for realtime (binary Protobuf client protocol and payloads)

```text
Config / credentials          API URL, WS URL, Ed25519 key material, Account ID
        |
`AsyncPolyester` / `Polyester`           wires transports, catalogs, and service accessors
  ├── Connect transport       public + authenticated unary calls
  ├── Realtime client         shared WebSocket multiplexer
  ├── Catalogs                spot + Zipper reference data / scales
  ├── Services                orders, market_data, balances, ...
  └── chain                   on-chain Funding helpers (not ConnectRPC)
```

Python ships **async** (`AsyncPolyester`) and **sync** (`Polyester`) clients with the same service tree. Prefer async for bots with streams.

Aliases: `client.candles` → `market_data`, `client.trading_withdraws` → `withdraw`. Account resolve is out of scope for API-key SDKs.

Services are accessed as attributes/fields on the client (`client.orders`, `client.market_data`, …). Catalog hydration usually starts on client create; wait before decimal writes that depend on scales.

Related: [Environments](https://testnet.polyester.com/docs/sdk/python/concepts/environments), [Client configuration](https://testnet.polyester.com/docs/sdk/python/reference/client-configuration), [Realtime](https://testnet.polyester.com/docs/sdk/python/reference/realtime).
