# Quickstart

Connect to testnet, read market data, stream trades, and place a test order.

About ten minutes on Polyester devnet: public reads, a live stream, then a place-and-cancel with an API key.

> **Prerequisites**
>
> [Install the SDK](https://testnet.polyester.com/docs/sdk/python/get-started/installation). Create an API key in the Polyester app (**API** in the sidebar). Copy the key id and private key when shown, the private key is only displayed once. Open the key's **Permissions**, enable **Spot trading**, choose the allowed markets, and set a maximum order size that covers this test. Copy your **Account ID** from Profile. The API-key SDK can use an assigned policy but cannot create or assign one.

1. Create a client

   ```python
   from polyester import AsyncPolyester

   async with AsyncPolyester(
       api_key_id="ak_...",
       api_private_key="...",  # 64-char hex from key creation
       default_account_id="...",  # Profile → Account ID
   ) as client:
       ...
   ```

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

2. Wait for catalogs

   Decimal order inputs need spot config scales. Wait before first write:

   ```python
   await client.wait_for_catalogs()
   ```

   See [Catalog & precision](https://testnet.polyester.com/docs/sdk/python/concepts/catalog-and-precision).

3. Read public market data

   ```python
   import asyncio
   from polyester import AsyncPolyester

   async def main() -> None:
       async with AsyncPolyester() as client:
           overview = await client.market_overview.list(limit=5)
           for market in overview.markets:
               print(market.symbol, market.last_price)

   asyncio.run(main())
   ```

4. Stream public trades

   ```python
   subscription = await client.market_data.subscribe_trades(symbol="BTC-USDT")
   async with subscription:
       async for trade in subscription:
           print(trade.price.ticks if trade.price else None)
           break
   ```

   Subscription queues are bounded. If your consumer falls behind, the SDK raises a realtime overflow error and faults the subscription, it does **not** silently drop updates. See [Streaming](https://testnet.polyester.com/docs/sdk/python/guides/streaming).

5. Place and cancel a limit order

   Your API key policy must allow Spot trading for `BTC-USDT`, and its maximum order size must cover the order below. Spot orders spend **trading** balance. Manage the policy from the key's **Permissions** page in the Polyester app.

   ```python
   from uuid import uuid4

   client_order_id = f"quickstart-{uuid4().hex[:20]}"
   result = await client.orders.create(
       symbol="BTC-USDT",
       side="buy",
       order_type="limit",
       tif="gtc",
       qty="0.001",
       price="50000",
       post_only=True,
       client_order_id=client_order_id,
   )
   print(result.status, result.order_id)  # status == "accepted" (admission ack)

   await client.orders.cancel(client_order_id=client_order_id)
   ```

Next: [Authentication](https://testnet.polyester.com/docs/sdk/python/guides/authentication) and [Trading](https://testnet.polyester.com/docs/sdk/python/guides/trading).
