> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.us/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Onboard a participant, place their first on-demand funded order, and sweep settled funds back.

<Note>
  **Audience: developers.** This is a hands-on, copy-paste guide. For eligibility, agreements, and the business setup, see [ISVs](/partners/partner-types/isvs) / [IBs](/partners/partner-types/ibs) and [Partner Onboarding](/partners/get-connected/onboarding).
</Note>

This guide walks the core partner loop end to end — the same three moves your production integration will repeat for every participant:

```mermaid theme={null}
flowchart LR
    A["1 · KYC"] --> B["2 · Funded order"] --> C["3 · Monitor"] --> D["4 · Sweep"]
```

By the end you'll have:

1. Authenticated with the API as your Firm — your only credential; every action after this is **on behalf of a participant**
2. Onboarded a Retail Participant via KYC and captured their trading account
3. Previewed and placed an **on-demand funded order** on their behalf
4. Seen where the money moves — and how settled funds sweep back

<Info>
  **Prerequisites:** Complete [Partner Onboarding](/partners/get-connected/onboarding) to receive your Client ID and register your public key, and have your **funding relationship** configured ([On-Demand Funding](/partners/funding/overview) is Beta, enabled per partner). This guide uses **pre-production** (`api.preprod.polymarketexchange.com`).
</Info>

## Step 1: Authenticate

