> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usetapp.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Order — EVM & Starknet

> The unified create-order endpoint, non-custodial branch. When network is an EVM or Starknet chain, Rails returns the unsigned createOrder params and the client's own wallet submits the transaction.

Create Order is a **single endpoint** — `POST /v1/sender/orders`. Rails
dispatches on the `network` you pass:

* **Sui** — custodial. Rails returns a deposit address / PTB (see
  [Create Order](/api-reference/endpoint-create-order)).
* **EVM & Starknet** — **non-custodial** (this page). Rails never takes
  custody, holds keys, or pays gas. It assembles the exact `createOrder`
  parameters your wallet needs — the Gateway address, live rate, token,
  amount, and the encrypted recipient blob — and records the order for
  status tracking.

Your wallet then `approve()`s the Gateway and calls `createOrder(...)` with
the returned params. After submitting, report the on-chain `orderId` back via
[Submit On-chain Order](/api-reference/endpoint-submit-evm-order); Rails polls
the settlement aggregator and webhooks you on every status change.

<Note>
  The `rate` returned is a live LP quote — a snapshot. Submit promptly. An order
  created above the LP's ceiling rate times out and auto-refunds to the order
  creator (`returnAddress`).
</Note>

<Warning>
  **Fees & approval.** The Gateway pulls `amount + senderFee`, so approve
  `approveAmount` (returned below), not just `amount`. Your fee (`senderFee`) is
  paid on-chain to `feeAddress`. This is separate from the protocol fee, which
  the aggregator charges automatically on-chain — you do not set it.
</Warning>

### Header Parameters

<ParamField header="API-Key" type="string" required>
  Unique API key issued manually through Telegram.
</ParamField>

### Request Body

<ParamField body="network" type="string" required>
  The settlement chain identifier. EVM: `ethereum`, `base`, `polygon`,
  `arbitrum-one`, `bnb-smart-chain`, `celo`, `lisk`, `scroll`. Non-EVM:
  `starknet`.
</ParamField>

<ParamField body="token" type="string" required>
  The stablecoin symbol to send (`USDC`, `USDT`, and `CNGN` on some chains).
  Must be enabled on the selected `network`.
</ParamField>

<ParamField body="amount" type="string" required>
  The token amount to convert, in human units (e.g. `"100.00"`).
</ParamField>

<ParamField body="rateId" type="string">
  A locked quote id from [Get Rate](/api-reference/endpoint-get-rate). Preferred
  over a raw `rate`. (For EVM/Starknet the live LP rate is also re-quoted
  server-side at settlement.)
</ParamField>

<ParamField body="rate" type="string">
  A raw rate — used only when `rateId` is omitted.
</ParamField>

<ParamField body="returnAddress" type="string" required>
  The wallet of the order creator — the wallet that will call `createOrder`.
  Refunds return here, and it is the default sender-fee recipient. Must match
  the chain's address format (EVM 20-byte hex, or a Starknet felt).
</ParamField>

<ParamField body="feeMode" type="string">
  How to compute your (the integrator's) fee: `percent` (default) or `fixed`.
</ParamField>

<ParamField body="feePercent" type="string">
  Used when `feeMode` is `percent` — your fee as a percentage of the order
  amount (e.g. `1.5` = 1.5%).
</ParamField>

<ParamField body="feeAmount" type="string">
  Used when `feeMode` is `fixed` — a flat fee in the order's token (e.g.
  `2` = 2 USDC). Must be less than `amount`.
</ParamField>

<ParamField body="feeAddress" type="string">
  The address that receives your fee on-chain (the Gateway's
  `senderFeeRecipient`). Required whenever a fee is set. Same address format as
  the chain.
</ParamField>

<ParamField body="recipientId" type="string">
  A staged beneficiary id from
  [Create Recipient](/api-reference/endpoint-create-recipient). Preferred over
  an inline `recipient`.
</ParamField>

<ParamField body="recipient" type="object">
  Payout beneficiary details — used only when `recipientId` is omitted.
  <ParamField body="currency" type="string" required>Destination fiat ISO code (`NGN`, `KES`, …).</ParamField>
  <ParamField body="institution" type="string" required>Payout institution code from `/v1/institutions/{currency_code}`.</ParamField>
  <ParamField body="accountIdentifier" type="string" required>Payout account number / wallet handle.</ParamField>
  <ParamField body="accountName" type="string" required>Exact account name of record.</ParamField>
  <ParamField body="memo" type="string" required>Bank transfer memo.</ParamField>
  <ParamField body="providerId" type="string">Optional preferred LP provider id.</ParamField>
