API Reference

USDT0 Transfers

USDT0 out of Stellar through LayerZero: quote, build the Soroban transaction the holder signs, submit it and follow the message to its destination. Native USDT on Ethereum, USDT0 elsewhere; mainnet only.

GET
/v1/usdt0/routes

USDT0 is Tether’s omnichain USDT. From Stellar it travels through LayerZero’s OFT: Ethereum receives native USDT (Tether’s OFT adapter unlocks it), every other network receives USDT0. All routes take an EVM recipient. USDT0 exists on Stellar mainnet only: a dev (testnet) key gets available: false and no routes.

Requires the swaps:read scope. The shared public key may call it.

apiKey
headerAuthorizationBearer <API key>

Your Cosmos Pay secret API key, sent as Authorization: Bearer <apiKey>.

OK

no_authenticated_consumer: The gateway forwarded no API key identity

insufficient_scope: the API key does not hold the scope this route requires. The shared public API key also gets this on every route that is not marked x-cosmos-public-key, with a message saying so; more scopes will not help, the key is the wrong one.

gateway_required: the request did not arrive through APISIX.

Unexpected server error. The detail is logged server-side and never returned: there is nothing in the body to branch on beyond the code.

Example Request
curl -X GET 'https://api.cosmospay.lat/cosmos-api/v1/usdt0/routes'
Example Response
{  "network": "public",  "available": true,  "token": {    "code": "USDT0",    "issuer": "GATISXX6BZ6NC7IKQBY37CJD4SOZL3CYZJWXEDG6JVIY4WBS6KXJHN6Q",    "contract": "CBSJZEIO5C7KC2SF3MKSNXXJSW5G3VTNBX4ATMKUI3B2MR4JKM4R26YF"  },  "oft": "CBOWOLFSDM5PZXNFIVDMP5NZ7U2GSIHED6H6R446QOHF266XINKUMMF6",  "eid": 30600,  "routes": [    {      "chain": "eth",      "name": "Ethereum",      "eid": 30101,      "receives": "USDT"    }  ]}
POST
/v1/usdt0/quote

Simulates the OFT’s quote_oft and quote_send on Stellar mainnet. The OFT carries 6 decimals and the asset has 7, so the 7th is dust that stays in the account. nativeFee is LayerZero’s fee, paid in XLM on top of the USDT0; nativeFeeLimit is what a transfer built now would offer (20% more, the excess refunded in the same transaction). Mainnet only.

Requires the swaps:read scope. The shared public key may call it.

apiKey
headerAuthorizationBearer <API key>

Your Cosmos Pay secret API key, sent as Authorization: Bearer <apiKey>.

application/json
  1. body

A USDT0 quote request: how much USDT0 to send from Stellar, and to which network. The OFT is asked by simulation; nothing is persisted.

to*string

The destination network (GET /v1/usdt0/routes). eth receives native USDT; every other network receives USDT0.

Value in"eth""arb""bera""conflux""flare""hedera""hyperevm""ink""mantle""megaeth""monad""morph""op""plasma""pol""rootstock""sei""stable""tempo""unichain""xlayer"
amount*string

USDT0 to send, decimal with up to 7 places. The OFT carries 6: a 7th decimal is dust that stays in the account (see dust).

source?string

The account that would send it: the quote is simulated as that account. Omitted, a fixed mainnet account is used; the price is the same.

OK

network_unsupported: a dev (testnet) key; USDT0 is on Stellar mainnet only. invalid_amount: less than 0.000001 USDT0 (all dust), or outside the OFT’s limits. provider_error: the OFT refused the quote; message carries its contract error.

no_authenticated_consumer: The gateway forwarded no API key identity

insufficient_scope: the API key does not hold the scope this route requires. The shared public API key also gets this on every route that is not marked x-cosmos-public-key, with a message saying so; more scopes will not help, the key is the wrong one.

gateway_required: the request did not arrive through APISIX.

The budget in x-cosmos-rate-limit is spent for this caller. Honour Retry-After.

The ratelimit-* triple rides along on successful responses too, so a client can pace itself instead of being refused. If the counter store itself is unreachable the guard fails closed and answers 503 provider_unavailable.

Unexpected server error. The detail is logged server-side and never returned: there is nothing in the body to branch on beyond the code.

provider_error: the Soroban RPC answered the simulation with no result, or in a shape the OFT never returns.

provider_unavailable: the Soroban RPC did not answer; retry. misconfigured: STELLAR_RPC_URL_MAINNET serves another network, or USDT0_FEE_WRAPPER is set with a plan commission and no STELLAR_SWAP_FEE_WALLET.

