Skip to content
Skip to main content

Account Types

TradeZero offers two account types: live and paper. Both live under the same base URL (https://webapi.tradezero.com), accept the same auth headers, and expose the same endpoint catalog. The API key pair you send is what selects the environment - paper keys hit paper, live keys hit live. There's no separate sandbox URL to remember and no environment flag to flip in your client.

Almost every workflow behaves identically between the two. The one substantive divergence is short locates, which require a live account. This page covers that exception, how to tell paper and live apart over the API, the paper-account lifecycle, what the portal exposes for each, and what changes when you're ready to move to live.

Paper vs live, at a glance

CapabilityPaperLive
REST API accessYesYes
WebSocket streaming (P&L, Portfolio)YesYes
Equities orders (market, limit, stop, stop-limit)YesYes
Multi-leg options orders (when options are enabled)YesYes
Short sellingYes - every symbol treated as easy-to-borrowYes - real ETB/HTB inventory
is-easy-to-borrow checkAlways returns trueReal classification
Locate quote / accept / cancel / sell-backReturns HTTP 200 with a Rejected status / no inventoryYes
Locate inventory & historyAlways empty ([])Yes
Real-time market data over APIComing soonComing soon
Starting balance$1,000,000 paper dollarsYour funded balance
Account expiration30 days (permanent if linked to a live account)None
Account-ID prefixAlways starts with TZPOpaque — use the server-issued accountType field instead of pattern-matching IDs

Locates are live-only

Locates require a live account

Locates allocate real borrow inventory and are fully supported on live accounts. On paper, the endpoints accept requests for integration testing, but quotes do not produce offerable inventory — see Short Locates for paper behavior details.

Paper accounts model short selling for order-flow testing: every symbol is treated as easy-to-borrow, and you can place short orders directly without a locate. Locate inventory and the quote → accept → sell-back workflow are available on live accounts.

If your integration uses locates, build the order side against paper, then move the locate-quote / accept / sell-back loop onto a live key pair to verify it works against the real borrow market.

Telling paper and live apart over the API

Every per-account detail response carries an accountType field. Paper accounts return accountType: "Paper". Live accounts typically return accountType: "Live", though specially-classified accounts can return other values (e.g. "Margin", "Cash"). Treat anything other than "Paper" as live.

Use this field. Paper account IDs often start with the TZP prefix — a portal convention — but live account IDs are opaque and should not be parsed. Read accountType from the API response so your client always targets the correct environment.

detail = client.get(f"/v1/api/account/{account_id}").json()
is_paper = detail.get("accountType") == "Paper"

The List All Your Accounts recipe walks through this end to end: list accounts, call the per-account detail endpoint in parallel when needed, then partition on accountType.

Paper account lifecycle

Starting balance. Every new paper account opens with $1,000,000 in paper money.

Lifespan. By default, a paper account is active for 30 days from creation. After that it's deactivated and you'd need to create a new one.

Make it permanent. If you link the paper account to your existing live TradeZero account in the portal, the paper account becomes permanent and never expires. This is the recommended setup for anyone using paper as a development sandbox alongside their live trading.

Reset. From the paper portal you can reset the account at any time. The balance returns to $1,000,000 and all positions, orders, and order history clear. Your API key pair keeps working - no need to regenerate keys after a reset.

Managing your accounts in the portal

Sign in at portal.tradezero.com/login with either a live or paper account. The portal recognizes the TZP prefix on paper account IDs and routes you to the paper-trading portal automatically; otherwise you land in the live portal.

From the paper portal you can:

  • Enable options on the paper account.
  • View and copy your API key pair and Trading API endpoint.
  • Reset the account back to a clean $1,000,000 balance with no positions or orders.

From the live portal you can also:

  • Send wires in and out of the account.
  • Enable options access and apply for higher option-trading levels (Level 2, Level 3).
  • Manage account settings, statements, market-data subscriptions, and the rest of the standard live-account toolset.

Market data is coming soon - on both environments

Neither paper nor live currently exposes real-time quotes, historical bars, or depth-of-market over the developer API. You can still place orders without that data — your client selects the route and the venue prices the order. For pre-trade logic that needs live quotes today, source market data from your preferred provider. Market-data endpoints for the developer API are coming soon.

Moving from paper to live

The migration story is small, because there's almost nothing to migrate:

  1. Swap the key pair. Replace your TZ-API-KEY-ID and TZ-API-SECRET-KEY env vars with the values from your live account's API Keys page. The base URL stays the same.
  2. Send explicit routes on live orders. Paper accounts auto-assign PAPER/PAPERM when you omit route; live accounts require an explicit route from GET /routes. Query /routes and include a matching routeName on every POST /order. See Get available routes.
  3. Verify your locate flow. Locates require a live account — plan to validate quote, accept, and sell-back on live before scaling short-side automation.
  4. Start small. Paper doesn't model market impact, queue position, partial-fill behavior, or borrow fees. Place a few small orders first to verify your assumptions hold against the real market.
  5. Guard live writes. If your tool can write to both environments, confirm accountType from the API before every mutating call: accountType === "Paper" when targeting paper, and accountType !== "Paper" when targeting live.

Where to next