Developers

API Overview

Public HTTP API for building bots and integrators against Amplifi — base URL, identifiers, concepts, errors, and rate limits.

This section describes every public HTTP flow a bot or external integrator needs to use Amplifi without the frontend: authenticate, fund a margin account, open and close leveraged positions on Polymarket outcome tokens, manage limit orders, and withdraw.

The frontend at https://amplifi.finance does not have privileged access — every flow documented here is exactly what the app performs against the same endpoints.

Base URL and transport

Production is reachable at https://amplifi.18.api.t1protocol.com (VM018). TLS termination is handled outside the app (Cloudflare → nginx → port 3000).

All requests/responses are JSON. Numeric on-chain values are returned as decimal strings in base units (USDC has 6 decimals, so "1000000" is one dollar). Decimal-string fields named *Formatted are pre-formatted for display only.

Identifiers

  • User address — a Polygon EOA the integrator controls. Used as the user identity across the entire API.
  • Deposit Wallet — an ERC-1967 proxy contract derived deterministically from the user EOA. Holds the user's pUSD and CTF shares. Created on demand by the relayer the first time the user calls POST /polymarket/wallet. The user EOA never holds pUSD or shares.
  • tokenId — Polymarket CLOB token ID (uint256 as decimal string). Each binary market has a YES tokenId and a NO tokenId.
  • conditionId — the CTF condition ID (bytes32 hex). Required when opening a position.

Concepts

  • Chain — everything runs on Polygon (chainId 137). The user funds with USDC.e (0x2791…); the protocol uses pUSD as its internal unit of account. Wrapping happens inside relayer batches; integrators only ever sign for USDC.e.
  • Isolated per-position margin — every leveraged position has its own loan from the lending pool and its own liquidation price. Losing one position cannot drain another. There is no cross-margin "Health Factor."
  • No user gas — Polymarket's relayer pays gas for every batch the protocol submits on behalf of the user (wallet create, deposits, opens, closes, withdrawals). The integrator only signs off-chain typed-data.
  • Relayer batching — position writes are asynchronous. POST /polymarket/positions/open returns immediately with status: PENDING; the position transitions PENDING → OPENING → OPEN | FAILED as the relayer batch lands. Poll GET /polymarket/positions/{id}/status until terminal.
  • Two auth modes for trade actions (see Authentication):
    1. Per-action EIP-712 signature (default): every open/close/cancel/withdraw is a fresh typed-data signature with a per-intent-type nonce.
    2. Trading session token: sign once for a session (up to 7 days), then send the token in x-trading-session and skip per-action signatures.

Where to go next

Errors

Errors are application/json with { "error": "human-readable message" } and a 4xx/5xx status. Known HttpError shapes preserve their message; unexpected errors return 500 { "error": "Internal error" } with no detail.

Rate limits

  • The global DDoS detector tracks 100 requests / 10s / IP and is configured but not currently enforced in production. Treat it as a soft guideline; expect it to be enabled if any one IP starts misbehaving.
  • POST /auth/submit-code is rate-limited to 10 attempts / 15 min / IP.
  • GET /polymarket/price/{token}, GET /polymarket/order-preview and the /ws/orderbook/{token} upgrade share one cap of 700 requests / 10 s / IP; past it they answer 429 { "error": "Too many requests. Wait a moment and try again.", "code": "RATE_LIMITED" }. A request carrying Authorization: Bearer <PARTNER_WS_API_KEY> is exempt, so an integrator proxying quotes from one egress IP is not cut off.

Idempotency and replay

  • All EIP-712 intents are nonce-protected. The same (intentType, nonce) cannot be replayed. Retry-on-error means: fetch a fresh nonce, sign again, resubmit.
  • POST /polymarket/bridge/deposit-confirmed is idempotent on (txHash, logIndex).
  • Position-open success means the request was accepted, not that the on-chain batch landed. Always poll …/status to terminal state.