@marketry/sdk

Typed HTTP client for paper trading. Authenticated routes use mkt_live_ keys; platform routes are public.

Reference bots
23
Open source
MIT
API routes
19
Zero risk
Paper

Install

shell
1# Monorepo (today — private workspace)2$ git clone https://github.com/Wkamfar/arc.git3$ cd arc && npm install4# @marketry/sdk and @marketry/bot-lab resolve via workspaces5 6# When published to npm (public repo):7# npm install @marketry/sdk8# npm install @marketry/bot-lab9 10# Pin version in production:11# npm install @marketry/sdk@0.1.0

Monorepo today

Packages resolve via npm workspaces while the repo is private. No npm publish required for local development.

When the repo goes public

shell
1# Today: monorepo workspaces (private repo)2$ npm install3# imports resolve: @marketry/sdk, @marketry/bot-lab4 5# When the repo is public on GitHub:6$ npm install @marketry/sdk7$ npm install @marketry/bot-lab8 9# Or link locally while developing bots:10$ npm link ../marketry/packages/sdk

OpenAPI

OpenAPI 3.1

Generated from shared Zod schemas in src/lib/api/schemas.ts. Regenerate with npm run openapi:generate.

shell
$ curl -s http://localhost:3000/api/openapi | jq '.info'

Authentication

path
1// Authorization header (preferred)2Authorization: Bearer mkt_live_your_key_here3 4// Alternative header5X-Api-Key: mkt_live_your_key_here
typescript
1import { createClientFromEnv, isMarketryError } from "@marketry/sdk";2 3const client = createClientFromEnv();4 5// Pick the top active market — same pattern as hello-trade6const [market] = await client.markets.list({ status: "active", limit: 1 });7if (!market) throw new Error("No active markets");8 9const price = Math.min(0.65, market.probability + 0.02);10 11try {12  const order = await client.orders.create({13    marketId: market.id,14    outcome: "yes",15    price,16    quantity: 5,17  });18  console.log("Filled on:", market.title, order);19} catch (e) {20  if (isMarketryError(e)) {21    console.error(e.status, e.message);22  }23  throw e;24}

SDK v2

Master automation key

Create a master-permission key in Portfolio → Sub-accounts → Automation key. Use for programmatic fleet setup. See External developer guide.

shell
1# Master automation key — fleet management without browser2$ export MARKETRY_URL=http://localhost:30003$ export MARKETRY_MASTER_KEY=mkt_live_paste_from_portfolio_automation4 5$ curl -s -H "Authorization: Bearer $MARKETRY_MASTER_KEY" \6$   http://localhost:3000/api/accounts/sub | jq '.subAccounts | length'7 8# Create sub-account programmatically:9$ curl -s -X POST -H "Authorization: Bearer $MARKETRY_MASTER_KEY" \10$   -H "Content-Type: application/json" \11$   -d '{"displayName":"Atlas"}' \12$   http://localhost:3000/api/accounts/sub | jq '.apiKey.rawKey'

SDK v2

Platform & live stream

Public endpoints — no API key. Use after hello-trade to find your bot on the leaderboard or build a live dashboard.

typescript
1// Public platform data — no API key (SDK v2)2const board = await client.platform.leaderboard();3const tape = await client.platform.recentTrades();4const pulse = await client.platform.activity();5 6// SSE stream (browser / Node 18+ with EventSource)7const stop = client.stream.subscribe({8  onEvent: (evt) => {9    console.log(evt.ts, evt.markets.length, "markets");10  },11});12// stop();

API

System

typescript
await client.health.check()
typescript
fetch('/api/openapi')

API

Markets & signals

typescript
1const markets = await client.markets.list({2  status: "active",3  sector: "tech",4  limit: 20,5});
typescript
await client.markets.get("nvda-dc-q1fy27")
typescript
await client.markets.orderbook(market.id)
typescript
const signals = await client.markets.signals()

API

Orders

typescript
1await client.orders.create({2  marketId: market.id,3  outcome: "yes",4  side: "buy",5  price: 0.52,6  quantity: 10,7})
typescript
await client.orders.list({ marketId: "optional-filter" })
typescript
await client.orders.cancel(orderId)

API

Portfolio

typescript
const pf = await client.portfolio.get()
typescript
await client.positions.list()

API

Sub-accounts

typescript
1await client.accounts.sub.create({2  displayName: "My Momentum Bot",3  permissions: ["view", "trade"],4})
typescript
await client.accounts.sub.list()
typescript
1await client.accounts.sub.createKey(subId, {2  name: "Rotation key",3  permissions: ["view", "trade"],4})
typescript
await client.accounts.keys.revoke(keyId)

API

Platform (public)

typescript
await client.platform.leaderboard()
typescript
await client.platform.recentTrades()
typescript
await client.platform.activity()
typescript
1const stop = client.stream.subscribe({2  onEvent: (evt) => console.log(evt.markets),3});

Error handling

typescript
1import { createClientFromEnv, isMarketryError } from "@marketry/sdk";2 3try {4  await client.orders.create({ /* … */ });5} catch (e) {6  if (isMarketryError(e)) {7    switch (e.status) {8      case 401:9        console.error("Check MARKETRY_API_KEY");10        break;11      case 403:12        console.error("Permission or KYC:", e.message);13        break;14      default:15        console.error(e.status, e.message);16    }17  }18  throw e;19}
HTTPMessage
401Not authenticated
401API key required for orders.create()…
403Forbidden
403Switch to your primary account…
400Insufficient balance
400Market is not active