# Check swap execution status (/docs/api-reference/get-execution-status)

GET/v0/status

The example below is a real `SUCCESS` swap (5 USDC → wNEAR). See [Status lifecycle](/docs/concepts/status-lifecycle). Retrieves the current status of a swap using the unique deposit address from the quote, if quote response included deposit memo, it is required as well. The response includes the state of the swap (e.g., pending, processing, success, refunded) and any associated swap and transaction details. **Operation id:** `getExecutionStatus` · **Auth:** optional (`X-API-Key` or `Authorization: Bearer`, any value) ## Request [#request] ```bash curl "https://www.usetidepool.tech/v0/status?depositAddress=c47208de64cde76fc6803b5f26c137bc51fbf151eb1c0964488ea56704142151" ``` ```ts const res = await fetch('https://www.usetidepool.tech/v0/status?depositAddress=c47208de64cde76fc6803b5f26c137bc51fbf151eb1c0964488ea56704142151'); const data = await res.json(); ``` ### Try it [#try-it] ### Query parameters [#query-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `depositAddress` | string | yes | | | `depositMemo` | string | | | ## Responses [#responses] ### 200 [#200] ```json { "correlationId": "6e7d2aad-b262-4b13-b88e-0c4d6b64325c", "quoteResponse": { "correlationId": "6e7d2aad-b262-4b13-b88e-0c4d6b64325c", "timestamp": "2026-10-24T21:30:28.060Z", "quoteRequest": { "swapType": "EXACT_INPUT", "slippageTolerance": 100, "originAsset": "nep141:usdc.tidepool-sandbox.testnet", "destinationAsset": "nep141:wnear.tidepool-sandbox.testnet", "amount": "5000000", "depositType": "INTENTS", "refundTo": "tidepool-try-0937467b.testnet", "refundType": "INTENTS", "recipient": "tidepool-try-0937467b.testnet", "recipientType": "DESTINATION_CHAIN", "dry": false, "deadline": "2026-10-24T21:40:27.927Z" }, "quote": { "amountIn": "5000000", "amountInFormatted": "5", "amountInUsd": "4.9979", "minAmountIn": "5000000", "amountOut": "1123407466216216112640000", "amountOutFormatted": "1.12340746621621611264", "amountOutUsd": "4.9879", "minAmountOut": "1112173391554053951513600", "timeEstimate": 10, "depositAddress": "c47208de64cde76fc6803b5f26c137bc51fbf151eb1c0964488ea56704142151", "deadline": "2026-10-24T21:40:27.927Z", "timeWhenInactive": "2026-10-24T21:40:27.927Z" }, "signature": "ed25519:3D679QeYbrSEAnHRmkG1eurAeWnnecYQBNWLgmQuEzSvdQpqmKzP2R9W4FqeqLzJvrem4JU3xVnXamFjz74sCKfj" }, "status": "SUCCESS", "updatedAt": "2026-10-24T21:30:42.751Z", "swapDetails": { "intentHashes": [ "DsrGVDFfwq6ifa9LctU2JaCzWB2kZB1VzNe1XHFCC3qS", "23MCaK5ZV2qanV6p1LYzpGh7zwPC3pa9vqGSm6hLij6H" ], "nearTxHashes": [ "EB5xfEyjiC1oESNjEyNjnkzW4Zpsi24e4H2s6aUGEh9d" ], "originChainTxHashes": [ { "hash": "HbwEo318L69bJS7XYse18mUTzBBa2tjK6wtGeDYo3dY8", "explorerUrl": "https://testnet.nearblocks.io/txns/HbwEo318L69bJS7XYse18mUTzBBa2tjK6wtGeDYo3dY8" } ], "destinationChainTxHashes": [ { "hash": "EB5xfEyjiC1oESNjEyNjnkzW4Zpsi24e4H2s6aUGEh9d", "explorerUrl": "https://testnet.nearblocks.io/txns/EB5xfEyjiC1oESNjEyNjnkzW4Zpsi24e4H2s6aUGEh9d" } ], "amountIn": "5000000", "amountInFormatted": "5", "amountInUsd": "4.9979", "amountOut": "1123407466216216112640000", "amountOutFormatted": "1.12340746621621611264", "amountOutUsd": "4.9879", "slippage": 0, "depositedAmount": "5000000", "depositedAmountFormatted": "5", "depositedAmountUsd": "4.9979" }, "tidepool": { "explorer": [ { "label": "swap (execute_intents)", "url": "https://testnet.nearblocks.io/txns/EB5xfEyjiC1oESNjEyNjnkzW4Zpsi24e4H2s6aUGEh9d" } ] } } ``` | Field | Type | Required | Description | | --- | --- | --- | --- | | `correlationId` | string | yes | Unique identifier for request tracing and debugging | | `quoteResponse` | object | yes | Quote response from the original request | | `quoteResponse.correlationId` | string | yes | Unique identifier for request tracing and debugging | | `quoteResponse.timestamp` | string | yes | Timestamp in ISO format that was used to derive the deposit address | | `quoteResponse.signature` | string | yes | Signature of the 1Click service confirming the quote for the specific deposit address. Must be saved on the client side (along with the whole quote) in order to resolve any disputes or mistakes. | | `quoteResponse.quoteRequest` | object | yes | User request | | `quoteResponse.quoteRequest.dry` | boolean | yes | Flag indicating whether this is a dry run request. If `true`, the response will **NOT** contain the following fields: - `depositAddress` - `timeWhenInactive` - `deadline` | | `quoteResponse.quoteRequest.depositMode` | "SIMPLE" \\| "MEMO" | | What deposit address mode you will get in the response, most chain supports only `SIMPLE` and some(for example `stellar`) only `MEMO`: - `SIMPLE` - usual deposit with only deposit address. - `MEMO` - some chains will **REQUIRE** the `memo` together with `depositAddress` for swap to work. `depositMode` applies only to deposit transaction metadata. | | `quoteResponse.quoteRequest.swapType` | "EXACT_INPUT" \\| "EXACT_OUTPUT" \\| "FLEX_INPUT" \\| "ANY_INPUT" | yes | How to interpret `amount` (and refunds) when performing the swap: - `EXACT_INPUT` — requests the output amount for an exact input. - If deposit is less than `amountIn`, the deposit is refunded by deadline. - If deposit is above than `amountIn`, the swap is processed and the excess is refunded to `refundTo` address after swap is complete. - `EXACT_OUTPUT` — requests the input amount for an exact output. - The output amount (`amountOut`) is fixed; slippage is applied to the **input** side. - The quote response includes `amountIn` (the proposed input with slippage tolerance baked in) and `minAmountIn` (the minimum input required). - **Important**: `amountIn` will appear higher than `minAmountIn` by approximately your `slippageTolerance`. This is **not** price degradation—it is a buffer to ensure successful execution. Any input amount above what is actually needed for the swap is **refunded** to your `refundTo` address after the swap completes. - If the deposit is above `amountIn`, the swap is processed and the excess is refunded to `refundTo` address after swap is complete. - If the deposit is less than `minAmountIn`, the deposit is refunded by deadline. - `FLEX_INPUT` — a flexible input amount that allows for partial deposits and variable amounts. - `slippage` applies both to `amountOut` and `amountIn` and defines an acceptable range (`minAmountIn` and `minAmountOut`). - Any amount higher than `minAmountIn` is accepted and converted to the output asset as long as `minAmountOut` is met. - The deposit must be at least `minAmountIn`, after applying the slippage constraint to the quoted amount. Deposits below `minAmountIn` are refunded if the total received by the deadline is below this amount. - If deposits exceed the upper bound, the swap is still processed - `ANY_INPUT` — collects deposits and converts them to a destination asset. Used for fee aggregation and similar use cases. Only available for authorized partners. | | `quoteResponse.quoteRequest.slippageTolerance` | number | yes | Slippage tolerance for the swap. This value is in basis points (1/100th of a percent), e.g. 100 for 1% slippage. | | `quoteResponse.quoteRequest.originAsset` | string | yes | ID of the origin asset. | | `quoteResponse.quoteRequest.depositType` | "ORIGIN_CHAIN" \\| "INTENTS" \\| "CONFIDENTIAL_INTENTS" | yes | Type of deposit address: - `ORIGIN_CHAIN` - deposit address on the origin chain. - `INTENTS` - the account ID within NEAR Intents to which you should transfer assets. - `CONFIDENTIAL_INTENTS` - the account ID within Confidential Intents to which assets are to be transferred. Fund the swap from a Confidential Intents account by submitting a signed transfer intent to the quote `depositAddress`. Direct token transfers are not supported. | | `quoteResponse.quoteRequest.destinationAsset` | string | yes | ID of the destination asset. | | `quoteResponse.quoteRequest.amount` | string | yes | Amount to swap as the base amount. It is interpreted as the input or output amount based on the `swapType` flag and is specified in the smallest unit of the currency (e.g., wei for ETH). Must be an integer string; decimal values like "0.01" are invalid—use base units (e.g. "10000000000000000" for 0.01 with 18 decimals). | | `quoteResponse.quoteRequest.refundTo` | string | yes | Address used for refunds. | | `quoteResponse.quoteRequest.refundType` | "ORIGIN_CHAIN" \\| "INTENTS" \\| "CONFIDENTIAL_INTENTS" | yes | Type of refund address: - `ORIGIN_CHAIN` - assets are refunded to the `refundTo` address on the origin chain. - `INTENTS` - assets are refunded to the `refundTo` Intents account. - `CONFIDENTIAL_INTENTS` - assets are refunded to the `refundTo` Confidential Intents account. On Confidential Intents, 1Click settles refunds via signed transfer intent rather than direct token transfer. | | `quoteResponse.quoteRequest.recipient` | string | yes | Recipient address. The format must match `recipientType`. Destination routing metadata, when required, must be encoded according to the destination chain address format. | | `quoteResponse.quoteRequest.connectedWallets` | string[] | | Addresses of connected wallets. | | `quoteResponse.quoteRequest.sessionId` | string | | Unique client session identifier for 1Click. | | `quoteResponse.quoteRequest.virtualChainRecipient` | string | | EVM address of a transfer recipient in a virtual chain | | `quoteResponse.quoteRequest.virtualChainRefundRecipient` | string | | EVM address of a refund recipient in a virtual chain | | `quoteResponse.quoteRequest.customRecipientMsg` | string | | **HIGHLY EXPERIMENTAL** Message to pass to `ft_transfer_call` when withdrawing assets to NEAR. Otherwise, `ft_transfer` will be used. **WARNING**: Funds will be lost if used with non NEP-141 tokens, in case of insufficient `storage_deposit` or if the recipient does not implement `ft_on_transfer` method. | | `quoteResponse.quoteRequest.recipientType` | "DESTINATION_CHAIN" \\| "INTENTS" \\| "CONFIDENTIAL_INTENTS" | yes | Type of recipient address: - `DESTINATION_CHAIN` - assets are transferred to the chain of `destinationAsset`. - `INTENTS` - assets are transferred to an account inside Intents. - `CONFIDENTIAL_INTENTS` - assets are transferred to the `recipient` account inside Confidential Intents. On Confidential Intents, 1Click settles swap output via signed transfer intent rather than direct token transfer. | | `quoteResponse.quoteRequest.deadline` | string | yes | Timestamp in ISO format that identifies when the user refund begins if the swap isn't completed by then. It must exceed the time required for the deposit transaction to be mined. For example, Bitcoin may require around one hour depending on the fees paid. | | `quoteResponse.quoteRequest.confidentiality` | "public" \\| "basic" \\| "advanced" | | Confidentiality mode for this quote. PUBLIC is the default; BASIC or ADVANCED request Confidential Intents handling. | | `quoteResponse.quoteRequest.referral` | string | | Distribution channel / venue identifier (for example: ledger, trustwallet). Keep lowercase for consistency. | | `quoteResponse.quoteRequest.rebates` | Rebate[] | | Rebate distribution for this quote. Provide up to 3 confidential Intents recipients (for example, `rebate-recipient.near` on confidential Intents); each item defines a recipient and its percent share, and all shares must add up to 100. | | `quoteResponse.quoteRequest.rebates[].[]recipient` | string | yes | Confidential Intents account identifier that receives this rebate share. Rebate delivery uses signed transfer intent on Confidential Intents; direct token transfers are not supported. | | `quoteResponse.quoteRequest.rebates[].[]share` | number | yes | Rebate share for this recipient in percent. | | `quoteResponse.quoteRequest.quoteWaitingTimeMs` | number | | Time in milliseconds the user is willing to wait for a quote from the relay. **Defaults to 0ms delay if not specified, if you want to receive the fastest quote. | | `quoteResponse.quoteRequest.appFees` | AppFee[] | | List of recipients and their fees | | `quoteResponse.quoteRequest.appFees[].[]recipient` | string | yes | Account ID within Intents to which this fee will be transferred | | `quoteResponse.quoteRequest.appFees[].[]fee` | number | yes | Fee for this recipient as part of amountIn in basis points (1/100th of a percent), e.g. 100 for 1% fee | | `quoteResponse.quoteRequest.insured` | boolean | | Opt into an insured swap. When `true`, an additional 0.02% (2 basis points) insurance fee is charged on top of any other fees. | | `quoteResponse.quote` | object | yes | Response containing the deposit address for sending the `amount` of `originAsset` and the expected output amount. | | `quoteResponse.quote.depositAddress` | string | | The deposit address on the chain of `originAsset` when `depositType` is `ORIGIN_CHAIN`. The deposit address inside NEAR Intents (the verifier smart contract) when `depositType` is `INTENTS`. The account ID within Confidential Intents to which assets are to be transferred when `depositType` is `CONFIDENTIAL_INTENTS`. Fund the swap by submitting a signed transfer intent to this value. Direct token transfers are not supported. | | `quoteResponse.quote.depositMemo` | string | | Some deposit addresses **REQUIRE** a `memo` together with `depositAddress` for the deposit to be processed. This field is deposit-side metadata. | | `quoteResponse.quote.chainDepositAddresses` | ChainDepositAddress[] | | Deposit addresses across all bridge-supported blockchains for funding the same Intents account. Present only for public `ANY_INPUT` quotes (`depositType` `INTENTS`); the confidential rail does not support multi-chain funding addresses yet. Each entry forwards to the Intents account in `depositAddress`, so the user may deposit from any listed chain. | | `quoteResponse.quote.chainDepositAddresses[].[]blockchain` | "near" | yes | Blockchain on which this deposit address accepts funds for the quote. | | `quoteResponse.quote.chainDepositAddresses[].[]address` | string | yes | Deposit address on `blockchain`. Funds sent here are credited to the same Intents account. | | `quoteResponse.quote.chainDepositAddresses[].[]memo` | string | | Memo required together with `address` on chains that need it (e.g. Stellar, XRP, TON). | | `quoteResponse.quote.amountIn` | string | yes | Amount of the origin asset | | `quoteResponse.quote.amountInFormatted` | string | yes | Amount of the origin asset in readable format | | `quoteResponse.quote.amountInUsd` | string | yes | Amount of the origin assets equivalent in USD | | `quoteResponse.quote.minAmountIn` | string | yes | Minimum amount of the origin asset that will be used for the swap | | `quoteResponse.quote.amountOut` | string | yes | Amount of the destination asset | | `quoteResponse.quote.amountOutFormatted` | string | yes | Amount of the destination asset in readable format | | `quoteResponse.quote.amountOutUsd` | string | yes | Amount of the destination asset equivalent in USD | | `quoteResponse.quote.minAmountOut` | string | yes | Minimum output amount after slippage is applied | | `quoteResponse.quote.deadline` | string | | Time when the deposit address becomes inactive and funds may be lost | | `quoteResponse.quote.timeWhenInactive` | string | | Time when the deposit address becomes cold, causing swap processing to take longer | | `quoteResponse.quote.timeEstimate` | number | yes | Estimated time in seconds for the swap to be executed after the deposit transaction is confirmed | | `quoteResponse.quote.virtualChainRecipient` | string | | EVM address of a transfer recipient in a virtual chain | | `quoteResponse.quote.virtualChainRefundRecipient` | string | | EVM address of a refund recipient in a virtual chain | | `quoteResponse.quote.customRecipientMsg` | string | | **HIGHLY EXPERIMENTAL** Message passed to `ft_transfer_call` when withdrawing assets to NEAR. Otherwise, `ft_transfer` will be used. **WARNING**: Funds will be lost if used with non NEP-141 tokens, in case of insufficient `storage_deposit` or if the recipient does not implement `ft_on_transfer` method. | | `quoteResponse.quote.refundFee` | string | | Fee charged for refunding assets to the refund address in the smallest unit of the origin asset | | `quoteResponse.quote.withdrawFee` | string | | Fee charged for withdrawing assets to the recipient in the smallest unit of the destination asset. This fee is already accounted for in the final amountOut result | | `status` | "KNOWN_DEPOSIT_TX" \\| "PENDING_DEPOSIT" \\| "INCOMPLETE_DEPOSIT" \\| "PROCESSING" \\| "SUCCESS" \\| "REFUNDED" \\| "FAILED" | yes | | | `updatedAt` | string | yes | Last time the state was updated | | `swapDetails` | object | yes | Details of actual swaps and withdrawals | | `swapDetails.intentHashes` | string[] | yes | All intent hashes that took part in this swap | | `swapDetails.nearTxHashes` | string[] | yes | All NEAR transactions executed for this swap | | `swapDetails.amountIn` | string | | Exact amount of `originToken` after the trade was settled | | `swapDetails.amountInFormatted` | string | | Exact amount of `originToken` in readable format after the trade was settled | | `swapDetails.amountInUsd` | string | | Exact amount of `originToken` equivalent in USD | | `swapDetails.amountOut` | string | | Exact amount of `destinationToken` after the trade was settled | | `swapDetails.amountOutFormatted` | string | | Exact amount of `destinationToken` in readable format after the trade was settled | | `swapDetails.amountOutUsd` | string | | Exact amount of `destinationToken` equivalent in USD | | `swapDetails.slippage` | number | | Actual slippage | | `swapDetails.originChainTxHashes` | TransactionDetails[] | yes | Hashes and explorer URLs for all transactions on the origin chain | | `swapDetails.originChainTxHashes[].[]hash` | string | yes | Transaction hash | | `swapDetails.originChainTxHashes[].[]explorerUrl` | string | yes | Explorer URL for the transaction | | `swapDetails.destinationChainTxHashes` | TransactionDetails[] | yes | Hashes and explorer URLs for all transactions on the destination chain | | `swapDetails.destinationChainTxHashes[].[]hash` | string | yes | Transaction hash | | `swapDetails.destinationChainTxHashes[].[]explorerUrl` | string | yes | Explorer URL for the transaction | | `swapDetails.refundedAmount` | string | | Amount of `originAsset` transferred to `refundTo` | | `swapDetails.refundedAmountFormatted` | string | | Refunded amount in readable format | | `swapDetails.refundedAmountUsd` | string | | Refunded amount equivalent in USD | | `swapDetails.refundReason` | string | | Reason for refund | | `swapDetails.depositedAmount` | string | | Amount deposited to `depositAddress` onchain | | `swapDetails.depositedAmountFormatted` | string | | Amount deposited in readable format | | `swapDetails.depositedAmountUsd` | string | | Amount deposited equivalent in USD | | `swapDetails.withdrawFee` | string | | Fee charged for withdrawing assets to the recipient in the smallest unit of the destination asset. This fee is already accounted for in the final amountOut result | | `swapDetails.referral` | string | | Referral identifier | ### 401 Unauthorized - API key or JWT token is invalid [#401-unauthorized---api-key-or-jwt-token-is-invalid] ### 404 Deposit address not found [#404-deposit-address-not-found] ```json { "message": "Deposit address not found" } ``` # Request a swap quote (/docs/api-reference/get-quote)