Example Request
curl -X POST 'https://api.cosmospay.lat/cosmos-api/v1/usdt0/quote' \  -H 'Content-Type: application/json' \  -d '{  "to": "eth",  "amount": "12.5"}'
Example Response
{  "to": "eth",  "eid": 30101,  "receives": "USDT",  "amount": "12.5000001",  "feeBps": 50,  "feeAmount": "0.0625",  "amountSent": "12.5",  "amountReceived": "12.5",  "dust": "0.0000001",  "nativeFee": "3.6664143",  "nativeFeeLimit": "4.3996972",  "minAmount": "0",  "maxAmount": "1844674407370.9551615"}
GET
/v1/usdt0/transfers

Answers from this service’s own table, as last refreshed; read one transfer to refresh it. Refused to the shared public key, which is every anonymous caller at once.

Requires the swaps:read scope.

apiKey
headerAuthorizationBearer <API key>

Your Cosmos Pay secret API key, sent as Authorization: Bearer <apiKey>.

status?string

Only transfers in this status, as last refreshed.

Value in"PENDING""SUBMITTED""DELIVERED""FAILED""EXPIRED"
take?number

How many transfers to return per page (1 to 100).

Rangevalue <= 100
Default20
skip?number

How many matching transfers to skip before the page starts (newest first).

Default0

OK

The body, query or path failed validation. message is an array of the individual failures.

Routes that reject a valid request for a reason of their own (an amount, a memo, a state) document the code for it on their own 400.

no_authenticated_consumer: The gateway forwarded no API key identity

insufficient_scope: the API key does not hold the scope this route requires. The shared public API key also gets this on every route that is not marked x-cosmos-public-key, with a message saying so; more scopes will not help, the key is the wrong one.

gateway_required: the request did not arrive through APISIX.

Unexpected server error. The detail is logged server-side and never returned: there is nothing in the body to branch on beyond the code.

Example Request
curl -X GET 'https://api.cosmospay.lat/cosmos-api/v1/usdt0/transfers'
Example Response
{  "data": [    {      "id": "cm2u0t0transfer0000000001",      "status": "PENDING",      "network": "public",      "source": "GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ",      "to": "eth",      "eid": 30101,      "receives": "USDT",      "recipient": "0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed",      "amount": "12.5000001",      "amountSent": "12.5",      "amountReceived": "12.5",      "dust": "0.0000001",      "nativeFee": "3.6664143",      "nativeFeeLimit": "4.3996972",      "networkFee": "1.4468825",      "feeBps": 50,      "feeAmount": "0.0625",      "feeWallet": "GBFEEWALLETEXAMPLE7XKXBOL5CH6OFGYUMVJZH7H7OZQXK6U2RG3UEZW34",      "xdr": "AAAAAgAAAABx…(base64 XDR)…AAAAAAAAAAA=",      "uri": "web+stellar:tx?xdr=AAAAAgAAAABx…",      "txHash": null,      "guid": null,      "destinationTxHash": null,      "scanStatus": null,      "scanUrl": null,      "failureReason": null,      "merchantFee": {        "bps": 150,        "fixed": "0.25",        "amount": "1.75",        "asset": "XLM",        "wallet": "GBDHAQXQQ75WVBUZ2IX3O7ME7JOKJUOUPUXRNDCORUJODWQCTVUEQ62R",        "paidBy": "recipient"      },      "idempotencyKey": null,      "expiresAt": "2026-10-25T12:05:00.000Z",      "submittedAt": null,      "createdAt": "2026-10-25T12:00:00.000Z",      "updatedAt": "2026-10-25T12:00:00.000Z"    }  ],  "total": 1,  "take": 20,  "skip": 0}
POST
/v1/usdt0/transfers

Builds send on USDT0’s LayerZero OFT: it burns the USDT0 on Stellar and LayerZero delivers it to recipient, as native USDT on Ethereum and as USDT0 elsewhere. The source signs one transaction (Freighter, or the SEP-7 uri) and pays two fees in XLM: LayerZero’s (nativeFeeLimit is offered, the unused part refunded in the same transaction) and the network’s (networkFee). A 7th decimal of amount is dust and stays in the account. No Cosmos Pay commission is charged. Mainnet only. Submit the signed XDR to POST /v1/usdt0/transfers/{id}/submit, then follow GET /v1/usdt0/transfers/{id}.

Requires the swaps:write scope. The shared public key may call it.

apiKey
headerAuthorizationBearer <API key>

Your Cosmos Pay secret API key, sent as Authorization: Bearer <apiKey>.