</ParamField>

### Response

<ResponseField name="status" type="string">Response state (`success`).</ResponseField>
<ResponseField name="message" type="string">Human-readable message.</ResponseField>

<ResponseField name="data" type="object">
  <ResponseField name="orderRef" type="string">Rails order id (UUID). Use it in the submit callback and status lookups.</ResponseField>

  <ResponseField name="params" type="object">
    The unsigned `createOrder` arguments. All integers are decimal strings
    (uint256 amount, uint96/u128 rate).
    <ResponseField name="network" type="string">Chain identifier.</ResponseField>
    <ResponseField name="chainType" type="string">`evm` or `starknet`.</ResponseField>
    <ResponseField name="chainId" type="number">Chain id (EVM decimal id, or the Starknet SN\_MAIN felt).</ResponseField>
    <ResponseField name="chainIdHex" type="string">Chain id in `0x` hex.</ResponseField>
    <ResponseField name="gatewayAddress" type="string">Gateway proxy — the `approve()` + `createOrder()` target.</ResponseField>
    <ResponseField name="token" type="string">Token contract to send.</ResponseField>
    <ResponseField name="tokenSymbol" type="string">Token symbol.</ResponseField>
    <ResponseField name="decimals" type="number">Token decimals.</ResponseField>
    <ResponseField name="amount" type="string">Order amount in token subunits.</ResponseField>

    <ResponseField name="approveAmount" type="string">
      `amount + senderFee` in token subunits. **Approve this** on the token
      before calling `createOrder` — the Gateway pulls `amount + senderFee`.
    </ResponseField>

    <ResponseField name="rate" type="string">Rate as fixed-point (fiat-per-token × 100).</ResponseField>
    <ResponseField name="senderFeeRecipient" type="string">Fee recipient address.</ResponseField>
    <ResponseField name="senderFee" type="string">Sender fee in token subunits.</ResponseField>
    <ResponseField name="refundAddress" type="string">Refund target — equals `returnAddress`.</ResponseField>
    <ResponseField name="messageHash" type="string">Base64 RSA-encrypted recipient blob (the Gateway `messageHash` argument).</ResponseField>
    <ResponseField name="currency" type="string">Destination fiat code.</ResponseField>
    <ResponseField name="providerIds" type="array">Eligible LP provider ids.</ResponseField>
  </ResponseField>
</ResponseField>

***

### Example Payloads

<RequestExample>
  ```json Request (Starknet) theme={null}
  {
    "network": "starknet",
    "token": "USDC",
    "amount": "100.00",
    "rate": "1",
    "returnAddress": "0x06ff3a3b1532da65594fc98f9ca7200af6c3dbaf37e7339b0ebd3b3f2390c583",
    "recipient": {
      "currency": "NGN",
      "institution": "GTBINGLA",
      "accountIdentifier": "0123456789",
      "accountName": "Jane Doe",
      "memo": "Invoice payment"
    }
  }
  ```
</RequestExample>

<ResponseExample>
  ```json Response (200 OK) theme={null}
  {
    "status": "success",
    "message": "Order ready — approve the Gateway and submit createOrder from your wallet, then POST the orderId to orders/:id/submitted",
    "data": {
      "orderRef": "c162cba7-f1b1-48aa-9f80-6f803f50e155",
      "params": {
        "network": "starknet",
        "chainType": "starknet",
        "chainId": 23448594291968334,
        "chainIdHex": "0x534e5f4d41494e",
        "gatewayAddress": "0x06ff3a3b1532da65594fc98f9ca7200af6c3dbaf37e7339b0ebd3b3f2390c583",
        "token": "0x33068f6539f8e6e6b131e6b2b814e6c34a5224bc66947c47dab9dfee93b35fb",
        "tokenSymbol": "USDC",
        "decimals": 6,
        "amount": "100000000",
        "approveAmount": "100000000",
        "rate": "137800",
        "senderFeeRecipient": "0x06ff3a3b1532da65594fc98f9ca7200af6c3dbaf37e7339b0ebd3b3f2390c583",
        "senderFee": "0",
        "refundAddress": "0x06ff3a3b1532da65594fc98f9ca7200af6c3dbaf37e7339b0ebd3b3f2390c583",
        "messageHash": "EbJcMEaq9nT+uCGBZyJ2fA9gKrvo...",
        "currency": "NGN",
        "providerIds": ["etoMCRIY"]
      }
    }
  }
  ```
</ResponseExample>