POST/v0/quote

Returns **HTTP 201** on success (the spec lists 200, matching 1Click). With `dry: false` the response adds `quote.depositAddress`, `deadline` and `timeWhenInactive`. See [Quotes and pricing](/docs/concepts/quotes) and [Swap types](/docs/concepts/swap-types). Generates a swap quote based on input parameters such as the assets, amount, slippage tolerance, and recipient/refund information. Returns pricing details, estimated time, and a unique **deposit address** to which tokens must be transferred to initiate the swap. You can set the `dry` parameter to `true` to simulate the quote request **without generating a deposit address** or initiating the swap process. This is useful for previewing swap parameters or validating input data without committing to an actual swap. This endpoint is the first required step in the swap process. Tidepool v1 supports EXACT_INPUT, EXACT_OUTPUT and FLEX_INPUT; ORIGIN_CHAIN and INTENTS deposit/refund types; DESTINATION_CHAIN and INTENTS recipient types. Other values return 400. **Operation id:** `getQuote` · **Auth:** optional (`X-API-Key` or `Authorization: Bearer`, any value) ## Request [#request] ```bash curl -X POST "https://www.usetidepool.tech/v0/quote" \ -H 'content-type: application/json' \ -d '{ "dry": true, "swapType": "EXACT_INPUT", "slippageTolerance": 100, "originAsset": "nep141:usdc.tidepool-sandbox.testnet", "depositType": "INTENTS", "destinationAsset": "nep141:wnear.tidepool-sandbox.testnet", "amount": "10000000", "refundTo": "alice.testnet", "refundType": "INTENTS", "recipient": "alice.testnet", "recipientType": "DESTINATION_CHAIN", "deadline": "2030-01-01T00:00:00.000Z" }' ``` ```ts const res = await fetch('https://www.usetidepool.tech/v0/quote', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ "dry": true, "swapType": "EXACT_INPUT", "slippageTolerance": 100, "originAsset": "nep141:usdc.tidepool-sandbox.testnet", "depositType": "INTENTS", "destinationAsset": "nep141:wnear.tidepool-sandbox.testnet", "amount": "10000000", "refundTo": "alice.testnet", "refundType": "INTENTS", "recipient": "alice.testnet", "recipientType": "DESTINATION_CHAIN", "deadline": "2030-01-01T00:00:00.000Z" }), }); const data = await res.json(); ``` ### Try it [#try-it] ### Body [#body] | Field | Type | Required | Description | | --- | --- | --- | --- | | `dry` | boolean | yes | Flag indicating whether this is a dry run request. If `true`, the response will **NOT** contain the following fields: - `depositAddress` - `timeWhenInactive` - `deadline` | | `depositMode` | "SIMPLE" \\| "MEMO" | | What deposit address mode you will get in the response, most chain supports only `SIMPLE` and some(for example `stellar`) only `MEMO`: - `SIMPLE` - usual deposit with only deposit address. - `MEMO` - some chains will **REQUIRE** the `memo` together with `depositAddress` for swap to work. `depositMode` applies only to deposit transaction metadata. | | `swapType` | "EXACT_INPUT" \\| "EXACT_OUTPUT" \\| "FLEX_INPUT" \\| "ANY_INPUT" | yes | How to interpret `amount` (and refunds) when performing the swap: - `EXACT_INPUT` — requests the output amount for an exact input. - If deposit is less than `amountIn`, the deposit is refunded by deadline. - If deposit is above than `amountIn`, the swap is processed and the excess is refunded to `refundTo` address after swap is complete. - `EXACT_OUTPUT` — requests the input amount for an exact output. - The output amount (`amountOut`) is fixed; slippage is applied to the **input** side. - The quote response includes `amountIn` (the proposed input with slippage tolerance baked in) and `minAmountIn` (the minimum input required). - **Important**: `amountIn` will appear higher than `minAmountIn` by approximately your `slippageTolerance`. This is **not** price degradation—it is a buffer to ensure successful execution. Any input amount above what is actually needed for the swap is **refunded** to your `refundTo` address after the swap completes. - If the deposit is above `amountIn`, the swap is processed and the excess is refunded to `refundTo` address after swap is complete. - If the deposit is less than `minAmountIn`, the deposit is refunded by deadline. - `FLEX_INPUT` — a flexible input amount that allows for partial deposits and variable amounts. - `slippage` applies both to `amountOut` and `amountIn` and defines an acceptable range (`minAmountIn` and `minAmountOut`). - Any amount higher than `minAmountIn` is accepted and converted to the output asset as long as `minAmountOut` is met. - The deposit must be at least `minAmountIn`, after applying the slippage constraint to the quoted amount. Deposits below `minAmountIn` are refunded if the total received by the deadline is below this amount. - If deposits exceed the upper bound, the swap is still processed - `ANY_INPUT` — collects deposits and converts them to a destination asset. Used for fee aggregation and similar use cases. Only available for authorized partners. | | `slippageTolerance` | number | yes | Slippage tolerance for the swap. This value is in basis points (1/100th of a percent), e.g. 100 for 1% slippage. | | `originAsset` | string | yes | ID of the origin asset. | | `depositType` | "ORIGIN_CHAIN" \\| "INTENTS" \\| "CONFIDENTIAL_INTENTS" | yes | Type of deposit address: - `ORIGIN_CHAIN` - deposit address on the origin chain. - `INTENTS` - the account ID within NEAR Intents to which you should transfer assets. - `CONFIDENTIAL_INTENTS` - the account ID within Confidential Intents to which assets are to be transferred. Fund the swap from a Confidential Intents account by submitting a signed transfer intent to the quote `depositAddress`. Direct token transfers are not supported. | | `destinationAsset` | string | yes | ID of the destination asset. | | `amount` | string | yes | Amount to swap as the base amount. It is interpreted as the input or output amount based on the `swapType` flag and is specified in the smallest unit of the currency (e.g., wei for ETH). Must be an integer string; decimal values like "0.01" are invalid—use base units (e.g. "10000000000000000" for 0.01 with 18 decimals). | | `refundTo` | string | yes | Address used for refunds. | | `refundType` | "ORIGIN_CHAIN" \\| "INTENTS" \\| "CONFIDENTIAL_INTENTS" | yes | Type of refund address: - `ORIGIN_CHAIN` - assets are refunded to the `refundTo` address on the origin chain. - `INTENTS` - assets are refunded to the `refundTo` Intents account. - `CONFIDENTIAL_INTENTS` - assets are refunded to the `refundTo` Confidential Intents account. On Confidential Intents, 1Click settles refunds via signed transfer intent rather than direct token transfer. | | `recipient` | string | yes | Recipient address. The format must match `recipientType`. Destination routing metadata, when required, must be encoded according to the destination chain address format. | | `connectedWallets` | string[] | | Addresses of connected wallets. | | `sessionId` | string | | Unique client session identifier for 1Click. | | `virtualChainRecipient` | string | | EVM address of a transfer recipient in a virtual chain | | `virtualChainRefundRecipient` | string | | EVM address of a refund recipient in a virtual chain | | `customRecipientMsg` | string | | **HIGHLY EXPERIMENTAL** Message to pass to `ft_transfer_call` when withdrawing assets to NEAR. Otherwise, `ft_transfer` will be used. **WARNING**: Funds will be lost if used with non NEP-141 tokens, in case of insufficient `storage_deposit` or if the recipient does not implement `ft_on_transfer` method. | | `recipientType` | "DESTINATION_CHAIN" \\| "INTENTS" \\| "CONFIDENTIAL_INTENTS" | yes | Type of recipient address: - `DESTINATION_CHAIN` - assets are transferred to the chain of `destinationAsset`. - `INTENTS` - assets are transferred to an account inside Intents. - `CONFIDENTIAL_INTENTS` - assets are transferred to the `recipient` account inside Confidential Intents. On Confidential Intents, 1Click settles swap output via signed transfer intent rather than direct token transfer. | | `deadline` | string | yes | Timestamp in ISO format that identifies when the user refund begins if the swap isn't completed by then. It must exceed the time required for the deposit transaction to be mined. For example, Bitcoin may require around one hour depending on the fees paid. | | `confidentiality` | "public" \\| "basic" \\| "advanced" | | Confidentiality mode for this quote. PUBLIC is the default; BASIC or ADVANCED request Confidential Intents handling. | | `referral` | string | | Distribution channel / venue identifier (for example: ledger, trustwallet). Keep lowercase for consistency. | | `rebates` | Rebate[] | | Rebate distribution for this quote. Provide up to 3 confidential Intents recipients (for example, `rebate-recipient.near` on confidential Intents); each item defines a recipient and its percent share, and all shares must add up to 100. | | `rebates[].[]recipient` | string | yes | Confidential Intents account identifier that receives this rebate share. Rebate delivery uses signed transfer intent on Confidential Intents; direct token transfers are not supported. | | `rebates[].[]share` | number | yes | Rebate share for this recipient in percent. | | `quoteWaitingTimeMs` | number | | Time in milliseconds the user is willing to wait for a quote from the relay. **Defaults to 0ms delay if not specified, if you want to receive the fastest quote. | | `appFees` | AppFee[] | | List of recipients and their fees | | `appFees[].[]recipient` | string | yes | Account ID within Intents to which this fee will be transferred | | `appFees[].[]fee` | number | yes | Fee for this recipient as part of amountIn in basis points (1/100th of a percent), e.g. 100 for 1% fee | | `insured` | boolean | | Opt into an insured swap. When `true`, an additional 0.02% (2 basis points) insurance fee is charged on top of any other fees. | ## Responses [#responses] ### 200 [#200] ```json { "correlationId": "922a68ad-3d13-4a3f-a396-2965f8cc79d4", "timestamp": "2026-10-24T21:31:23.183Z", "quoteRequest": { "dry": true, "swapType": "EXACT_INPUT", "slippageTolerance": 100, "originAsset": "nep141:usdc.tidepool-sandbox.testnet", "depositType": "INTENTS", "destinationAsset": "nep141:wnear.tidepool-sandbox.testnet", "amount": "10000000", "refundTo": "alice.testnet", "refundType": "INTENTS", "recipient": "alice.testnet", "recipientType": "DESTINATION_CHAIN", "deadline": "2030-01-01T00:00:00.000Z" }, "quote": { "amountIn": "10000000", "amountInFormatted": "10", "amountInUsd": "9.9958", "minAmountIn": "10000000", "amountOut": "2241186638513513306880000", "amountOutFormatted": "2.24118663851351330688", "amountOutUsd": "9.9509", "minAmountOut": "2218774772128378173811200", "timeEstimate": 10 }, "signature": "ed25519:peWDyRaujC7pRHxRRU7DnSTWiw1vuiu8T5Pz9gNdfFYbGPedmnYLYKv7nfgLh9JbvZ5Nu6otgbKscHkDYU3JPaL" } ``` | Field | Type | Required | Description | | --- | --- | --- | --- | | `correlationId` | string | yes | Unique identifier for request tracing and debugging | | `timestamp` | string | yes | Timestamp in ISO format that was used to derive the deposit address | | `signature` | string | yes | Signature of the 1Click service confirming the quote for the specific deposit address. Must be saved on the client side (along with the whole quote) in order to resolve any disputes or mistakes. | | `quoteRequest` | object | yes | User request | | `quoteRequest.dry` | boolean | yes | Flag indicating whether this is a dry run request. If `true`, the response will **NOT** contain the following fields: - `depositAddress` - `timeWhenInactive` - `deadline` | | `quoteRequest.depositMode` | "SIMPLE" \\| "MEMO" | | What deposit address mode you will get in the response, most chain supports only `SIMPLE` and some(for example `stellar`) only `MEMO`: - `SIMPLE` - usual deposit with only deposit address. - `MEMO` - some chains will **REQUIRE** the `memo` together with `depositAddress` for swap to work. `depositMode` applies only to deposit transaction metadata. | | `quoteRequest.swapType` | "EXACT_INPUT" \\| "EXACT_OUTPUT" \\| "FLEX_INPUT" \\| "ANY_INPUT" | yes | How to interpret `amount` (and refunds) when performing the swap: - `EXACT_INPUT` — requests the output amount for an exact input. - If deposit is less than `amountIn`, the deposit is refunded by deadline. - If deposit is above than `amountIn`, the swap is processed and the excess is refunded to `refundTo` address after swap is complete. - `EXACT_OUTPUT` — requests the input amount for an exact output. - The output amount (`amountOut`) is fixed; slippage is applied to the **input** side. - The quote response includes `amountIn` (the proposed input with slippage tolerance baked in) and `minAmountIn` (the minimum input required). - **Important**: `amountIn` will appear higher than `minAmountIn` by approximately your `slippageTolerance`. This is **not** price degradation—it is a buffer to ensure successful execution. Any input amount above what is actually needed for the swap is **refunded** to your `refundTo` address after the swap completes. - If the deposit is above `amountIn`, the swap is processed and the excess is refunded to `refundTo` address after swap is complete. - If the deposit is less than `minAmountIn`, the deposit is refunded by deadline. - `FLEX_INPUT` — a flexible input amount that allows for partial deposits and variable amounts. - `slippage` applies both to `amountOut` and `amountIn` and defines an acceptable range (`minAmountIn` and `minAmountOut`). - Any amount higher than `minAmountIn` is accepted and converted to the output asset as long as `minAmountOut` is met. - The deposit must be at least `minAmountIn`, after applying the slippage constraint to the quoted amount. Deposits below `minAmountIn` are refunded if the total received by the deadline is below this amount. - If deposits exceed the upper bound, the swap is still processed - `ANY_INPUT` — collects deposits and converts them to a destination asset. Used for fee aggregation and similar use cases. Only available for authorized partners. | | `quoteRequest.slippageTolerance` | number | yes | Slippage tolerance for the swap. This value is in basis points (1/100th of a percent), e.g. 100 for 1% slippage. | | `quoteRequest.originAsset` | string | yes | ID of the origin asset. | | `quoteRequest.depositType` | "ORIGIN_CHAIN" \\| "INTENTS" \\| "CONFIDENTIAL_INTENTS" | yes | Type of deposit address: - `ORIGIN_CHAIN` - deposit address on the origin chain. - `INTENTS` - the account ID within NEAR Intents to which you should transfer assets. - `CONFIDENTIAL_INTENTS` - the account ID within Confidential Intents to which assets are to be transferred. Fund the swap from a Confidential Intents account by submitting a signed transfer intent to the quote `depositAddress`. Direct token transfers are not supported. | | `quoteRequest.destinationAsset` | string | yes | ID of the destination asset. | | `quoteRequest.amount` | string | yes | Amount to swap as the base amount. It is interpreted as the input or output amount based on the `swapType` flag and is specified in the smallest unit of the currency (e.g., wei for ETH). Must be an integer string; decimal values like "0.01" are invalid—use base units (e.g. "10000000000000000" for 0.01 with 18 decimals). | | `quoteRequest.refundTo` | string | yes | Address used for refunds. | | `quoteRequest.refundType` | "ORIGIN_CHAIN" \\| "INTENTS" \\| "CONFIDENTIAL_INTENTS" | yes | Type of refund address: - `ORIGIN_CHAIN` - assets are refunded to the `refundTo` address on the origin chain. - `INTENTS` - assets are refunded to the `refundTo` Intents account. - `CONFIDENTIAL_INTENTS` - assets are refunded to the `refundTo` Confidential Intents account. On Confidential Intents, 1Click settles refunds via signed transfer intent rather than direct token transfer. | | `quoteRequest.recipient` | string | yes | Recipient address. The format must match `recipientType`. Destination routing metadata, when required, must be encoded according to the destination chain address format. | | `quoteRequest.connectedWallets` | string[] | | Addresses of connected wallets. | | `quoteRequest.sessionId` | string | | Unique client session identifier for 1Click. | | `quoteRequest.virtualChainRecipient` | string | | EVM address of a transfer recipient in a virtual chain | | `quoteRequest.virtualChainRefundRecipient` | string | | EVM address of a refund recipient in a virtual chain | | `quoteRequest.customRecipientMsg` | string | | **HIGHLY EXPERIMENTAL** Message to pass to `ft_transfer_call` when withdrawing assets to NEAR. Otherwise, `ft_transfer` will be used. **WARNING**: Funds will be lost if used with non NEP-141 tokens, in case of insufficient `storage_deposit` or if the recipient does not implement `ft_on_transfer` method. | | `quoteRequest.recipientType` | "DESTINATION_CHAIN" \\| "INTENTS" \\| "CONFIDENTIAL_INTENTS" | yes | Type of recipient address: - `DESTINATION_CHAIN` - assets are transferred to the chain of `destinationAsset`. - `INTENTS` - assets are transferred to an account inside Intents. - `CONFIDENTIAL_INTENTS` - assets are transferred to the `recipient` account inside Confidential Intents. On Confidential Intents, 1Click settles swap output via signed transfer intent rather than direct token transfer. | | `quoteRequest.deadline` | string | yes | Timestamp in ISO format that identifies when the user refund begins if the swap isn't completed by then. It must exceed the time required for the deposit transaction to be mined. For example, Bitcoin may require around one hour depending on the fees paid. | | `quoteRequest.confidentiality` | "public" \\| "basic" \\| "advanced" | | Confidentiality mode for this quote. PUBLIC is the default; BASIC or ADVANCED request Confidential Intents handling. | | `quoteRequest.referral` | string | | Distribution channel / venue identifier (for example: ledger, trustwallet). Keep lowercase for consistency. | | `quoteRequest.rebates` | Rebate[] | | Rebate distribution for this quote. Provide up to 3 confidential Intents recipients (for example, `rebate-recipient.near` on confidential Intents); each item defines a recipient and its percent share, and all shares must add up to 100. | | `quoteRequest.rebates[].[]recipient` | string | yes | Confidential Intents account identifier that receives this rebate share. Rebate delivery uses signed transfer intent on Confidential Intents; direct token transfers are not supported. | | `quoteRequest.rebates[].[]share` | number | yes | Rebate share for this recipient in percent. | | `quoteRequest.quoteWaitingTimeMs` | number | | Time in milliseconds the user is willing to wait for a quote from the relay. **Defaults to 0ms delay if not specified, if you want to receive the fastest quote. | | `quoteRequest.appFees` | AppFee[] | | List of recipients and their fees | | `quoteRequest.appFees[].[]recipient` | string | yes | Account ID within Intents to which this fee will be transferred | | `quoteRequest.appFees[].[]fee` | number | yes | Fee for this recipient as part of amountIn in basis points (1/100th of a percent), e.g. 100 for 1% fee | | `quoteRequest.insured` | boolean | | Opt into an insured swap. When `true`, an additional 0.02% (2 basis points) insurance fee is charged on top of any other fees. | | `quote` | object | yes | Response containing the deposit address for sending the `amount` of `originAsset` and the expected output amount. | | `quote.depositAddress` | string | | The deposit address on the chain of `originAsset` when `depositType` is `ORIGIN_CHAIN`. The deposit address inside NEAR Intents (the verifier smart contract) when `depositType` is `INTENTS`. The account ID within Confidential Intents to which assets are to be transferred when `depositType` is `CONFIDENTIAL_INTENTS`. Fund the swap by submitting a signed transfer intent to this value. Direct token transfers are not supported. | | `quote.depositMemo` | string | | Some deposit addresses **REQUIRE** a `memo` together with `depositAddress` for the deposit to be processed. This field is deposit-side metadata. | | `quote.chainDepositAddresses` | ChainDepositAddress[] | | Deposit addresses across all bridge-supported blockchains for funding the same Intents account. Present only for public `ANY_INPUT` quotes (`depositType` `INTENTS`); the confidential rail does not support multi-chain funding addresses yet. Each entry forwards to the Intents account in `depositAddress`, so the user may deposit from any listed chain. | | `quote.chainDepositAddresses[].[]blockchain` | "near" | yes | Blockchain on which this deposit address accepts funds for the quote. | | `quote.chainDepositAddresses[].[]address` | string | yes | Deposit address on `blockchain`. Funds sent here are credited to the same Intents account. | | `quote.chainDepositAddresses[].[]memo` | string | | Memo required together with `address` on chains that need it (e.g. Stellar, XRP, TON). | | `quote.amountIn` | string | yes | Amount of the origin asset | | `quote.amountInFormatted` | string | yes | Amount of the origin asset in readable format | | `quote.amountInUsd` | string | yes | Amount of the origin assets equivalent in USD | | `quote.minAmountIn` | string | yes | Minimum amount of the origin asset that will be used for the swap | | `quote.amountOut` | string | yes | Amount of the destination asset | | `quote.amountOutFormatted` | string | yes | Amount of the destination asset in readable format | | `quote.amountOutUsd` | string | yes | Amount of the destination asset equivalent in USD | | `quote.minAmountOut` | string | yes | Minimum output amount after slippage is applied | | `quote.deadline` | string | | Time when the deposit address becomes inactive and funds may be lost | | `quote.timeWhenInactive` | string | | Time when the deposit address becomes cold, causing swap processing to take longer | | `quote.timeEstimate` | number | yes | Estimated time in seconds for the swap to be executed after the deposit transaction is confirmed | | `quote.virtualChainRecipient` | string | | EVM address of a transfer recipient in a virtual chain | | `quote.virtualChainRefundRecipient` | string | | EVM address of a refund recipient in a virtual chain | | `quote.customRecipientMsg` | string | | **HIGHLY EXPERIMENTAL** Message passed to `ft_transfer_call` when withdrawing assets to NEAR. Otherwise, `ft_transfer` will be used. **WARNING**: Funds will be lost if used with non NEP-141 tokens, in case of insufficient `storage_deposit` or if the recipient does not implement `ft_on_transfer` method. | | `quote.refundFee` | string | | Fee charged for refunding assets to the refund address in the smallest unit of the origin asset | | `quote.withdrawFee` | string | | Fee charged for withdrawing assets to the recipient in the smallest unit of the destination asset. This fee is already accounted for in the final amountOut result | ### 400 Bad Request - Invalid input data [#400-bad-request---invalid-input-data] ```json { "message": "swapType is required" } ``` ### 401 Unauthorized - API key or JWT token is invalid [#401-unauthorized---api-key-or-jwt-token-is-invalid] # Get supported tokens (/docs/api-reference/get-tokens)

