FUNCTOR API

API reference · testnet

Exchange endpoint and signing

Every change to an account is a signed action sent to POST /exchange. The node checks the signature, runs the action in a block straight away and returns its result.

Request

{
  "action": {
    "type": "order",
    "account": "0x5b1e…",
    "market": 0,
    "isBuy": true,
    "price": 83300,
    "size": 10,
    "tif": "Ioc",
    "reduceOnly": false
  },
  "nonce": 1791409090058,
  "signature": "0x6c1d…1b",
  "signatureChainId": null
}
FieldTypeDescription
actionobjectOne of the actions below; type selects it
nonceu64Current time in ms (nonce rules)
signaturehex string65 bytes: r ‖ s ‖ v, v = 27 or 28 (0 or 1 accepted). s must be in the lower half of the curve order (EIP-2)
signatureChainIdu64Wallet-signed actions: required, the chain id the wallet signed on. Session-key actions: omit it (1337 is used)

Signing

Actions are signed as EIP-712 typed data, which MetaMask, Rabby and other Ethereum wallets show in readable form. The digest is keccak256(0x1901 ‖ domainSeparator ‖ hashStruct(message)), with this domain:

{
  "name": "Functor",
  "version": "1",
  "chainId": "<see below>",
  "verifyingContract": "0x0000000000000000000000000000000000000000"
}
Who signsActionschainId
The wallet (owner of the account)approveAgent, withdraw, usdClassTransfer, spotSendThe chain the wallet is on; send it as signatureChainId
A session key (agent) the wallet approved, or the walletorder, cancel, setLeverage, spotOrder, spotCancel, vaultTransfer1337

Every typed struct ends with uint64 nonce. tif is signed as uint8: Gtc = 0, Ioc = 1, Alo = 2. The signer recovered from the signature must be the account field or a session key it approved; wallet-signed actions act on the signer's own account. A session key approved by one wallet trades only for that wallet, and can never withdraw or send funds. There is no action to revoke a session key yet: to retire one, stop using it and approve a new one.

Response

The action runs in a block immediately. The answer carries the block height and the result:

