Skip to main content
PredictStreet’s integrator API is server-to-server only. Every authenticated endpoint takes a single header — X-Api-Key — backed by a per-partner secret your ops contact hands you at onboarding. There is no OAuth, no SIWE, no cookie session. Public read endpoints (markets / events / matches / tags) need no key. They are rate-limited per source IP, so sending a key does not change their limit.

First time here?

1

Get an API key

Partner keys are issued by PredictStreet ops, never self-service. Email your integration manager (or partners@predictstreet.com) with the items listed in API keys → Getting a key: partner name, contact email, partner kind (single_wallet or multi_wallet), associated wallet (the EOA you’ll sign EIP-712 orders with; required for single_wallet write keys), and the scopes you need.
2

Walk through the testnet quickstart

Quickstart walks the private key of your associatedWallet through five steps — mint test USDC, get your vault address, approve and deposit, sign and place orders, and split USDC into YES + NO so you can sell. Every code block is real ethers v6 against the live testnet; copy-paste, swap your secrets, run.
3

Mental model — Wallet, vault, scopes

A single_wallet key is bound at issue time to one associated wallet — the EOA whose private key you hold and which signs EIP-712 orders. A multi_wallet key is not bound to a wallet: you name the acting wallet on every request with the X-User-Wallet header. Each acting wallet has its own vault contract that holds your USDC and your outcome shares; the vault is the maker field of every signed Order. The platform deploys vaults for you when the wallet is onboarded (see Backend auto-deploy) — for multi_wallet partners without per-wallet KYC, on the wallet’s first API request — so you never call VaultFactory.deployVault() yourself. Scopes on the key gate which endpoint groups the key can hit (orders:write, portfolio:read, vault:write, public reads). The full mental model lives at Platform overview; the concept pages on Vaults and Deposits round it out.

Authentication on the playground

Every locked endpoint shows a lock icon with ApiKey. To enable Try-it-out:
  1. Click Authorize.
  2. Paste the full key (e.g. ps_live_0123456789abcdef_AbCdEfGhIjKlMnOpQrStUvWxYz1234567) into the X-Api-Key field.
  3. The key persists across endpoint pages in your browser session.
Scopes are enforced server-side — your key must carry the scope listed on the operation (orders:write, portfolio:read, etc.) or the request returns 403 api_key_scope_missing. For multi-wallet partners (one key dispatching N actor wallets), set the X-User-Wallet header on every request to the actor wallet the call should run as. Single-wallet partners ignore that header — the key’s static associatedWallet is used unconditionally. See Partner kinds for the full distinction. See API keys for format, full scope taxonomy, endpoint coverage table, rate-limit buckets, and rotation procedure.

Endpoint groups

Use the left sidebar to browse. The Scope column lists the API-key scope each group requires — write scopes (orders:write, vault:write) are issued to a single_wallet key only once its associatedWallet has cleared KYC tier 1. For multi_wallet partners the check moves to request time: each X-User-Wallet must clear KYC itself unless the partner has requirePerWalletKyc: false; see Partner kinds. Surfaces that require a signed-in retail user session (user profile, KYC submission, consent management, responsible-gambling, session management) live on the retail web surface — the web app at app.dev.predictstreet.sde.adifoundation.ai on testnet, adipredictstreet.com on mainnet — and are intentionally not exposed to integrators. The SUMSUB / geo-fingerprinting layer expects a live retail session for those flows. Partners who need a use case currently outside the API-key surface should reach out — some can be unlocked with a stricter scope set, others are architecturally out of scope.

Conventions

  • Base URL: https://core.api.dev.predictstreet.sde.adifoundation.ai (testnet). Staging and mainnet URLs delivered at partner onboarding.
  • Numeric fields are encoded as strings to preserve precision (e.g. "price": "0.52", not 0.52). Deserialize into decimal.Decimal / BigDecimal / ethers.parseUnits — not Number.
  • Timestamps are ISO-8601 UTC (e.g. "2026-04-22T10:31:05.124Z").
  • Errors share a common envelope: { status, error: { code, message, trace_id?, retryAfterSec?, retryable?, details? } }. Switch on error.code. See Errors overview and Error codes for the full catalogue.
  • Rate limits — each endpoint applies a per-IP bucket, a per-wallet bucket, or both (the /api/v1/partner/* feeds are also bucketed per partner); see Rate limits.
  • Pagination — list endpoints use endpoint-specific offset, page-number, cursor, or time-cursor pagination. See Pagination for the complete endpoint matrix and limits.
  • Business rejects on some endpoints return HTTP 200 (or 201 for POSTs) with a status: "REJECTED" + code field inside the response envelope — notably POST /api/orders/place, which returns 201 Created even when the matcher rejects the order. Always read the body’s status field, not just the HTTP code. Full catalogue in Errors overview.
  • Enum query params reject unknown values with HTTP 400 instead of returning an empty page; the code is endpoint-specific. For example, ?status=CANCELED (one L) on /api/orders/history returns invalid_request (the failing field is in error.details.fields), and an unknown ?interval= on /api/markets/{symbol}/ohlc returns invalid_interval with the accepted values in error.details.allowed.
  • Unknown query params — handling is endpoint-specific. /api/orders/open, /api/orders/history, /api/v1/partner/trades, /api/v1/partner/mm-kpis and /api/v1/partner/reconciliation/snapshot reject any parameter they don’t define with 400 invalid_request. /api/events rejects offset, cursor, skip, start and pageSize with a 400. Other endpoints currently ignore unknown parameters. Send only the parameters documented for each endpoint.
  • Address case — compare addresses case-insensitively. Most responses return lowercase addresses, but some fields are EIP-55 checksum-cased — for example walletAddress on /api/leaderboard and makerWallet / takerWallet on /api/markets/{symbol}/trades. Lowercase both sides before comparing. Request bodies and headers accept either case.
  • Order id field — created via POST /api/orders/place returns the identifier under orderId; the same value surfaces under id on GET /api/orders/{id}, GET /api/orders/open, and GET /api/orders/history. The cancel request body uses orderId to match the placement response. Treat both names as the same value — the variance is request-vs-response convention, not a different identifier. Without the id (for example after a place request timed out), GET /api/orders/lookup finds the order by your clientOrderId or its EIP-712 orderHash.
  • Standard response headers — every response carries these beyond the rate-limit triple already documented in Rate limits:
    • X-API-Version — additive version tag (2026-04-01 today). Breaking changes go to /api/v2/*; the header lets a client pin behaviour without parsing URLs.
    • X-Server-Time — server wall-clock in ms epoch, stamped when the request is received, before it is processed. The WebSocket companion is the serverTs field stamped on every outbound frame; compare the two to order events across the transports. The response body may already reflect events stamped slightly after X-Server-Time.
    • X-Request-Id — unique per-request identifier echoed in audit logs. Include it when filing a support ticket so ops can correlate end-to-end. All three are in the CORS Access-Control-Expose-Headers allowlist so browser clients can read them on cross-origin responses.

Where to go next

API keys — format, scopes, rotation

The canonical reference for the auth header, scope taxonomy, multi_wallet vs single_wallet kinds, and key rotation procedure.

Quickstart — testnet end-to-end

Five-step copy-paste from API key to deposited, trading vault against the live testnet.

Vaults — what they are + how they deploy

Why every partner has a vault, how auto-deploy works, what Order.maker should be, and when you’d ever deploy manually.

EIP-712 signing — Order struct + domain

The 11-field Order struct, the binary vs neg-risk verifyingContract swap, and end-to-end signing examples.