GET/v0/tokens

Returns all six Tidepool test tokens (two shown below) with live USD prices. `ondoTokens` is accepted and ignored. Retrieves a list of tokens currently supported by the 1Click API for asset swaps. Each token entry includes its blockchain, contract address (if available), price in USD, and other metadata such as symbol and decimals. **Operation id:** `getTokens` ## Request [#request] ```bash curl "https://www.usetidepool.tech/v0/tokens" ``` ```ts const res = await fetch('https://www.usetidepool.tech/v0/tokens'); const data = await res.json(); ``` ### Try it [#try-it] ### Query parameters [#query-parameters] | Name | Type | Required | Description | | --- | --- | --- | --- | | `ondoTokens` | string | | Show Ondo tokens if the query is set | ## Responses [#responses] ### 200 [#200] ```json [ { "assetId": "nep141:usdc.tidepool-sandbox.testnet", "decimals": 6, "blockchain": "near", "symbol": "USDC", "price": 0.999585, "priceUpdatedAt": "2026-10-24T21:30:25.128Z", "contractAddress": "usdc.tidepool-sandbox.testnet", "coingeckoId": "usd-coin" }, { "assetId": "nep141:usdt.tidepool-sandbox.testnet", "decimals": 6, "blockchain": "near", "symbol": "USDT", "price": 0.999101, "priceUpdatedAt": "2026-10-24T21:30:25.128Z", "contractAddress": "usdt.tidepool-sandbox.testnet", "coingeckoId": "tether" } ] ``` | Field | Type | Required | Description | | --- | --- | --- | --- | | `[]assetId` | string | yes | Unique asset identifier | | `[]decimals` | number | yes | Number of decimals for the token | | `[]blockchain` | "near" | yes | Blockchain associated with the token | | `[]symbol` | string | yes | Token symbol (e.g. BTC, ETH) | | `[]price` | number | yes | Current price of the token in USD | | `[]priceUpdatedAt` | string | yes | Date when the token price was last updated | | `[]contractAddress` | string | | Contract address of the token | | `[]coingeckoId` | string | | CoinGecko coin id, when known. Use it to fetch price history from CoinGecko. | # API reference (/docs/api-reference) Base URL: `https://www.usetidepool.tech` · Spec: [`/openapi.json`](/openapi.json) (1Click Swap API v0.1.10 shapes plus two Tidepool extensions). All amounts are strings in the token's base units. Errors return `{ "message": "…" }` with HTTP 400, 404 or 429. CORS is open (`*`). | Method | Path | What it does | | | --- | --- | --- | --- | | GET | [`/v0/tokens`](/docs/api-reference/get-tokens) | Get supported tokens | 1Click | | POST | [`/v0/quote`](/docs/api-reference/get-quote) | Request a swap quote | 1Click | | GET | [`/v0/status`](/docs/api-reference/get-execution-status) | Check swap execution status | 1Click | | POST | [`/v0/deposit/submit`](/docs/api-reference/submit-deposit-tx) | Submit deposit transaction hash | 1Click | | POST | [`/v0/faucet`](/docs/api-reference/tidepool-faucet) | Get testnet tokens | Tidepool only | | GET | [`/v0/health`](/docs/api-reference/tidepool-health) | Service health | Tidepool only | ## Authentication [#authentication] Optional. Send any `X-API-Key: ` or `Authorization: Bearer ` to get the lower fee tier. See [Quotes](/docs/concepts/quotes#fees). # Submit deposit transaction hash (/docs/api-reference/submit-deposit-tx)

