> For the complete documentation index, see [llms.txt](https://docs.yifi.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.yifi.io/api-reference/transactions.md).

# Transactions

Poll status and submit an on-chain deposit hash

## Get transaction status

> Returns the current status of an order created via \`POST /v1/swap\`.\
> \
> \`id\` is the \*\*YiFi UUID\*\* from \`transactionId\` in the create-swap response. A provider order id is not accepted and returns \`404\` \`TRANSACTION\_NOT\_FOUND\`. Empty / whitespace \`id\` → \`400\` \`INVALID\_TRANSACTION\_UUID\`.\
> \
> Token fields are expanded to objects (\`ticker\`, \`network\`, logos, \`contractAddress\`, \`chainId\`, \`decimals\`). \`inputAmount\` is the stored deposit amount. \`exchangeRate\` is \`receiveAmount / inputAmount\` when both parse as numbers and input > 0; otherwise \`null\`.\
> \
> \`fee\` from storage is \*\*not\*\* returned. Extra workflow fields that are returned when present: \`txDepositHash\`, \`txOutputHash\`, \`depositAddress\`, \`receiveAddress\`, \`statusList\`.\
> \
> There is \*\*no\*\* \`access\_token\` query on this public route when \`id\` is a YiFi UUID (unlike api-gateway).\
> \
> \*\*Top-level \`status\`:\*\* \`pending\` → \`processing\` → \`completed\`, or \`failed\` / \`cancelled\`. \`statusList\` keys are provider-specific booleans.

```json
{"openapi":"3.0.0","info":{"title":"YiFi Swap Public API","version":"1.0"},"tags":[{"name":"Transactions","description":"Poll status and submit an on-chain deposit hash"}],"servers":[{"url":"https://api.yifi.io","description":"Production"},{"url":"https://api-dev.yifi.io","description":"Development / Staging"}],"paths":{"/v1/transactions/{id}":{"get":{"description":"Returns the current status of an order created via `POST /v1/swap`.\n\n`id` is the **YiFi UUID** from `transactionId` in the create-swap response. A provider order id is not accepted and returns `404` `TRANSACTION_NOT_FOUND`. Empty / whitespace `id` → `400` `INVALID_TRANSACTION_UUID`.\n\nToken fields are expanded to objects (`ticker`, `network`, logos, `contractAddress`, `chainId`, `decimals`). `inputAmount` is the stored deposit amount. `exchangeRate` is `receiveAmount / inputAmount` when both parse as numbers and input > 0; otherwise `null`.\n\n`fee` from storage is **not** returned. Extra workflow fields that are returned when present: `txDepositHash`, `txOutputHash`, `depositAddress`, `receiveAddress`, `statusList`.\n\nThere is **no** `access_token` query on this public route when `id` is a YiFi UUID (unlike api-gateway).\n\n**Top-level `status`:** `pending` → `processing` → `completed`, or `failed` / `cancelled`. `statusList` keys are provider-specific booleans.","operationId":"getTransactionStatus","parameters":[{"name":"id","required":true,"in":"path","description":"YiFi transaction UUID from `POST /v1/swap` → `transactionId`. Provider order ids are rejected.","schema":{"type":"string"}}],"responses":{"200":{"description":"Transaction details and current status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransactionStatusResponseDto"}}}},"400":{"description":"`INVALID_TRANSACTION_UUID` (empty id)","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string","description":"Machine-readable code (`COIN_NOT_FOUND`, `RATE_EXPIRED`, `INVALID_API_KEY`, `HTTP_EXCEPTION` for class-validator, …)"},"message":{"description":"Human-readable message. Class-validator 400s may return a string **array** of constraint texts.","oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"requestId":{"type":"string"},"timestamp":{"type":"string","format":"date-time"},"details":{"description":"Present for some validation (4xx) errors when thrown with `details`.","oneOf":[{"type":"object","additionalProperties":true},{"type":"array"}]}},"required":["code","message","requestId","timestamp"]}}}}}},"404":{"description":"`TRANSACTION_NOT_FOUND`","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string","description":"Machine-readable code (`COIN_NOT_FOUND`, `RATE_EXPIRED`, `INVALID_API_KEY`, `HTTP_EXCEPTION` for class-validator, …)"},"message":{"description":"Human-readable message. Class-validator 400s may return a string **array** of constraint texts.","oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"requestId":{"type":"string"},"timestamp":{"type":"string","format":"date-time"},"details":{"description":"Present for some validation (4xx) errors when thrown with `details`.","oneOf":[{"type":"object","additionalProperties":true},{"type":"array"}]}},"required":["code","message","requestId","timestamp"]}}}}}},"408":{"description":"`WORKFLOW_TIMEOUT` (30s)","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string","description":"Machine-readable code (`COIN_NOT_FOUND`, `RATE_EXPIRED`, `INVALID_API_KEY`, `HTTP_EXCEPTION` for class-validator, …)"},"message":{"description":"Human-readable message. Class-validator 400s may return a string **array** of constraint texts.","oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"requestId":{"type":"string"},"timestamp":{"type":"string","format":"date-time"},"details":{"description":"Present for some validation (4xx) errors when thrown with `details`.","oneOf":[{"type":"object","additionalProperties":true},{"type":"array"}]}},"required":["code","message","requestId","timestamp"]}}}}}},"500":{"description":"`INCOMPLETE_TRANSACTION_DATA` or `TRANSACTION_STATUS_ERROR`","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string","description":"Machine-readable code (`COIN_NOT_FOUND`, `RATE_EXPIRED`, `INVALID_API_KEY`, `HTTP_EXCEPTION` for class-validator, …)"},"message":{"description":"Human-readable message. Class-validator 400s may return a string **array** of constraint texts.","oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"requestId":{"type":"string"},"timestamp":{"type":"string","format":"date-time"},"details":{"description":"Present for some validation (4xx) errors when thrown with `details`.","oneOf":[{"type":"object","additionalProperties":true},{"type":"array"}]}},"required":["code","message","requestId","timestamp"]}}}}}}},"summary":"Get transaction status","tags":["App","Transactions"]}}},"components":{"schemas":{"TransactionStatusResponseDto":{"type":"object","properties":{"uuid":{"type":"string","description":"YiFi UUID. Same value as `POST /v1/swap` → `transactionId` and as the path `{id}` you queried."},"transactionId":{"type":"string","description":"Provider-side transaction id (may differ from `uuid`)"},"status":{"type":"string","description":"Current top-level swap status","enum":["pending","processing","completed","failed","cancelled"]},"statusList":{"type":"object","description":"Granular step-by-step status map. Keys vary by provider and engine."},"engine":{"type":"string","description":"Swap engine used for this transaction","enum":["on-chain","off-chain","private"]},"provider":{"type":"string","description":"Provider slug executing this swap"},"logoProvider":{"type":"object","description":"Provider logo URL"},"fromToken":{"description":"Source token details","allOf":[{"$ref":"#/components/schemas/TransactionTokenDto"}]},"toToken":{"description":"Target token details","allOf":[{"$ref":"#/components/schemas/TransactionTokenDto"}]},"inputAmount":{"type":"string","description":"Amount sent by the user in source token units"},"receiveAmount":{"type":"string","description":"Amount received (or expected) in target token units"},"startTime":{"type":"string","description":"Timestamp when the transaction was created"},"completionTime":{"type":"string","description":"Timestamp when the transaction reached a terminal state (`completed`, `failed`, or `cancelled`). `null` while in progress."},"exchangeRate":{"type":"object","description":"Effective exchange rate (`receiveAmount / inputAmount`). Populated once the swap reaches `completed` status.","nullable":true},"expirationTime":{"type":"object","description":"Order expiration captured at swap creation (same as in create-swap response; mapped via exchanger expirationTimePath)","nullable":true},"txCreateMeta":{"type":"object","description":"Raw provider metadata from transaction creation. May be an empty object or JSON string."},"txDepositHash":{"type":"object","description":"On-chain deposit hash once known. `null` / omitted while waiting.","nullable":true},"txOutputHash":{"type":"object","description":"On-chain output / payout hash once known. `null` / omitted while waiting.","nullable":true},"depositAddress":{"type":"object","description":"Deposit address the user must send to (CEX / private)","nullable":true},"receiveAddress":{"type":"object","description":"Destination address that receives the output token","nullable":true}},"required":["uuid","transactionId","status","engine","provider","fromToken","toToken","inputAmount","receiveAmount"]},"TransactionTokenDto":{"type":"object","properties":{"ticker":{"type":"string","description":"Token ticker"},"network":{"type":"string","description":"Chain slug"},"logoTicker":{"type":"object","description":"Token logo URL or structured logo payload. May be an empty object `{}` while not loaded."},"logoNetwork":{"type":"object","description":"Network logo URL or structured logo payload. May be an empty object `{}` while not loaded."},"contractAddress":{"type":"object","description":"Token contract address (null for native coins)","nullable":true},"chainId":{"type":"object","description":"EVM chainId of the network (null when unknown or non-EVM)","nullable":true},"decimals":{"type":"object","description":"Token decimals","nullable":true}},"required":["ticker","network"]}}}}
```

## Submit deposit transaction hash

> Forwards \`{ from, to, hash }\` to \`setDepositHashWorkflow\` after the user broadcasts a \*\*DEX\*\* deposit.\
> \
> Query \`access\_token\` is required (the secret from \`POST /v1/swap\`). Missing token → \`400\` \`ACCESS\_TOKEN\_REQUIRED\` without an order lookup.\
> \
> \`transactionProvider\` is the provider order id passed to the workflow as \`transactionId\`.\
> \
> \`engine\` is case-insensitive and must be \`dex\`. \`cex\` and \`private\` → \`400\` \`INVALID\_ENGINE\` and the workflow is not started.\
> \
> The hash is stored once. The same hash returns \`true\` without rewriting. A different hash → \`409\` \`DEPOSIT\_HASH\_ALREADY\_SET\`.\
> \
> Optional body field \`input\` is passed through as workflow \`meta.data\`.\
> \
> Success body is JSON \`true\` (\`201\`).

```json
{"openapi":"3.0.0","info":{"title":"YiFi Swap Public API","version":"1.0"},"tags":[{"name":"Transactions","description":"Poll status and submit an on-chain deposit hash"}],"servers":[{"url":"https://api.yifi.io","description":"Production"},{"url":"https://api-dev.yifi.io","description":"Development / Staging"}],"paths":{"/v1/transactions/{transactionProvider}/{engine}/set-deposit-hash":{"post":{"description":"Forwards `{ from, to, hash }` to `setDepositHashWorkflow` after the user broadcasts a **DEX** deposit.\n\nQuery `access_token` is required (the secret from `POST /v1/swap`). Missing token → `400` `ACCESS_TOKEN_REQUIRED` without an order lookup.\n\n`transactionProvider` is the provider order id passed to the workflow as `transactionId`.\n\n`engine` is case-insensitive and must be `dex`. `cex` and `private` → `400` `INVALID_ENGINE` and the workflow is not started.\n\nThe hash is stored once. The same hash returns `true` without rewriting. A different hash → `409` `DEPOSIT_HASH_ALREADY_SET`.\n\nOptional body field `input` is passed through as workflow `meta.data`.\n\nSuccess body is JSON `true` (`201`).","operationId":"setDepositHash","parameters":[{"name":"transactionProvider","required":true,"in":"path","description":"Provider-side transaction id / slug passed to `setDepositHashWorkflow` as `transactionId`","schema":{"type":"string"}},{"name":"engine","required":true,"in":"path","description":"Must be `dex`. Other engines are rejected.","schema":{"type":"string","enum":["dex"]}},{"name":"access_token","required":true,"in":"query","description":"Order access token returned by `POST /v1/swap`","schema":{}}],"requestBody":{"required":true,"description":"On-chain deposit transfer identifiers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetDepositHashDto"}}}},"responses":{"201":{"description":"Workflow returned success (`true`)","content":{"application/json":{"schema":{"type":"boolean"}}}},"400":{"description":"Invalid `engine`, missing `access_token`, or `from` / `to` / `hash` missing or not strings (`INVALID_BODY`)","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string","description":"Machine-readable code (`COIN_NOT_FOUND`, `RATE_EXPIRED`, `INVALID_API_KEY`, `HTTP_EXCEPTION` for class-validator, …)"},"message":{"description":"Human-readable message. Class-validator 400s may return a string **array** of constraint texts.","oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"requestId":{"type":"string"},"timestamp":{"type":"string","format":"date-time"},"details":{"description":"Present for some validation (4xx) errors when thrown with `details`.","oneOf":[{"type":"object","additionalProperties":true},{"type":"array"}]}},"required":["code","message","requestId","timestamp"]}}}}}},"500":{"description":"`DEX_NOT_CONFIGURED` or `WORKFLOW_EXECUTION_FAILED`","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"string","description":"Machine-readable code (`COIN_NOT_FOUND`, `RATE_EXPIRED`, `INVALID_API_KEY`, `HTTP_EXCEPTION` for class-validator, …)"},"message":{"description":"Human-readable message. Class-validator 400s may return a string **array** of constraint texts.","oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"requestId":{"type":"string"},"timestamp":{"type":"string","format":"date-time"},"details":{"description":"Present for some validation (4xx) errors when thrown with `details`.","oneOf":[{"type":"object","additionalProperties":true},{"type":"array"}]}},"required":["code","message","requestId","timestamp"]}}}}}}},"summary":"Submit deposit transaction hash","tags":["App","Transactions"]}}},"components":{"schemas":{"SetDepositHashDto":{"type":"object","properties":{"from":{"type":"string","description":"Sender wallet address that broadcast the deposit"},"to":{"type":"string","description":"Deposit destination: provider deposit address (CEX/private) or the contract the user sent to (DEX)"},"hash":{"type":"string","description":"On-chain transaction hash of the broadcast deposit"},"input":{"type":"object","description":"Optional raw input forwarded to the provider workflow as `meta.data`. Shape is provider-specific."}},"required":["from","to","hash"]}}}}
```
