Actions

Start a wallet action (setup, order, cancel, login)

Starts one action for a self-custody wallet and returns its first step. Kairos never holds the wallet's key: each step either asks the wallet for one EIP-1193 request (status: needs_signature) or reports progress (working) or the outcome (done / failed).

The step loop.

  1. POST /v3/actions → a step.
  2. While status is needs_signature: switch the wallet to chainId (when non-null), run request through the wallet's EIP-1193 provider, and POST /v3/actions/{id} with {"signature": "0x…"} (or {"result": …} for wallet_sendCalls). Answer before expiresAtMs.
  3. While status is working: GET /v3/actions/{id} every 1–2 s (or after holdUntilMs when present).
  4. Stop at done (read result) or failed (read error and errorCode).

Action types. setup prepares the wallet on each requested venue; order places one order and runs any missing setup first, in the same action; cancel cancels orders on every venue with one Polygon signature; login returns a sign-in token for the private reads. There are no other action types.

Body rules. Field names are camelCase only: unknown fields — including snake_case spellings such as time_in_force, post_only, client_order_id, expires_at, order_ids — are silently ignored, so a snake_case order becomes a GTC, non-post-only order without a client id. price and size must be JSON strings; a JSON number is rejected with a plain-text 422. expiresAt is an integer (Unix seconds).

Idempotency. Idempotency-Key is not honoured here. Use clientOrderId on orders: the same clientOrderId with the same terms returns the existing order (nothing is signed), and different terms are refused with CLIENT_ORDER_ID_CONFLICT.

Timing. An action lives 15 minutes from creation and stays readable for 10 more minutes, then reads 404. Polymarket and Predict.fun order signatures are accepted for about 60 s, Hyperliquid order signatures for 300 s, and cancel signatures (every venue) for 300 s; expiresAtMs on the step is authoritative.

Errors before the first signature are HTTP errors. When the action fails before the wallet was ever asked to sign (for example every requested venue is unavailable), the response is that error's status and body rather than a failed step.

Send X-Kairos-Wallet-Api: 2; without it this route serves the original Polymarket-only contract.

post/v3/actions

Request

  • Base URL
    https://execution.kairos.trade
  • Auth
    • API key in header X-Kairos-Partner-Id
    • or API key in header X-Client-Id and API key in header X-Api-Key and API key in header X-Api-Secret

Headers

X-Kairos-Wallet-Api'2' required

Wallet API contract version. Send 2 — the multi-venue contract this reference documents. Without the header (or with any other value) /v3/actions and /v3/wallets/* serve the original Polymarket-only contract, which ignores venue prefixes, expiresAt and setup.venues, omits chainId, venue and fallbackRequests from steps, refuses orders on a wallet that is not set up (409), and returns snake_case order and position rows.

Request body

walletstring required

EVM address, 0x + 40 hex.

Example request

{
  "wallet": "0x8ba1f109551bd432803012645ac136ddd64dba72",
  "action": {
    "market": "predictfun:1027194",
    "outcome": "Yes",
    "price": "0.52",
    "size": "10",
    "clientOrderId": "acme-7f3a91",
    "expiresAt": 1793300000
  }
}

Response

The action's first step. Usually needs_signature; done when nothing needs signing (a wallet already set up, or a clientOrderId that already names this exact order).

idstring uuid required

Action id. One id for the whole action, across venues.

type'setup' | 'order' | 'cancel' | 'login' required
status'needs_signature' | 'working' | 'done' | 'failed' required

needs_signature — run request and answer; working — poll; done — read result; failed — read error and errorCode.

descriptionstring nullable required

Text to show with the wallet prompt (e.g. Confirm this Hyperliquid order), or progress text while working.

chainIdstring nullable required

EIP-155 chain id (hex) the wallet must be on to answer — 0x89 Polygon, 0x38 BNB Chain, 0xa4b1 Arbitrum One (0x66eee Arbitrum Sepolia on Hyperliquid testnet). null for personal_sign and when nothing is asked.

venue'polymarket' | 'predictfun' | 'hyperliquid' required

Venue id. predict.fun is accepted as an input alias of predictfun.

expiresAtMsinteger

Last accepted millisecond (Unix ms) for answering this prompt. Answers after it fail the action with SIGNATURE_EXPIRED.

holdUntilMsinteger

On a working order the venue is still matching — poll again after this time (Unix ms). result then holds a provisional outcome with final: false.

errorstring nullable required

Why the action failed; non-null on failed.

errorCode'NO_MATCH' | 'VENUE_REJECTED' | 'ORDER_OUTCOME_UNKNOWN' | 'CANCEL_OUTCOME_UNKNOWN' | 'SIGNATURE_EXPIRED' | 'CLIENT_ORDER_ID_CONFLICT' | 'HYPERLIQUID_AGENT_MISSING'

Machine-readable reason on a failed step; the key is omitted when the failure has no code. Codes may be added; treat an unknown code as a failure whose order was not placed.

CodeMeaningOrder placed?
NO_MATCHAn immediate order (FOK/FAK/IOC) found nothing to match.No
VENUE_REJECTEDThe venue refused the order.No
ORDER_OUTCOME_UNKNOWNThe submission's outcome is unknown. Read the wallet's orders before placing again.Maybe
CANCEL_OUTCOME_UNKNOWNSome venue may have cancelled. Read the wallet's orders.Maybe
SIGNATURE_EXPIREDThe signing window closed before a signature was accepted. Nothing was sent.No
CLIENT_ORDER_ID_CONFLICTThe clientOrderId names an order with different terms.No
HYPERLIQUID_AGENT_MISSINGHyperliquid no longer lists this wallet's trading approval. Run setup again.No

Example response

{
  "request": {
    "method": "personal_sign",
    "params": [
      "0x6b6169726f732e7472616465207761…",
      "0x8ba1f109551bD432803012645Ac136ddd64DBA72"
    ]
  },
  "chainId": "0x38",
  "fallbackRequests": [
    {
      "method": "personal_sign",
      "params": [
        "0x6b6169726f732e7472616465207761…",
        "0x8ba1f109551bD432803012645Ac136ddd64DBA72"
      ]
    }
  ],
  "expiresAtMs": 1793130772999,
  "result": {
    "ready": false,
    "venues": {
      "polymarket": {
        "ready": true,
        "tradingWallet": "0x2f9c4b8e1d7a6c5b4a3f2e1d0c9b8a7f6e5d4c3b",
        "transactionHash": "0x7c3e9a1b5d2f4c6e8a0b2d4f6a8c0e2b4d6f8a0c2e4b6d8f0a2c4e6b8d0f2a4c"
      },
      "predictfun": {
        "ready": false,
        "next": "fund",
        "tradingWallet": "0x8ba1f109551bd432803012645ac136ddd64dba72",
        "venueDetail": {
          "reason": "needs about 0.0004 BNB on BNB Chain to pay gas for 2 Predict.fun approvals",
          "approvals": 2,
          "gasWei": "400000000000000"
        }
      }
    },
    "tradingWallet": "0x2f9c4b8e1d7a6c5b4a3f2e1d0c9b8a7f6e5d4c3b",
    "transactionHash": "0x7c3e9a1b5d2f4c6e8a0b2d4f6a8c0e2b4d6f8a0c2e4b6d8f0a2c4e6b8d0f2a4c"
  }
}

Changes

No recorded changes to this operation across all 1 revision of this API.