Skip to main content
Pre-position a pooled balance with us and move cash from it into a participant account one transfer at a time; trading proceeds and settlement credits stay in the participant account. This page covers the model, the one RPC that moves cash, and the sub-cent residue that model leaves behind.
Before this page
  • Your firm’s API credentials work against the gRPC target for your environment, and you can mint an access token holding the write:cash-movements grant — see Authentication.
  • You know which of your two firms is which — see Firms, participants and accounts.
  • At least one participant has reached kyc.approved, and you recorded its participantId and its provisionedAccount — see KYC flow.
API reference: Funding. Opens on the public documentation site in a new tab. Where it disagrees with this page, this page is authoritative for the partner surface.

The funding model

The model

Cash is pre-positioned so that a user who just deposited in your app is not paced by a bank rail: you fund your pool in advance, and each order is funded from it by a transfer into the user’s participant account.

The three parties

You do not hold customer funds, and an omnibus account at our DCO is not available to ISVs. Every end-user dollar sits either in your pool or in that user’s participant clearing account, never in an account of yours that mixes users.Cash movement is firm-scoped: you name only the participant account and we resolve your funding account from the relationship established at KYC. Do not send x-participant-id on these calls. The mechanics are under Move cash.

Your funding entity must exist first

Your Wallet Co funding entity must exist and be active before your firm’s API credentials are enabled. There is no order of operations in which you integrate against a live credential and add the funding entity afterwards.

Removed 2026-08-06

CreateFundedOrder, PreviewFundedOrder and OdfSweep were removed on 2026-08-06, and the removal shipped with no changelog entry. If your money path calls any of the three, it is broken and no announcement told you so. One partner discovered the removal through gRPC reflection after their whole money path stopped working.What replaces them: CreateVendorOrder for the order, plus a transfer on CashMovementService for the cash. There is no funded-order preview on the partner surface. There is no sweep: settlement credits, realized profit and released collateral stay in the participant’s clearing account and become buying power there, so nothing needs sweeping after a fill or a settlement.The proto reference is consistent with the removal — OrderEntryAPI declares exactly CreateOrderSubscription, InsertOrder and CancelOrder. Note that gRPC server reflection is entitlement-gated and returns PermissionDenied: method not permitted without the grant, so reflection is not a reliable way to check what you still have.
Do not credit your user from your own ledger on the strength of this page. We credit the participant’s clearing account at resolution. Who pays the user, and from which side, is settled on Who credits the user and nowhere else.

Rails you cannot use

CheckoutAPI and Aeropay are not entitled for ISVs. Both return 403 method not permitted. Do not build a deposit UX against either; the 403 is the entitlement, not a misconfiguration on your side.

Rails you can use

Production deposits into your pool are wire only, as of August 2026. There is no card, ACH or wallet rail on the ISV funding path.Pre-production pools are funded manually by us on a Slack request. There is no self-service test funding, so plan a preprod pool top-up as a human step with a lead time, not as a scripted fixture.

Move cash

If you are an IB, this differs. For an ISV the pool is a working-capital question. For you it is the whole of the permitted structure, because you may not accept or hold customer funds at any point — see Funds handling. Wallet Co segregation is a prerequisite and is unspecified in writing, so get it confirmed. The sub-cent residue below is a reporting problem for you, not only a reconciliation annoyance — see Reporting pack.
Move cash between your funding pool and one participant account with CashMovementService, and read the outcome off the returned status.

The service

CashMovementService has three RPCs. CreateCashMovement is the one that moves cash.
Not yet published. The other two RPCs on CashMovementService are not enumerated in anything we have published, and the service itself is absent from the published proto bundle — the bundle advertises 14 services and defines 5, and this is one of the omissions.Use the proto your integration lead sent you, and confirm the RPC list with them before you build a client around it.
CashMovementService is firm-scoped. Do not send x-participant-id on any call to it. That header is required on account-scoped reads such as positions and reports, and sending it here is wrong rather than harmless.

Direction is fixed by the reason

You do not name a source and a destination. You name the reason, and the reason fixes the direction. You name only the participant account; we resolve your funding account from the relationship established server-side at KYC.
[VERIFY] — the per-reason directions above are inferred, not published. What is published is that direction is fixed by the reason and that the three reasons are DEPOSIT, WITHDRAWAL and VENDOR_FEES. The direction each one resolves to is not stated anywhere, and VENDOR_FEES is the one to confirm first: nothing published says whether it debits the participant account, the pool, or something else.Confirm all three with your integration lead before you move money on this table, and test each reason in preprod against the balance ledger rather than against this page.
Three transfers you may be planning are structurally impossible, not merely unsupported: a transfer to your own firm, a transfer between two participants, and a transfer to any external destination. There is no field on the request that could express them, so do not design a product flow that needs one.

