Skip to main content
Move between collateral and a market’s outcome tokens directly on-chain, without going through the order book. Outcome tokens are issued by the CTF — the on-chain conditional-token contracts behind each market — and these three endpoints operate on them directly: split mints a complete outcome-token set from collateral, merge burns one back into collateral before resolution, and redeem converts winning tokens into collateral after the market resolves. Each is an on-chain transaction, and a successful response carries a tx_hash. Full parameter reference and a live tester: API Reference.

Base URL

Authentication

Same API-key headers as Orders. These are fund-moving operations and require the trade:execute scope.
Examples below read credentials from KAIROS_CLIENT_ID, KAIROS_API_KEY, and KAIROS_API_SECRET in your shell. Identity is resolved server-side from the authenticated caller, not the request body. user_id, turnkey_org_id, and wallet_address are all optional: omit them and the signer wallet is looked up from the authenticated user; if you send them anyway they must match the authenticated identity (a mismatch is rejected 403 with error_details.code = AUTH_IDENTITY_MISMATCH, naming the offending field), and they can never widen scope to another user’s wallet. API keys carry no Turnkey organization, so a turnkey_org_id sent with API-key auth is simply ignored — the organization is read from your account, and the field is never grounds for rejection on that auth method. A turnkey_org_id only has to match for session-JWT callers, whose token carries one. Omitting the field is always the simplest call. All three endpoints sit behind a mutation gate that runs before user auth, so an API-key triple that fails to authenticate here is a 403, not a 401. They also require the caller’s installed Turnkey trading policies to be current — see AUTH_POLICY_OUTDATED in Errors.

Exchange support

Availability is also readable per venue: GET /exchanges/{exchange_id}/capabilities returns supports_redemption, which is true only for polymarket and predictfun. All three actions require an on-chain CTF, so only polymarket and predictfun are wired. Kalshi settles off-exchange and needs no redemption call.
Gotcha: any other exchange_id — including kalshi and opinion — has no handler registered and returns 404 (VALIDATION_MARKET_NOT_FOUND) on split, merge, and redeem alike. It is not a 400, so do not treat an unsupported venue as a malformed request.

Concepts

  • Complete set — one YES + one NO of the same market is always worth exactly 1 unit of collateral, regardless of resolution. Split mints a complete set from collateral; merge burns one back. Both legs settle 1:1, so the implied per-token cost basis is 0.5.
  • NegRisk — multi-outcome markets whose conditionId was issued by Polymarket’s / predict.fun’s NegRisk contracts. They route through the venue-specific adapter automatically — see NegRisk markets.
  • Holding wallet — deposit-wallet users hold tokens on their on-chain proxy/Safe; EOA users hold them directly. The endpoint resolves the correct holder for you.

Split

Converts amount of collateral into amount YES and amount NO tokens. This does not open a market position — it mints equal tokens on every outcome. Auth: API key or session JWT, scope trade:execute.

Request

Response

action is always the lowercase "split" / "merge".
Gotcha: tx_hash is nullable. Branch on success rather than assuming a hash is present.

Merge

Burns amount YES and amount NO tokens and returns amount collateral. Requires holding at least amount of every outcome token — this is how you recover capital from matched inventory without waiting for resolution. Auth: API key or session JWT, scope trade:execute.

Request

Identical to Split: condition_id, market_id, amount, plus the optional identity-override fields. Example — free up capital from 290 YES + 290 NO:
Burns 290 YES + 290 NO and returns ~290 collateral to the wallet.

Response

Redeem

After a market resolves, converts the winning outcome tokens into collateral. Unlike merge, this only needs the winning side and only works once the market has resolved on-chain — losing shares are worthless and not redeemable. Auth: API key or session JWT, scope trade:execute.
Polymarket auto-redeems winners by default when enabled — see Copy Trading. Use this endpoint to redeem on demand.
This redeems a single market’s outcome tokens. Multi-leg parlay positions are a different instrument with their own redemption call — see POST /combo/redeem.

Request

The position is only marked redeemed when either position_id, or both market_id and token_id, are supplied.

Response

Gotcha: db_update_failed: true appears only when the on-chain redeem succeeded but the position-state DB write failed after retries. The funds are safe — only the bookkeeping needs a retry, which the caller should perform itself.

NegRisk markets

Multi-outcome (NegRisk) markets are detected from the conditionId and routed through the appropriate adapter automatically — no flag needed:
  • Polymarket — CLOB-v2 NegRisk split, merge, and redeem use NegRiskCtfCollateralAdapter at 0xadA2005600Dec949baf300f4C6120000bDB6eAab. It exposes the standard five-argument CTF split/merge ABI, accepts pUSD at the caller boundary, and returns pUSD directly. Kairos never sends new actions to the deprecated CLOB-v1 adapter.
  • predict.fun — has four contract sets across yield × NegRisk. The endpoint picks the conditional-token contract and collateral per (is_yield_bearing, is_neg_risk): non-yield non-NegRisk uses the shared CTF + USDC; yield variants use the yield-bearing CT; NegRisk variants route through the NegRiskAdapter with wrapped collateral. All resolved internally from market metadata.
The caller only ever provides condition_id + market_id; routing is automatic.

Gas & signing

  • Transactions are signed by Kairos’s custodial signer, under the caller’s resolved account.
  • Deposit-wallet users execute gaslessly through the relayer (tokens held on the proxy/Safe). For EOA holders the action is gas-sponsored where eligible; otherwise the wallet pays gas.
  • All three actions are idempotent at the chain level by nature — re-issuing a merge/redeem for already-consumed tokens simply has nothing left to burn/redeem.

How actions appear in your history

Split and merge are recorded into your orders/trades/positions exactly like fills, so balances stay consistent:
  • Split → two synthetic BUY legs at price 0.5 (N collateral → N YES + N NO).
  • Merge → two synthetic SELL legs at price 0.5 (N YES + N NO → N collateral).
A merge correctly reduces your YES and NO positions and credits the collateral, and shows up in Trading Data and PnL like any other execution.

Errors

Most CTF / redeem failures return the same Order Execution envelope as Orders — Errors:
Match on error_details.code (SCREAMING_SNAKE_CASE). Top-level code is a legacy PascalCase debug string. error_details.details and error_details.metadata are omitted when absent, never null. Several rejections on these paths are raised as a bare status and then wrapped, so they arrive with a generic code and the literal message "Request failed with status <n>". Treat the status as authoritative on this page and use error_details.code for the cases below where a specific code is named. The Code column holds the error_details.code value.
Gotcha: a 502 here is not always a transport fault. Missing-approval and short-balance conditions reported by the chain or venue are classified as 502 from the failure text, so read error_details.code before retrying.
Client tip: surface error_details.message when present. A bare transport failure has no useful reason; an over-long internal detail should not be shown verbatim in a toast.