POST/v0/deposit/submit

Optional. Returns **HTTP 201** and the current status object. Moves `PENDING_DEPOSIT` to `KNOWN_DEPOSIT_TX`; the worker detects deposits on its own either way. Optionally notifies the 1Click service that a deposit has been sent to the specified address, using the blockchain transaction hash. This step can speed up swap processing by allowing the system to preemptively verify the deposit. **Operation id:** `submitDepositTx` · **Auth:** optional (`X-API-Key` or `Authorization: Bearer`, any value) ## Request [#request] ```bash curl -X POST "https://www.usetidepool.tech/v0/deposit/submit" \ -H 'content-type: application/json' \ -d '{ "txHash": "HbwEo318L69bJS7XYse18mUTzBBa2tjK6wtGeDYo3dY8", "depositAddress": "c47208de64cde76fc6803b5f26c137bc51fbf151eb1c0964488ea56704142151" }' ``` ```ts const res = await fetch('https://www.usetidepool.tech/v0/deposit/submit', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ "txHash": "HbwEo318L69bJS7XYse18mUTzBBa2tjK6wtGeDYo3dY8", "depositAddress": "c47208de64cde76fc6803b5f26c137bc51fbf151eb1c0964488ea56704142151" }), }); const data = await res.json(); ``` ### Body [#body] | Field | Type | Required | Description | | --- | --- | --- | --- | | `txHash` | string | yes | Transaction hash of your deposit | | `depositAddress` | string | yes | Deposit address for the quote | | `nearSenderAccount` | string | | Sender account (used only for NEAR blockchain) | | `memo` | string | | Memo (use if deposit was submitted with one) | ## Responses [#responses] ### 200 [#200] ```json { "correlationId": "6e7d2aad-b262-4b13-b88e-0c4d6b64325c", "quoteResponse": { "correlationId": "6e7d2aad-b262-4b13-b88e-0c4d6b64325c", "timestamp": "2026-10-24T21:30:28.060Z", "quoteRequest": { "swapType": "EXACT_INPUT", "slippageTolerance": 100, "originAsset": "nep141:usdc.tidepool-sandbox.testnet", "destinationAsset": "nep141:wnear.tidepool-sandbox.testnet", "amount": "5000000", "depositType": "INTENTS", "refundTo": "tidepool-try-0937467b.testnet", "refundType": "INTENTS", "recipient": "tidepool-try-0937467b.testnet", "recipientType": "DESTINATION_CHAIN", "dry": false, "deadline": "2026-10-24T21:40:27.927Z" }, "quote": { "amountIn": "5000000", "amountInFormatted": "5", "amountInUsd": "4.9979", "minAmountIn": "5000000", "amountOut": "1123407466216216112640000", "amountOutFormatted": "1.12340746621621611264", "amountOutUsd": "4.9879", "minAmountOut": "1112173391554053951513600", "timeEstimate": 10, "depositAddress": "c47208de64cde76fc6803b5f26c137bc51fbf151eb1c0964488ea56704142151", "deadline": "2026-10-24T21:40:27.927Z", "timeWhenInactive": "2026-10-24T21:40:27.927Z" }, "signature": "ed25519:3D679QeYbrSEAnHRmkG1eurAeWnnecYQBNWLgmQuEzSvdQpqmKzP2R9W4FqeqLzJvrem4JU3xVnXamFjz74sCKfj" }, "status": "SUCCESS", "updatedAt": "2026-10-24T21:30:42.751Z", "swapDetails": { "intentHashes": [ "DsrGVDFfwq6ifa9LctU2JaCzWB2kZB1VzNe1XHFCC3qS", "23MCaK5ZV2qanV6p1LYzpGh7zwPC3pa9vqGSm6hLij6H" ], "nearTxHashes": [ "EB5xfEyjiC1oESNjEyNjnkzW4Zpsi24e4H2s6aUGEh9d" ], "originChainTxHashes": [ { "hash": "HbwEo318L69bJS7XYse18mUTzBBa2tjK6wtGeDYo3dY8", "explorerUrl": "https://testnet.nearblocks.io/txns/HbwEo318L69bJS7XYse18mUTzBBa2tjK6wtGeDYo3dY8" } ], "destinationChainTxHashes": [ { "hash": "EB5xfEyjiC1oESNjEyNjnkzW4Zpsi24e4H2s6aUGEh9d", "explorerUrl": "https://testnet.nearblocks.io/txns/EB5xfEyjiC1oESNjEyNjnkzW4Zpsi24e4H2s6aUGEh9d" } ], "amountIn": "5000000", "amountInFormatted": "5", "amountInUsd": "4.9979", "amountOut": "1123407466216216112640000", "amountOutFormatted": "1.12340746621621611264", "amountOutUsd": "4.9879", "slippage": 0, "depositedAmount": "5000000", "depositedAmountFormatted": "5", "depositedAmountUsd": "4.9979" }, "tidepool": { "explorer": [ { "label": "swap (execute_intents)", "url": "https://testnet.nearblocks.io/txns/EB5xfEyjiC1oESNjEyNjnkzW4Zpsi24e4H2s6aUGEh9d" } ] } } ``` | Field | Type | Required | Description | | --- | --- | --- | --- | | `correlationId` | string | yes | Unique identifier for request tracing and debugging | | `quoteResponse` | object | yes | Quote response from the original request | | `quoteResponse.correlationId` | string | yes | Unique identifier for request tracing and debugging | | `quoteResponse.timestamp` | string | yes | Timestamp in ISO format that was used to derive the deposit address | | `quoteResponse.signature` | string | yes | Signature of the 1Click service confirming the quote for the specific deposit address. Must be saved on the client side (along with the whole quote) in order to resolve any disputes or mistakes. | | `quoteResponse.quoteRequest` | object | yes | User request | | `quoteResponse.quoteRequest.dry` | boolean | yes | Flag indicating whether this is a dry run request. If `true`, the response will **NOT** contain the following fields: - `depositAddress` - `timeWhenInactive` - `deadline` | | `quoteResponse.quoteRequest.depositMode` | "SIMPLE" \\| "MEMO" | | What deposit address mode you will get in the response, most chain supports only `SIMPLE` and some(for example `stellar`) only `MEMO`: - `SIMPLE` - usual deposit with only deposit address. - `MEMO` - some chains will **REQUIRE** the `memo` together with `depositAddress` for swap to work. `depositMode` applies only to deposit transaction metadata. | | `quoteResponse.quoteRequest.swapType` | "EXACT_INPUT" \\| "EXACT_OUTPUT" \\| "FLEX_INPUT" \\| "ANY_INPUT" | yes | How to interpret `amount` (and refunds) when performing the swap: - `EXACT_INPUT` — requests the output amount for an exact input. - If deposit is less than `amountIn`, the deposit is refunded by deadline. - If deposit is above than `amountIn`, the swap is processed and the excess is refunded to `refundTo` address after swap is complete. - `EXACT_OUTPUT` — requests the input amount for an exact output. - The output amount (`amountOut`) is fixed; slippage is applied to the **input** side. - The quote response includes `amountIn` (the proposed input with slippage tolerance baked in) and `minAmountIn` (the minimum input required). - **Important**: `amountIn` will appear higher than `minAmountIn` by approximately your `slippageTolerance`. This is **not** price degradation—it is a buffer to ensure successful execution. Any input amount above what is actually needed for the swap is **refunded** to your `refundTo` address after the swap completes. - If the deposit is above `amountIn`, the swap is processed and the excess is refunded to `refundTo` address after swap is complete. - If the deposit is less than `minAmountIn`, the deposit is refunded by deadline. - `FLEX_INPUT` — a flexible input amount that allows for partial deposits and variable amounts. - `slippage` applies both to `amountOut` and `amountIn` and defines an acceptable range (`minAmountIn` and `minAmountOut`). - Any amount higher than `minAmountIn` is accepted and converted to the output asset as long as `minAmountOut` is met. - The deposit must be at least `minAmountIn`, after applying the slippage constraint to the quoted amount. Deposits below `minAmountIn` are refunded if the total received by the deadline is below this amount. - If deposits exceed the upper bound, the swap is still processed - `ANY_INPUT` — collects deposits and converts them to a destination asset. Used for fee aggregation and similar use cases. Only available for authorized partners. | | `quoteResponse.quoteRequest.slippageTolerance` | number | yes | Slippage tolerance for the swap. This value is in basis points (1/100th of a percent), e.g. 100 for 1% slippage. | | `quoteResponse.quoteRequest.originAsset` | string | yes | ID of the origin asset. | | `quoteResponse.quoteRequest.depositType` | "ORIGIN_CHAIN" \\| "INTENTS" \\| "CONFIDENTIAL_INTENTS" | yes | Type of deposit address: - `ORIGIN_CHAIN` - deposit address on the origin chain. - `INTENTS` - the account ID within NEAR Intents to which you should transfer assets. - `CONFIDENTIAL_INTENTS` - the account ID within Confidential Intents to which assets are to be transferred. Fund the swap from a Confidential Intents account by submitting a signed transfer intent to the quote `depositAddress`. Direct token transfers are not supported. | | `quoteResponse.quoteRequest.destinationAsset` | string | yes | ID of the destination asset. | | `quoteResponse.quoteRequest.amount` | string | yes | Amount to swap as the base amount. It is interpreted as the input or output amount based on the `swapType` flag and is specified in the smallest unit of the currency (e.g., wei for ETH). Must be an integer string; decimal values like "0.01" are invalid—use base units (e.g. "10000000000000000" for 0.01 with 18 decimals). | | `quoteResponse.quoteRequest.refundTo` | string | yes | Address used for refunds. | | `quoteResponse.quoteRequest.refundType` | "ORIGIN_CHAIN" \\| "INTENTS" \\| "CONFIDENTIAL_INTENTS" | yes | Type of refund address: - `ORIGIN_CHAIN` - assets are refunded to the `refundTo` address on the origin chain. - `INTENTS` - assets are refunded to the `refundTo` Intents account. - `CONFIDENTIAL_INTENTS` - assets are refunded to the `refundTo` Confidential Intents account. On Confidential Intents, 1Click settles refunds via signed transfer intent rather than direct token transfer. | | `quoteResponse.quoteRequest.recipient` | string | yes | Recipient address. The format must match `recipientType`. Destination routing metadata, when required, must be encoded according to the destination chain address format. | | `quoteResponse.quoteRequest.connectedWallets` | string[] | | Addresses of connected wallets. | | `quoteResponse.quoteRequest.sessionId` | string | | Unique client session identifier for 1Click. | | `quoteResponse.quoteRequest.virtualChainRecipient` | string | | EVM address of a transfer recipient in a virtual chain | | `quoteResponse.quoteRequest.virtualChainRefundRecipient` | string | | EVM address of a refund recipient in a virtual chain | | `quoteResponse.quoteRequest.customRecipientMsg` | string | | **HIGHLY EXPERIMENTAL** Message to pass to `ft_transfer_call` when withdrawing assets to NEAR. Otherwise, `ft_transfer` will be used. **WARNING**: Funds will be lost if used with non NEP-141 tokens, in case of insufficient `storage_deposit` or if the recipient does not implement `ft_on_transfer` method. | | `quoteResponse.quoteRequest.recipientType` | "DESTINATION_CHAIN" \\| "INTENTS" \\| "CONFIDENTIAL_INTENTS" | yes | Type of recipient address: - `DESTINATION_CHAIN` - assets are transferred to the chain of `destinationAsset`. - `INTENTS` - assets are transferred to an account inside Intents. - `CONFIDENTIAL_INTENTS` - assets are transferred to the `recipient` account inside Confidential Intents. On Confidential Intents, 1Click settles swap output via signed transfer intent rather than direct token transfer. | | `quoteResponse.quoteRequest.deadline` | string | yes | Timestamp in ISO format that identifies when the user refund begins if the swap isn't completed by then. It must exceed the time required for the deposit transaction to be mined. For example, Bitcoin may require around one hour depending on the fees paid. | | `quoteResponse.quoteRequest.confidentiality` | "public" \\| "basic" \\| "advanced" | | Confidentiality mode for this quote. PUBLIC is the default; BASIC or ADVANCED request Confidential Intents handling. | | `quoteResponse.quoteRequest.referral` | string | | Distribution channel / venue identifier (for example: ledger, trustwallet). Keep lowercase for consistency. | | `quoteResponse.quoteRequest.rebates` | Rebate[] | | Rebate distribution for this quote. Provide up to 3 confidential Intents recipients (for example, `rebate-recipient.near` on confidential Intents); each item defines a recipient and its percent share, and all shares must add up to 100. | | `quoteResponse.quoteRequest.rebates[].[]recipient` | string | yes | Confidential Intents account identifier that receives this rebate share. Rebate delivery uses signed transfer intent on Confidential Intents; direct token transfers are not supported. | | `quoteResponse.quoteRequest.rebates[].[]share` | number | yes | Rebate share for this recipient in percent. | | `quoteResponse.quoteRequest.quoteWaitingTimeMs` | number | | Time in milliseconds the user is willing to wait for a quote from the relay. **Defaults to 0ms delay if not specified, if you want to receive the fastest quote. | | `quoteResponse.quoteRequest.appFees` | AppFee[] | | List of recipients and their fees | | `quoteResponse.quoteRequest.appFees[].[]recipient` | string | yes | Account ID within Intents to which this fee will be transferred | | `quoteResponse.quoteRequest.appFees[].[]fee` | number | yes | Fee for this recipient as part of amountIn in basis points (1/100th of a percent), e.g. 100 for 1% fee | | `quoteResponse.quoteRequest.insured` | boolean | | Opt into an insured swap. When `true`, an additional 0.02% (2 basis points) insurance fee is charged on top of any other fees. | | `quoteResponse.quote` | object | yes | Response containing the deposit address for sending the `amount` of `originAsset` and the expected output amount. | | `quoteResponse.quote.depositAddress` | string | | The deposit address on the chain of `originAsset` when `depositType` is `ORIGIN_CHAIN`. The deposit address inside NEAR Intents (the verifier smart contract) when `depositType` is `INTENTS`. The account ID within Confidential Intents to which assets are to be transferred when `depositType` is `CONFIDENTIAL_INTENTS`. Fund the swap by submitting a signed transfer intent to this value. Direct token transfers are not supported. | | `quoteResponse.quote.depositMemo` | string | | Some deposit addresses **REQUIRE** a `memo` together with `depositAddress` for the deposit to be processed. This field is deposit-side metadata. | | `quoteResponse.quote.chainDepositAddresses` | ChainDepositAddress[] | | Deposit addresses across all bridge-supported blockchains for funding the same Intents account. Present only for public `ANY_INPUT` quotes (`depositType` `INTENTS`); the confidential rail does not support multi-chain funding addresses yet. Each entry forwards to the Intents account in `depositAddress`, so the user may deposit from any listed chain. | | `quoteResponse.quote.chainDepositAddresses[].[]blockchain` | "near" | yes | Blockchain on which this deposit address accepts funds for the quote. | | `quoteResponse.quote.chainDepositAddresses[].[]address` | string | yes | Deposit address on `blockchain`. Funds sent here are credited to the same Intents account. | | `quoteResponse.quote.chainDepositAddresses[].[]memo` | string | | Memo required together with `address` on chains that need it (e.g. Stellar, XRP, TON). | | `quoteResponse.quote.amountIn` | string | yes | Amount of the origin asset | | `quoteResponse.quote.amountInFormatted` | string | yes | Amount of the origin asset in readable format | | `quoteResponse.quote.amountInUsd` | string | yes | Amount of the origin assets equivalent in USD | | `quoteResponse.quote.minAmountIn` | string | yes | Minimum amount of the origin asset that will be used for the swap | | `quoteResponse.quote.amountOut` | string | yes | Amount of the destination asset | | `quoteResponse.quote.amountOutFormatted` | string | yes | Amount of the destination asset in readable format | | `quoteResponse.quote.amountOutUsd` | string | yes | Amount of the destination asset equivalent in USD | | `quoteResponse.quote.minAmountOut` | string | yes | Minimum output amount after slippage is applied | | `quoteResponse.quote.deadline` | string | | Time when the deposit address becomes inactive and funds may be lost | | `quoteResponse.quote.timeWhenInactive` | string | | Time when the deposit address becomes cold, causing swap processing to take longer | | `quoteResponse.quote.timeEstimate` | number | yes | Estimated time in seconds for the swap to be executed after the deposit transaction is confirmed | | `quoteResponse.quote.virtualChainRecipient` | string | | EVM address of a transfer recipient in a virtual chain | | `quoteResponse.quote.virtualChainRefundRecipient` | string | | EVM address of a refund recipient in a virtual chain | | `quoteResponse.quote.customRecipientMsg` | string | | **HIGHLY EXPERIMENTAL** Message passed to `ft_transfer_call` when withdrawing assets to NEAR. Otherwise, `ft_transfer` will be used. **WARNING**: Funds will be lost if used with non NEP-141 tokens, in case of insufficient `storage_deposit` or if the recipient does not implement `ft_on_transfer` method. | | `quoteResponse.quote.refundFee` | string | | Fee charged for refunding assets to the refund address in the smallest unit of the origin asset | | `quoteResponse.quote.withdrawFee` | string | | Fee charged for withdrawing assets to the recipient in the smallest unit of the destination asset. This fee is already accounted for in the final amountOut result | | `status` | "KNOWN_DEPOSIT_TX" \\| "PENDING_DEPOSIT" \\| "INCOMPLETE_DEPOSIT" \\| "PROCESSING" \\| "SUCCESS" \\| "REFUNDED" \\| "FAILED" | yes | | | `updatedAt` | string | yes | Last time the state was updated | | `swapDetails` | object | yes | Details of actual swaps and withdrawals | | `swapDetails.intentHashes` | string[] | yes | All intent hashes that took part in this swap | | `swapDetails.nearTxHashes` | string[] | yes | All NEAR transactions executed for this swap | | `swapDetails.amountIn` | string | | Exact amount of `originToken` after the trade was settled | | `swapDetails.amountInFormatted` | string | | Exact amount of `originToken` in readable format after the trade was settled | | `swapDetails.amountInUsd` | string | | Exact amount of `originToken` equivalent in USD | | `swapDetails.amountOut` | string | | Exact amount of `destinationToken` after the trade was settled | | `swapDetails.amountOutFormatted` | string | | Exact amount of `destinationToken` in readable format after the trade was settled | | `swapDetails.amountOutUsd` | string | | Exact amount of `destinationToken` equivalent in USD | | `swapDetails.slippage` | number | | Actual slippage | | `swapDetails.originChainTxHashes` | TransactionDetails[] | yes | Hashes and explorer URLs for all transactions on the origin chain | | `swapDetails.originChainTxHashes[].[]hash` | string | yes | Transaction hash | | `swapDetails.originChainTxHashes[].[]explorerUrl` | string | yes | Explorer URL for the transaction | | `swapDetails.destinationChainTxHashes` | TransactionDetails[] | yes | Hashes and explorer URLs for all transactions on the destination chain | | `swapDetails.destinationChainTxHashes[].[]hash` | string | yes | Transaction hash | | `swapDetails.destinationChainTxHashes[].[]explorerUrl` | string | yes | Explorer URL for the transaction | | `swapDetails.refundedAmount` | string | | Amount of `originAsset` transferred to `refundTo` | | `swapDetails.refundedAmountFormatted` | string | | Refunded amount in readable format | | `swapDetails.refundedAmountUsd` | string | | Refunded amount equivalent in USD | | `swapDetails.refundReason` | string | | Reason for refund | | `swapDetails.depositedAmount` | string | | Amount deposited to `depositAddress` onchain | | `swapDetails.depositedAmountFormatted` | string | | Amount deposited in readable format | | `swapDetails.depositedAmountUsd` | string | | Amount deposited equivalent in USD | | `swapDetails.withdrawFee` | string | | Fee charged for withdrawing assets to the recipient in the smallest unit of the destination asset. This fee is already accounted for in the final amountOut result | | `swapDetails.referral` | string | | Referral identifier | ### 400 Bad Request - Invalid input data [#400-bad-request---invalid-input-data] ```json { "message": "txHash and depositAddress are required" } ``` ### 401 Unauthorized - API key or JWT token is invalid [#401-unauthorized---api-key-or-jwt-token-is-invalid] # Get testnet tokens (/docs/api-reference/tidepool-faucet)

