---
title: "Submit a signed chain write"
method: POST
path: "/v1/chain/{channel}/{contract}/{method}"
tags: ["chain"]
---

# Submit a signed chain write

`POST /v1/chain/{channel}/{contract}/{method}`

## Request

- Base URL: `https://swap-backend.stage.defi.ovh.gala.com`
- URL: `https://swap-backend.stage.defi.ovh.gala.com/v1/chain/{channel}/{contract}/{method}`
- Auth: none declared
- TypeScript: <https://skmtc.dev/gala/apis/gala-defi-backend-api/docs/v1/chain/:channel/:contract/:method/post.ts> (a function with typed inputs; its response is checked against the schema)

Mirrors the chain path: POST the signed DTO to the same {channel}/{contract}/{method} tail you would call directly. The method comes from the URL, never the body. Registered paths: asset/dexv3-contract/RemoveLiquidity, asset/dexv3-contract/CollectPositionFees, asset/dex-contract/RequestTrade, asset/dex-contract/AddLiquidity, asset/dex-contract/RemoveLiquidity, asset/dex-contract/CollectPositionFees, asset/dex-contract/CreatePool, */token-contract/TransferToken, */fee-contract/AuthorizeFee. Optional X-Shadow: true header marks a dex-contract RequestTrade private before dispatch (Shadow Mode, enabled in every environment): any other dex-contract method sent with it is refused 400 SHADOW_UNSUPPORTED_TYPE, a mark that cannot be confirmed is refused 503 SHADOW_UNAVAILABLE (the swap is never relayed un-shadowed), and the header is ignored for dexv3-contract, token-contract and fee-contract. A dispatch failure of a shadow swap is answered 400 SHADOW_RELAY_REJECTED (chain refused, do not retry) or 503 SHADOW_UNAVAILABLE (transient); a replay of an already-consumed uniqueKey is instead answered 409 CHAIN_DISPATCH_FAILED (errorKey UNIQUE_TRANSACTION_CONFLICT, original transaction id in message): confirm the key, it may be applied. A refused write answers { status, error: true, code, message }; when the chain itself refused it the code is CHAIN_DISPATCH_FAILED and the body also carries the chain's machine-readable errorKey (e.g. CONFLICT 409, OBJECT_NOT_FOUND 404, NOT_FOUND 404, PAYMENT_REQUIRED 402, VALIDATION_FAILED 400) whenever the chain supplied one; branch on errorKey, never on message. Gateway-side refusals (BOUNDS_VIOLATION, SIGNATURE_INVALID, ...) never carry errorKey. A queued RequestTrade is acknowledged with data.mode "queued" and the request uniqueKey; confirm it via GET /v1/chain/apply-results/{uniqueKey} or GET /v2/trade/transaction?uniqueKey=.

## Path parameters

- `channel` string, required
- `contract` string, required
- `method` string, required

## Headers

- `x-wallet-address` string
- `x-shadow` string

## Request body

- object

## Response `201`

The chain write was accepted synchronously or queued for application.

- ChainSubmissionResponseDto
  - `status` number, required
  - `error` boolean, required
  - `message` string, required
  - `data` union, required
    - ChainSyncWriteDataResponseDto
      - `mode` 'sync', required
      - `transactionId` string, required
      - `result` object, required: Executed chain result; fields depend on the registered method.
      - `blockNumber` number
    - ChainQueuedWriteDataResponseDto
      - `mode` 'queued', required
      - `transactionId` string
      - `uniqueKey` string
      - `blockNumber` number

## Other responses

- `default`: An error response using the shared backend error envelope.

---

[API](https://skmtc.dev/gala/apis/gala-defi-backend-api.md) - [All operations](https://skmtc.dev/gala/apis/gala-defi-backend-api/llms.txt) - [OpenAPI document](https://skmtc.dev/gala/apis/gala-defi-backend-api/revisions/84f8184e2828?raw)