Idempotency-Key?string

Optional idempotency key. A retry with the same key and the same request returns the stored transfer unchanged; the same key with a different request is 409 idempotency_conflict. Takes precedence over body.idempotencyKey.

application/json
  1. body

A USDT0 transfer from Stellar: the holder, the destination network, the EVM recipient and the amount. The service builds the one Soroban transaction the holder signs and never holds a key.

source*string

The Stellar account that holds the USDT0, signs the transaction and pays its fees in XLM (LayerZero fee plus network fee).

to*string

The destination network (GET /v1/usdt0/routes). eth receives native USDT; every other network receives USDT0.

Value in"eth""arb""bera""conflux""flare""hedera""hyperevm""ink""mantle""megaeth""monad""morph""op""plasma""pol""rootstock""sei""stable""tempo""unichain""xlayer"
recipient*string

The EVM address credited on the destination network (0x + 40 hex). A mixed-case address must carry a valid EIP-55 checksum.

amount*string

USDT0 to send, decimal with up to 7 places. The OFT carries 6: a 7th decimal is dust that stays in the account (see dust).

idempotencyKey?string

Optional idempotency key. Prefer the Idempotency-Key request header; when both are set, the header wins. A retry with the same key and the same request returns the stored transfer; the same key with a different request is 409 idempotency_conflict.

merchantFee?

Your own fee on this transfer, in USDT0, paid to wallet (a Stellar account that trusts USDT0) in the same transaction: the operation is then the fee wrapper (USDT0_FEE_WRAPPER), which pays the fee and calls the OFT's send under the holder's one authorization. paidBy: recipient takes it from amount (less is sent); payer adds it on top. Without a configured wrapper, merchant_fee_unsupported.

The transfer. With the shared public key it carries publicToken: send it as X-Record-Token to read the transfer or submit it.

merchant_fee_unsupported: a merchantFee and no merchant fee wrapper configured (USDT0_FEE_WRAPPER). network_unsupported: a dev (testnet) key; USDT0 is on Stellar mainnet only. validation_failed: the source account does not exist, or the recipient has a bad EIP-55 checksum. trustline_missing: the source does not trust USDT0. insufficient_balance: it holds less USDT0 than the transfer takes, or too little XLM for LayerZero’s fee limit, the network fee and its reserve (the message says how much XLM to add). invalid_amount: all dust, or outside the OFT’s limits. provider_error: the OFT refused the transfer; message carries its contract error. With a merchant fee, trustline_missing also answers a fee wallet that does not trust USDT0, and insufficient_balance counts the fee the holder pays on top.

no_authenticated_consumer: The gateway forwarded no API key identity

insufficient_scope: the API key does not hold the scope this route requires. The shared public API key also gets this on every route that is not marked x-cosmos-public-key, with a message saying so; more scopes will not help, the key is the wrong one.

gateway_required: the request did not arrive through APISIX.

This Idempotency-Key was already used for a different USDT0 transfer request, or an identical transfer was built from the same account in the same second.

The budget in x-cosmos-rate-limit is spent for this caller. Honour Retry-After.

The ratelimit-* triple rides along on successful responses too, so a client can pace itself instead of being refused. If the counter store itself is unreachable the guard fails closed and answers 503 provider_unavailable.

Unexpected server error. The detail is logged server-side and never returned: there is nothing in the body to branch on beyond the code.

provider_error: the OFT cannot be called right now (part of its state is archived on the ledger, or it asks for a signature the transaction cannot carry), or the RPC answered in an unexpected shape.

provider_unavailable: Horizon or the Soroban RPC did not answer; retry. misconfigured: STELLAR_RPC_URL_MAINNET serves another network, or USDT0_FEE_WRAPPER is not the reviewed wrapper bound to USDT0's OFT and token, or the plan commission has no STELLAR_SWAP_FEE_WALLET, or one that does not trust USDT0.

