Skip to main content
Paper account management endpoints require a server-side x-app-api-key or admin key. Never call them from the browser.
Use the paper account management APIs when your backend needs to manage server-side paper accounts for user simulators, QA runs, and automated test fixtures. This is separate from the normal browser execution path in Paper Trading, where users sign in and trade through the regular balances, route, fill, positions, and orders flow with mode: "paper". Server-side paper accounts let your backend create known accounts, reset cash before a QA run, place direct simulated orders, and inspect portfolio state. They still use simulated funds only: no venue submits, bridges, custody transfers, deposits, withdrawals, or redemptions run from this surface.

API Reference

Use the SDK methods below for implementation. Each method maps to a dedicated API reference page with the full request and response schema.
SDK methodAPI reference
createPaperTradingAccountCreate a paper trading account
listPaperTradingAccountsList paper trading accounts
getPaperTradingAccountGet a paper trading account
setPaperTradingBalanceSet a paper trading account cash balance
resetPaperTradingAccountReset a paper trading account
placePaperTradingOrderPlace a paper trading order
listPaperTradingPositionsList paper trading positions
listPaperTradingOrdersList paper trading orders
getPaperTradingPortfolioGet a paper trading portfolio

Create A Server Client

import { createAggClient } from "@agg-build/sdk";

const agg = createAggClient({
  baseUrl: process.env.AGG_API_BASE_URL!,
  appId: process.env.AGG_APP_ID!,
  apiKey: process.env.AGG_APP_API_KEY!, // server-side only
});

Seed A User’s Paper Account

Normal browser paper mode uses externalId = user:<aggUserId>. If you create or reset that account from your backend, the same signed-in user will see the seeded balance in EventMarketPage, PlaceOrder, and UserProfilePage.
const aggUserId = "usr_...";

const account = await agg.createPaperTradingAccount({
  name: "QA paper account",
  externalId: `user:${aggUserId}`,
  initialBalanceRaw: "100000000", // 100.000000 PAPER_USD
});
If the account already exists, create returns a validation error because externalId is unique per app. For repeatable test runs, store the returned account.id, list accounts from your backend, or keep the mapping in your own user table.

Reset Or Set Cash

Use resetPaperTradingAccount before each QA scenario or user-initiated simulator reset when you want a clean position book. Use setPaperTradingBalance when you only want to change cash.
await agg.resetPaperTradingAccount(account.id, {
  balanceRaw: "250000000", // 250.000000 PAPER_USD
  reason: "Reset before QA run",
});

await agg.setPaperTradingBalance(account.id, {
  balanceRaw: "50000000", // 50.000000 PAPER_USD
  reason: "Low-balance test case",
});
Raw amounts use 6 decimals. You can pass initialBalance, balance, or spend as numbers for convenience, but raw strings are better for deterministic fixtures.

Place A Direct Simulated Order

Direct paper orders are useful for building known positions before a UI test. They simulate against the current order book and return either a filled or rejected paper order.
const order = await agg.placePaperTradingOrder(account.id, {
  venueMarketOutcomeId: "vmo_...",
  side: "buy",
  spendRaw: "25000000",
  slippageBps: 100,
  clientOrderId: "qa-run-123-buy-1",
});

if (order.status === "rejected") {
  console.log(order.rejectionReason);
}
clientOrderId is stored for your own traceability. Do not treat it as an idempotency key unless your backend enforces that behavior.

Fixture Strategies

For execution tests, paper account management gives your backend deterministic starting state while the browser still uses the normal mode: "paper" execution flow.
  • Reset the user’s user:<aggUserId> paper account before a test that needs known cash and no open positions.
  • Set cash without clearing positions when testing low-balance or balance-display states.
  • Place direct simulated orders to create known positions before a profile, portfolio, or sell-flow test.
  • Read portfolio, positions, and orders after the browser flow runs to assert final state from the server side.
  • Use clientOrderId values owned by the test scenario so your logs can distinguish fixture orders from user-created paper orders.

Inspect Portfolio State

const portfolio = await agg.getPaperTradingPortfolio(account.id);
const positions = await agg.listPaperTradingPositions(account.id, { limit: 50 });
const orders = await agg.listPaperTradingOrders(account.id, { limit: 50 });

console.log(portfolio.equity, portfolio.unrealizedPnl, positions.data, orders.data);

Operational Notes

  • Paper accounts are scoped to one AGG app.
  • Paper mode creates user accounts lazily, so your backend can seed first or let the first browser paper call create the account.
  • Reset clears open paper positions and cash P&L; order history remains useful for audit and debugging.
  • Paper fills do not submit to live venues and do not trigger deposits, withdrawals, bridges, custody operations, or settlement redemption.
  • Hide funding, withdrawal, and redemption UI when a user is operating only in paper mode.