Authentication uses **Private Key JWT** — you sign a JWT with your private key and exchange it for a short-lived access token. The full mechanism, claims, and key rotation are covered in the [Authentication](/partners/get-connected/authentication) guide; the complete, runnable token code is in the [full script](#complete-example) at the bottom of this page.

Once you have a token, set your auth header and confirm your identity with [`GET /v1/whoami`](/institutional/accounts/overview#endpoints):

```python theme={null}
import requests

BASE_URL = "https://api.preprod.polymarketexchange.com"
headers = {
    "Authorization": f"Bearer {access_token}",  # from the auth guide
    "Content-Type": "application/json",
}

resp = requests.get(f"{BASE_URL}/v1/whoami", headers=headers)
resp.raise_for_status()
print(f"Authenticated as: {resp.json()}")
```

Expected response:

```json theme={null}
{
  "user": "firms/ISV-Participant-Acme/users/admin",
  "userDisplayName": "Your Company",
  "firm": "ISV-Participant-Acme",
  "firmDisplayName": "Acme Trading",
  "firmType": "FIRM_TYPE_PARTICIPANT"
}
```

<Note>
  **Your Firm authenticates; it never trades.** The Firm identity above is a permissions container — it holds no funds and places no orders of its own. Every trading action in this guide is performed **on behalf of a Retail Participant**: participant-scoped REST calls (positions, reports) identify them with the `x-participant-id` header — see [Authentication → Acting on behalf of a participant](/partners/get-connected/authentication#acting-on-behalf-of-a-participant) — while funded orders carry the participant's **trading account** (`customer_account_id`) in the request body. You'll capture both identifiers in Step 2.
</Note>

## Step 2: Onboard a participant (KYC)

Before you can fund and place an order for a Retail Participant, they must pass KYC. Submit their identity data with [`POST /v1/kyc/start`](/partners/onboarding/kyc/verification-flow):

```python theme={null}
kyc = {
    "external_id": "user-123",           # your internal ID for this participant
    "ssn": "123456789",
    "first_name": "Jane",
    "last_name": "Smith",
    "date_of_birth": "1990-06-15",
    "email": "jane.smith@example.com",
    "phone_number": "+12125551234",
    "address": {
        "address_line_1": "123 Main St",
        "city": "New York",
        "state": "NY",
        "postal_code": "10001",
        "country": "US",
    },
    "agreement": {"version": "PMX.ISV.v1.0", "signed_at": "2026-04-24T14:30:00Z"},
    "ip_address": "203.0.113.42",        # the participant's IP
}

resp = requests.post(f"{BASE_URL}/v1/kyc/start", headers=headers, json=kyc)
resp.raise_for_status()
print(resp.json()["status"])  # decision path — see the decision matrix
```

The outcome may be instant approval, document verification, or manual review — handle each per the [decision matrix](/partners/onboarding/kyc/verification-flow#decision-matrix). **Approval is asynchronous**: the terminal outcome arrives on your registered [webhook](/partners/onboarding/kyc/webhooks) as a `kyc.approved` event, which carries the two identifiers you need:

* **`provisioned_participant`** (e.g. `firms/ISV-Participant-Acme/users/user-123`) — the `x-participant-id` value for participant-scoped REST calls.
* The participant's provisioned **trading account** — the `customer_account_id` for funded orders. You can also list accounts under your Firm at any time:

```python theme={null}
resp = requests.get(f"{BASE_URL}/v1/accounts", headers=headers)
resp.raise_for_status()
print(resp.json()["accounts"])
# ["firms/ISV-Participant-Acme/accounts/user-123-trading", ...]

customer_account_id = resp.json()["accounts"][0]
```

<Info>
  **No deposit step.** The account is provisioned with a **\$0 balance** and that's fine — on-demand funding moves the exact cost of each order into the account at placement time. The participant can trade the moment KYC clears.
</Info>

## Step 3: Pick a market

Funded orders identify markets by **slug**. Discover markets with the [Market API](/api-reference/market/overview), then confirm the one you want:

```python theme={null}
market_slug = "example-market-slug"

resp = requests.get(f"{BASE_URL}/v1/market/slug/{market_slug}", headers=headers)
resp.raise_for_status()
market = resp.json()
print(market["slug"], market["orderPriceMinTickSize"], market["minimumTradeQty"])
```

Use `orderPriceMinTickSize` and `minimumTradeQty` from the response to validate prices and quantities before submitting.

## Step 4: Preview the funded order

The funding API is **gRPC-only** ([`OrderFundingService`](/partners/funding/overview#api-surface)). [`PreviewFundedOrder`](/partners/funding/preview-funded-order) quotes the full prefund — collateral, exchange fee reserve, and your vendor fee — without moving funds, so you can show the participant the cost before they commit:

```python theme={null}
import grpc
from polymarket.us.orderfunding.v1 import order_funding_pb2, order_funding_pb2_grpc

channel = grpc.secure_channel("<grpc-endpoint>:443", grpc.ssl_channel_credentials())
stub = order_funding_pb2_grpc.OrderFundingServiceStub(channel)
metadata = [("authorization", f"Bearer {access_token}")]

order = order_funding_pb2.FundedOrder(
    market_slug=market_slug,
    type=order_funding_pb2.ORDER_TYPE_LIMIT,
    price=order_funding_pb2.MoneyAmount(value="0.45", currency="USD"),
    quantity="100",
    tif=order_funding_pb2.TIME_IN_FORCE_DAY,
    intent=order_funding_pb2.ORDER_INTENT_OPEN,
    outcome_side=order_funding_pb2.OUTCOME_SIDE_YES,
    action=order_funding_pb2.ORDER_ACTION_BUY,
    manual_order_indicator=order_funding_pb2.MANUAL_ORDER_INDICATOR_MANUAL,  # human-entered
)

preview = stub.PreviewFundedOrder(
    order_funding_pb2.PreviewFundedOrderRequest(
        order=order,
        customer_account_id=customer_account_id,   # from Step 2
        vendor_fee=order_funding_pb2.MoneyAmount(value="0.10", currency="USD"),
    ),
    metadata=metadata,
)

cb = preview.cost_breakdown
print(f"collateral={cb.collateral.value} exchange_fee={cb.exchange_fee.value} "
      f"vendor_fee={cb.vendor_fee.value} total_prefund={cb.total_prefund.value}")
```

Preview is informational — placement recomputes all economics. See the [cost model](/partners/funding/overview#cost-model) for how each component is calculated.

## Step 5: Place the funded order

[`CreateFundedOrder`](/partners/funding/create-funded-order) transfers the total prefund from your partner funding account into the participant's account and submits the order — one idempotent call:

```python theme={null}
import uuid

idempotency_key = str(uuid.uuid4())   # persist this BEFORE sending, so you can retry safely

result = stub.CreateFundedOrder(
    order_funding_pb2.CreateFundedOrderRequest(
        order=order,
        customer_account_id=customer_account_id,
        vendor_fee=order_funding_pb2.MoneyAmount(value="0.10", currency="USD"),
        idempotency_key=idempotency_key,
    ),
    metadata=metadata,
)
print(result.status, result.id, result.funding_request_id)
```

Handle the three outcomes:

| Status                         | Meaning                                                                                       | What you do                                               |
| ------------------------------ | --------------------------------------------------------------------------------------------- | --------------------------------------------------------- |
| `FUNDED_ORDER_STATUS_ACCEPTED` | Order durably reached the book (or matched). Prefund stays in the participant account.        | Show the order as live; track fills.                      |
| `FUNDED_ORDER_STATUS_REJECTED` | Order never reached the book. The prefund was automatically reversed to your funding account. | Surface the rejection; nothing to clean up.               |
| `FUNDED_ORDER_STATUS_PENDING`  | Outcome not confirmed within the deadline.                                                    | Retry with the **same** `idempotency_key` until terminal. |

On transport errors (`UNAVAILABLE`, timeouts), also retry with the **same key** — it can never double-fund or double-place. See [idempotency and retries](/partners/funding/create-funded-order#idempotency-and-retries).

## Step 6: Watch the money

Every cash movement is visible in real time — this is how your backend knows what happened and when funds become sweepable:

* The **prefund transfer** (and any compensating reversal) appears on the [Balance Ledger Stream](/streaming-endpoints/balance-ledger-stream) for the participant account and your funding account.
* **Fills** arrive on the [Drop Copy Stream](/streaming-endpoints/dropcopy-stream); per-execution fee collection and settlement credits land on the ledger.
* Log the `correlation` identifiers (`idempotency_key`, `funding_request_id`, `request_id`) from every response — they tie ledger entries back to orders.

## Step 7: Sweep settled funds back

After fills settle, cancels release collateral, or positions close, cash accumulates in the participant's account — **it does not move back automatically**. Your backend watches the ledger, determines the sweepable amount per your agreements, and initiates a **sweep** back to the partner funding account. See [settlement and sweeps](/partners/funding/overview#after-acceptance-settlement-and-sweeps) for the lifecycle, and [Settlement Sweeps](/partners/funding/sweeps) for the planned sweep API contract.

<Warning>
  **Settlement sweeps are part of the beta rollout.** The sweep API is not yet available — its planned contract is on [Settlement Sweeps](/partners/funding/sweeps). Contact [institutional@polymarket.us](mailto:institutional@polymarket.us) for availability.
</Warning>

## Complete example

A single runnable script covering the funded-order path — including the full token exchange (see the [Authentication](/partners/get-connected/authentication) guide for an explanation of each claim). KYC is omitted because its terminal outcome arrives on your webhook; run Step 2 once and plug in the resulting account:

```python theme={null}
#!/usr/bin/env python3
"""Polymarket US partner quickstart — preview and place a funded order."""

import jwt
import uuid
import time
import grpc
import requests
from cryptography.hazmat.primitives import serialization

from polymarket.us.orderfunding.v1 import order_funding_pb2, order_funding_pb2_grpc

# Configuration (from Partner Onboarding)
AUTH_DOMAIN = "pmx-preprod.us.auth0.com"
CLIENT_ID = "your_client_id"
AUDIENCE = "https://api.preprod.polymarketexchange.com"
PRIVATE_KEY_PATH = "private_key.pem"
BASE_URL = "https://api.preprod.polymarketexchange.com"
GRPC_ENDPOINT = "<grpc-endpoint>:443"

# From Step 2 (kyc.approved webhook / GET /v1/accounts) and Step 3
CUSTOMER_ACCOUNT_ID = "firms/ISV-Participant-Acme/accounts/user-123-trading"
MARKET_SLUG = "example-market-slug"


def get_access_token():
    with open(PRIVATE_KEY_PATH, "rb") as f:
        private_key = serialization.load_pem_private_key(f.read(), password=None)

    now = int(time.time())
    claims = {
        "iss": CLIENT_ID,
        "sub": CLIENT_ID,
        "aud": f"https://{AUTH_DOMAIN}/oauth/token",
        "iat": now,
        "exp": now + 300,
        "jti": str(uuid.uuid4()),
    }
    assertion = jwt.encode(claims, private_key, algorithm="RS256")

    response = requests.post(
        f"https://{AUTH_DOMAIN}/oauth/token",
        json={
            "client_id": CLIENT_ID,
            "client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
            "client_assertion": assertion,
            "audience": AUDIENCE,
            "grant_type": "client_credentials",
        },
    )
    response.raise_for_status()
    return response.json()["access_token"]


def main():
    token = get_access_token()
    headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}

    # Verify identity
    resp = requests.get(f"{BASE_URL}/v1/whoami", headers=headers)
    resp.raise_for_status()
    print(f"Logged in as: {resp.json()}")

    # Confirm the market
    resp = requests.get(f"{BASE_URL}/v1/market/slug/{MARKET_SLUG}", headers=headers)
    resp.raise_for_status()
    print(f"Trading market: {resp.json()['slug']}")

    # gRPC channel for the funding API
    channel = grpc.secure_channel(GRPC_ENDPOINT, grpc.ssl_channel_credentials())
    stub = order_funding_pb2_grpc.OrderFundingServiceStub(channel)
    metadata = [("authorization", f"Bearer {token}")]

    order = order_funding_pb2.FundedOrder(
        market_slug=MARKET_SLUG,
        type=order_funding_pb2.ORDER_TYPE_LIMIT,
        price=order_funding_pb2.MoneyAmount(value="0.45", currency="USD"),
        quantity="100",
        tif=order_funding_pb2.TIME_IN_FORCE_DAY,
        intent=order_funding_pb2.ORDER_INTENT_OPEN,
        outcome_side=order_funding_pb2.OUTCOME_SIDE_YES,
        action=order_funding_pb2.ORDER_ACTION_BUY,
        manual_order_indicator=order_funding_pb2.MANUAL_ORDER_INDICATOR_MANUAL,
    )
    vendor_fee = order_funding_pb2.MoneyAmount(value="0.10", currency="USD")

    # Preview the cost
    preview = stub.PreviewFundedOrder(
        order_funding_pb2.PreviewFundedOrderRequest(
            order=order,
            customer_account_id=CUSTOMER_ACCOUNT_ID,
            vendor_fee=vendor_fee,
        ),
        metadata=metadata,
    )
    cb = preview.cost_breakdown
    print(f"Prefund: collateral={cb.collateral.value} exchange_fee={cb.exchange_fee.value} "
          f"vendor_fee={cb.vendor_fee.value} total={cb.total_prefund.value}")

    # Fund and place — persist the key first so a crash can be retried safely
    idempotency_key = str(uuid.uuid4())
    result = stub.CreateFundedOrder(
        order_funding_pb2.CreateFundedOrderRequest(
            order=order,
            customer_account_id=CUSTOMER_ACCOUNT_ID,
            vendor_fee=vendor_fee,
            idempotency_key=idempotency_key,
        ),
        metadata=metadata,
    )
    print(f"Status: {order_funding_pb2.FundedOrderStatus.Name(result.status)}")
    print(f"Order ID: {result.id}  funding_request_id: {result.funding_request_id}")


if __name__ == "__main__":
    main()
```

**Required packages:**

```bash theme={null}
pip install PyJWT cryptography requests grpcio
```

The `polymarket.us.orderfunding.v1` stubs are generated from the funding API protos provided during beta enablement — contact [institutional@polymarket.us](mailto:institutional@polymarket.us) if you don't have them.

## Next steps

<CardGroup cols={2}>
  <Card title="On-Demand Funding" icon="building-columns" href="/partners/funding/overview">
    The full model — parties, cost model, sweeps, and reconciliation.
  </Card>

  <Card title="KYC Verification" icon="id-card" href="/partners/onboarding/kyc/overview">
    All four verification outcomes and webhook handling.
  </Card>

  <Card title="Balance Ledger Stream" icon="scale-balanced" href="/streaming-endpoints/balance-ledger-stream">
    Track every prefund, fill, and settlement credit in real time.
  </Card>

  <Card title="Authentication" icon="key" href="/partners/get-connected/authentication">
    Token refresh, key rotation, and scopes.
  </Card>
</CardGroup>