POST/v0/faucet

This endpoint is not part of the 1Click API. Do not call it on mainnet. Limits: one drip per account per mode per hour, six per IP per hour. Response lists all drips (trimmed here). See [Faucet](/docs/guides/faucet). Drips every Tidepool test token to a NEAR testnet account. mode=wallet mints NEP-141 tokens to the account; mode=intents credits the account inside the Tidepool verifier. One drip per account and mode per hour; 6 per IP per hour. **Operation id:** `TidepoolFaucet` ## Request [#request] ```bash curl -X POST "https://www.usetidepool.tech/v0/faucet" \ -H 'content-type: application/json' \ -d '{ "accountId": "alice.testnet", "mode": "wallet" }' ``` ```ts const res = await fetch('https://www.usetidepool.tech/v0/faucet', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ "accountId": "alice.testnet", "mode": "wallet" }), }); const data = await res.json(); ``` ### Body [#body] | Field | Type | Required | Description | | --- | --- | --- | --- | | `accountId` | string | yes | | | `mode` | "wallet" \\| "intents" | | | | `assets` | string[] | | Optional subset (assetId or symbol) | ## Responses [#responses] ### 200 Drip sent [#200-drip-sent] ```json { "accountId": "alice.testnet", "mode": "wallet", "drips": [ { "assetId": "nep141:usdc.tidepool-sandbox.testnet", "symbol": "USDC", "amount": "100" }, { "assetId": "nep141:usdt.tidepool-sandbox.testnet", "symbol": "USDT", "amount": "100" } ], "transactions": [ { "assetId": "nep141:usdc.tidepool-sandbox.testnet", "amount": "100", "txHash": "F6JiEXj2LSkzhAdGoBV5hBs5etTjdgNvvNsH72aBACcN", "explorerUrl": "https://testnet.nearblocks.io/txns/F6JiEXj2LSkzhAdGoBV5hBs5etTjdgNvvNsH72aBACcN" } ] } ``` ### 400 Bad request [#400-bad-request] ```json { "message": "error message" } ``` ### 429 Rate limited [#429-rate-limited] ```json { "message": "Rate limited: alice.testnet can use the wallet faucet again after 2026-10-24T22:20:00.000Z" } ``` # Service health (/docs/api-reference/tidepool-health)

GET/v0/health