Create a transfer

There is no REST path for CashMovementService. Every call in this section is gRPC against grpc-api.{env}.polymarketexchange.com:443. The command-line tab below is grpcurl with a local proto file rather than curl, and it passes -proto because gRPC server reflection is entitlement-gated and returns PermissionDenied: method not permitted without the grant.
Not yet published. These identifiers on the request and response are not in anything we have published, so confirm each against your proto copy before you compile:The field names that are confirmed and used below are transfer (field 4 on the request), amount and idempotency_key, and the reason values DEPOSIT, WITHDRAWAL and VENDOR_FEES.
Response, with the field you branch on:

The four statuses

Not yet published. The CashMovementStatus enum is never defined and the rejection_reason values are never listed, on three pages that reference them. There is also no published deadline by which a PENDING or AMBIGUOUS movement becomes terminal, and no status-lookup RPC on the partner surface.Treat anything non-terminal as money in flight that only the balance ledger can settle, and ask your integration lead for the resolution procedure before you go live.

Idempotency

The dedupe key is idempotency_key. What is established is the terminal-rejection case: a terminally-rejected key replays its stored rejection instead of making a fresh attempt.
[VERIFY] — replay is established for terminally-rejected keys only. Whether a retry on a key whose movement is PENDING, AMBIGUOUS or CONFIRMED replays, is rejected, or starts a second attempt is not published.So do not treat “retrying is safe” as a general property. Key idempotency_key off your own user-action row, retry the same key on a non-terminal movement, and reconcile against the balance ledger rather than against a retry’s response.
A terminally-rejected idempotency_key replays its stored rejection. After a REJECTED response, retrying the same key returns that same rejection forever, no matter what you fixed in between. Use a new idempotency_key for the next attempt. This is the most common way a partner concludes a fixed problem is not fixed.The inverse holds for anything non-terminal: keep the key you have. Minting a new key for a PENDING or AMBIGUOUS movement creates a second transfer.

Two decimal places

amount accepts at most 2 decimal places. Balances carry more, and have been observed at 172.395 and 1377.57275. Never round a balance up to construct an amount; the consequences and the interim practice are under Sub-cent balances.

Rate limit

Not yet published. The transfer rate limit is being confirmed, and three different statements are live today: they disagree on the number and on the scope, with at least one of them scoping the ceiling across all partners rather than per firm.Do not size your order pipeline from any number you have been given verbally. Build backpressure and a retry queue in front of CreateCashMovement, honour whatever retry delay the error carries, and confirm the value and its scope with your integration lead before a launch that depends on throughput. This limit blocked one partner’s entire order flow.

Sub-cent balances

Balances carry more decimal places than transfers accept, so there is a residue you cannot move. Before you act on this section, know which balance figure you are reading — see Which number is spendable.

The numbers

  • Balances carry more than two decimal places. Observed values: 172.395 and 1377.57275.
  • amount on a transfer accepts at most two decimal places.

The consequence

Your balance sheet cannot reach zero today. A participant account holding 172.395 can be drained to 172.39 by one WITHDRAWAL and no further. The residue is real cash in a real account that no call on the partner surface can move, and there is no sanctioned handling for it.
Not yet published. There is no sanctioned treatment of the sub-cent residue: no rounding rule, no sweep, and no statement of whether the residue is ever swept by us.Confirm the current answer with your integration lead before you sign off a zero-balance requirement with your own finance team or an auditor.

Interim practice

Do these three things until the sanctioned answer exists.
1

Track the residue in your own ledger

Carry the full-precision balance and the two-decimal transferable amount as separate columns per account. The difference is the residue. Parse money as a decimal type, never as a float you then round — int64 fields are serialized as strings in JSON for the same reason.
2

Never round up into a transfer

Truncate toward zero when you derive amount from a balance. Rounding 172.395 up to 172.40 asks for cash that is not there, and the failure lands on a money path rather than in your tests.
3

Reconcile the difference as a known standing balance

Close your daily reconciliation with the residue as an expected, named line rather than as a break. A per-account residue under one cent that does not change between runs is the correct state today, not a defect to chase.

What can go wrong

Next

Balances, fees and reconciliation