Example Request
curl -X POST 'https://api.cosmospay.lat/cosmos-api/v1/usdt0/transfers' \  -H 'Content-Type: application/json' \  -d '{  "source": "GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ",  "to": "eth",  "recipient": "0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed",  "amount": "12.5"}'
Example Response
{  "id": "cm2u0t0transfer0000000001",  "status": "PENDING",  "network": "public",  "source": "GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ",  "to": "eth",  "eid": 30101,  "receives": "USDT",  "recipient": "0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed",  "amount": "12.5000001",  "amountSent": "12.5",  "amountReceived": "12.5",  "dust": "0.0000001",  "nativeFee": "3.6664143",  "nativeFeeLimit": "4.3996972",  "networkFee": "1.4468825",  "feeBps": 50,  "feeAmount": "0.0625",  "feeWallet": "GBFEEWALLETEXAMPLE7XKXBOL5CH6OFGYUMVJZH7H7OZQXK6U2RG3UEZW34",  "xdr": "AAAAAgAAAABx…(base64 XDR)…AAAAAAAAAAA=",  "uri": "web+stellar:tx?xdr=AAAAAgAAAABx…",  "qr": null,  "txHash": null,  "guid": null,  "destinationTxHash": null,  "scanStatus": null,  "scanUrl": null,  "failureReason": null,  "merchantFee": {    "bps": 150,    "fixed": "0.25",    "amount": "1.75",    "asset": "XLM",    "wallet": "GBDHAQXQQ75WVBUZ2IX3O7ME7JOKJUOUPUXRNDCORUJODWQCTVUEQ62R",    "paidBy": "recipient"  },  "idempotencyKey": null,  "expiresAt": "2026-10-25T12:05:00.000Z",  "submittedAt": null,  "createdAt": "2026-10-25T12:00:00.000Z",  "updatedAt": "2026-10-25T12:00:00.000Z",  "publicToken": "q3Zx0r8vH6c1yJ2bN5mT4kW9sD7fL0aE1gP3uR6iO2w"}
GET
/v1/usdt0/transfers/{id}

While PENDING or SUBMITTED, a read asks the Stellar ledger (a wallet may have broadcast the transaction itself) and LayerZero Scan, at most once every 15 seconds per transfer, and moves it to SUBMITTED, DELIVERED (with destinationTxHash), FAILED or EXPIRED. Delivery takes about 27 minutes on every route: LayerZero’s verifiers wait for Stellar confirmations. The shared public key may call it, but only with the transfer’s publicToken in X-Record-Token: without it, or with another transfer’s, the answer is 404. Every other key reads its own transfers as before.

Requires the swaps:read scope. The shared public key may call it.

apiKey
headerAuthorizationBearer <API key>

Your Cosmos Pay secret API key, sent as Authorization: Bearer <apiKey>.

id*string
X-Record-Token?string

Required with the shared public key: the publicToken the create response returned for this record. Without it, or with the token of another record, the answer is 404, as for a record that does not exist. Ignored for every other API key.

OK

The body, query or path failed validation. message is an array of the individual failures.

Routes that reject a valid request for a reason of their own (an amount, a memo, a state) document the code for it on their own 400.

no_authenticated_consumer: The gateway forwarded no API key identity

insufficient_scope: the API key does not hold the scope this route requires. The shared public API key also gets this on every route that is not marked x-cosmos-public-key, with a message saying so; more scopes will not help, the key is the wrong one.

gateway_required: the request did not arrive through APISIX.

No such resource, or it exists and belongs to another consumer. The two are deliberately the same answer: "exists but not yours" is an ownership oracle.

Unexpected server error. The detail is logged server-side and never returned: there is nothing in the body to branch on beyond the code.

Example Request
curl -X GET 'https://api.cosmospay.lat/cosmos-api/v1/usdt0/transfers/string'
Example Response
{  "id": "cm2u0t0transfer0000000001",  "status": "PENDING",  "network": "public",  "source": "GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ",  "to": "eth",  "eid": 30101,  "receives": "USDT",  "recipient": "0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed",  "amount": "12.5000001",  "amountSent": "12.5",  "amountReceived": "12.5",  "dust": "0.0000001",  "nativeFee": "3.6664143",  "nativeFeeLimit": "4.3996972",  "networkFee": "1.4468825",  "feeBps": 50,  "feeAmount": "0.0625",  "feeWallet": "GBFEEWALLETEXAMPLE7XKXBOL5CH6OFGYUMVJZH7H7OZQXK6U2RG3UEZW34",  "xdr": "AAAAAgAAAABx…(base64 XDR)…AAAAAAAAAAA=",  "uri": "web+stellar:tx?xdr=AAAAAgAAAABx…",  "qr": null,  "txHash": null,  "guid": null,  "destinationTxHash": null,  "scanStatus": null,  "scanUrl": null,  "failureReason": null,  "merchantFee": {    "bps": 150,    "fixed": "0.25",    "amount": "1.75",    "asset": "XLM",    "wallet": "GBDHAQXQQ75WVBUZ2IX3O7ME7JOKJUOUPUXRNDCORUJODWQCTVUEQ62R",    "paidBy": "recipient"  },  "idempotencyKey": null,  "expiresAt": "2026-10-25T12:05:00.000Z",  "submittedAt": null,  "createdAt": "2026-10-25T12:00:00.000Z",  "updatedAt": "2026-10-25T12:00:00.000Z"}
POST
/v1/usdt0/transfers/{id}/submit

