Skip to main content
POST
/
2
/
pm
/
approval
/
build
Build the 8 Safe.execTransaction calldatas needed before trading
curl --request POST \
  --url https://demo-api.mobula.io/api/2/pm/approval/build \
  --header 'Content-Type: application/json' \
  --data '
{
  "address": "<string>",
  "isNegRisk": true
}
'
{
  "hostname": "<string>",
  "took": 123,
  "data": "<unknown>"
}
Alpha — This endpoint is part of the Prediction Markets API, currently in early access. May change without notice.

Request Body

address
string
required
The wallet address that will approve tokens.
isNegRisk
boolean
default:"false"
Reserved. Currently ignored; both standard and neg-risk exchange approvals are always returned.

Response

data
array
Array of transaction calldata objects to send on-chain.
hostname
string
Server node identifier.
took
number
Request processing time in milliseconds.

Transactions Returned

Always returns 8 Safe execTransaction calldatas — every approval is executed from the Safe, signed by the EOA owner. Order doesn’t matter (each one is idempotent). CLOB V2 + pUSD migration (post-2026-04-29) checks pUSD balances/allowances, not USDC.e. The set covers both the V2 trading spenders and the wrap/unwrap routing.
#TokenSpenderWhy
1pUSD 0xC011a7E1…2E82DFBCTFExchangeV2 0xE111180000d2663C0091e4f400237545B87B996BSpend pUSD on standard markets
2ConditionalTokens 0x4D97DCd9…ce5EA0476045CTFExchangeV2 (same)Sell outcome tokens on standard markets
3pUSDNegRiskCTFExchangeV2 0xe2222d279d744050d28e00520010520000310F59Spend pUSD on neg-risk markets
4ConditionalTokensNegRiskCTFExchangeV2 (same)Sell outcome tokens on neg-risk markets
5pUSDNegRiskAdapter 0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296Allowance the adapter checks before allowing trades
6ConditionalTokensNegRiskAdapter (same)Outcome-token allowance for the adapter
7USDC.e 0x2791Bca1…Aa84174CollateralOnramp 0x93070a847efEf7F70739046A929D47a521F5B8eeLets the Onramp pull USDC.e during /pm/wrap
8pUSDCollateralOfframp 0x2957922Eb93258b93368531d39fAcCA3B4dC5854Lets the Offramp pull pUSD during /pm/unwrap

Usage Example

curl -X POST "https://api.mobula.io/api/2/pm/approval/build" \
  -H "Content-Type: application/json" \
  -d '{ "address": "0xYourWalletAddress" }'

Integration Example

// Build approval transactions
const res = await fetch('https://api.mobula.io/api/2/pm/approval/build', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ address: walletAddress })
});
const { data: approvals } = await res.json();

// Send each approval transaction on-chain (Polygon)
for (const tx of approvals) {
  await walletClient.sendTransaction({
    to: tx.to,
    data: tx.calldata,
    chain: polygon
  });
}
Each calldata is a Safe execTransaction payload. The EOA owner broadcasts it on Polygon — it triggers the Safe to make the approval call. The Safe is the actual token holder, not the EOA.
Approvals are idempotent and only need to land once per wallet. After they’re set, you can place unlimited V2 orders and call /pm/wrap / /pm/unwrap without re-approving.

Body

application/json
address
string
required
Minimum string length: 1
isNegRisk
boolean

Response

201 - application/json

Prediction Markets response

hostname
string
required
took
number
required
data
any | null

See the per-endpoint reference for the exact response shape.