> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Fund Your Account
> Deposit and withdraw pUSD collateral for Perps trading
Fund the Perps account with pUSD before placing orders. Deposits move pUSD from
the user's Polymarket wallet into the Perps account. Withdrawals move available
pUSD back to the authenticated wallet.
## Deposit Collateral
Deposit pUSD when the account needs collateral for opening or maintaining Perps
positions.
Create a `SecureClient` for the wallet that will fund the Perps account. If you
already have a Polymarket wallet, pass it as `wallet` and include a Relayer API
key so the SDK can submit gasless transactions. If you are creating a wallet
programmatically, use a Builder API key so the SDK can create the Deposit Wallet
for that signer.
```ts Existing Account theme={null}
import { createSecureClient, relayerApiKey } from "@polymarket/client";
import { privateKey } from "@polymarket/client/viem";
const client = await createSecureClient({
wallet: process.env.POLYMARKET_WALLET_ADDRESS!,
signer: privateKey(process.env.PRIVATE_KEY!),
apiKey: relayerApiKey({
key: process.env.RELAYER_API_KEY!,
address: process.env.RELAYER_API_KEY_ADDRESS!,
}),
});
```
```ts New Programmatic Wallet theme={null}
import { createSecureClient } from "@polymarket/client";
import { builderApiKey } from "@polymarket/client/node";
import { privateKey } from "@polymarket/client/viem";
const client = await createSecureClient({
signer: privateKey(process.env.PRIVATE_KEY!),
apiKey: builderApiKey({
key: process.env.BUILDER_API_KEY!,
secret: process.env.BUILDER_SECRET!,
passphrase: process.env.BUILDER_PASSPHRASE!,
}),
});
```
Set up the approvals required for Perps collateral deposits. The SDK skips work
that is already complete.
```ts theme={null}
await client.setupTradingApprovals();
```
Deposit pUSD from the user's Polymarket wallet into the Perps account. Make sure
the wallet has pUSD before depositing. The minimum Perps deposit is 10 pUSD.
Amounts use raw pUSD base units, so 10 pUSD is `10_000_000n`.
```ts theme={null}
const deposit = await client.depositToPerps({
amount: 10_000_000n,
});
const receipt = await deposit.wait();
// receipt.transactionHash: TxHash
```
`deposit.wait()` confirms that the chain transaction settled. Perps may take a
moment to credit the account after that.
Open a Perps session and read account state after the deposit settles.
```ts theme={null}
const session = await client.openPerpsSession();
try {
const portfolio = await session.fetchPortfolio();
const deposits = await session.listDeposits().firstPage();
} finally {
await session.close();
}
```
Use `portfolio.withdrawable` to check available collateral and `deposits.items`
to reconcile deposit history.
Create an `AsyncSecureClient` for the wallet that will fund the Perps account.
If you already have a Polymarket wallet, pass it as `wallet` and include a
Relayer API key so the SDK can submit gasless transactions. If you are creating a
wallet programmatically, use a Builder API key so the SDK can create the Deposit
Wallet for that signer.
```python Existing Account theme={null}
import os
from polymarket import AsyncSecureClient, RelayerApiKey
client = await AsyncSecureClient.create(
private_key=os.environ["PRIVATE_KEY"],
wallet=os.environ["POLYMARKET_WALLET_ADDRESS"],
api_key=RelayerApiKey(
key=os.environ["RELAYER_API_KEY"],
address=os.environ["RELAYER_API_KEY_ADDRESS"],
),
)
```
```python New Programmatic Wallet theme={null}
import os
from polymarket import AsyncSecureClient, BuilderApiKey
client = await AsyncSecureClient.create(
private_key=os.environ["PRIVATE_KEY"],
api_key=BuilderApiKey(
key=os.environ["BUILDER_API_KEY"],
secret=os.environ["BUILDER_SECRET"],
passphrase=os.environ["BUILDER_PASSPHRASE"],
),
)
```
Set up the approvals required for Perps collateral deposits. The SDK skips work
that is already complete.
```python theme={null}
await client.setup_trading_approvals()
```
Deposit pUSD from the user's Polymarket wallet into the Perps account. Make sure
the wallet has pUSD before depositing. The minimum Perps deposit is 10 pUSD.
Amounts use raw pUSD base units, so 10 pUSD is `10_000_000`.
```python theme={null}
deposit = await client.deposit_to_perps(amount=10_000_000)
receipt = await deposit.wait()
# receipt.transaction_hash: TransactionHash
```
`deposit.wait()` confirms that the chain transaction settled. Perps may take a
moment to credit the account after that.
Open a Perps session and read account state after the deposit settles.
```python theme={null}
session = await client.open_perps_session()
try:
portfolio = await session.fetch_portfolio()
deposits = await session.list_deposits().first_page()
finally:
await session.close()
```
Use `portfolio.withdrawable` to check available collateral and `deposits.items`
to reconcile deposit history.
Before depositing, the Polymarket wallet must approve the Perps deposit contract
to spend pUSD. If the approval is already in place, skip the approval call.
```solidity Approval Call theme={null}
pUSD.approve(PerpsDepositContract, maxUint256)
```
Use these contract addresses when building the approval call.
| Contract | Address |
| ---------------------- | -------------------------------------------- |
| pUSD collateral token | `0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB` |
| Perps deposit contract | `0xDCa4af75705dbB50f62437045afF9921947917d2` |
The following steps show the Deposit Wallet batch path. If you are trading
with a Safe or Poly Proxy wallet, use an SDK that handles the wallet-specific
transaction flow for you.
Create the Perps deposit call. Deposit amounts use pUSD base units, so 10 pUSD
is `10000000`.
```solidity theme={null}
function deposit(address token, uint256 amount, address to);
```
Encode the deposit calldata with these arguments.
| Argument | Value |
| -------- | -------------------------------------------- |
| `token` | `0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB` |
| `amount` | `10000000` |
| `to` | Signer address for the Polymarket account. |
Build the final ordered call list. Include the approval call first only when
approval is needed.
```json Without Approval theme={null}
[
{
"target": "0xDCa4af75705dbB50f62437045afF9921947917d2",
"value": "0",
"data": ""
}
]
```
```json With Approval theme={null}
[
{
"target": "0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB",
"value": "0",
"data": ""
},
{
"target": "0xDCa4af75705dbB50f62437045afF9921947917d2",
"value": "0",
"data": ""
}
]
```
Fetch a fresh `WALLET` nonce before submitting the Deposit Wallet batch.
```bash theme={null}
curl -G "https://relayer-v2.polymarket.com/v1/account/transactions/params" \
-H "RELAYER_API_KEY: $RELAYER_API_KEY" \
-H "RELAYER_API_KEY_ADDRESS: $RELAYER_API_KEY_ADDRESS" \
--data-urlencode "address=" \
--data-urlencode "type=WALLET"
```
The response includes the nonce to sign with the batch.
```json theme={null}
{
"address": "",
"nonce": ""
}
```
Build the EIP-712 `Batch` typed data for the Deposit Wallet. Use the final
ordered call list from the previous step, and omit the approval call when
allowance is already sufficient. Set `deadline` to a Unix timestamp in seconds
after which the relayer should reject the batch.
```json theme={null}
{
"domain": {
"name": "DepositWallet",
"version": "1",
"chainId": 137,
"verifyingContract": ""
},
"primaryType": "Batch",
"types": {
"Call": [
{ "name": "target", "type": "address" },
{ "name": "value", "type": "uint256" },
{ "name": "data", "type": "bytes" }
],
"Batch": [
{ "name": "wallet", "type": "address" },
{ "name": "nonce", "type": "uint256" },
{ "name": "deadline", "type": "uint256" },
{ "name": "calls", "type": "Call[]" }
]
},
"message": {
"wallet": "",
"nonce": "",
"deadline": "",
"calls": [
{
"target": "0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB",
"value": "0",
"data": ""
},
{
"target": "0xDCa4af75705dbB50f62437045afF9921947917d2",
"value": "0",
"data": ""
}
]
}
}
```
Sign this typed data with the signer for the Polymarket account.
Submit the signed batch to the Relayer API. Use the same ordered call list you
signed in the previous step.
```bash theme={null}
curl -X POST "https://relayer-v2.polymarket.com/submit" \
-H "Content-Type: application/json" \
-H "RELAYER_API_KEY: $RELAYER_API_KEY" \
-H "RELAYER_API_KEY_ADDRESS: $RELAYER_API_KEY_ADDRESS" \
-d '{
"type": "WALLET",
"from": "",
"to": "0x00000000000Fb5C9ADea0298D729A0CB3823Cc07",
"nonce": "",
"signature": "",
"metadata": "Deposit pUSD to Perps",
"depositWalletParams": {
"depositWallet": "",
"deadline": "",
"calls": [
{
"target": "0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB",
"value": "0",
"data": ""
},
{
"target": "0xDCa4af75705dbB50f62437045afF9921947917d2",
"value": "0",
"data": ""
}
]
}
}'
```
The response includes the relayer transaction ID.
```json theme={null}
{
"transactionID": "",
"state": "STATE_NEW"
}
```
Poll the relayer transaction until it reaches `STATE_CONFIRMED` before relying
on the deposited collateral.
```bash theme={null}
curl "https://relayer-v2.polymarket.com/v1/account/transactions/" \
-H "RELAYER_API_KEY: $RELAYER_API_KEY" \
-H "RELAYER_API_KEY_ADDRESS: $RELAYER_API_KEY_ADDRESS"
```
```json theme={null}
{
"transaction_id": "",
"transaction_hash": "",
"state": "STATE_CONFIRMED",
"error_msg": null
}
```
Perps may take a moment to credit the account after the onchain transaction
settles. Treat `STATE_FAILED` and `STATE_INVALID` as terminal failures.
## Withdraw Collateral
Withdraw pUSD when the account has available collateral that should return to the
authenticated wallet.
Request a withdrawal to the authenticated wallet.
Amounts use raw pUSD base units, so 10 pUSD is `10_000_000n`.
```ts theme={null}
const withdrawalId = await client.withdrawFromPerps({
amount: 10_000_000n,
});
```
The SDK signs the withdrawal request with the Polymarket account signer and
returns the Perps withdrawal ID.
To track the withdrawal, open a Perps session and list withdrawals.
```ts theme={null}
const session = await client.openPerpsSession();
try {
const withdrawals = await session.listWithdrawals().firstPage();
} finally {
await session.close();
}
```
For more details on authenticated sessions, see [Authenticated
Sessions](/perps/authenticated-sessions).
Request a withdrawal to the authenticated wallet. Amounts use raw pUSD base
units, so 10 pUSD is `10_000_000`.
```python theme={null}
withdrawal_id = await client.withdraw_from_perps(amount=10_000_000)
```
The SDK signs the withdrawal request with the Polymarket account signer and
returns the Perps withdrawal ID.
To track the withdrawal, open a Perps session and list withdrawals.
```python theme={null}
session = await client.open_perps_session()
try:
withdrawals = await session.list_withdrawals().first_page()
finally:
await session.close()
```
For more details on authenticated sessions, see [Authenticated
Sessions](/perps/authenticated-sessions).
Create a `withdraw` operation with the account signer, pUSD token, raw token
amount, and destination wallet. For withdrawals, `amount` is the raw pUSD token
amount, so 10 pUSD is `10000000`.
```json theme={null}
{
"type": "withdraw",
"args": {
"account": "",
"token": "0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB",
"amount": "10000000",
"to": ""
}
}
```
| Field | Value |
| --------- | ------------------------------------------ |
| `account` | Signer address for the Polymarket account. |
| `token` | pUSD collateral token address. |
| `amount` | Raw pUSD token amount. |
| `to` | Wallet that receives the withdrawal. |
The withdrawal signature uses EIP-712 typed data with `Withdraw` as the primary
type. Use the same `account`, `token`, `amount`, and `to` values from the
withdrawal operation.
For withdrawals, `ts` is a Unix timestamp in seconds because the onchain contract
validates it against `block.timestamp`. It must match the `ts` value in the
request body.
```json theme={null}
{
"domain": {
"name": "Polymarket",
"version": "1",
"chainId": 137,
"verifyingContract": "0xDCa4af75705dbB50f62437045afF9921947917d2"
},
"primaryType": "Withdraw",
"types": {
"Withdraw": [
{ "name": "account", "type": "address" },
{ "name": "token", "type": "address" },
{ "name": "amount", "type": "uint256" },
{ "name": "fee", "type": "uint256" },
{ "name": "to", "type": "address" },
{ "name": "salt", "type": "uint64" },
{ "name": "ts", "type": "uint64" }
]
},
"message": {
"account": "",
"token": "0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB",
"amount": "10000000",
"fee": "0",
"to": "",
"salt": 555555555,
"ts": 1767000014
}
}
```
| Field | Value |
| ------ | ---------------------------------------------------- |
| `salt` | Random integer generated for this signed request. |
| `ts` | Current Unix timestamp in seconds, not milliseconds. |
Sign the typed data with the Polymarket account signer. The example below uses
Viem.
```ts Viem theme={null}
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount("");
const signature = await account.signTypedData({
domain: {
name: "Polymarket",
version: "1",
chainId: 137,
verifyingContract: "0xDCa4af75705dbB50f62437045afF9921947917d2",
},
primaryType: "Withdraw",
types: {
Withdraw: [
{ name: "account", type: "address" },
{ name: "token", type: "address" },
{ name: "amount", type: "uint256" },
{ name: "fee", type: "uint256" },
{ name: "to", type: "address" },
{ name: "salt", type: "uint64" },
{ name: "ts", type: "uint64" },
],
},
message: {
account: "",
token: "0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB",
amount: 10000000n,
fee: 0n,
to: "",
salt: 555555555n,
ts: 1767000014n,
},
});
```
Submit the signed withdrawal request to `POST /v1/account/withdraw`. Use the
same operation values, `salt`, and `ts` from the typed data.
```bash theme={null}
curl -X POST "https://api.perpetuals.polymarket.com/v1/account/withdraw" \
-H "content-type: application/json" \
-d '{
"op": {
"type": "withdraw",
"args": {
"account": "",
"token": "0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB",
"amount": "10000000",
"to": ""
}
},
"sig": "",
"salt": 555555555,
"ts": 1767000014
}'
```
The response indicates whether the withdrawal was accepted.
```json Success theme={null}
{
"status": "ok",
"withdraw_id": 1234567890
}
```
```json Failure theme={null}
{
"status": "err",
"withdraw_id": 1234567890,
"error": "insufficient_balance"
}
```
Use the returned `withdraw_id` to match the withdrawal against history results.
```bash theme={null}
curl -G "https://api.perpetuals.polymarket.com/v1/account/withdrawals" \
-H "polymarket-proxy: " \
-H "polymarket-secret: " \
--data-urlencode "withdrawal_status=pending"
```
For more details on proxy credentials and private account-read headers, see
[Authenticated Sessions](/perps/authenticated-sessions).
## Review Funding History
Use deposit and withdrawal history to reconcile collateral movements after your
integration submits funding requests.
See [Authenticated Sessions](/perps/authenticated-sessions) for how to create an
authenticated session for private account history reads.
List deposit or withdrawal history from an authenticated Perps session.
```ts Deposits theme={null}
import type { PerpsDeposit } from "@polymarket/client";
const session = await client.openPerpsSession();
try {
const deposits: PerpsDeposit[] = [];
for await (const page of session.listDeposits()) {
deposits.push(...page.items);
}
} finally {
await session.close();
}
```
```ts Withdrawals theme={null}
import type { PerpsWithdrawal } from "@polymarket/client";
const session = await client.openPerpsSession();
try {
const withdrawals: PerpsWithdrawal[] = [];
for await (const page of session.listWithdrawals()) {
withdrawals.push(...page.items);
}
} finally {
await session.close();
}
```
List deposit or withdrawal history from an authenticated Perps session.
```python Deposits theme={null}
session = await client.open_perps_session()
try:
deposits = []
async for page in session.list_deposits():
deposits.extend(page.items)
finally:
await session.close()
```
```python Withdrawals theme={null}
session = await client.open_perps_session()
try:
withdrawals = []
async for page in session.list_withdrawals():
withdrawals.extend(page.items)
finally:
await session.close()
```
List deposit history.
```bash theme={null}
curl -G "https://api.perpetuals.polymarket.com/v1/account/deposits" \
-H "polymarket-proxy: " \
-H "polymarket-secret: "
```
List withdrawal history.
```bash theme={null}
curl -G "https://api.perpetuals.polymarket.com/v1/account/withdrawals" \
-H "polymarket-proxy: " \
-H "polymarket-secret: "
```
Use the optional `deposit_status`, `withdrawal_status`, `start_timestamp`, and
`end_timestamp` query parameters when reconciling a specific window.