The signed XDR must hash to the transfer’s transaction and carry a signature. Accepted and applied: SUBMITTED, with LayerZero’s guid. Applied and failed: FAILED. Refused by the network: the transfer stays PENDING (submitted: false, reason) and can be submitted again until it expires. Waits up to 30 seconds for the ledger.

Requires the swaps:write scope. The shared public key may call it.

apiKey
headerAuthorizationBearer <API key>

Your Cosmos Pay secret API key, sent as Authorization: Bearer <apiKey>.

id*string
X-Record-Token?string

Required with the shared public key: the publicToken the create response returned for this record. Without it, or with the token of another record, the answer is 404, as for a record that does not exist. Ignored for every other API key.

application/json
  1. body

A USDT0 transfer's transaction, signed, to relay to Stellar mainnet. It must be the transaction the service built (its hash is checked) and carry a signature.

signedXdr*string

The signed transaction envelope (base64 XDR).

OK

validation_failed: signedXdr is not a transaction, is not the one built for this transfer, or carries no signature. invalid_state_transition: the transfer is FAILED or EXPIRED, or its transaction expired; build a new one. network_unsupported: a dev (testnet) key.

no_authenticated_consumer: The gateway forwarded no API key identity

insufficient_scope: the API key does not hold the scope this route requires. The shared public API key also gets this on every route that is not marked x-cosmos-public-key, with a message saying so; more scopes will not help, the key is the wrong one.

gateway_required: the request did not arrive through APISIX.

No such resource, or it exists and belongs to another consumer. The two are deliberately the same answer: "exists but not yours" is an ownership oracle.

The budget in x-cosmos-rate-limit is spent for this caller. Honour Retry-After.

The ratelimit-* triple rides along on successful responses too, so a client can pace itself instead of being refused. If the counter store itself is unreachable the guard fails closed and answers 503 provider_unavailable.

Unexpected server error. The detail is logged server-side and never returned: there is nothing in the body to branch on beyond the code.

provider_unavailable: the Soroban RPC did not answer, or the network asked to try again later; the transfer stays PENDING, submit again. misconfigured: STELLAR_RPC_URL_MAINNET serves another network.

Example Request
curl -X POST 'https://api.cosmospay.lat/cosmos-api/v1/usdt0/transfers/string/submit' \  -H 'Content-Type: application/json' \  -d '{  "signedXdr": "AAAAAgAAAABx…(signed base64 XDR)…AAAAAAAAAAA="}'
Example Response
{  "submitted": true,  "status": "SUBMITTED",  "txHash": "6bc5348acd5dfa908c8d8ff8401d5cce5e659566b0f6707a84950b16ca7410e8",  "reason": null,  "transfer": {    "id": "cm2u0t0transfer0000000001",    "status": "PENDING",    "network": "public",    "source": "GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ",    "to": "eth",    "eid": 30101,    "receives": "USDT",    "recipient": "0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed",    "amount": "12.5000001",    "amountSent": "12.5",    "amountReceived": "12.5",    "dust": "0.0000001",    "nativeFee": "3.6664143",    "nativeFeeLimit": "4.3996972",    "networkFee": "1.4468825",    "feeBps": 50,    "feeAmount": "0.0625",    "feeWallet": "GBFEEWALLETEXAMPLE7XKXBOL5CH6OFGYUMVJZH7H7OZQXK6U2RG3UEZW34",    "xdr": "AAAAAgAAAABx…(base64 XDR)…AAAAAAAAAAA=",    "uri": "web+stellar:tx?xdr=AAAAAgAAAABx…",    "qr": null,    "txHash": null,    "guid": null,    "destinationTxHash": null,    "scanStatus": null,    "scanUrl": null,    "failureReason": null,    "merchantFee": {      "bps": 150,      "fixed": "0.25",      "amount": "1.75",      "asset": "XLM",      "wallet": "GBDHAQXQQ75WVBUZ2IX3O7ME7JOKJUOUPUXRNDCORUJODWQCTVUEQ62R",      "paidBy": "recipient"    },    "idempotencyKey": null,    "expiresAt": "2026-10-25T12:05:00.000Z",    "submittedAt": null,    "createdAt": "2026-10-25T12:00:00.000Z",    "updatedAt": "2026-10-25T12:00:00.000Z"  }}