This endpoint is not part of the 1Click API. Do not call it on mainnet. Cached for 10 seconds. Re-checks the verifier code hash against the `defuse/v0.4.2` release. See [Live status](/docs/status). **Operation id:** `TidepoolHealth` ## Request [#request] ```bash curl "https://www.usetidepool.tech/v0/health" ``` ```ts const res = await fetch('https://www.usetidepool.tech/v0/health'); const data = await res.json(); ``` ### Try it [#try-it] ## Responses [#responses] ### 200 Health report [#200-health-report] ```json { "service": "tidepool", "network": "testnet", "verifier": "verifier.tidepool-sandbox.testnet", "verifierWasmSha256": "f67f9559b3b512c52dfa11723a28b9119bcf773ac01780370d6409e5f1fb20e5", "verifierRelease": "https://github.com/near/intents/releases/tag/defuse/v0.4.2", "maker": "maker.tidepool-sandbox.testnet", "checks": { "rpc": { "ok": true, "height": 274605756, "ms": 80 }, "verifier": { "ok": true, "codeHashHex": "f67f9559b3b512c52dfa11723a28b9119bcf773ac01780370d6409e5f1fb20e5" }, "prices": { "ok": true, "source": "coingecko", "updatedAt": "2026-10-24T21:30:25.128Z" }, "makerInventory": { "ok": true, "balances": { "USDC": "1999720", "USDT": "1999710", "wNEAR": "799875.5214169960396638752", "wBTC": "19.99693796", "ETH": "599.907873451968147949", "XAUT": "599.91" } } }, "swaps": { "total": 4, "success": 3, "refunded": 1, "failed": 0, "active": 0 }, "recent": [ { "status": "SUCCESS", "pair": "usdc → wnear", "updatedAt": "2026-10-24T21:30:42.751Z", "tx": "https://testnet.nearblocks.io/txns/EB5xfEyjiC1oESNjEyNjnkzW4Zpsi24e4H2s6aUGEh9d" }, { "status": "REFUNDED", "pair": "usdc → eth", "updatedAt": "2026-10-24T21:10:30.279Z", "tx": "https://testnet.nearblocks.io/txns/4LaFRDyTHHyAWP4PNz2z38MC34GAcr6aE2KTUTdTHysy" }, { "status": "SUCCESS", "pair": "usdt → wbtc", "updatedAt": "2026-10-24T21:09:07.722Z", "tx": "https://testnet.nearblocks.io/txns/F4NQXgVoczTixw1bvekQf7k5NGNKoDY4huveLxhkoToX" }, { "status": "SUCCESS", "pair": "usdc → wnear", "updatedAt": "2026-10-24T21:08:51.970Z", "tx": "https://testnet.nearblocks.io/txns/CTnAzK9YrbNy64GR9hhEQUF7ctn6KHYY5tpt57g5pEPe" } ], "ok": true } ``` # Deposit modes (/docs/concepts/deposits) Every live quote has a fresh `depositAddress`. `depositType` says **how** you will fund it. ## ORIGIN_CHAIN [#origin_chain] Send the NEP-141 token straight to the deposit address, like sending to any wallet. It is a brand-new implicit account, so register storage first: ```bash near contract call-function as-transaction usdc.tidepool-sandbox.testnet storage_deposit \ json-args '{"account_id":"","registration_only":true}' \ prepaid-gas '30 Tgas' attached-deposit '0.00125 NEAR' sign-as you.testnet network-config testnet sign-with-keychain send near contract call-function as-transaction usdc.tidepool-sandbox.testnet ft_transfer \ json-args '{"receiver_id":"","amount":"5000000"}' \ prepaid-gas '30 Tgas' attached-deposit '1 yoctoNEAR' sign-as you.testnet network-config testnet sign-with-keychain send ``` The worker then funds the address with 0.12 NEAR for gas (from root) and moves the tokens into the verifier. Expect one or two extra transactions in `/v0/status`. ## INTENTS [#intents] Credit the deposit address **inside the verifier**. Two ways: **From a wallet balance**, one call, no storage step: ```bash near contract call-function as-transaction usdc.tidepool-sandbox.testnet ft_transfer_call \ json-args '{"receiver_id":"verifier.tidepool-sandbox.testnet","amount":"5000000","msg":""}' \ prepaid-gas '100 Tgas' attached-deposit '1 yoctoNEAR' sign-as you.testnet network-config testnet sign-with-keychain send ``` **From an intents balance** (for example after an `intents` faucet drip): sign a NEP-413 `transfer` intent `{ "intent": "transfer", "receiver_id": "", "tokens": { "nep141:usdc.tidepool-sandbox.testnet": "5000000" } }` and submit it with `execute_intents` on the verifier. `examples/swap.mjs` in the repo does exactly this. Before your first intents signature, your account needs a public key registered on the verifier (`add_public_key`), or it must be an implicit account. ## Tell Tidepool about the deposit (optional) [#tell-tidepool-about-the-deposit-optional] The worker polls every deposit address, so this is optional, but it moves the status to `KNOWN_DEPOSIT_TX` right away: ```bash curl -X POST https://www.usetidepool.tech/v0/deposit/submit -H 'content-type: application/json' \ -d '{"txHash":"","depositAddress":""}' ``` ## Not supported [#not-supported] `depositMode: "MEMO"` (shared address plus memo) and `CONFIDENTIAL_INTENTS` return 400. Only `blockchain: "near"` exists. # How it works (/docs/concepts/how-it-works) Tidepool has four moving parts. Three run on NEAR testnet and one is the API server. ## The verifier [#the-verifier] The verifier is the **official NEAR Intents contract** (`defuse` v0.4.2), deployed unmodified at [`verifier.tidepool-sandbox.testnet`](https://testnet.nearblocks.io/address/verifier.tidepool-sandbox.testnet). Its wasm SHA-256 is `f67f9559…20e5`, byte-identical to the [GitHub release](https://github.com/near/intents/releases/tag/defuse/v0.4.2). [`/v0/health`](/docs/api-reference/tidepool-health) re-checks the on-chain code hash on every call. The verifier keeps an internal multi-token ledger (NEP-245). Tokens enter it via `ft_transfer_call` and leave via `ft_withdraw` intents. Inside it, accounts swap by signing **intents**: NEP-413 messages that say "my balance of X goes down by a, my balance of Y goes up by b". The verifier executes a batch only if every `token_diff` in the batch nets to zero, so neither side can be shortchanged. That atomicity is the whole trust story of a swap. ## The maker (solver) [#the-maker-solver] The maker is [`maker.tidepool-sandbox.testnet`](https://testnet.nearblocks.io/address/maker.tidepool-sandbox.testnet), an account that **Tidepool runs**. It holds inventory of every test token inside the verifier and is the counterparty to every swap. On mainnet 1Click, many independent solvers compete to fill a quote. On Tidepool there is exactly one, so the price you get is Tidepool's price (see [Quotes](/docs/concepts/quotes)). ## Deposit addresses [#deposit-addresses] Every live quote (`dry: false`) gets its own deposit address: a NEAR **implicit account** (64 hex characters) whose ed25519 key is derived on the server as `HMAC-SHA256(master seed, "tidepool-deposit:" + correlationId)`. Nobody holds a list of keys and no account is reused. Because the server can derive the key, deposit addresses are **custodial**: Tidepool signs on their behalf to settle or refund. See [Trust model](/docs/resources/trust-model). ## The API server [#the-api-server] The server exposes the 1Click-shaped endpoints, prices quotes, watches deposit addresses every few seconds, and submits settlement and refund transactions. ## One swap, step by step [#one-swap-step-by-step] **Quote.** You `POST /v0/quote`. Tidepool fetches prices, applies the fee and slippage, checks the maker has enough of the destination token, and signs the quote. With `dry: false` it also derives and returns `depositAddress`. **Deposit.** You send `amountIn` of the origin token. With `ORIGIN_CHAIN` you `ft_transfer` to the deposit address. With `INTENTS` you credit the deposit address inside the verifier (`ft_transfer_call` with `msg` = address, or an intents `transfer`). See [Deposits](/docs/concepts/deposits). **Sweep (ORIGIN_CHAIN only).** The worker tops up the deposit address with 0.12 NEAR for gas if needed, adds its key, and moves the tokens into the verifier with `ft_transfer_call`. **Settle.** Once the in-verifier balance reaches `minAmountIn` before the deadline, the worker re-prices, checks slippage, and submits one `execute_intents` with two signed payloads: the maker's `token_diff` (+in, −out) and the deposit address's `token_diff` (−in, +out), plus a transfer or `ft_withdraw` of the output to `recipient` and of any excess back to `refundTo`. **Report.** `/v0/status` moves to `SUCCESS` with `swapDetails.nearTxHashes` and `intentHashes`. If anything fails, the deposit is refunded. See [Refunds](/docs/concepts/refunds). ## Accounts [#accounts] | Account | Role | | --- | --- | | `tidepool-sandbox.testnet` | Root. Deploys the system and pays gas top-ups. Allowed minter on every token. | | `verifier.tidepool-sandbox.testnet` | The official verifier contract. | | `maker.tidepool-sandbox.testnet` | The maker. Holds inventory, signs the solver side of each swap, funds intents-mode faucet drips. | | `usdc. usdt. wnear. wbtc. eth. xaut.tidepool-sandbox.testnet` | NEP-141 test tokens. Owner: `privacei.testnet`. | | 64-hex implicit accounts | Per-quote deposit addresses. | # Quotes and pricing (/docs/concepts/quotes) ## Where prices come from [#where-prices-come-from] USD prices come from **CoinGecko** (`usd-coin`, `tether`, `near`, `bitcoin`, `ethereum`, `tether-gold`), cached briefly. If CoinGecko is unreachable, fixed fallback prices are used and `/v0/health` shows a non-`coingecko` source. The rate for a pair is `priceIn / priceOut`, computed with 18 decimals of fixed-point precision and integer (BigInt) maths in base units. ## Fees [#fees] The fee is taken from the output, in basis points: | Pair | No API key | Any API key | | --- | --- | --- | | Stable ↔ stable (USDC, USDT) | 26 bps | 1 bp | | Everything else | 45 bps | 20 bps | The +25 bps for keyless calls mirrors mainnet 1Click. On Tidepool **any** `X-API-Key` or `Authorization: Bearer` value counts as a key. ## Amounts in a quote [#amounts-in-a-quote] | Field | Meaning | | --- | --- | | `amountIn` | What you should deposit. | | `minAmountIn` | The least deposit that will still be swapped. Less than this waits as `INCOMPLETE_DEPOSIT` and is refunded at the deadline. | | `amountOut` | Expected output at the quoted price, after fees. | | `minAmountOut` | `amountOut × (1 − slippageTolerance)`. Settlement below this is refused and refunded. | | `*Formatted`, `*Usd` | Human-readable decimals and USD values. | | `deadline` | Last moment a deposit counts. 60 s to 24 h in the future for live quotes. | | `timeEstimate` | Seconds to settle after deposit (about 10). | ## Live checks [#live-checks] - The maker must hold at least `amountOut` of the destination token, or the quote fails with `Not enough maker liquidity`. - At settlement the worker **re-prices**. If the new output is below `minAmountOut` (pro rata to what was swapped), the deposit is refunded with `SLIPPAGE_EXCEEDED`. The maker never pays more than the quoted `amountOut`. ## Signature [#signature] `signature` is an ed25519 signature by the maker key over the quote body, prefixed `ed25519:`. It proves the quote came from Tidepool. It is **not** a 1Click signature. ## Dry vs live [#dry-vs-live] | | `dry: true` | `dry: false` | | --- | --- | --- | | Price and amounts | ✓ | ✓ | | `depositAddress` | — | ✓ | | Watched and settled | — | ✓ | | Deadline rule | any | 60 s to 24 h ahead | # Refunds (/docs/concepts/refunds) A refund always returns the **origin token** to `refundTo`, as a wallet balance (`refundType: ORIGIN_CHAIN`) or an intents balance (`refundType: INTENTS`). It is signed by the deposit address and executed on the verifier, so you can audit it on NearBlocks. | Reason | When | | --- | --- | | `PARTIAL_DEPOSIT` | Deadline passed with less than `minAmountIn` deposited. | | `DEADLINE_PASSED` | Funds landed only after the deadline. | | `SLIPPAGE_EXCEEDED` | At settlement the re-priced output fell below `minAmountOut`. | | `PRICE_MOVED` | `EXACT_OUTPUT`: the deposit no longer covers the requested output. | | `INSUFFICIENT_LIQUIDITY` | The maker ran out of the destination token. | | `SWAP_FAILED` | The settlement transaction failed on chain. | ## Excess is not a refund [#excess-is-not-a-refund] If you deposit **more** than `amountIn` (or more than an `EXACT_OUTPUT` swap needs), the swap still succeeds and the excess is returned in the **same** transaction. The status is `SUCCESS` and `swapDetails.refundedAmount` shows the excess. ## Example [#example] A real `PARTIAL_DEPOSIT` refund on testnet: deposit [452vagfg…](https://testnet.nearblocks.io/txns/452vagfgdDpY8bEcFzsVsvcWjiAqQVsoUjrgR9zKH8xb), refund [4LaFRDyT…](https://testnet.nearblocks.io/txns/4LaFRDyTHHyAWP4PNz2z38MC34GAcr6aE2KTUTdTHysy). Reproduce it with `node examples/swap.mjs --refund`. # Status lifecycle (/docs/concepts/status-lifecycle) | Status | Meaning | Final | | --- | --- | --- | | `PENDING_DEPOSIT` | Live quote created. Nothing deposited yet. | | | `KNOWN_DEPOSIT_TX` | You called `/v0/deposit/submit`, but the funds have not landed in the verifier yet. | | | `INCOMPLETE_DEPOSIT` | Something arrived, but less than `minAmountIn`. Top up before the deadline or it is refunded. | | | `PROCESSING` | Enough arrived. Settlement transaction is being sent. | | | `SUCCESS` | Swapped. `swapDetails` has amounts, tx hashes and intent hashes. | ✓ | | `REFUNDED` | Deposit returned to `refundTo`. `swapDetails.refundReason` says why. | ✓ | | `FAILED` | Settlement and refund both failed. Rare; contact the maintainer with the deposit address. | ✓ | ## Polling [#polling] ```bash curl "https://www.usetidepool.tech/v0/status?depositAddress=" ``` Poll every 2–5 seconds and stop on a final status. The worker checks each active address about every 4 seconds and stops watching a quote 24 hours after its deadline. ## swapDetails [#swapdetails] | Field | Meaning | | --- | --- | | `amountIn`, `amountOut` (+ `Formatted`, `Usd`) | What was actually swapped. | | `depositedAmount` (+ `Formatted`, `Usd`) | What the deposit address holds in the verifier. | | `slippage` | Realised slippage vs. the quote, as a fraction. | | `refundedAmount` (+ `Formatted`, `Usd`) | Excess or refunded input. | | `refundReason` | `PARTIAL_DEPOSIT`, `DEADLINE_PASSED`, `SLIPPAGE_EXCEEDED`, `PRICE_MOVED`, `INSUFFICIENT_LIQUIDITY`, `SWAP_FAILED`. | | `nearTxHashes` | Settlement / refund transaction(s). | | `originChainTxHashes`, `destinationChainTxHashes` | `{ hash, explorerUrl }` on NearBlocks testnet. | | `intentHashes` | Intent hashes logged by the verifier. | The response also carries a Tidepool-only `tidepool` object: `explorer` (a labelled list of every transaction, such as "gas top-up", "move deposit into verifier", "swap (execute_intents)" or "refund") and `note` (the last error, if any). 1Click clients ignore it. # Swap types (/docs/concepts/swap-types) `swapType` decides which side of the trade `amount` fixes. `amount` is what you **send**. `amountIn = minAmountIn = amount`. Output floats with price, floored by `minAmountOut`. Send exactly 10 USDC, receive about 10 USDC worth of wNEAR: ```json { "swapType": "EXACT_INPUT", "amount": "10000000", "slippageTolerance": 100 } ``` A larger deposit swaps `amountIn` and refunds the excess in the same transaction. `amount` is what the recipient **receives**. Tidepool works out the input needed (`minAmountIn`) and asks you to deposit `amountIn = minAmountIn × (1 + slippage)` as a buffer. At settlement it uses only what the current price requires and **refunds the rest**. If the price moved so far that the deposit no longer covers the output, everything is refunded with `PRICE_MOVED`. Receive exactly 1 wNEAR: ```json { "swapType": "EXACT_OUTPUT", "amount": "1000000000000000000000000", "slippageTolerance": 100 } ``` Like `EXACT_INPUT`, but a deposit down to `minAmountIn = amount × (1 − slippage)` is still accepted and swapped pro rata. Useful when fees or rounding on the sending side may shave a little off. ```json { "swapType": "FLEX_INPUT", "amount": "10000000", "slippageTolerance": 100 } ``` Here any deposit of at least 9.9 USDC is swapped. `ANY_INPUT` returns 400. It needs streaming deposits, which Tidepool v1 does not implement. ## Recipient and refund types [#recipient-and-refund-types] | Field | Values | Meaning | | --- | --- | --- | | `recipientType` | `DESTINATION_CHAIN` | Output is withdrawn to `recipient` as a normal NEP-141 balance (`ft_withdraw`). Tidepool registers storage for you. | | | `INTENTS` | Output stays in the verifier, credited to `recipient`'s intents balance. | | `refundType` | `ORIGIN_CHAIN` | Refunds and excess are withdrawn to `refundTo`'s wallet. | | | `INTENTS` | Refunds are credited inside the verifier. | # Tidepool for agents (/docs/guides/agents) Tidepool is built to be read and used by coding agents and autonomous agents. ## Files for agents [#files-for-agents] - [`/llms.txt`](/llms.txt): an index of every page with a one-line summary. - [`/llms-full.txt`](/llms-full.txt): every page in one plain-text file. - [`/AGENTS.md`](/AGENTS.md): rules of the road for agents that call the API. - [`/openapi.json`](/openapi.json): the machine-readable API. - Any docs page as Markdown: add `.md` to its URL, for example [`/docs/quickstart.md`](/docs/quickstart.md). ## A full swap from a script [#a-full-swap-from-a-script] The repo ships `examples/swap.mjs`. It uses a fresh testnet account, so it needs no setup beyond Node 20: ```bash git clone && cd tidepool/examples && npm install TIDEPOOL_URL=https://www.usetidepool.tech node swap.mjs # quote → deposit → status → SUCCESS TIDEPOOL_URL=https://www.usetidepool.tech node swap.mjs --refund # deposit too little, wait for REFUNDED ``` What it does: 1. Creates a throwaway testnet account through the public testnet helper. 2. Calls `POST /v0/faucet` with `mode: "intents"`. 3. Calls `POST /v0/quote` with `dry: false` and `depositType: "INTENTS"`. 4. Deposits with a signed NEP-413 `transfer` intent to the deposit address. The script submits it with `execute_intents` from its own account, so it pays its own gas. 5. Calls `POST /v0/deposit/submit`, then polls `GET /v0/status` until `SUCCESS` or `REFUNDED`. ## Rules for agents [#rules-for-agents] - Always get a dry quote first and check `amountOut` and `minAmountOut` before going live. - Deposit exactly `quote.amountIn`. Under `minAmountIn` waits for more until the deadline, then refunds. - Poll `/v0/status` every 2 to 5 seconds. Stop on `SUCCESS`, `REFUNDED` or `FAILED`. - Faucet: one drip per account and mode per hour. Do not loop on it. - Never send real assets. Tidepool is testnet only. ## Prompt snippet [#prompt-snippet] Paste this into your agent's system prompt: ```text You can swap test tokens on NEAR testnet through Tidepool, a 1Click-compatible sandbox (base URL https://www.usetidepool.tech). Read /llms-full.txt for the API. Flow: POST /v0/faucet → POST /v0/quote (dry:true, then dry:false) → deposit quote.amountIn to quote.depositAddress → POST /v0/deposit/submit → poll GET /v0/status until SUCCESS, REFUNDED or FAILED. Amounts are strings in base units. Testnet only. ``` Every docs page also has **Copy Markdown** and **Open in ChatGPT / Claude** buttons at the top. # Faucet (/docs/guides/faucet) ## What you get per drip [#what-you-get-per-drip] | Token | Amount | Contract | | --- | --- | --- | | USDC | 100 | `usdc.tidepool-sandbox.testnet` (6 decimals) | | USDT | 100 | `usdt.tidepool-sandbox.testnet` (6 decimals) | | wNEAR | 40 | `wnear.tidepool-sandbox.testnet` (24 decimals) | | wBTC | 0.001 | `wbtc.tidepool-sandbox.testnet` (8 decimals) | | ETH | 0.03 | `eth.tidepool-sandbox.testnet` (18 decimals) | | XAUT | 0.03 | `xaut.tidepool-sandbox.testnet` (6 decimals) | Pass `"assets": ["USDC", "wNEAR"]` (symbols or asset ids) to drip only some tokens. ## Modes [#modes] | `mode` | Where tokens land | Needs | | --- | --- | --- | | `wallet` | NEP-141 wallet balance. Minted fresh by the root account, one `mint` tx per token. | The account must exist on testnet. Storage is registered automatically. | | `intents` | Your intents balance inside the verifier. One `mt_batch_transfer` from the maker. | Nothing. Works for any account id, even one that does not exist yet. | ## Limits [#limits] - **One drip per account per mode per hour.** `alice.testnet` can take one `wallet` and one `intents` drip each hour. - **Six drips per IP per hour.** - Over the limit returns **HTTP 429** with the time you can retry. - If a transfer fails, the limit is not consumed. Supply is not capped, but the faucet can only mint these fixed amounts. Only the token owner (`privacei.testnet`) and the two allowed minters (`tidepool-sandbox.testnet`, `maker.tidepool-sandbox.testnet`) can call `mint`. ## API [#api] ```bash curl -X POST https://www.usetidepool.tech/v0/faucet -H 'content-type: application/json' \ -d '{"accountId":"alice.testnet","mode":"wallet"}' ``` See [POST /v0/faucet](/docs/api-reference/tidepool-faucet) for the full response. Test tokens have **no value** and are not bridged. Do not list or trade them anywhere. # First swap in 5 minutes (/docs/guides/first-swap) You need a NEAR testnet account. If you do not have one, create it in a testnet wallet or with `near-cli-rs`. ## 1. Get test tokens (30 seconds) [#1-get-test-tokens-30-seconds] ```bash curl -X POST https://www.usetidepool.tech/v0/faucet -H 'content-type: application/json' \ -d '{"accountId":"alice.testnet","mode":"wallet"}' ``` `mode: "wallet"` mints every test token to your account. `mode: "intents"` credits your balance inside the Tidepool verifier instead, so you can deposit with an in-verifier transfer. You can also use the [faucet page](/docs/guides/faucet). ## 2. Get a live quote [#2-get-a-live-quote] ```bash DEADLINE=$(date -u -d '+10 min' +%Y-%m-%dT%H:%M:%SZ) curl -s -X POST https://www.usetidepool.tech/v0/quote -H 'content-type: application/json' -d '{ "dry": false, "swapType": "EXACT_INPUT", "slippageTolerance": 100, "originAsset": "nep141:usdc.tidepool-sandbox.testnet", "depositType": "ORIGIN_CHAIN", "destinationAsset": "nep141:wnear.tidepool-sandbox.testnet", "amount": "5000000", "refundTo": "alice.testnet", "refundType": "ORIGIN_CHAIN", "recipient": "alice.testnet", "recipientType": "DESTINATION_CHAIN", "deadline": "'$DEADLINE'"}' | tee quote.json ``` Note `quote.depositAddress` and `quote.amountIn`. ## 3. Deposit [#3-deposit] With `depositType: "ORIGIN_CHAIN"`, send the origin token straight to the deposit address. Register its storage first (it is a fresh account): ```bash near contract call-function as-transaction usdc.tidepool-sandbox.testnet storage_deposit \ json-args '{"account_id":"","registration_only":true}' \ prepaid-gas '30 Tgas' attached-deposit '0.00125 NEAR' sign-as alice.testnet network-config testnet sign-with-keychain send near contract call-function as-transaction usdc.tidepool-sandbox.testnet ft_transfer \ json-args '{"receiver_id":"","amount":"5000000"}' \ prepaid-gas '30 Tgas' attached-deposit '1 yoctoNEAR' sign-as alice.testnet network-config testnet sign-with-keychain send ``` Or, with `depositType: "INTENTS"`, deposit into the verifier for the deposit address in one call, no storage step needed: ```bash near contract call-function as-transaction usdc.tidepool-sandbox.testnet ft_transfer_call \ json-args '{"receiver_id":"verifier.tidepool-sandbox.testnet","amount":"5000000","msg":""}' \ prepaid-gas '100 Tgas' attached-deposit '1 yoctoNEAR' sign-as alice.testnet network-config testnet sign-with-keychain send ``` Optionally tell Tidepool about the tx: ```bash curl -X POST https://www.usetidepool.tech/v0/deposit/submit -H 'content-type: application/json' \ -d '{"txHash":"","depositAddress":""}' ``` ## 4. Watch it settle [#4-watch-it-settle] ```bash curl "https://www.usetidepool.tech/v0/status?depositAddress=" ``` You will see `PENDING_DEPOSIT` or `KNOWN_DEPOSIT_TX`, then `PROCESSING`, then `SUCCESS` with `swapDetails.nearTxHashes`. Open them on [NearBlocks testnet](https://testnet.nearblocks.io). ## What happens if it goes wrong [#what-happens-if-it-goes-wrong] - **Deposit too small or late:** when the deadline passes, everything deposited goes back to `refundTo` and the status becomes `REFUNDED` with `refundReason: "PARTIAL_DEPOSIT"`. - **Price moved past your slippage:** refunded with `SLIPPAGE_EXCEEDED` (Tidepool-specific reason). - **More than `amountIn` deposited:** the swap uses `amountIn` and the excess is refunded in the same transaction. ## Real examples [#real-examples] These ran on the live deployment: | Flow | Transactions | | --- | --- | | USDC → wNEAR, `INTENTS` deposit | deposit [FF748tdK…](https://testnet.nearblocks.io/txns/FF748tdK7Dn75oRUjh6drpuJV9ZeR1uX9K717aZjrP6k) · settle [CTnAzK9Y…](https://testnet.nearblocks.io/txns/CTnAzK9YrbNy64GR9hhEQUF7ctn6KHYY5tpt57g5pEPe) | | USDT → wBTC, `ORIGIN_CHAIN` deposit | deposit [HDiVNZxM…](https://testnet.nearblocks.io/txns/HDiVNZxM4s6TzbZSXBs5uF3fpDWxNJHN8BinYymsysiJ) · gas top-up [8gXfnRvU…](https://testnet.nearblocks.io/txns/8gXfnRvUPM1xXZnC5688gbSwkDNkhewUYStjN6KqLE1e) · move [25PDfgMj…](https://testnet.nearblocks.io/txns/25PDfgMj1PHGekzrCLDmhrQjHZJMZhztLsnD5ZZ1V92Y) · settle [F4NQXgVo…](https://testnet.nearblocks.io/txns/F4NQXgVoczTixw1bvekQf7k5NGNKoDY4huveLxhkoToX) | | USDC → ETH, partial deposit → `REFUNDED` | deposit [452vagfg…](https://testnet.nearblocks.io/txns/452vagfgdDpY8bEcFzsVsvcWjiAqQVsoUjrgR9zKH8xb) · refund [4LaFRDyT…](https://testnet.nearblocks.io/txns/4LaFRDyTHHyAWP4PNz2z38MC34GAcr6aE2KTUTdTHysy) | # Moving to mainnet 1Click (/docs/guides/mainnet-migration) Tidepool mirrors the 1Click request and response shapes, so most code moves unchanged. This checklist covers what does change. **Base URL.** Replace `https://www.usetidepool.tech` with `https://1click.chaindefuser.com`. With the SDK, delete the `OpenAPI.BASE = …` line. **Real auth.** Get a real JWT from the 1Click partner portal and set it as `OpenAPI.TOKEN` / `Authorization: Bearer`. Tidepool accepts any value; mainnet does not. Keyless mainnet calls pay an extra fee. **Real asset ids.** Load ids from `GET /v0/tokens` at runtime. Never hardcode `nep141:*.tidepool-sandbox.testnet`; those contracts exist only on testnet. **Real chains.** Mainnet supports many `blockchain` values and deposit addresses on other chains (EVM, Solana, Bitcoin…). Your deposit code must send on the origin chain, not with `ft_transfer` on NEAR. `refundTo` and `recipient` must be valid addresses on their chains. **Features Tidepool lacks.** `ANY_INPUT`, `depositMode: MEMO`, `appFees`, `CONFIDENTIAL_INTENTS` and `/v0/auth/*` exist on mainnet. Test them there with small amounts. **Prices and timing.** Mainnet quotes come from competing solvers and settle cross-chain, so `timeEstimate` can be minutes. Keep your polling loop tolerant of long `PROCESSING` periods. **Ignore Tidepool-only fields.** Drop any use of `tidepool.explorer`, `tidepool.note`, `/v0/faucet` and `/v0/health`. Always confirm the current mainnet API in the official 1Click documentation before shipping. Tidepool tracks OpenAPI v0.1.10 and may lag behind. # Official 1Click SDK (/docs/guides/sdk) The official TypeScript client, [`@defuse-protocol/one-click-sdk-typescript`](https://www.npmjs.com/package/@defuse-protocol/one-click-sdk-typescript), works against Tidepool unchanged. Point `OpenAPI.BASE` at Tidepool and use the same calls. We tested `getTokens`, `getQuote` and `getExecutionStatus` with SDK version 0.1.26. ```bash npm i @defuse-protocol/one-click-sdk-typescript ``` ```ts import { OpenAPI, OneClickService, QuoteRequest } from '@defuse-protocol/one-click-sdk-typescript'; OpenAPI.BASE = 'https://www.usetidepool.tech'; // the only change; remove it to go to mainnet // OpenAPI.TOKEN = 'any-dummy-jwt'; // optional: selects the lower fee tier const tokens = await OneClickService.getTokens(); const quote = await OneClickService.getQuote({ dry: false, swapType: QuoteRequest.swapType.EXACT_INPUT, slippageTolerance: 100, originAsset: 'nep141:usdc.tidepool-sandbox.testnet', destinationAsset: 'nep141:wnear.tidepool-sandbox.testnet', amount: '5000000', depositType: QuoteRequest.depositType.INTENTS, refundTo: 'you.testnet', refundType: QuoteRequest.refundType.INTENTS, recipient: 'you.testnet', recipientType: QuoteRequest.recipientType.INTENTS, deadline: new Date(Date.now() + 10 * 60_000).toISOString(), }); // Deposit to quote.quote.depositAddress (see First swap), then: await OneClickService.submitDepositTx({ txHash: '', depositAddress: quote.quote.depositAddress! }); const status = await OneClickService.getExecutionStatus(quote.quote.depositAddress!); console.log(status.status); // PENDING_DEPOSIT → PROCESSING → SUCCESS | REFUNDED ``` > Asset ids differ from mainnet: Tidepool tokens live under `tidepool-sandbox.testnet`. Read them from `getTokens()` instead of hardcoding mainnet ids. ## Other languages [#other-languages] Any OpenAPI generator works with [`/openapi.json`](/openapi.json), which mirrors the 1Click v0.1.10 schemas plus two Tidepool-only operations (`/v0/faucet`, `/v0/health`): ```bash npx @openapitools/openapi-generator-cli generate -i https://www.usetidepool.tech/openapi.json -g python -o tidepool-client ``` ## Plain fetch [#plain-fetch] ```ts const BASE = 'https://www.usetidepool.tech'; const q = await fetch(`${BASE}/v0/quote`, { method: 'POST', headers: { 'content-type': 'application/json', authorization: 'Bearer dummy' }, body: JSON.stringify({ /* QuoteRequest */ }), }).then(r => r.json()); for (;;) { const s = await fetch(`${BASE}/v0/status?depositAddress=${q.quote.depositAddress}`).then(r => r.json()); if (['SUCCESS', 'REFUNDED', 'FAILED'].includes(s.status)) break; await new Promise(r => setTimeout(r, 3000)); } ``` # Introduction (/docs) Tidepool is community-built and **not affiliated with NEAR, Defuse or 1Click**. It runs on NEAR **testnet** only. Never send real assets to a Tidepool address. Tidepool gives you everything a 1Click swap needs, on testnet: - **The official NEAR Intents verifier** (`defuse` v0.4.2, wasm byte-identical to the GitHub release) deployed at `verifier.tidepool-sandbox.testnet`. - **Six test tokens**: USDC, USDT, wNEAR, wBTC, ETH and XAUT, with a public faucet. - **A live maker** that quotes every pair from real CoinGecko prices and fills every quote by signing intents on the verifier. - **The 1Click Swap API shape** (`/v0/tokens`, `/v0/quote`, `/v0/deposit/submit`, `/v0/status`), so the official SDK works by changing one base URL. ## Where to start [#where-to-start] ## Endpoints at a glance [#endpoints-at-a-glance] | | Base URL | | --- | --- | | API | `https://www.usetidepool.tech` | | OpenAPI | [`/openapi.json`](/openapi.json) | | Agent index | [`/llms.txt`](/llms.txt) · [`/llms-full.txt`](/llms-full.txt) · [`/AGENTS.md`](/AGENTS.md) | Every page has a **Copy Markdown** button and an **Open** menu (view as Markdown, open in ChatGPT or Claude) at the top. # Quickstart (/docs/quickstart) Tidepool speaks the 1Click Swap API (OpenAPI v0.1.10) shape on NEAR testnet. If you already have a 1Click client, change its base URL to `https://www.usetidepool.tech` and use the testnet asset ids from `/v0/tokens`. ### List tokens [#list-tokens] ```bash curl https://www.usetidepool.tech/v0/tokens ``` Each token has an `assetId` such as `nep141:usdc.tidepool-sandbox.testnet`, a `decimals` value and a live USD `price`. Use those ids in quotes. ### Ask for a dry quote [#ask-for-a-dry-quote] A dry quote prices the swap without creating a deposit address or committing the maker. ```bash curl -X POST https://www.usetidepool.tech/v0/quote \ -H 'content-type: application/json' \ -d '{ "dry": true, "swapType": "EXACT_INPUT", "slippageTolerance": 100, "originAsset": "nep141:usdc.tidepool-sandbox.testnet", "depositType": "INTENTS", "destinationAsset": "nep141:wnear.tidepool-sandbox.testnet", "amount": "10000000", "refundTo": "alice.testnet", "refundType": "INTENTS", "recipient": "alice.testnet", "recipientType": "DESTINATION_CHAIN", "deadline": "2030-01-01T00:00:00.000Z" }' ``` `amount` is in base units (USDC has 6 decimals, so `10000000` is 10 USDC). `slippageTolerance` is in basis points (100 = 1%). ### Go live [#go-live] Send the same request with `"dry": false` and a deadline a few minutes ahead. The response's `quote.depositAddress` is a fresh NEAR account used by this quote only. Deposit `quote.amountIn` of the origin token to it ([how](/docs/concepts/deposits)), then poll: ```bash curl "https://www.usetidepool.tech/v0/status?depositAddress=" ``` Try it here (dry quote, nothing is committed): ## Auth and fees [#auth-and-fees] Auth is optional. Any `X-API-Key` header or `Authorization: Bearer ` value is accepted, so a dummy JWT works. A key selects the lower fee tier, as it does on mainnet 1Click: | Pair | No key | Any key | | --- | --- | --- | | Most pairs | 45 bps | 20 bps | | Stable to stable (USDC/USDT) | 26 bps | 1 bp | ## Differences from mainnet 1Click [#differences-from-mainnet-1click] - Tokens are Tidepool test tokens on NEAR testnet, not bridged assets. Only `blockchain: "near"` exists. - Supported: `EXACT_INPUT`, `EXACT_OUTPUT`, `FLEX_INPUT`; deposit and refund types `ORIGIN_CHAIN` and `INTENTS`; recipient types `DESTINATION_CHAIN` and `INTENTS`. - `ANY_INPUT`, `CONFIDENTIAL_INTENTS`, `appFees`, `depositMode: MEMO` and `/v0/auth/*` return 400 or 404. - One maker (Tidepool's) fills every quote. There is no solver competition. - The quote `signature` is Tidepool's maker key over the quote body, not 1Click's. Next: [First swap in 5 minutes](/docs/guides/first-swap). # Changelog (/docs/resources/changelog) ## 2026-10-24 · Docs v2 and token ownership [#2026-10-24--docs-v2-and-token-ownership] - New documentation site: concepts, lifecycle diagrams, an API reference generated from `openapi.json`, live faucet and status widgets, Copy Markdown / Open in ChatGPT or Claude on every page, `llms.txt` and `llms-full.txt`. - Token contracts gained `set_owner`, `add_minter`, `remove_minter` and `is_minter`. Ownership of all six tokens moved to `privacei.testnet`. The root and maker accounts stay as minters, so the faucet is unchanged. - `ORIGIN_CHAIN` deposits: gas top-up raised to 0.12 NEAR so the sweep never runs out of prepaid gas. - `/v0/status`: duplicate `intentHashes` removed. ## 2026-10-24 · v1 [#2026-10-24--v1] - First public release: official verifier v0.4.2, six test tokens, faucet, maker, and the 1Click-shaped `/v0/tokens`, `/v0/quote`, `/v0/deposit/submit`, `/v0/status`. - `EXACT_INPUT`, `EXACT_OUTPUT`, `FLEX_INPUT`; `ORIGIN_CHAIN` and `INTENTS` deposits. # FAQ (/docs/resources/faq) No. Tidepool is a community-built sandbox that copies the 1Click API shape. It is not affiliated with NEAR or 1Click. Tidepool's own maker, `maker.tidepool-sandbox.testnet`. It is the only solver, like a single market maker behind a swap app. No. The public faucet gives fixed amounts (for example 100 USDC) once per account per mode per hour, and six requests per IP per hour. Only the token owner and the two minter accounts can mint arbitrary amounts. No. Any `X-API-Key` or Bearer value is accepted and only lowers the fee tier. Check you sent the origin token (not another one) to the exact `depositAddress`, that `ORIGIN_CHAIN` deposits registered storage first, and that the deadline has not passed. Calling `/v0/deposit/submit` with your tx hash helps. Status shows `INCOMPLETE_DEPOSIT`. Send the rest before the deadline, or wait and it is refunded with `PARTIAL_DEPOSIT`. The swap uses `amountIn` and returns the excess in the same transaction. Yes. `@defuse-protocol/one-click-sdk-typescript` 0.1.26 was tested with `getTokens`, `getQuote` and `getExecutionStatus`. Set `OpenAPI.BASE`. The code is in a private repository today. Contact the maintainer for access. No. Its wasm hash matches the `defuse/v0.4.2` release and is checked on every `/v0/health` call. # Tokens and contracts (/docs/resources/tokens) | Symbol | Asset id | Decimals | Faucet drip | | --- | --- | --- | --- | | USDC | `nep141:usdc.tidepool-sandbox.testnet` | 6 | 100 | | USDT | `nep141:usdt.tidepool-sandbox.testnet` | 6 | 100 | | wNEAR | `nep141:wnear.tidepool-sandbox.testnet` | 24 | 40 | | wBTC | `nep141:wbtc.tidepool-sandbox.testnet` | 8 | 0.001 | | ETH | `nep141:eth.tidepool-sandbox.testnet` | 18 | 0.03 | | XAUT | `nep141:xaut.tidepool-sandbox.testnet` | 6 | 0.03 | All are standard NEP-141 tokens (with NEP-145 storage) and use the same contract code. Names read "Tidepool Testnet X (no value)". Read the live list, including USD prices, from [`GET /v0/tokens`](/docs/api-reference/get-tokens). ## Admin methods [#admin-methods] | Method | Who | Effect | | --- | --- | --- | | `owner_id()` | view | Returns the owner. Currently `privacei.testnet` on all six. | | `is_minter({ account_id })` | view | `true` for the owner and allowed minters. | | `mint({ account_id, amount })` | owner or minter | Mints any amount. Used by the faucet. | | `add_minter` / `remove_minter({ account_id })` | owner | Manage the minter allowlist. | | `set_owner({ new_owner })` | owner | Transfers ownership and registers storage for the new owner. | Current minters: `tidepool-sandbox.testnet` (wallet faucet) and `maker.tidepool-sandbox.testnet`. # Trust model and limitations (/docs/resources/trust-model) Testnet only. Test tokens have no value. Do not send mainnet assets to any address Tidepool shows you. ## What is trustless [#what-is-trustless] - **Swap atomicity.** Settlement is one `execute_intents` call on the unmodified verifier. Either both `token_diff`s apply or neither does. - **The verifier code.** Byte-identical to `near/intents` `defuse/v0.4.2`, checked live by `/v0/health`. - **Auditability.** Every deposit, settlement and refund is a public testnet transaction listed in `/v0/status`. ## What you trust Tidepool for [#what-you-trust-tidepool-for] - **Deposit addresses are custodial.** Their keys are derived on the server from a master seed. Tidepool could move funds sent to them. This is the same trust you give 1Click's deposit addresses. - **One maker sets every price.** Tidepool's maker is the only solver. Prices follow CoinGecko plus a fixed fee, not a competitive market. - **Liveness.** If the server is down, deposits wait. Funds are not lost; they are refunded once the worker runs again and the deadline has passed. - **Token admin.** The six token contracts are owned by `privacei.testnet`, which can mint any amount and change minters. The root and maker accounts are minters. - **Contract keys.** The token accounts still hold full-access keys controlled by the Tidepool deployer, so their code could be upgraded. Treat balances as test data. ## Limitations (v1) [#limitations-v1] - NEAR testnet only; `blockchain: "near"` only. - No `ANY_INPUT`, `depositMode: MEMO`, `appFees`, `CONFIDENTIAL_INTENTS` or `/v0/auth/*`. - Single maker with finite inventory. Large quotes fail with `Not enough maker liquidity`. - Faucet: one drip per account per mode per hour, six per IP per hour. - Live quotes need a deadline between 60 seconds and 24 hours ahead. - State is a JSON file on one server volume; there is no SLA. ## Affiliation [#affiliation] Tidepool is community-built. It is **not** operated, endorsed or reviewed by NEAR Foundation, Defuse Labs or 1Click. # Live status (/docs/status) This page calls [`GET /v0/health`](/docs/api-reference/tidepool-health) every 15 seconds.