---
title: "Build the typed data for a Hyperliquid spot↔perp transfer (step 1 of 2)"
method: POST
path: "/exchanges/hyperliquid/transfer/prepare"
tags: ["Hyperliquid"]
---

# Build the typed data for a Hyperliquid spot↔perp transfer (step 1 of 2)

`POST /exchanges/hyperliquid/transfer/prepare`

## Request

- Base URL: `https://execution.kairos.trade`
- URL: `https://execution.kairos.trade/exchanges/hyperliquid/transfer/prepare`
- Auth: API key in header `X-Client-Id` and API key in header `X-Api-Key` and API key in header `X-Api-Secret`

Builds the EIP-712 `usdClassTransfer` payload for moving USDC between your own Hyperliquid spot and perp balances. **Funds never leave your account** — there is no destination and nothing to mis-address.
Your MAIN wallet must sign: Hyperliquid forbids agent wallets from class transfers, so a Kairos-held agent key cannot do this for you.
**This call is pure** — same properties as the withdraw prepare: no writes, no reservation, no binding to the submit step.
**Auth & scope.** Requires `trade:execute` for `hyperliquid`, wallet ownership, and the mutation gate. Not rate limited.

## Request body

- OrderHyperliquidTransferPrepareRequest: Body for `POST /exchanges/hyperliquid/transfer/prepare`. Pure — writes nothing.
  - `wallet_address` string, required
  - `amount` string, required: USDC amount, same plain-decimal validation as withdraw. No Kairos-side minimum or maximum.
  - `to_perp` boolean, required: `true` moves spot → perp; `false` moves perp → spot. Funds never leave the account.

## Response `200`

Typed data to sign, plus the `time` nonce to echo back.

- OrderHyperliquidTransferPrepareResponse
  - `typed_data` object, required: EIP-712 typed data for Hyperliquid's `usdClassTransfer` action.
  - `time` integer, required: Millisecond timestamp, doubles as the nonce.
  - `amount` string, required
  - `to_perp` boolean, required

## Other responses

- `400`: `ValidationInvalidOrder` — invalid user id, or `Invalid withdraw amount: …` (the withdraw-worded message is reused for transfers).
- `401`: No valid credential presented — missing/invalid API-key headers or an invalid/expired session token.
- `403`: Missing scope, provider access disabled, or wallet not owned by the caller.
- `500`: `DatabaseError`, or `InternalError` — "Hyperliquid signing misconfigured".
- `503`: API-key access to `hyperliquid` could not be checked (fails closed).

---

[API](https://skmtc.dev/kairos/apis/kairos-order-execution-api.md) - [All operations](https://skmtc.dev/kairos/apis/kairos-order-execution-api/llms.txt) - [OpenAPI document](https://skmtc.dev/kairos/apis/kairos-order-execution-api/revisions/9ba7d463d505?raw)