{
  "status": "ok",
  "response": {
    "ticket": 4,
    "height": 40539,
    "result": {
      "ticket": 4,
      "ok": true,
      "error": null,
      "restingOid": null,
      "filledLots": 10,
      "avgPx": 83300,
      "vaultUsd": null,
      "vaultShares": null
    }
  }
}
FieldDescription
statusok if the action succeeded in its block, err if it failed or was refused
result.errorWhy it failed in the block (chain errors), else null
result.restingOidThe order id if part of the order rests on the book
result.filledLotsLots filled on arrival (or in this block's auction)
result.avgPxAverage fill price in ticks
result.vaultUsd, result.vaultSharesVault transfers: dollars moved and shares minted or burned

A request refused before it reaches a block (bad signature, bad nonce, limit) answers 400 with {"status": "err", "response": "<reason>"} (list). approveAgent answers {"status": "ok", "response": {"ticket": n, "result": {"ok": true}}} with no height: it takes effect without a block.

Actions

approveAgent wallet-signed

Approve a session key (agent) to trade for this account. Takes effect at once. The agent can place and cancel orders, set leverage and move USDC between the account and a vault; it can never withdraw or send funds.

FieldTypeDescription
agentaddressThe session key's address. Not the signer itself, not a protocol account

Signed as

ApproveAgent(address agent,uint64 nonce)

Action

{
  "type": "approveAgent",
  "agent": "0x8f3c…"
}

order session key or wallet

Place a perpetuals order. A buy fills against asks at or below price; what doesn't fill rests (GTC), is cancelled (IOC), or the whole order is refused if it would trade on arrival (ALO, post-only).

FieldTypeDescription
accountaddressThe account trading
marketu32Market id (0 BTC, 1 ETH, 2 SOL)
isBuybool
priceu64Limit price in ticks (dollars ÷ tick)
sizeu64Size in lots (coins ÷ lot)
tifstringGtc, Ioc or Alo. Signed as 0, 1, 2
reduceOnlyboolOnly reduces an existing position

Signed as

Order(address account,uint32 market,bool isBuy,uint64 price,uint64 size,uint8 tif,bool reduceOnly,uint64 nonce)

Action

{
  "type": "order",
  "account": "0x5b1e…",
  "market": 0,
  "isBuy": true,
  "price": 83300,
  "size": 10,
  "tif": "Ioc",
  "reduceOnly": false
}

cancel session key or wallet

Cancel a resting perpetuals order.

FieldTypeDescription
accountaddress
marketu32Market id
orderIdu64restingOid from the order's result, or oid from openOrders

Signed as

Cancel(address account,uint32 market,uint64 orderId,uint64 nonce)

Action

{
  "type": "cancel",
  "account": "0x5b1e…",
  "market": 0,
  "orderId": 1954694
}

setLeverage session key or wallet

Set the account's leverage on one market (cross margin). Without it, an account uses the market's maximum.

FieldTypeDescription
accountaddress
marketu32Market id
leverageu321 to the market's maximum leverage

Signed as

SetLeverage(address account,uint32 market,uint32 leverage,uint64 nonce)

Action

{
  "type": "setLeverage",
  "account": "0x5b1e…",
  "market": 0,
  "leverage": 5
}

withdraw wallet-signed

Withdraw USDC from the perpetuals account. On the testnet the USDC leaves the chain (there is no bridge yet). Allowed up to withdrawable: what is left after max(initial margin, 10% of position notional).

FieldTypeDescription
amountu64Micro-USDC (1 USDC = 1,000,000)

Signed as

Withdraw(uint64 amount,uint64 nonce)

Action

{
  "type": "withdraw",
  "amount": 100000000
}

spotOrder session key or wallet

Place an FCTR/USDC order from the spot wallet. Bids are fully funded: the USDC is held while the order rests. During an auction phase only GTC orders are accepted and nothing trades until the auction ends.

FieldTypeDescription
accountaddress
isBuybool
priceu64Ticks of $0.0001 per FCTR
sizeu64Lots of 0.01 FCTR (minimum 100 = 1 FCTR)
tifstringGtc, Ioc or Alo (IOC and ALO only in continuous trading)

Signed as

SpotOrder(address account,bool isBuy,uint64 price,uint64 size,uint8 tif,uint64 nonce)

Action

{
  "type": "spotOrder",
  "account": "0x5b1e…",
  "isBuy": true,
  "price": 10000,
  "size": 10000,
  "tif": "Gtc"
}

spotCancel session key or wallet

Cancel a resting FCTR/USDC order. Refused in the opening auction's closing window.

FieldTypeDescription
accountaddress
orderIdu64Spot order id

Signed as

SpotCancel(address account,uint64 orderId,uint64 nonce)

Action

{
  "type": "spotCancel",
  "account": "0x5b1e…",
  "orderId": 12
}

usdClassTransfer wallet-signed

Move USDC between the perpetuals account and the spot wallet (Hyperliquid's usdClassTransfer). Perpetuals to spot is limited to withdrawable.

FieldTypeDescription
amountu64Micro-USDC
toPerpbooltrue: spot → perpetuals; false: perpetuals → spot

Signed as

UsdClassTransfer(uint64 amount,bool toPerp,uint64 nonce)

Action

{
  "type": "usdClassTransfer",
  "amount": 50000000,
  "toPerp": false
}

spotSend wallet-signed

Send FCTR to another address. Locked (vesting) FCTR can't be sent; nothing can be sent to protocol accounts.

FieldTypeDescription
destinationaddress
amountu64FCTR base units (1 FCTR = 1,000,000,000)

Signed as

SpotSend(address destination,uint64 amount,uint64 nonce)

Action

{
  "type": "spotSend",
  "destination": "0x9a7d…",
  "amount": 2000000000
}

vaultTransfer session key or wallet

Deposit into or withdraw from an FLP vault. Money only moves between the account and the vault, so a session key may sign it. Withdrawals open 4 days after the account's last deposit into that vault; an amount above the account's value withdraws everything.

FieldTypeDescription
accountaddress
vaultAddressaddressFrom vaults
isDepositbool
usdu64Micro-USDC

Signed as

VaultTransfer(address account,address vaultAddress,bool isDeposit,uint64 usd,uint64 nonce)

Action

{
  "type": "vaultTransfer",
  "account": "0x5b1e…",
  "vaultAddress": "0xf1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1",
  "isDeposit": true,
  "usd": 100000000
}

Faucet (testnet)

POST /faucet with {"user": "0x…"} credits 10,000 mock USDC to the perpetuals account and, while the testnet faucet bucket lasts, 1,000 test FCTR to the spot wallet. No signature. Same response shape as /exchange; the ticket is the USDC credit. Limits: Rules.

Generated from the node's source code by tools/api-docs.mjs; examples are real responses from https://api.functorfund.com. Questions: Telegram. Changes: News.

On this page

RequestSigningResponseActionsapproveAgentordercancelsetLeveragewithdrawspotOrderspotCancelusdClassTransferspotSendvaultTransferFaucet