ORCHESTRATION API

POST /orders/{originChain}/{orderId}/cancel

Builds a cancellation transaction for an existing limit order.

This endpoint builds a cancellation transaction for an existing limit order. The returned payload must be signed and submitted to the blockchain by the caller to complete the cancellation.

TypeScript Types: Generate types for this API with a single command. See Type Generation.
API Reference: For detailed schema definitions and interactive testing, see the API Reference.

Request

Endpoint

POST /orders/{originChain}/{orderId}/cancel

Headers

Content-Type: application/json
x-api-key: YOUR_API_KEY

Path Parameters

FieldTypeRequiredDescription
originChainChainYesThe chain where the order was created (e.g., Ethereum)
orderIdstringYesThe ID of the limit order to cancel

Body Parameters (optional)

FieldTypeRequiredDescription
callerstringNoSVM only: the base58 pubkey that will sign and pay for the resulting Solana transaction. Required for a permissionless cancel after the order's fillDeadline; defaults to the original sender. Ignored for EVM destinations.

Example Request

import type { components } from "./m0-swap"; // From type generation

type TransactionPayload = components["schemas"]["TransactionPayload"];

const originChain = "Ethereum";
const orderId = "0xabc123...";

const response = await fetch(
  `https://gateway.m0.xyz/v1/orchestration/orders/${originChain}/${orderId}/cancel`,
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "x-api-key": "YOUR_API_KEY",
    },
  },
);

if (!response.ok) {
  const error = await response.text();
  throw new Error(`Cancel order failed: ${error}`);
}

const payload: TransactionPayload = await response.json();

Response

Success Response (200)

Returns a TransactionPayload to submit on-chain to complete the cancellation — either an EvmPayload or SvmPayload depending on the chain.

import type { components } from "./m0-swap";

type TransactionPayload = components["schemas"]["TransactionPayload"];
type EvmPayload = components["schemas"]["EvmPayload"];
type SvmPayload = components["schemas"]["SvmPayload"];

The payload carries its own chain (and chainId for EVM payloads) indicating where the transaction must be broadcast:

  • Same-chain orders (origin == destination): broadcast on the order's chain. The payload's chain matches the URL originChain.
  • Cross-chain orders (origin != destination): the cancel must be initiated on the order's destination chain, which then dispatches a CancelReport message back to the origin chain to release the deposited funds. The payload's chain is the destination chain and differs from the URL path parameter. The payload's value includes the bridge fee.

Always read payload.chain (and payload.chainId for EVM) to determine the broadcast target — do not assume it matches the URL path parameter.

See the Quote docs for payload execution examples.

Error Responses

All errors share the { code, message, requestId } body shape. Branch on code rather than on the HTTP status.

StatusCodeDescription
400BadOrderRequestMalformed request (unknown chain, malformed orderId, unsupported caller)
404OrderNotFoundThe referenced order does not exist on-chain
409OrderNotCancellableThe order is already in a terminal state (CANCELLED / COMPLETED)
500CancelOrderErrorUnexpected internal failure — retrying may succeed

Example Response

{
  "type": "evm",
  "chain": "Ethereum",
  "chainId": 1,
  "to": "0x1234567890abcdef...",
  "data": "0xabcdef...",
  "value": "0"
}

Executing the Cancellation

Once you have the response, submit the payload to the blockchain to complete the cancellation:

import { createWalletClient, http } from "viem";
import { mainnet } from "viem/chains";
import type { components } from "./m0-swap";

type EvmPayload = components["schemas"]["EvmPayload"];

async function executeCancelOrder(payload: EvmPayload, account: `0x${string}`) {
  const client = createWalletClient({
    chain: mainnet,
    transport: http(),
    account,
  });

  const hash = await client.sendTransaction({
    to: payload.to as `0x${string}`,
    data: payload.data as `0x${string}`,
    value: BigInt(payload.value),
  });

  return hash;
}

Notes

  • Only the original order creator can cancel a limit order before its fillDeadline; on SVM, a permissionless cancel after the deadline requires the caller body parameter
  • A 409 response means the order is in a terminal state (filled or already cancelled) and no action is needed
  • The cancellation is not final until the returned transaction payload is submitted and confirmed on-chain
Copyright © M0 Foundation 2026