# LocalCoinSwap Exchange API Rendered reference: https://localcoinswap.com/developers. OpenAPI spec: https://localcoinswap.com/openapi.json. ## Introduction Use this API to search offers, manage your own offers, run trades and their chat, and use your LocalCoinSwap wallet, with an API key instead of the website. All trading is non-custodial: escrow is funded and released from your own wallet, so trade actions need your signatures (see "Signing trades"). Supported coins are listed at `/api/v2/currencies/active-cryptos/`. Every operation has curl, Python and JavaScript samples. They read your key from the `LCS_API_KEY` environment variable, so you can run them as they are. The whole spec is at [`/openapi.json`](https://localcoinswap.com/openapi.json) for client generators; for coding agents, see "Coding agents". We try to keep changes backwards compatible, but the API can change at short notice. Questions, or a use case the API doesn't cover: email [dev@localcoinswap.com](mailto:dev@localcoinswap.com). ## Authentication API calls use an API key, not your website login token. A key does not expire when you log out, and it is not deleted with old login sessions. You can have up to five active keys. 1. How to create an API key: - Register on [LocalCoinSwap](https://localcoinswap.com/register/) - Turn on the authenticator app under [Security](https://localcoinswap.com/preferences/security) - Open [Preferences → API](https://localcoinswap.com/preferences/api-token) - Enter a name, choose the key's access, and enter the 6-digit authenticator code, then click **Create key** - Copy the secret immediately. It is shown once and looks like `lcs__` 2. Send that secret on every request in the `Authorization` header: ```HTTP Authorization: ApiKey lcs_a1b2c3d4_your_secret ``` Keep it in an environment variable rather than in code. The samples use `LCS_API_KEY`: ```bash export LCS_API_KEY="lcs_a1b2c3d4_your_secret" curl https://api.localcoinswap.com/api/v2/trades/list/ \ --header "Authorization: ApiKey $LCS_API_KEY" ``` 3. A missing or invalid key returns HTTP 401: ```HTTP WWW-Authenticate: ApiKey ``` ```json { "message": "Authentication credentials were not provided.", "code": "not_authenticated", "error": true } ``` Each key has scopes that limit what it can do: | Scope | Allows | |-------|--------| | `read` | `GET` requests outside the wallet endpoints. Every key has it. | | `trade` | Writes: offers, trades, chat, feedback, notifications. | | `wallet` | Wallet endpoints: sign and broadcast transactions, read encrypted keys, set referral payouts. | The wallet endpoints are everything under `/api/v2/wallets/`, `/api/v2/legacy-wallets/`, `/api/v2/eth-push-tx/`, `/api/v2/trade-utxos/` and `/api/v2/profile/encrypted-blob/`, plus `PATCH /api/v2/referrals/overview/` (it sets where referral payouts go). Wallet balances and the referral overview only need `read`. A request outside the key's scopes returns HTTP 403 with code `api_key_scope`. Keys created before scopes existed have all three. Within its scopes, an API key can call the same endpoints as a logged-in user, except account security. Password changes, email changes, MFA, creating or revoking keys, setting or resetting the wallet PIN, and resetting wallets require the website session. API-key traffic is limited to 60 requests per minute per account, in addition to any limit on the endpoint itself. Revoke a key from the same API page when you no longer use it. The list shows when each key was last used. ## Rate limits - API keys: 60 requests per minute per account, shared by all of the account's keys. - Calls without a key (public endpoints): 120 requests per minute per IP. - Some endpoints have a lower limit of their own, shown on the endpoint as **Rate limit** and in its `x-rateLimit` extension. For example, trade status allows 2 requests per minute, and wallet balance and wallet reads share 30 per minute across all coins. Over a limit, the API returns HTTP 429 with code `throttled` and a `Retry-After` header in seconds. ## Errors Errors are JSON with `"error": true`. - 400 (invalid request): each failing field maps to a list of `{message, code}`, and errors about the request as a whole are under `non_field_errors`: ```json { "fiat_amount": [{"message": "This field is required.", "code": "required"}], "error": true } ``` - Every other error has a readable `message` and a stable `code` to match on (`detail` repeats the message): ```json { "message": "This API key does not have the trade scope.", "code": "api_key_scope", "detail": "This API key does not have the trade scope.", "error": true } ``` Match on `code`, not `message`; messages may be reworded or translated. ## Signing trades Trades are non-custodial: the escrow is a smart contract, and moving funds in or out of it needs your signature. This covers the v2 escrow contracts for ETH and ERC20 tokens (trades with `tx_meta.escrow_version` `"v2"`), BNB and BEP20 tokens, and TRC20 tokens. Sign with the private key of your trade address: `seller_meta.address` if you're the seller, `buyer_meta.address` if you're the buyer. ### Approval and escrow transactions The seller funds the escrow with a transaction the API builds: 1. Tokens only: PATCH the trade to `TRANSFER_APPROVED`. Sign `tx_meta.approve_unsigned_tx` and PATCH `WAITING_FOR_MIN_APPROVE_CONFIRMS` with it. 2. PATCH `CRYPTO_ESC`. Sign `tx_meta.escrow_unsigned_tx` and PATCH `WAITING_FOR_MIN_ESCROW_CONFIRMS` with it. To sign one: - ETH, ERC20, BNB, BEP20: a legacy (EIP-155) transaction with `chainId`, `to`, `value`, `gas` (the gas limit), `gasPrice`, `nonce` and `data`. `value` and `gasPrice` are decimal strings in wei. Send the raw signed transaction hex as `signed_txn`. - TRC20: sign `txID` (the SHA-256 of `raw_data`) with secp256k1. The signature is `r`, `s` and the recovery id (0 or 1) as 65 bytes of hex, without `0x`. Add it to the transaction's `signature` list, then send the whole transaction object as `trx_signed_txn` and the signature as `signed_txn`. ### Release, cancel and dispute signatures Releasing the escrow, cancelling it and disputing are signed messages, not transactions. LocalCoinSwap submits them to the contract. Every message starts from `tx_meta.trade_hash`, which is set once the escrow is prepared. | Action | Who | Message | Sent as | | --- | --- | --- | --- | | Release to the buyer | Seller | relay, instruction `0x01` | `signed_relay_signature` with status `FUND_RECEIVED` | | Cancel after escrow | Buyer | relay, instruction `0x02` | `cancellation_signature` with status `CANCELLED` | | Dispute | Either | dispute | `extra_data` on `openDispute` | The message hash is `keccak256` of the ABI-encoded values: - Relay (ETH, ERC20, BNB, BEP20): `abi.encode(uint256 2, uint256 chainId, address escrow, bytes32 tradeHash, uint8 instruction, uint128 maxGasPrice, uint256 deadline)`. - Relay (TRC20): the same without `maxGasPrice`: `abi.encode(uint256 2, uint256 chainId, address escrow, bytes32 tradeHash, uint8 instruction, uint256 deadline)`. - Dispute (all of them): `abi.encode(uint256 3, uint256 chainId, address escrow, bytes32 tradeHash, uint256 deadline)`. For `deadline`, use `2^256 - 1` (no expiry). A dispute can use an earlier deadline in unix seconds, but then add it to `extra_data` as `dispute_deadline`. Relays always use `2^256 - 1`. Sign the hash as an Ethereum personal message (EIP-191, `"\x19Ethereum Signed Message:\n32"` + hash). This is what `eth_account`'s `encode_defunct(primitive=hash)` and ethers' `signMessage(arrayify(hash))` do. TRC20 uses the same signature scheme. Send `{"r": "0x…", "s": "0x…", "v": 27}` (`v` is 27 or 28). `signed_relay_signature` and `cancellation_signature` take it as an object, and the dispute's `extra_data` takes it as a JSON string. | Coin | `chainId` | `escrow` | `maxGasPrice` (wei) | | --- | --- | --- | --- | | ETH | 1 | `0x3a362a1966FF5aAB35298E1565bDa2c9FB124e41` | 500000000000 | | ERC20 tokens | 1 | `0xCcB2718d633Ed28bDF0639134380e2f5B05162b5` | 500000000000 | | BNB | 56 | `0xD92b329584eF5485cb5719870f13F05E2eFbf055` | 5100000000 | | BEP20 tokens | 56 | `0x769b7deE146565F8C98682f6bdD4dF6DABa2F27e` | 5100000000 | | TRC20 tokens | 728126428 | `TX2diN6aM1Ym5GRQWvZWrXrxNDWyFD4WuZ` | none | For TRC20, encode the escrow as its 20-byte address: the base58 address decoded, without the leading `0x41`. In Python, for an ETH release: ```python from eth_abi import encode from eth_account import Account from eth_account.messages import encode_defunct from eth_utils import keccak, to_checksum_address MAX = 2**256 - 1 message = keccak(encode( ["uint256", "uint256", "address", "bytes32", "uint8", "uint128", "uint256"], [2, 1, to_checksum_address("0x3a362a1966FF5aAB35298E1565bDa2c9FB124e41"), bytes.fromhex(trade["tx_meta"]["trade_hash"].removeprefix("0x")), 0x01, 500_000_000_000, MAX], )) signed = Account.sign_message(encode_defunct(primitive=message), private_key) signature = {"r": f"0x{signed.r:064x}", "s": f"0x{signed.s:064x}", "v": signed.v} ``` ## camelCase keys Requests and responses use snake_case keys. To send and receive camelCase instead, add this header (or `?key_case=camel` while debugging): ```HTTP X-Key-Case: camel ``` ## Coding agents To build against this API with a coding agent (Claude Code, Codex, Cursor and others), give it the reference, not your key: - [`/llms.txt`](https://localcoinswap.com/llms.txt) indexes the reference, and [`/llms-full.txt`](https://localcoinswap.com/llms-full.txt) is all of it as one Markdown file. [`/openapi.json`](https://localcoinswap.com/openapi.json) is the spec. - Create a key with the narrowest scope the job needs: `read` to watch offers and trades, `trade` to manage offers and run trades, `wallet` only if the agent's code must sign or broadcast transactions. - Set `LCS_API_KEY` in the environment the agent's code runs in. Don't paste the key into the chat, a prompt or a file the agent commits. Add this to your project's `AGENTS.md` (or `CLAUDE.md`): ```markdown ### LocalCoinSwap API - Reference: https://localcoinswap.com/llms-full.txt (OpenAPI spec: https://localcoinswap.com/openapi.json). - Base URL https://api.localcoinswap.com. Every request sends `Authorization: ApiKey $LCS_API_KEY`. - Read the key from the `LCS_API_KEY` environment variable. Never print, log or commit it, and never ask me to paste it. - A 403 with code `api_key_scope` means the key lacks a scope. Stop and tell me; don't look for another way round. - Trades are non-custodial: funding, release, cancel and dispute are signed with the trade address's private key ("Signing trades"). Ask me before anything signs a transaction or moves funds. - Back off on 429 for `Retry-After` seconds. API keys share 60 requests a minute per account. ``` # Endpoints ## Market data ### Currency details `GET /api/v2/currencies/{symbol}/`. Scope: `read`. Returns full detail of a currency by slug, for example `BTC` or `USDT-TRC20`. A symbol such as `ETH` or `USD` also works when only one currency has it. Symbols shared across chains, such as `USDT`, return 400 with the matching slugs. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `symbol` | path | string | yes | | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/currencies/LCS/' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "id": 3, "title": "LCS Cryptoshares", "symbol": "LCS", "symbol_filename": "lcs.svg", "is_crypto": true, "metadata": { "banner_image": "/media/currency/start_trading_lcs.png", "about": "Cryptoshares (LCS) are the native currency of the LocalCoinSwap platform", "official_website": "https://localcoinswap.com/", "initial_release": 1523750400, "min_unit_name": "None", "total_supply": 72732420, "circulating_supply": 40211430, "cmc_analytics": { "id": 3, "symbol": "LCS", "usd_price": "0.0093986938", "usd_market_cap": "492841.1945892310", "usd_volume_24h": "8037.5140275405", "percent_change_1h": "0.9349020000", "percent_change_24h": "2.4310200000", "percent_change_7d": "26.4646000000", "usd_last_updated": 1597384689, "last_updated": 1597384789 } }, "slug": "lcs-cryptoshares-LCS" } ``` ### Active cryptos on exchange `GET /api/v2/currencies/active-cryptos/`. Scope: `read`. Get a list of all the cryptos currently active on the exchange and their associated information. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `limit` | query | integer | | Number of results to return per page. | | `offset` | query | integer | | The initial index from which to return the results. | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/currencies/active-cryptos/' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "count": 123, "next": "http://api.example.org/accounts/?offset=400&limit=100", "previous": "http://api.example.org/accounts/?offset=200&limit=100", "results": [ { "id": 1, "title": "Bitcoin", "symbol": "BTC", "symbol_filename": "btc.svg", "is_crypto": true, "slug": "bitcoin-BTC", "active_status": "currency_active" } ] } ``` ### Local currencies `GET /api/v2/currencies/fiat-currencies/`. Scope: `read`. List of local (fiat) currencies supported on the platform. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `limit` | query | integer | | Number of results to return per page. | | `offset` | query | integer | | The initial index from which to return the results. | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/currencies/fiat-currencies/' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "count": 123, "next": "http://api.example.org/accounts/?offset=400&limit=100", "previous": "http://api.example.org/accounts/?offset=200&limit=100", "results": [ { "title": "Afghan Afghani", "symbol": "AFN", "symbol_filename": "None", "is_crypto": false } ] } ``` ### Payment methods `GET /api/v2/offers/payment-methods/`. Scope: `read`. List of payment methods supported for offer listing. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `limit` | query | integer | | Number of results to return per page. | | `offset` | query | integer | | The initial index from which to return the results. | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/offers/payment-methods/' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "active_page": 1, "count": 18, "next": null, "previous": null, "offset": 0, "limit": 5, "total_pages": 4, "results": [ { "name": "Abra", "slug": "abra" } ] } ``` ### Search all offers `GET /api/v2/offers/search/`. Scope: `read`. Search through publicly listed trade offers. Supports sorting and filtering based on with multiple parameter combinations. On Popularity sorts (``ordering`` includes ``reputation``) for lightly filtered searches, results are reordered so each page shows at most ``POPULARITY_MAX_OFFERS_PER_USER_PER_PAGE`` offers from the same user. Price sorts and heavily filtered searches (coin + payment method) are unchanged. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `coin_currency` | query | array of string | | | | `country_code` | query | string | | To prioritize given country in the list. If no offers found in the given country then other relevant offers may still show up. | | `country_code_exact` | query | string | | To filter by given country, returns empty if no offers in given country. | | `created_by` | query | string | | | | `fiat_currency` | query | array of string | | | | `hide_new` | query | string | | Whether to hide offers from new users or not. | | `last_seen` | query | string | | Filter by last seen time of the trader. Supported input: `"30mins"`, `"24hours"`, `"1week"`, `"2weeks"`, `"1month"` | | `limit` | query | integer | | Number of results to return per page. | | `offset` | query | integer | | The initial index from which to return the results. | | `ordering` | query | array of `-coin_currency__priority` | `-coin_currency__symbol` | `-country_first` | `-created_by__completed_trades` | `-current_price_usd` | `-fiat_currency__priority` | `-fiat_currency__symbol` | `-local_currency_first` | `-payment_method__name` | `-payment_method__priority` | `-reputation` | `coin_currency__priority` | `coin_currency__symbol` | `country_first` | `created_by__completed_trades` | `current_price_usd` | `fiat_currency__priority` | `fiat_currency__symbol` | `local_currency_first` | `payment_method__name` | `payment_method__priority` | `reputation` | | Ordering * `coin_currency__priority` - Coin currency priority * `-coin_currency__priority` - Coin currency priority (descending) * `fiat_currency__priority` - Fiat currency priority * `-fiat_currency__priority` - Fiat currency priority (descending) * `coin_currency__symbol` - Coin currency symbol * `-coin_currency__symbol` - Coin currency symbol (descending) * `fiat_currency__symbol` - Fiat currency symbol * `-fiat_currency__symbol` - Fiat currency symbol (descending) * `payment_method__name` - Payment method name * `-payment_method__name` - Payment method name (descending) * `payment_method__priority` - Payment method priority * `-payment_method__priority` - Payment method priority (descending) * `current_price_usd` - Current price usd * `-current_price_usd` - Current price usd (descending) * `country_first` - Country first * `-country_first` - Country first (descending) * `local_currency_first` - Local currency first * `-local_currency_first` - Local currency first (descending) * `reputation` - Reputation * `-reputation` - Reputation (descending) * `created_by__completed_trades` - Created by completed trades * `-created_by__completed_trades` - Created by completed trades (descending) | | `payment_method` | query | array of string | | | | `trading_type` | query | array of string | | | | `username` | query | string | | Search by username of traders. | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/offers/search/?coin_currency=BTC&trading_type=sell&fiat_currency=USD' ``` Response 200: ```json { "active_page": 1, "count": 18, "next": null, "previous": null, "offset": 0, "limit": 5, "total_pages": 4, "results": [ { "uuid": "cd6e7394-9b75-4f5e-9652-542befe5c55d", "created_by": { "username": "satoshi_au", "activity_status": "active", "activity_tooltip": "online", "last_seen": 1793817600, "is_legacy": false, "user_uuid": "e98f2078-a4e7-4f59-908f-b5513be95bd6", "hide_from_google": false, "imported_total_trades": null, "imported_volume": null, "completed_trades": 182, "platform_volume": 96000, "feedback_score": "99.20000", "avg_response_time": 4, "is_kyc_verified": true, "xp_level": "EXPERT" }, "trading_type": { "slug": "sell", "name": "sell", "opposite_name": "buy" }, "coin_currency": { "title": "Bitcoin", "symbol": "BTC", "token_standard": null, "symbol_filename": "btc.svg", "is_crypto": true, "slug": "BTC" }, "fiat_currency": { "title": "United States Dollar", "symbol": "USD", "token_standard": null, "symbol_filename": null, "is_crypto": false, "slug": "united-states-dollar" }, "payment_method": { "name": "Bank Transfer", "slug": "bank-transfers" }, "location_name": "Adelaide", "country_code": "AU", "min_trade_size": "50.0000000000", "max_trade_size": "3000.0000000000", "headline": "Fast BTC by bank transfer", "sms_required": false, "minimum_feedback": "0", "price_formula_value": "104328.51", "current_margin_percentage": "2.5000000000", "slug": "buy-btc-for-usd-in-australia", "automatic_cancel_time": "240", "enforced_sizes": "", "reputation": 1035, "is_featured": false } ] } ``` ### Trade types `GET /api/v2/offers/trade-types/`. Scope: `read`. The `trading_type` values an offer can have: `buy` or `sell`. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `limit` | query | integer | | Number of results to return per page. | | `offset` | query | integer | | The initial index from which to return the results. | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/offers/trade-types/' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "active_page": 1, "count": 18, "next": null, "previous": null, "offset": 0, "limit": 5, "total_pages": 4, "results": [ { "slug": "buy", "name": "buy", "opposite_name": "sell" } ] } ``` ## Offers Offers are listed on LocalCoinSwap listings for other traders to respond to. #### Following operations are possible using Offers: - Create - Edit - Delete - Read - Search ### List your offers `GET /api/v2/offers/`. Scope: `read`. Your offers, active and paused, with view and trade stats. In this list `trading_type`, `coin_currency`, `fiat_currency` and `payment_method` are internal IDs; fetch one offer for the full objects. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `limit` | query | integer | | Number of results to return per page. | | `offset` | query | integer | | The initial index from which to return the results. | | `trading_type` | query | `buy` | `sell` | | Only `buy` or only `sell` offers. | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/offers/?trading_type=sell' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "active_page": 1, "count": 18, "next": null, "previous": null, "offset": 0, "limit": 5, "total_pages": 4, "results": [ { "uuid": "cd6e7394-9b75-4f5e-9652-542befe5c55d", "is_active": true, "created_by": 8324323, "trading_type": 2, "coin_currency": 1, "fiat_currency": 10001, "payment_method": 32, "custodial_type": 1, "location_name": "Adelaide", "country_code": "AU", "min_trade_size": "50.0000000000", "max_trade_size": "3000.0000000000", "headline": "", "hidden": false, "sms_required": false, "minimum_feedback": "0", "price_formula_value": "104328.51", "current_margin_percentage": "2.5000000000", "slug": "buy-btc-for-usd-in-australia", "stats": { "lifetime": { "views": 412, "trades_started": 9, "trades_completed": 7, "trades_cancelled": 2, "completion_rate": 0.78, "volume_usd": "6120.00", "last_viewed_at": "2026-11-03T18:22:10Z", "last_trade_at": "2026-11-02T09:41:55Z" }, "last_30d": { "views": 120, "trades_started": 3, "trades_completed": 3, "trades_cancelled": 0, "completion_rate": 1.0, "volume_usd": "2150.00" }, "views_measured_since": "2026-10-24", "window_days": 30 } } ] } ``` ### Create offer `POST /api/v2/offers/`. Scope: `trade`. Create a trade offer for others to respond to. This can be done only by authenticated users. Request body: | Field | Type | Required | Description | | --- | --- | --- | --- | | `trading_type` | string | yes | Trade type. It can either be `buy` or `sell`. | | `coin_currency` | string | yes | Crypto currency slug. Examples: `BTC`, `ETH`, `USDT-ERC20`. Full list of available cryptocurrencies can be found at `/currencies/active-cryptos/` | | `fiat_currency` | string | yes | Fiat currency symbol. Examples: `USD`, `GBP`, `AUD`. Full list of available fiat-currencies can be found at `/currencies/fiat-currencies/` | | `payment_method` | string | yes | Payment method slug. Examples: `paypal`, `cash-deposit`. Full list of available payment-methods can be found at `/offers/payment-methods/` | | `country_code` | object | yes | Country code in alpha-2 format (two characters only). See the list of available choices above. * `EU` - EU * `AW` - AW * `AF` - AF * `AO` - AO * `AI` - AI * `AX` - AX * `AL` - AL * `AD` - AD * `AE` - AE * `AR` - AR * `AM` - AM * `AS` - AS * `AQ` - AQ * `TF` - TF * `AG` - AG * `AU` - AU * `AT` - AT * `AZ` - AZ * `BI` - BI * `BE` - BE * `BJ` - BJ * `BQ` - BQ * `BF` - BF * `BD` - BD * `BG` - BG * `BH` - BH * `BS` - BS * `BA` - BA * `BL` - BL * `BY` - BY * `BZ` - BZ * `BM` - BM * `BO` - BO * `BR` - BR * `BB` - BB * `BN` - BN * `BT` - BT * `BV` - BV * `BW` - BW * `CF` - CF * `CA` - CA * `CC` - CC * `CH` - CH * `CL` - CL * `CN` - CN * `CI` - CI * `CM` - CM * `CD` - CD * `CG` - CG * `CK` - CK * `CO` - CO * `KM` - KM * `CV` - CV * `CR` - CR * `CU` - CU * `CW` - CW * `CX` - CX * `KY` - KY * `CY` - CY * `CZ` - CZ * `DE` - DE * `DJ` - DJ * `DM` - DM * `DK` - DK * `DO` - DO * `DZ` - DZ * `EC` - EC * `EG` - EG * `ER` - ER * `EH` - EH * `ES` - ES * `EE` - EE * `ET` - ET * `FI` - FI * `FJ` - FJ * `FK` - FK * `FR` - FR * `FO` - FO * `FM` - FM * `GA` - GA * `GB` - GB * `GE` - GE * `GG` - GG * `GH` - GH * `GI` - GI * `GN` - GN * `GP` - GP * `GM` - GM * `GW` - GW * `GQ` - GQ * `GR` - GR * `GD` - GD * `GL` - GL * `GT` - GT * `GF` - GF * `GU` - GU * `GY` - GY * `HK` - HK * `HM` - HM * `HN` - HN * `HR` - HR * `HT` - HT * `HU` - HU * `ID` - ID * `IM` - IM * `IN` - IN * `IO` - IO * `IE` - IE * `IR` - IR * `IQ` - IQ * `IS` - IS * `IL` - IL * `IT` - IT * `JM` - JM * `JE` - JE * `JO` - JO * `JP` - JP * `KZ` - KZ * `KE` - KE * `KG` - KG * `KH` - KH * `KI` - KI * `KN` - KN * `KR` - KR * `KW` - KW * `LA` - LA * `LB` - LB * `LR` - LR * `LY` - LY * `LC` - LC * `LI` - LI * `LK` - LK * `LS` - LS * `LT` - LT * `LU` - LU * `LV` - LV * `MO` - MO * `MF` - MF * `MA` - MA * `MC` - MC * `MD` - MD * `MG` - MG * `MV` - MV * `MX` - MX * `MH` - MH * `MK` - MK * `ML` - ML * `MT` - MT * `MM` - MM * `ME` - ME * `MN` - MN * `MP` - MP * `MZ` - MZ * `MR` - MR * `MS` - MS * `MQ` - MQ * `MU` - MU * `MW` - MW * `MY` - MY * `YT` - YT * `NA` - NA * `NC` - NC * `NE` - NE * `NF` - NF * `NG` - NG * `NI` - NI * `NU` - NU * `NL` - NL * `NO` - NO * `NP` - NP * `NR` - NR * `NZ` - NZ * `OM` - OM * `PK` - PK * `PA` - PA * `PN` - PN * `PE` - PE * `PH` - PH * `PW` - PW * `PG` - PG * `PL` - PL * `PR` - PR * `KP` - KP * `PT` - PT * `PY` - PY * `PS` - PS * `PF` - PF * `QA` - QA * `RE` - RE * `RO` - RO * `RU` - RU * `RW` - RW * `SA` - SA * `SD` - SD * `SN` - SN * `SG` - SG * `GS` - GS * `SH` - SH * `SJ` - SJ * `SB` - SB * `SL` - SL * `SV` - SV * `SM` - SM * `SO` - SO * `PM` - PM * `RS` - RS * `SS` - SS * `ST` - ST * `SR` - SR * `SK` - SK * `SI` - SI * `SE` - SE * `SZ` - SZ * `SX` - SX * `SC` - SC * `SY` - SY * `TC` - TC * `TD` - TD * `TG` - TG * `TH` - TH * `TJ` - TJ * `TK` - TK * `TM` - TM * `TL` - TL * `TO` - TO * `TT` - TT * `TN` - TN * `TR` - TR * `TV` - TV * `TW` - TW * `TZ` - TZ * `UG` - UG * `UA` - UA * `UM` - UM * `UY` - UY * `US` - US * `UZ` - UZ * `VA` - VA * `VC` - VC * `VE` - VE * `VG` - VG * `VI` - VI * `VN` - VN * `VU` - VU * `WF` - WF * `WS` - WS * `YE` - YE * `ZA` - ZA * `ZM` - ZM * `ZW` - ZW | | `location_name` | string | | City or place name, consider using a discoverable location name. Eg: `Mountain View, California` or `Sydney`. Please make sure this name is within the `country_code` chosen above. Behind the scenes we perform a reverse lookup under that country code to find geo-coordinates which further help in search APIs. | | `min_trade_size` | integer | | Expressed in terms of the fiat currency. Should be >= 1. | | `max_trade_size` | integer | yes | Expressed in terms of the fiat currency. Should be >= `min_trade_size`. | | `pricing_type` | object | | | | `pricing_market` | object | | | | `pricing_expression` | string | | | | `trading_conditions` | string | | The conditions under which you trade with others. | | `trading_condition_keys` | object | | Structured trading conditions as a list of selected option keys. | | `headline` | string | null | | Headline for the offer, highlighted on the listings page. | | `trading_hours_type` | object | | Choose whether you want to specify common availability hours for every day or specify individual hours for each day * `daily` - daily * `specific` - specific | | `trading_hours_json` | object | yes | If `trading_hours_type` is `daily` then the format should be: ``` { "anyday": { "from": "08:30", "to": "21:00" } }``` Else the format should be: ``` { "monday": { "from": "06:30", "to": "21:00" }, "tuesday": { "from": "06:30", "to": "21:00" }, "wednesday": { "from": "06:30", "to": "21:00" }, "thursday": { "from": "09:30", "to": "21:00" }, "friday": { "from": "00:30", "to": "21:00" }, "saturday": { "from": "18:30", "to": "19:00" }, "sunday": { "from": "08:30", "to": "21:00" } }``` | | `hidden` | boolean | | If true, offer is hidden and only accessible directly through the URL | | `enforced_sizes` | string | null | | These are the accepted sizes, comma separated. Eg: if you are exchanging for gift cards of values $50 and $100, enter `50,100` | | `msg_on_trade_accepted` | string | | | | `msg_on_trade_escrowed` | string | | | | `msg_on_trade_released` | string | | | | `blocked_countries` | string | null | | Comma separated list of iso2 country codes like NG,KE | | `automatic_cancel_time` | integer | | Time (in minutes) until the trade will automatically cancel/expire if you don't respond | | `sms_required` | boolean | | Require potential traders to have verified their phone number. | | `minimum_feedback` | integer | | Minimum feedback percentage required for traders to initiate a trade on this offer. | ```bash curl --request POST 'https://api.localcoinswap.com/api/v2/offers/' \ --header "Authorization: ApiKey $LCS_API_KEY" \ --header 'Content-Type: application/json' \ --data-raw '{"trading_type": "sell", "coin_currency": "BTC", "fiat_currency": "USD", "payment_method": "bank-transfers", "country_code": "AU", "location_name": "Adelaide", "min_trade_size": 50, "max_trade_size": 2000, "pricing_type": "MARGIN", "pricing_market": "cmc", "pricing_expression": "2", "trading_hours_type": "daily", "trading_hours_json": {"anyday": {"from": "08:30", "to": "21:00"}}}' ``` Response 201: ```json { "trading_type": { "slug": "sell", "name": "sell", "opposite_name": "buy" }, "coin_currency": { "title": "Bitcoin", "symbol": "BTC", "token_standard": null, "symbol_filename": "btc.svg", "is_crypto": true, "slug": "BTC" }, "fiat_currency": { "title": "United States Dollar", "symbol": "USD", "token_standard": null, "symbol_filename": null, "is_crypto": false, "slug": "united-states-dollar" }, "payment_method": { "name": "Bank Transfer", "slug": "bank-transfers" }, "uuid": "cd6e7394-9b75-4f5e-9652-542befe5c55d", "slug": "buy-btc-for-usd-in-australia", "country_code": "AU", "location_name": "Adelaide", "min_trade_size": 50, "max_trade_size": 2000, "trading_conditions": "", "trading_condition_keys": [], "headline": "", "hidden": false, "enforced_sizes": "", "blocked_countries": "", "automatic_cancel_time": 240, "sms_required": false, "minimum_feedback": 0 } ``` ### Get an offer `GET /api/v2/offers/{uuid}/`. Scope: `read`. Anyone can read an offer, including hidden and paused ones, given its UUID. The `msg_on_trade_*` automatic messages are only returned to the offer's creator; everyone else gets `null`. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `uuid` | path | string | yes | | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/offers/cd6e7394-9b75-4f5e-9652-542befe5c55d/' ``` Response 200: ```json { "uuid": "cd6e7394-9b75-4f5e-9652-542befe5c55d", "slug": "buy-btc-for-usd-in-australia", "is_active": true, "created_by": { "username": "satoshi_au", "activity_status": "active", "activity_tooltip": "online", "is_email_verified": true, "is_phone_verified": true, "phone_country_code": "AU", "avg_response_time": 4, "completed_trades": 182, "platform_volume": 96000, "feedback_score": "99.20000", "last_seen": 1793817600, "is_legacy": false, "bio": "", "user_uuid": "e98f2078-a4e7-4f59-908f-b5513be95bd6", "on_holiday": false, "hide_from_google": false, "date_joined": "2021-06-21T05:24:49.500000Z", "profile_image": "https://pwa-cdn.localcoinswap.com/default_user.jpg", "is_kyc_verified": true, "xp_level": "EXPERT" }, "trading_type": { "id": 2, "slug": "sell", "name": "sell", "action_name": "Selling", "opposite_name": "buy", "opposite_action_name": "Buying" }, "coin_currency": { "title": "Bitcoin", "symbol": "BTC", "token_standard": null, "symbol_filename": "btc.svg", "is_crypto": true, "slug": "BTC" }, "fiat_currency": { "title": "United States Dollar", "symbol": "USD", "token_standard": null, "symbol_filename": null, "is_crypto": false, "slug": "united-states-dollar" }, "payment_method": { "name": "Bank Transfer", "slug": "bank-transfers" }, "location_name": "Adelaide", "country_code": "AU", "custodial_type": 1, "min_trade_size": "50.0000000000", "max_trade_size": "3000.0000000000", "trading_conditions": "Bank transfers from accounts in your own name only.", "trading_condition_keys": [], "headline": "Fast BTC by bank transfer", "hidden": false, "enforced_sizes": "", "blocked_countries": "", "automatic_cancel_time": "240", "sms_required": false, "minimum_feedback": "0", "price_formula": { "display_formula": "2.5", "prefix_formula": "exchange.btcusd|v||exchange.usdusd|v||*|o||1.025|n||*|o", "pricing_type": "MARGIN", "market": "cmc" }, "price_formula_value": "104328.51", "trading_hours_localised": "Mon - Sun: 8:30 am - 9:00 pm
\n", "trading_hours_type": "daily", "trading_hours_json": { "anyday": { "from": "8:30", "to": "21:0" } }, "current_margin_percentage": "2.5000000000", "msg_on_trade_accepted": null, "msg_on_trade_escrowed": null, "msg_on_trade_released": null } ``` ### Update your offer `PATCH /api/v2/offers/{uuid}/`. Scope: `trade`. Send only the fields you want to change. The coin, fiat currency, payment method and trade type can't be changed; create a new offer instead. `pricing_type` and `pricing_expression` must be sent together, as must `trading_hours_type` and `trading_hours_json`. Send `is_active` to pause or resume the offer. Returns 404 for offers you didn't create. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `uuid` | path | string | yes | | Request body: | Field | Type | Required | Description | | --- | --- | --- | --- | | `country_code` | object | | Country code in alpha-2 format (two characters only). See the list of available choices above. * `EU` - EU * `AW` - AW * `AF` - AF * `AO` - AO * `AI` - AI * `AX` - AX * `AL` - AL * `AD` - AD * `AE` - AE * `AR` - AR * `AM` - AM * `AS` - AS * `AQ` - AQ * `TF` - TF * `AG` - AG * `AU` - AU * `AT` - AT * `AZ` - AZ * `BI` - BI * `BE` - BE * `BJ` - BJ * `BQ` - BQ * `BF` - BF * `BD` - BD * `BG` - BG * `BH` - BH * `BS` - BS * `BA` - BA * `BL` - BL * `BY` - BY * `BZ` - BZ * `BM` - BM * `BO` - BO * `BR` - BR * `BB` - BB * `BN` - BN * `BT` - BT * `BV` - BV * `BW` - BW * `CF` - CF * `CA` - CA * `CC` - CC * `CH` - CH * `CL` - CL * `CN` - CN * `CI` - CI * `CM` - CM * `CD` - CD * `CG` - CG * `CK` - CK * `CO` - CO * `KM` - KM * `CV` - CV * `CR` - CR * `CU` - CU * `CW` - CW * `CX` - CX * `KY` - KY * `CY` - CY * `CZ` - CZ * `DE` - DE * `DJ` - DJ * `DM` - DM * `DK` - DK * `DO` - DO * `DZ` - DZ * `EC` - EC * `EG` - EG * `ER` - ER * `EH` - EH * `ES` - ES * `EE` - EE * `ET` - ET * `FI` - FI * `FJ` - FJ * `FK` - FK * `FR` - FR * `FO` - FO * `FM` - FM * `GA` - GA * `GB` - GB * `GE` - GE * `GG` - GG * `GH` - GH * `GI` - GI * `GN` - GN * `GP` - GP * `GM` - GM * `GW` - GW * `GQ` - GQ * `GR` - GR * `GD` - GD * `GL` - GL * `GT` - GT * `GF` - GF * `GU` - GU * `GY` - GY * `HK` - HK * `HM` - HM * `HN` - HN * `HR` - HR * `HT` - HT * `HU` - HU * `ID` - ID * `IM` - IM * `IN` - IN * `IO` - IO * `IE` - IE * `IR` - IR * `IQ` - IQ * `IS` - IS * `IL` - IL * `IT` - IT * `JM` - JM * `JE` - JE * `JO` - JO * `JP` - JP * `KZ` - KZ * `KE` - KE * `KG` - KG * `KH` - KH * `KI` - KI * `KN` - KN * `KR` - KR * `KW` - KW * `LA` - LA * `LB` - LB * `LR` - LR * `LY` - LY * `LC` - LC * `LI` - LI * `LK` - LK * `LS` - LS * `LT` - LT * `LU` - LU * `LV` - LV * `MO` - MO * `MF` - MF * `MA` - MA * `MC` - MC * `MD` - MD * `MG` - MG * `MV` - MV * `MX` - MX * `MH` - MH * `MK` - MK * `ML` - ML * `MT` - MT * `MM` - MM * `ME` - ME * `MN` - MN * `MP` - MP * `MZ` - MZ * `MR` - MR * `MS` - MS * `MQ` - MQ * `MU` - MU * `MW` - MW * `MY` - MY * `YT` - YT * `NA` - NA * `NC` - NC * `NE` - NE * `NF` - NF * `NG` - NG * `NI` - NI * `NU` - NU * `NL` - NL * `NO` - NO * `NP` - NP * `NR` - NR * `NZ` - NZ * `OM` - OM * `PK` - PK * `PA` - PA * `PN` - PN * `PE` - PE * `PH` - PH * `PW` - PW * `PG` - PG * `PL` - PL * `PR` - PR * `KP` - KP * `PT` - PT * `PY` - PY * `PS` - PS * `PF` - PF * `QA` - QA * `RE` - RE * `RO` - RO * `RU` - RU * `RW` - RW * `SA` - SA * `SD` - SD * `SN` - SN * `SG` - SG * `GS` - GS * `SH` - SH * `SJ` - SJ * `SB` - SB * `SL` - SL * `SV` - SV * `SM` - SM * `SO` - SO * `PM` - PM * `RS` - RS * `SS` - SS * `ST` - ST * `SR` - SR * `SK` - SK * `SI` - SI * `SE` - SE * `SZ` - SZ * `SX` - SX * `SC` - SC * `SY` - SY * `TC` - TC * `TD` - TD * `TG` - TG * `TH` - TH * `TJ` - TJ * `TK` - TK * `TM` - TM * `TL` - TL * `TO` - TO * `TT` - TT * `TN` - TN * `TR` - TR * `TV` - TV * `TW` - TW * `TZ` - TZ * `UG` - UG * `UA` - UA * `UM` - UM * `UY` - UY * `US` - US * `UZ` - UZ * `VA` - VA * `VC` - VC * `VE` - VE * `VG` - VG * `VI` - VI * `VN` - VN * `VU` - VU * `WF` - WF * `WS` - WS * `YE` - YE * `ZA` - ZA * `ZM` - ZM * `ZW` - ZW | | `location_name` | string | | City or place name, consider using a discoverable location name. Eg: `Mountain View, California` or `Sydney`. Please make sure this name is within the `country_code` chosen above. Behind the scenes we perform a reverse lookup under that country code to find geo-coordinates which further help in search APIs. | | `min_trade_size` | integer | | Expressed in terms of the fiat currency. Should be >= 1. | | `max_trade_size` | integer | | Expressed in terms of the fiat currency. Should be >= `min_trade_size`. | | `pricing_type` | object | | | | `pricing_market` | object | | | | `pricing_expression` | string | | | | `trading_conditions` | string | | The conditions under which you trade with others. | | `trading_condition_keys` | object | | Structured trading conditions as a list of selected option keys. | | `headline` | string | null | | Headline for the offer, highlighted on the listings page. | | `trading_hours_type` | object | | Choose whether you want to specify common availability hours for every day or specify individual hours for each day * `daily` - daily * `specific` - specific | | `trading_hours_json` | object | | If `trading_hours_type` is `daily` then the format should be: ``` { "anyday": { "from": "08:30", "to": "21:00" } }``` Else the format should be: ``` { "monday": { "from": "06:30", "to": "21:00" }, "tuesday": { "from": "06:30", "to": "21:00" }, "wednesday": { "from": "06:30", "to": "21:00" }, "thursday": { "from": "09:30", "to": "21:00" }, "friday": { "from": "00:30", "to": "21:00" }, "saturday": { "from": "18:30", "to": "19:00" }, "sunday": { "from": "08:30", "to": "21:00" } }``` | | `hidden` | boolean | | If true, offer is hidden and only accessible directly through the URL | | `enforced_sizes` | string | null | | These are the accepted sizes, comma separated. Eg: if you are exchanging for gift cards of values $50 and $100, enter `50,100` | | `msg_on_trade_accepted` | string | | | | `msg_on_trade_escrowed` | string | | | | `msg_on_trade_released` | string | | | | `blocked_countries` | string | null | | Comma separated list of iso2 country codes like NG,KE | | `automatic_cancel_time` | integer | | Time (in minutes) until the trade will automatically cancel/expire if you don't respond | | `sms_required` | boolean | | Require potential traders to have verified their phone number. | | `minimum_feedback` | integer | | Minimum feedback percentage required for traders to initiate a trade on this offer. | | `is_active` | boolean | | | ```bash curl --request PATCH 'https://api.localcoinswap.com/api/v2/offers/cd6e7394-9b75-4f5e-9652-542befe5c55d/' \ --header "Authorization: ApiKey $LCS_API_KEY" \ --header 'Content-Type: application/json' \ --data-raw '{"max_trade_size": 3000, "pricing_type": "MARGIN", "pricing_expression": "2.5"}' ``` Response 200: ```json { "uuid": "cd6e7394-9b75-4f5e-9652-542befe5c55d", "is_active": true, "created_by": 8324323, "trading_type": 2, "coin_currency": 1, "fiat_currency": 10001, "payment_method": 32, "custodial_type": 1, "location_name": "Adelaide", "country_code": "AU", "min_trade_size": "50.0000000000", "max_trade_size": "3000.0000000000", "headline": "", "hidden": false, "sms_required": false, "minimum_feedback": "0", "price_formula_value": "104328.51", "current_margin_percentage": "2.5000000000", "slug": "buy-btc-for-usd-in-australia", "stats": { "lifetime": { "views": 412, "trades_started": 9, "trades_completed": 7, "trades_cancelled": 2, "completion_rate": 0.78, "volume_usd": "6120.00", "last_viewed_at": "2026-11-03T18:22:10Z", "last_trade_at": "2026-11-02T09:41:55Z" }, "last_30d": { "views": 120, "trades_started": 3, "trades_completed": 3, "trades_cancelled": 0, "completion_rate": 1.0, "volume_usd": "2150.00" }, "views_measured_since": "2026-10-24", "window_days": 30 } } ``` ### Delete your offer `DELETE /api/v2/offers/{uuid}/`. Scope: `trade`. Deleted offers disappear from search and can't be restored. Trades already open on the offer carry on. Returns 404 for offers you didn't create. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `uuid` | path | string | yes | | ```bash curl --request DELETE 'https://api.localcoinswap.com/api/v2/offers/cd6e7394-9b75-4f5e-9652-542befe5c55d/' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` ### Create several offers `POST /api/v2/offers/bulk/`. Scope: `trade`. Create up to 100 offers in one request. Fields shared by every offer go at the top level, as for a single create; `combos` lists the offers, each with its own coin, fiat currency, payment method, location, price or sizes. Each offer is validated and created on its own, so some can fail while the rest succeed: check `failed`. The request fails as a whole only if `combos` is empty, too long, or would take you over your offer limit. Request body: | Field | Type | Required | Description | | --- | --- | --- | --- | | `trading_type` | string | yes | Trade type. It can either be `buy` or `sell`. | | `coin_currency` | string | | Default coin slug for combos that omit it. | | `fiat_currency` | string | | Default fiat symbol for combos that omit it. | | `payment_method` | string | | Default payment method slug for combos that omit it. | | `country_code` | string | | | | `location_name` | string | | | | `min_trade_size` | integer | | | | `max_trade_size` | integer | | | | `pricing_type` | object | | | | `pricing_market` | object | | | | `pricing_expression` | string | | | | `trading_conditions` | string | | The conditions under which you trade with others. | | `trading_condition_keys` | object | | Structured trading conditions as a list of selected option keys. | | `headline` | string | null | | Headline for the offer, highlighted on the listings page. | | `trading_hours_type` | object | | Choose whether you want to specify common availability hours for every day or specify individual hours for each day * `daily` - daily * `specific` - specific | | `trading_hours_json` | object | yes | If `trading_hours_type` is `daily` then the format should be: ``` { "anyday": { "from": "08:30", "to": "21:00" } }``` Else the format should be: ``` { "monday": { "from": "06:30", "to": "21:00" }, "tuesday": { "from": "06:30", "to": "21:00" }, "wednesday": { "from": "06:30", "to": "21:00" }, "thursday": { "from": "09:30", "to": "21:00" }, "friday": { "from": "00:30", "to": "21:00" }, "saturday": { "from": "18:30", "to": "19:00" }, "sunday": { "from": "08:30", "to": "21:00" } }``` | | `hidden` | boolean | | If true, offer is hidden and only accessible directly through the URL | | `enforced_sizes` | string | null | | These are the accepted sizes, comma separated. Eg: if you are exchanging for gift cards of values $50 and $100, enter `50,100` | | `msg_on_trade_accepted` | string | | | | `msg_on_trade_escrowed` | string | | | | `msg_on_trade_released` | string | | | | `blocked_countries` | string | null | | Comma separated list of iso2 country codes like NG,KE | | `automatic_cancel_time` | integer | | Time (in minutes) until the trade will automatically cancel/expire if you don't respond | | `sms_required` | boolean | | Require potential traders to have verified their phone number. | | `minimum_feedback` | integer | | Minimum feedback percentage required for traders to initiate a trade on this offer. | | `combos` | array of object | yes | One entry per offer to create. A combo's values override the top-level ones. | ```bash curl --request POST 'https://api.localcoinswap.com/api/v2/offers/bulk/' \ --header "Authorization: ApiKey $LCS_API_KEY" \ --header 'Content-Type: application/json' \ --data-raw '{"trading_type": "sell", "fiat_currency": "USD", "payment_method": "bank-transfers", "country_code": "AU", "location_name": "Adelaide", "min_trade_size": 50, "max_trade_size": 2000, "pricing_type": "MARGIN", "pricing_market": "cmc", "pricing_expression": "2", "trading_hours_type": "daily", "trading_hours_json": {"anyday": {"from": "08:30", "to": "21:00"}}, "combos": [{"coin_currency": "BTC"}, {"coin_currency": "ETH", "pricing_expression": "2.5"}, {"coin_currency": "USDT-ERC20", "payment_method": "paypal"}]}' ``` Response 200: `application/json`. ### Calculate advanced price `POST /api/v2/offers/dryrun-expression/`. Scope: `read`. The formula expression is directly passed into this endpoint to compute the result. This can be done only by authenticated users. Request body: | Field | Type | Required | Description | | --- | --- | --- | --- | | `expression` | string | yes | An expression is a mathematical formula which uses variables supported by LocalCoinSwap. Eg: `market.binance.btcusdt.ask + (market.binance.btcusdt.ask * 0.1)` is a valid expression to get 10% higher value for the current ask for `BTC` on Binance market. | ```bash curl --request POST 'https://api.localcoinswap.com/api/v2/offers/dryrun-expression/' \ --header "Authorization: ApiKey $LCS_API_KEY" \ --header 'Content-Type: application/json' \ --data-raw '{"expression": "market.binance.btcusdt.ask + (market.binance.btcusdt.ask * 0.1)"}' ``` Response 200: ```json { "price": "12863.983" } ``` ### Get price for market `POST /api/v2/offers/dryrun-formula/`. Scope: `read`. We create a formula expression from the parameters passed and then compute the result. This can be done only by authenticated users. Request body: | Field | Type | Required | Description | | --- | --- | --- | --- | | `pricing_market` | object | | | | `coin_currency` | string | yes | Crypto currency slug. Examples: `BTC`, `ETH`, `USDT-ERC20`. Full list of available cryptocurrencies can be found at `/currencies/active-cryptos/` | | `fiat_currency` | string | yes | Fiat currency symbol. Examples: `USD`, `GBP`, `AUD`. Full list of available fiat-currencies can be found at `/currencies/fiat-currencies/` | | `margin_percent` | string | yes | | ```bash curl --request POST 'https://api.localcoinswap.com/api/v2/offers/dryrun-formula/' \ --header "Authorization: ApiKey $LCS_API_KEY" \ --header 'Content-Type: application/json' \ --data-raw '{"pricing_market": "cmc", "coin_currency": "ETH", "fiat_currency": "USD", "margin_percent": "10"}' ``` Response 200: ```json { "price": "3712.48" } ``` ## Trades ### Get a trade `GET /api/v2/trades/{uuid}/`. Scope: `read`. Full details of a trade you are the buyer or seller of; anyone else gets 403. `crypto_in_local_currency` is the trade's value in your account's local currency. `tx_meta`, `buyer_meta` and `seller_meta` carry the escrow data each side's wallet needs to fund, release or cancel. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `uuid` | path | string | yes | | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/trades/f3c6120b-d63a-4a1f-9d18-f181c4be29c2/' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "id": 22949, "ad": { "uuid": "6ab3a6f8-5a70-41d2-80c9-8f91b27f85bd", "slug": "buy-eth-for-aud-in-australia", "is_active": true, "created_by": { "username": "satoshi_au", "activity_status": "active", "activity_tooltip": "online", "is_email_verified": true, "is_phone_verified": true, "phone_country_code": "AU", "avg_response_time": 4, "completed_trades": 182, "platform_volume": 96000, "feedback_score": "99.20000", "last_seen": 1793817600, "is_legacy": false, "user_uuid": "e98f2078-a4e7-4f59-908f-b5513be95bd6", "hide_from_google": false, "date_joined": "2021-06-21T05:24:49.500000Z", "profile_image": "https://pwa-cdn.localcoinswap.com/default_user.jpg", "bio": "", "on_holiday": false, "is_kyc_verified": true, "xp_level": "EXPERT" }, "trading_type": { "id": 2, "slug": "sell", "name": "sell", "action_name": "Selling", "opposite_name": "buy", "opposite_action_name": "Buying" }, "coin_currency": { "title": "Ethereum", "symbol": "ETH", "token_standard": null, "symbol_filename": "eth.svg", "is_crypto": true, "slug": "ETH" }, "fiat_currency": { "title": "Australian Dollar", "symbol": "AUD", "token_standard": null, "symbol_filename": null, "is_crypto": false, "slug": "australian-dollar" }, "payment_method": { "name": "Bank Transfer", "slug": "bank-transfers" }, "location_name": "Adelaide", "country_code": "AU", "custodial_type": 1, "min_trade_size": "50.0000000000", "max_trade_size": "3000.0000000000", "trading_conditions": "Bank transfers from accounts in your own name only.", "trading_condition_keys": [], "headline": "Fast ETH by bank transfer", "hidden": false, "enforced_sizes": "", "blocked_countries": "", "automatic_cancel_time": "240", "sms_required": false, "minimum_feedback": "0", "price_formula": { "display_formula": "2.5", "prefix_formula": "exchange.ethaud|v||1.025|n||*|o", "pricing_type": "MARGIN", "market": "cmc" }, "price_formula_value": "3048.78", "current_margin_percentage": "2.5000000000" }, "status": "FUND_PAID", "status_meta": {}, "uuid": "f3c6120b-d63a-4a1f-9d18-f181c4be29c2", "contract_responder": { "username": "hal_f", "activity_status": "active", "activity_tooltip": "online", "is_email_verified": true, "is_phone_verified": true, "phone_country_code": "AU", "avg_response_time": 4, "completed_trades": 12, "platform_volume": 96000, "feedback_score": "99.20000", "last_seen": 1793817600, "is_legacy": false, "user_uuid": "11ae74df-3dcb-4752-9114-c8b7774faa49", "hide_from_google": false, "date_joined": "2021-06-21T05:24:49.500000Z", "profile_image": "https://pwa-cdn.localcoinswap.com/default_user.jpg" }, "buyer": { "username": "hal_f", "activity_status": "active", "activity_tooltip": "online", "is_email_verified": true, "is_phone_verified": true, "phone_country_code": "AU", "avg_response_time": 4, "completed_trades": 12, "platform_volume": 96000, "feedback_score": "99.20000", "last_seen": 1793817600, "is_legacy": false, "user_uuid": "11ae74df-3dcb-4752-9114-c8b7774faa49", "hide_from_google": false, "date_joined": "2021-06-21T05:24:49.500000Z", "profile_image": "https://pwa-cdn.localcoinswap.com/default_user.jpg" }, "seller": { "username": "satoshi_au", "activity_status": "active", "activity_tooltip": "online", "is_email_verified": true, "is_phone_verified": true, "phone_country_code": "AU", "avg_response_time": 4, "completed_trades": 182, "platform_volume": 96000, "feedback_score": "99.20000", "last_seen": 1793817600, "is_legacy": false, "user_uuid": "e98f2078-a4e7-4f59-908f-b5513be95bd6", "hide_from_google": false, "date_joined": "2021-06-21T05:24:49.500000Z", "profile_image": "https://pwa-cdn.localcoinswap.com/default_user.jpg" }, "disputed_by": null, "fiat_amount": "250.000000000000000000", "coin_amount": "0.082000000000000000", "time_of_expiry": 1793844845, "time_created": 1793830445, "coin_currency": { "title": "Ethereum", "symbol": "ETH", "token_standard": null, "symbol_filename": "eth.svg", "is_crypto": true, "slug": "ETH", "id": 2, "chain": null, "active_status": "currency_active" }, "fiat_currency": { "title": "Australian Dollar", "symbol": "AUD", "token_standard": null, "symbol_filename": null, "is_crypto": false, "slug": "australian-dollar", "id": 10002, "chain": null, "active_status": "currency_active" }, "crypto_in_usd": "164.120000000000000000", "responder_geo": {}, "tx_meta": { "escrow_version": "v2", "escrow_contract": "0x3a362a1966FF5aAB35298E1565bDa2c9FB124e41", "trade_hash": "0x5d0f2c7a1b9e48c3a6f1d2e0b7c4a9f8e3d2c1b0a9f8e7d6c5b4a39281706f5e", "escrow_unsigned_tx": { "to": "0x3a362a1966FF5aAB35298E1565bDa2c9FB124e41", "data": "0x6c1b3f2a...", "value": "82820000000000000", "nonce": 27, "gas": 180000, "gasPrice": "4400000000", "chainId": 1 }, "escrow_signed_tx": "0x02f9017201..." }, "buyer_meta": { "address": "0x7D1f14c29825b052004A5eF02d8F0BC7E2c9A2A0", "wallet_type": "webwallet", "address_pubkey": "04a3f1c2...", "public_key": "03b7e94d..." }, "seller_meta": { "address": "0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF", "wallet_type": "webwallet", "address_pubkey": "04c81e5b...", "public_key": "02f4a6d1..." }, "non_custodial": true, "amount_to_escrow": "0.082820000000000000", "fees": "0.000820000000000000", "btc_escrow_data": null, "eth_escrow_data": { "approve_tx": null, "escrow_tx": "0x9c1e4b7f0d2a6e83f5c1b2a49d7e0f36a8c5b1e2d4f6a7b8c9d0e1f2a3b4c5d6", "release_tx": null, "dispute_tx": null, "cancel_tx": null }, "multisig_escrow_data": null, "local_currency_symbol": "AUD", "crypto_in_local_currency": "250.12" } ``` ### Download a trade receipt `GET /api/v2/trades/{uuid}/invoice/`. Scope: `read`. Rate limit: 100 per day. The PDF receipt of a completed trade (including one completed by dispute resolution). Only the buyer, the seller or staff can download it; anyone else, and trades that aren't completed, get a 404. **Rate limit:** 100 per day Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `uuid` | path | string | yes | | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/trades/f3c6120b-d63a-4a1f-9d18-f181c4be29c2/invoice/' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: `application/pdf`. ### Get a trade's status `GET /api/v2/trades/{uuid}/status/`. Scope: `read`. Rate limit: 2 per minute. Just the `uuid` and `status`. API keys can't use the WebSocket feeds the website uses, so poll this to follow a trade, at most twice a minute per account. Buyer, seller or staff only; anyone else gets a 404. **Rate limit:** 2 per minute Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `uuid` | path | string | yes | | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/trades/f3c6120b-d63a-4a1f-9d18-f181c4be29c2/status/' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "uuid": "f3c6120b-d63a-4a1f-9d18-f181c4be29c2", "status": "FUND_PAID" } ``` ### Open a dispute `POST /api/v2/trades/dispute/{uuid}/`. Scope: `trade`. Moves the trade to `DISPUTED` and opens a ticket for staff, who decide who gets the escrow. Only the buyer or seller can dispute, and only once the escrow is funded. Withdraw it with `withdrawDispute`. What to send besides `description` depends on the coin, because staff settle on chain with your signatures: - ETH and ERC20 on the v2 escrow, BNB, BEP20, TRX, TRC20: `extra_data` with your dispute signature (**required**). - LTC: `release_signature` and `cancel_signature`. - BTC: nothing else; the escrow secrets are already held. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `uuid` | path | string | yes | | Request body: | Field | Type | Required | Description | | --- | --- | --- | --- | | `description` | string | yes | What went wrong. Staff read it when they review the dispute. | | `extra_data` | string | | Your dispute signature, as a JSON string: `{"r": "0x…", "s": "0x…", "v": 27}` (`r` and `s` are 32 bytes hex, `v` is 27 or 28). Staff settle the escrow on chain with it. **Required** for ETH and ERC20 trades on the v2 escrow (`tx_meta.escrow_version` is `"v2"`), BNB and BEP20 tokens, and TRX and TRC20 tokens; missing or malformed is a 400 on `extra_data`. Not used for BTC or LTC. Optionally add `dispute_deadline` (unix seconds) if you signed with one; without it the signature never expires. See "Signing trades". | | `release_signature` | string | | LTC only: your partial signature on the release to the buyer, so staff can pay out if the buyer wins. Send with `cancel_signature`. | | `cancel_signature` | string | | LTC only: your partial signature on the refund to the seller, so staff can pay out if the seller wins. | ```bash curl --request POST 'https://api.localcoinswap.com/api/v2/trades/dispute/f3c6120b-d63a-4a1f-9d18-f181c4be29c2/' \ --header "Authorization: ApiKey $LCS_API_KEY" \ --header 'Content-Type: application/json' \ --data-raw '{"description": "I paid by bank transfer 2 hours ago; seller is not replying.", "extra_data": "{\"r\": \"0x1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f\", \"s\": \"0x2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e\", \"v\": 27}"}' ``` Response 200: ```json { "message": "Ticket generated successfully" } ``` ### Download trade history `GET /api/v2/trades/history/`. Scope: `read`. A CSV of your completed trades, including those completed or cancelled by dispute resolution, newest first. Times are in your account's timezone. Optional `start_date` and `end_date` (YYYY-MM-DD) filter by time created, in your timezone. Send both or neither. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `end_date` | query | string | | YYYY-MM-DD, in your timezone. | | `start_date` | query | string | | YYYY-MM-DD, in your timezone. | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/trades/history/?start_date=2026-01-01&end_date=2026-03-31' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: `text/csv`. ### List your trades `GET /api/v2/trades/list/`. Scope: `read`. Trades where you are the buyer or the seller, newest first. Use `stage=live` for open trades and `stage=past` for finished ones. With `user`, at most 20 trades are returned per page. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `coin_currency` | query | array of string | | | | `fiat_currency` | query | array of string | | | | `limit` | query | integer | | Number of results to return per page. | | `offset` | query | integer | | The initial index from which to return the results. | | `ordering` | query | array of `-time_created` | `time_created` | | Ordering * `time_created` - Time created * `-time_created` - Time created (descending) | | `payment_method` | query | array of string | | | | `stage` | query | `live` | `past` | | Enum: `"live"`, `"past"`. Useful when you only want to view all live/ongoing trades for example. * `live` - live * `past` - past | | `status` | query | `ACCEPTED` | `BROADCASTING_ESCROW` | `BROADCASTING_ESCROW_FAILED` | `BROADCASTING_RELEASE` | `BROADCASTING_RELEASE_FAILED` | `CANCELLATION_REJECTED` | `CANCELLATION_REQUESTED` | `CANCELLED` | `CANCELLED_AFTER_ESCROW` | `COMPLETED` | `CREATED` | `CRYPTO_ESC` | `CRYPTO_ESC_FAILED` | `CRYPTO_REL` | `CRYPTO_REL_FAILED` | `DISPUTED` | `DISPUTE_RESOLVE_BUYER` | `DISPUTE_RESOLVE_SELLER` | `EXPIRED` | `FUND_PAID` | `FUND_RECEIVED` | `REJECTED` | `TRANSFER_APPROVED` | `WAITING_FOR_CRYPTO_RELEASE_CONFIRMS` | `WAITING_FOR_DISPUTE_CONFIRMS` | `WAITING_FOR_ESCROW` | `WAITING_FOR_MIN_APPROVE_CONFIRMS` | `WAITING_FOR_MIN_ESCROW_CONFIRMS` | `WAITING_FOR_TRANSFER_APPROVE` | | * `CREATED` - Created * `ACCEPTED` - Accepted * `REJECTED` - Rejected * `WAITING_FOR_ESCROW` - Waiting for escrow * `BROADCASTING_ESCROW` - Broadcasting escrow * `BROADCASTING_ESCROW_FAILED` - Broadcasting escrow failed * `WAITING_FOR_MIN_ESCROW_CONFIRMS` - Awaiting min escrow confs * `CRYPTO_ESC` - Crypto escrowed * `CRYPTO_ESC_FAILED` - Crypto escrow failed * `FUND_PAID` - Payment done * `FUND_RECEIVED` - Payment received * `COMPLETED` - Completed * `EXPIRED` - Expired * `DISPUTED` - Disputed * `WAITING_FOR_DISPUTE_CONFIRMS` - Awaiting min dispute confs * `DISPUTE_RESOLVE_BUYER` - Dispute released to buyer * `DISPUTE_RESOLVE_SELLER` - Dispute reverted to seller * `CANCELLATION_REQUESTED` - Cancellation requested * `CANCELLED` - Cancelled * `CANCELLED_AFTER_ESCROW` - Cancelled after escrow * `CANCELLATION_REJECTED` - Cancellation rejected * `BROADCASTING_RELEASE` - Broadcasting release * `BROADCASTING_RELEASE_FAILED` - Broadcasting release failed * `WAITING_FOR_CRYPTO_RELEASE_CONFIRMS` - Awaiting min release confs * `CRYPTO_REL` - Released * `CRYPTO_REL_FAILED` - Release failed * `WAITING_FOR_MIN_APPROVE_CONFIRMS` - Awaiting min approval confs * `TRANSFER_APPROVED` - Transfer approved * `WAITING_FOR_TRANSFER_APPROVE` - Waiting for transfer approval | | `text` | query | string | | Search by username of traders. | | `trade_format` | query | `non-custodial` | `standard` | | Enum: `"standard"`, `"non-custodial"`. * `standard` - standard * `non-custodial` - non-custodial | | `trade_status` | query | `CANCELLED` | `CANCELLED_AFTER_ESCROW` | `COMPLETED` | `DISPUTE_RESOLVE_BUYER` | `DISPUTE_RESOLVE_SELLER` | | * `COMPLETED` - COMPLETED * `CANCELLED` - CANCELLED * `CANCELLED_AFTER_ESCROW` - CANCELLED_AFTER_ESCROW * `DISPUTE_RESOLVE_BUYER` - DISPUTE_RESOLVE_BUYER * `DISPUTE_RESOLVE_SELLER` - DISPUTE_RESOLVE_SELLER | | `trade_type` | query | `buy` | `sell` | | Enum: `"buy"`, `"sell"`. * `buy` - buy * `sell` - sell | | `user` | query | string | | Filter by exact username. | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/trades/list/?stage=live&coin_currency=BTC' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "active_page": 1, "count": 18, "next": null, "previous": null, "offset": 0, "limit": 5, "total_pages": 4, "results": [ { "status": "FUND_PAID", "uuid": "f3c6120b-d63a-4a1f-9d18-f181c4be29c2", "offer": { "uuid": "6ab3a6f8-5a70-41d2-80c9-8f91b27f85bd", "slug": "buy-eth-for-aud-in-australia", "is_active": true, "created_by": { "username": "satoshi_au", "activity_status": "active", "activity_tooltip": "online", "is_email_verified": true, "is_phone_verified": true, "phone_country_code": "AU", "avg_response_time": 4, "completed_trades": 182, "platform_volume": 96000, "feedback_score": "99.20000", "last_seen": 1793817600, "is_legacy": false, "user_uuid": "e98f2078-a4e7-4f59-908f-b5513be95bd6", "hide_from_google": false, "date_joined": "2021-06-21T05:24:49.500000Z", "profile_image": "https://pwa-cdn.localcoinswap.com/default_user.jpg", "bio": "", "on_holiday": false, "is_kyc_verified": true, "xp_level": "EXPERT" }, "trading_type": { "id": 2, "slug": "sell", "name": "sell", "action_name": "Selling", "opposite_name": "buy", "opposite_action_name": "Buying" }, "coin_currency": { "title": "Ethereum", "symbol": "ETH", "token_standard": null, "symbol_filename": "eth.svg", "is_crypto": true, "slug": "ETH" }, "fiat_currency": { "title": "Australian Dollar", "symbol": "AUD", "token_standard": null, "symbol_filename": null, "is_crypto": false, "slug": "australian-dollar" }, "payment_method": { "name": "Bank Transfer", "slug": "bank-transfers" }, "location_name": "Adelaide", "country_code": "AU", "custodial_type": 1, "min_trade_size": "50.0000000000", "max_trade_size": "3000.0000000000", "trading_conditions": "Bank transfers from accounts in your own name only.", "trading_condition_keys": [], "headline": "Fast ETH by bank transfer", "hidden": false, "enforced_sizes": "", "blocked_countries": "", "automatic_cancel_time": "240", "sms_required": false, "minimum_feedback": "0", "price_formula": { "display_formula": "2.5", "prefix_formula": "exchange.ethaud|v||1.025|n||*|o", "pricing_type": "MARGIN", "market": "cmc" }, "price_formula_value": "3048.78", "current_margin_percentage": "2.5000000000" }, "buyer": { "username": "hal_f", "activity_status": "active", "activity_tooltip": "online", "last_seen": 1793817600, "is_legacy": false, "user_uuid": "11ae74df-3dcb-4752-9114-c8b7774faa49" }, "seller": { "username": "satoshi_au", "activity_status": "active", "activity_tooltip": "online", "last_seen": 1793817600, "is_legacy": false, "user_uuid": "e98f2078-a4e7-4f59-908f-b5513be95bd6" }, "fiat_amount": "250.000000000000000000", "coin_amount": "0.082000000000000000", "time_created": 1793830445, "coin_currency": { "title": "Ethereum", "symbol": "ETH", "token_standard": null, "symbol_filename": "eth.svg", "is_crypto": true, "slug": "ETH" }, "fiat_currency": { "title": "Australian Dollar", "symbol": "AUD", "token_standard": null, "symbol_filename": null, "is_crypto": false, "slug": "australian-dollar" } } ] } ``` ### Start a trade `POST /api/v2/trades/non-custodial/create/`. Scope: `trade`. Rate limit: 3 per minute. Start a non-custodial trade on someone else's offer. Send either `fiat_amount` or `coin_amount`, within the offer's limits, and one of your web wallet addresses. The trade starts as `CREATED`; the offer creator then accepts or cancels it with the update endpoint. **Rate limit:** 3 per minute Request body: | Field | Type | Required | Description | | --- | --- | --- | --- | | `offer` | string | yes | UUID of the Offer you want to initiate the trade with. | | `fiat_amount` | string | yes | Amount in fiat (local) currency corresponding to the crypto value to buy/sell. | | `coin_amount` | string | yes | Crypto value for the trade. | | `wallet_address` | string | yes | Wallet address you want to use to start the trade. | | `wallet_pubkey` | string | | Public key hex corresponding to `wallet_address`. | | `wallet_type` | object | | `webwallet`, the non-custodial LocalCoinSwap Wallet, is the only type. `wallet_address` must be one of your web wallet addresses. * `webwallet` - Web wallet | | `btc_trade_secrets` | object | | This is **only required** for non-custodial BTC trades. | ```bash curl --request POST 'https://api.localcoinswap.com/api/v2/trades/non-custodial/create/' \ --header "Authorization: ApiKey $LCS_API_KEY" \ --header 'Content-Type: application/json' \ --data-raw '{"offer": "6ab3a6f8-5a70-41d2-80c9-8f91b27f85bd", "fiat_amount": "250.00", "coin_amount": "0.082", "wallet_address": "0x7D1f14c29825b052004A5eF02d8F0BC7E2c9A2A0", "wallet_type": "webwallet"}' ``` Response 201: ```json { "status": "CREATED", "uuid": "f3c6120b-d63a-4a1f-9d18-f181c4be29c2" } ``` ### Move a trade to its next status `PATCH /api/v2/trades/non-custodial/update/{uuid}/`. Scope: `trade`. Send the `status` to move the trade into, plus the fields that status needs. Only the buyer or seller can update a trade, and each status can only be sent by one side (see `status`). Returns the full trade. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `uuid` | path | string | yes | | Request body: | Field | Type | Required | Description | | --- | --- | --- | --- | | `status` | object | | #### The status in which you want to move the trade into. - `ACCEPTED` - When you want to accept a trade initiated on your offer. - Only offer creator can accept a trade. - When seller accepts the trade and if they have enough funds in their LocalCoinSwap Wallet, transition to `CRYPTO_ESC` happens automatically. - `WAITING_FOR_MIN_APPROVE_CONFIRMS` - When you are waiting for the minimum number of blockchain confirmations for an ERC20 approval transaction. - This step is required only for ERC20 token (excluding ETH) - `TRANSFER_APPROVED` - When you want to approve ERC20 non-custodial escrow. - Only seller can perform this action. - This step is required only for ERC20 token (excluding ETH) - `WAITING_FOR_MIN_ESCROW_CONFIRMS` - When you are waiting for the minimum number of blockchain confirmations for an escrow transaction. - `CRYPTO_ESC` - When you want to fund the Escrow. - Only seller can perform this action. - Requires enough funds in the selected non-custodial Wallet. - `FUND_PAID` - When you want to indicate that you have transferred fiat/local currency payment via the payment method agreed upon based on offer terms. - Only buyer can perform this action. - `FUND_RECEIVED` - When you want to indicate that you have received fiat/local currency payment from the buyer. - `CANCELLED` - When you want to cancel a trade. - If the current status of the trade allows cancellation right away, the trade will be marked cancelled. - Else, the trade will follow double-confirmation flow where both seller and buyer have to mutually agree to cancel the trade. - `CANCELLATION_REJECTED` - When you want to reject the cancellation request. - The user who requested cancellation can send this to withdraw their request. Each status needs its own extra fields; see the field descriptions below. * `ACCEPTED` - ACCEPTED * `WAITING_FOR_MIN_APPROVE_CONFIRMS` - WAITING_FOR_MIN_APPROVE_CONFIRMS * `TRANSFER_APPROVED` - TRANSFER_APPROVED * `WAITING_FOR_MIN_ESCROW_CONFIRMS` - WAITING_FOR_MIN_ESCROW_CONFIRMS * `CRYPTO_ESC` - CRYPTO_ESC * `FUND_PAID` - FUND_PAID * `FUND_RECEIVED` - FUND_RECEIVED * `CANCELLED` - CANCELLED * `CANCELLATION_REJECTED` - CANCELLATION_REJECTED | | `wallet_address` | string | | Wallet address you want to use to accept the trade. Required only at the time of accepting a non-custodial trade. | | `wallet_pubkey` | string | | Public key hex corresponding to `wallet_address`. | | `wallet_type` | object | | Required only at the time of accepting a non-custodial trade. `webwallet`, the non-custodial LocalCoinSwap Wallet, is the only type. * `webwallet` - Web wallet | | `signed_txn` | string | | | | `trx_signed_txn` | object | | | | `broadcasted_txn_hash` | string | | This is used only when you connect a hardware wallet like Metamask with LocalCoinSwap. You have to broadcast the signed transaction yourself and pass the broadcasted transaction hash to the API. | | `signed_relay_signature` | object | | The seller's release signature `{r, s, v}` (relay instruction `0x01`), required with `FUND_RECEIVED` on ETH, ERC20, BNB, BEP20 and TRC20 trades. See "Signing trades". | | `release_signature` | string | | This is **only required** to release escrow for LTC trades. | | `release_psbt_base64` | string | | This is **only required** to release escrow for LTC trades. | | `cancel_signature` | string | | This is **only required** to cancel escrow for LTC trades. | | `cancel_psbt_base64` | string | | This is **only required** to cancel escrow for LTC trades. | | `btc_trade_secrets` | object | | This is **only required** to accept non-custodial BTC trades. When you accept as the buyer (on your buy offer), `hashed_secret_signed` and `address_signed` are required too. | | `seller_secret` | string | | This is **only required** to mark non-custodial BTC trades as FUND_RECEIVED by the seller. | | `cancellation_secret` | string | | This is only required to cancel BTC trades that have escrowed | | `cancellation_signature` | object | | The buyer's cancel signature `{r, s, v}` (relay instruction `0x02`), required to cancel an escrowed ETH, ERC20, BNB, BEP20 or TRC20 trade. See "Signing trades". | | `cancellation_reason` | object | | | ```bash curl --request PATCH 'https://api.localcoinswap.com/api/v2/trades/non-custodial/update/f3c6120b-d63a-4a1f-9d18-f181c4be29c2/' \ --header "Authorization: ApiKey $LCS_API_KEY" \ --header 'Content-Type: application/json' \ --data-raw '{"status": "FUND_PAID"}' ``` Response 200: ```json { "id": 22949, "ad": { "uuid": "6ab3a6f8-5a70-41d2-80c9-8f91b27f85bd", "slug": "buy-eth-for-aud-in-australia", "is_active": true, "created_by": { "username": "satoshi_au", "activity_status": "active", "activity_tooltip": "online", "is_email_verified": true, "is_phone_verified": true, "phone_country_code": "AU", "avg_response_time": 4, "completed_trades": 182, "platform_volume": 96000, "feedback_score": "99.20000", "last_seen": 1793817600, "is_legacy": false, "user_uuid": "e98f2078-a4e7-4f59-908f-b5513be95bd6", "hide_from_google": false, "date_joined": "2021-06-21T05:24:49.500000Z", "profile_image": "https://pwa-cdn.localcoinswap.com/default_user.jpg", "bio": "", "on_holiday": false, "is_kyc_verified": true, "xp_level": "EXPERT" }, "trading_type": { "id": 2, "slug": "sell", "name": "sell", "action_name": "Selling", "opposite_name": "buy", "opposite_action_name": "Buying" }, "coin_currency": { "title": "Ethereum", "symbol": "ETH", "token_standard": null, "symbol_filename": "eth.svg", "is_crypto": true, "slug": "ETH" }, "fiat_currency": { "title": "Australian Dollar", "symbol": "AUD", "token_standard": null, "symbol_filename": null, "is_crypto": false, "slug": "australian-dollar" }, "payment_method": { "name": "Bank Transfer", "slug": "bank-transfers" }, "location_name": "Adelaide", "country_code": "AU", "custodial_type": 1, "min_trade_size": "50.0000000000", "max_trade_size": "3000.0000000000", "trading_conditions": "Bank transfers from accounts in your own name only.", "trading_condition_keys": [], "headline": "Fast ETH by bank transfer", "hidden": false, "enforced_sizes": "", "blocked_countries": "", "automatic_cancel_time": "240", "sms_required": false, "minimum_feedback": "0", "price_formula": { "display_formula": "2.5", "prefix_formula": "exchange.ethaud|v||1.025|n||*|o", "pricing_type": "MARGIN", "market": "cmc" }, "price_formula_value": "3048.78", "current_margin_percentage": "2.5000000000" }, "status": "FUND_PAID", "status_meta": {}, "uuid": "f3c6120b-d63a-4a1f-9d18-f181c4be29c2", "contract_responder": { "username": "hal_f", "activity_status": "active", "activity_tooltip": "online", "is_email_verified": true, "is_phone_verified": true, "phone_country_code": "AU", "avg_response_time": 4, "completed_trades": 12, "platform_volume": 96000, "feedback_score": "99.20000", "last_seen": 1793817600, "is_legacy": false, "user_uuid": "11ae74df-3dcb-4752-9114-c8b7774faa49", "hide_from_google": false, "date_joined": "2021-06-21T05:24:49.500000Z", "profile_image": "https://pwa-cdn.localcoinswap.com/default_user.jpg" }, "buyer": { "username": "hal_f", "activity_status": "active", "activity_tooltip": "online", "is_email_verified": true, "is_phone_verified": true, "phone_country_code": "AU", "avg_response_time": 4, "completed_trades": 12, "platform_volume": 96000, "feedback_score": "99.20000", "last_seen": 1793817600, "is_legacy": false, "user_uuid": "11ae74df-3dcb-4752-9114-c8b7774faa49", "hide_from_google": false, "date_joined": "2021-06-21T05:24:49.500000Z", "profile_image": "https://pwa-cdn.localcoinswap.com/default_user.jpg" }, "seller": { "username": "satoshi_au", "activity_status": "active", "activity_tooltip": "online", "is_email_verified": true, "is_phone_verified": true, "phone_country_code": "AU", "avg_response_time": 4, "completed_trades": 182, "platform_volume": 96000, "feedback_score": "99.20000", "last_seen": 1793817600, "is_legacy": false, "user_uuid": "e98f2078-a4e7-4f59-908f-b5513be95bd6", "hide_from_google": false, "date_joined": "2021-06-21T05:24:49.500000Z", "profile_image": "https://pwa-cdn.localcoinswap.com/default_user.jpg" }, "disputed_by": null, "fiat_amount": "250.000000000000000000", "coin_amount": "0.082000000000000000", "time_of_expiry": 1793844845, "time_created": 1793830445, "coin_currency": { "title": "Ethereum", "symbol": "ETH", "token_standard": null, "symbol_filename": "eth.svg", "is_crypto": true, "slug": "ETH", "id": 2, "chain": null, "active_status": "currency_active" }, "fiat_currency": { "title": "Australian Dollar", "symbol": "AUD", "token_standard": null, "symbol_filename": null, "is_crypto": false, "slug": "australian-dollar", "id": 10002, "chain": null, "active_status": "currency_active" }, "crypto_in_usd": "164.120000000000000000", "responder_geo": {}, "tx_meta": { "escrow_version": "v2", "escrow_contract": "0x3a362a1966FF5aAB35298E1565bDa2c9FB124e41", "trade_hash": "0x5d0f2c7a1b9e48c3a6f1d2e0b7c4a9f8e3d2c1b0a9f8e7d6c5b4a39281706f5e", "escrow_unsigned_tx": { "to": "0x3a362a1966FF5aAB35298E1565bDa2c9FB124e41", "data": "0x6c1b3f2a...", "value": "82820000000000000", "nonce": 27, "gas": 180000, "gasPrice": "4400000000", "chainId": 1 }, "escrow_signed_tx": "0x02f9017201..." }, "buyer_meta": { "address": "0x7D1f14c29825b052004A5eF02d8F0BC7E2c9A2A0", "wallet_type": "webwallet", "address_pubkey": "04a3f1c2...", "public_key": "03b7e94d..." }, "seller_meta": { "address": "0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF", "wallet_type": "webwallet", "address_pubkey": "04c81e5b...", "public_key": "02f4a6d1..." }, "non_custodial": true, "amount_to_escrow": "0.082820000000000000", "fees": "0.000820000000000000", "btc_escrow_data": null, "eth_escrow_data": { "approve_tx": null, "escrow_tx": "0x9c1e4b7f0d2a6e83f5c1b2a49d7e0f36a8c5b1e2d4f6a7b8c9d0e1f2a3b4c5d6", "release_tx": null, "dispute_tx": null, "cancel_tx": null }, "multisig_escrow_data": null, "local_currency_symbol": "AUD", "crypto_in_local_currency": "250.12" } ``` ### Withdraw your dispute `POST /api/v2/trades/withdraw-dispute/{uuid}/`. Scope: `trade`. Rate limit: 1 per 5 seconds. Closes a dispute you opened and moves the trade back to the status it had before. Only the user who opened the dispute can withdraw it, and only while the trade is still `DISPUTED`. **Rate limit:** 1 per 5 seconds Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `uuid` | path | string | yes | | ```bash curl --request POST 'https://api.localcoinswap.com/api/v2/trades/withdraw-dispute/f3c6120b-d63a-4a1f-9d18-f181c4be29c2/' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "uuid": "f3c6120b-d63a-4a1f-9d18-f181c4be29c2", "status": "FUND_PAID" } ``` ## Trade chat ### Send a trade chat message `POST /api/v2/trades/message/{uuid}/`. Scope: `trade`. Send `content` (text, at most 1000 characters are kept), an `attachment` (PDF, image or video, up to 50 MB), or both. Attachments need `multipart/form-data`; text-only messages can also be JSON. Only the buyer and seller can post. The other side is notified if they aren't on the trade page. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `uuid` | path | string | yes | | Request body: | Field | Type | Required | Description | | --- | --- | --- | --- | | `content` | string | null | | | | `attachment` | string | | | ```bash curl --request POST 'https://api.localcoinswap.com/api/v2/trades/message/f3c6120b-d63a-4a1f-9d18-f181c4be29c2/' \ --header "Authorization: ApiKey $LCS_API_KEY" \ --header 'Content-Type: application/json' \ --data-raw '{"content": "Paid by bank transfer, reference LCS-4821."}' ``` Response 201: ```json { "id": 90214, "content": "Paid by bank transfer, reference LCS-4821.", "message": "Paid by bank transfer, reference LCS-4821.", "attachment": null, "time_created": 1793830871, "created_by": { "username": "hal_f", "timezone": "Australia/Adelaide", "local_currency_symbol": "AUD", "bio": "", "is_staff": false, "is_email_verified": true, "last_seen": 1793817600, "cached_last_seen": 1793817600, "profile_image": "https://pwa-cdn.localcoinswap.com/default_user.jpg", "activity_status": "active", "activity_tooltip": "online", "feedback_score": "99.20000", "completed_trades": 12, "trades_30d": 6, "platform_volume": 96000, "platform_volume_30d": 4100, "avg_response_time": 4, "user_uuid": "11ae74df-3dcb-4752-9114-c8b7774faa49", "date_joined": "2021-06-21T05:24:49.500000Z", "is_phone_verified": true, "is_legacy": false, "primary_language": "en", "lang_list": "en", "times_blocked": 0, "times_followed": 3, "imported_total_trades": null, "imported_volume": null, "on_holiday": false, "non_custodial": true, "xp_level": "EXPERT", "xp": 240, "stats": { "trades_started": 14, "trades_started_completed": 12 } }, "recipient": null, "file": null } ``` ### List trade chat messages `GET /api/v2/trades/message/list/{contract_uuid}/`. Scope: `read`. The trade's chat, oldest first. Besides the two traders' messages it holds support staff replies, dispute notices posted by the LocalCoinSwap admin account, and the offer's automatic messages, posted as the offer creator. Page with `limit` (up to 1000) and `offset`. Only the buyer and seller can read it; anyone else gets 403. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `contract_uuid` | path | string | yes | | | `limit` | query | integer | | Number of results to return per page. | | `offset` | query | integer | | The initial index from which to return the results. | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/trades/message/list/f3c6120b-d63a-4a1f-9d18-f181c4be29c2/?limit=50' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "count": 18, "next": null, "previous": null, "offset": 0, "limit": 5, "results": [ { "id": 90211, "content": "Escrow funded. Send the payment now.", "attachment": { "url": "", "attachment_name": "" }, "time_created": 1793830502, "created_by": { "username": "satoshi_au", "timezone": "Australia/Adelaide", "local_currency_symbol": "AUD", "bio": "", "is_staff": false, "is_email_verified": true, "last_seen": 1793817600, "cached_last_seen": 1793817600, "profile_image": "https://pwa-cdn.localcoinswap.com/default_user.jpg", "activity_status": "active", "activity_tooltip": "online", "feedback_score": "99.20000", "completed_trades": 182, "trades_30d": 6, "platform_volume": 96000, "platform_volume_30d": 4100, "avg_response_time": 4, "user_uuid": "e98f2078-a4e7-4f59-908f-b5513be95bd6", "date_joined": "2021-06-21T05:24:49.500000Z", "is_phone_verified": true, "is_legacy": false, "primary_language": "en", "lang_list": "en", "times_blocked": 0, "times_followed": 3, "imported_total_trades": null, "imported_volume": null, "on_holiday": false, "non_custodial": true, "xp_level": "EXPERT", "xp": 240, "stats": { "trades_started": 14, "trades_started_completed": 12 } }, "recipient": null, "file": null } ] } ``` ## Feedback ### Get your feedback on a trade `GET /api/v2/trades/{uuid}/feedback/`. Scope: `read`. The feedback you left on this trade, or 404 if you haven't left any. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `uuid` | path | string | yes | | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/trades/f3c6120b-d63a-4a1f-9d18-f181c4be29c2/feedback/' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "feedback_for": { "username": "satoshi_au", "local_currency_symbol": "AUD", "bio": "", "is_staff": false, "user_uuid": "e98f2078-a4e7-4f59-908f-b5513be95bd6", "date_joined": "2021-06-21T05:24:49.500000Z", "primary_language": "en", "non_custodial": true, "hide_from_google": false }, "rating": "5.0", "feedback": "Fast and friendly.", "feedback_by": { "username": "hal_f", "local_currency_symbol": "AUD", "bio": "", "is_staff": false, "user_uuid": "11ae74df-3dcb-4752-9114-c8b7774faa49", "date_joined": "2024-02-03T11:02:41.118204Z", "primary_language": "en", "non_custodial": true, "hide_from_google": false }, "id": 7780, "rating_percentage": 100.0, "time_created": 1793832100, "trade": "f3c6120b-d63a-4a1f-9d18-f181c4be29c2" } ``` ### Leave feedback on a trade `POST /api/v2/trades/feedback/create/`. Scope: `trade`. Rate limit: 3 per hour. Rate the other trader 1 to 5 stars, once per trade. The trade must be finished: after a normal completion both sides can leave feedback; after a dispute only the side it was resolved for can. **Rate limit:** 3 per hour Request body: | Field | Type | Required | Description | | --- | --- | --- | --- | | `rating` | object | yes | 1 to 5 stars. * `1` - 1 * `2` - 2 * `3` - 3 * `4` - 4 * `5` - 5 | | `feedback` | string | null | yes | At most 500 characters. | | `trade` | string | yes | UUID of the trade you want to provide the feedback on. | ```bash curl --request POST 'https://api.localcoinswap.com/api/v2/trades/feedback/create/' \ --header "Authorization: ApiKey $LCS_API_KEY" \ --header 'Content-Type: application/json' \ --data-raw '{"trade": "f3c6120b-d63a-4a1f-9d18-f181c4be29c2", "rating": "5", "feedback": "Fast and friendly."}' ``` Response 201: ```json { "feedback_for": { "username": "satoshi_au", "local_currency_symbol": "AUD", "bio": "", "is_staff": false, "user_uuid": "e98f2078-a4e7-4f59-908f-b5513be95bd6", "date_joined": "2021-06-21T05:24:49.500000Z", "primary_language": "en", "non_custodial": true, "hide_from_google": false }, "rating": "5.0", "feedback": "Fast and friendly.", "feedback_by": { "username": "hal_f", "local_currency_symbol": "AUD", "bio": "", "is_staff": false, "user_uuid": "11ae74df-3dcb-4752-9114-c8b7774faa49", "date_joined": "2024-02-03T11:02:41.118204Z", "primary_language": "en", "non_custodial": true, "hide_from_google": false }, "id": 7780, "rating_percentage": 100.0, "time_created": 1793832100, "trade": "f3c6120b-d63a-4a1f-9d18-f181c4be29c2" } ``` ### List feedback `GET /api/v2/trades/feedback/list/`. Scope: `read`. Feedback a user received (`feedback_for`) or left (`feedback_by`), by their `user_uuid`, newest first. One of the two is required. Filter by `rating` (1 to 5); `count` gives the total for each filter. At most 10 per page. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `feedback_by` | query | string | | | | `feedback_for` | query | string | | | | `limit` | query | integer | | Number of results to return per page. | | `offset` | query | integer | | The initial index from which to return the results. | | `rating` | query | number | | | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/trades/feedback/list/?feedback_for=e98f2078-a4e7-4f59-908f-b5513be95bd6&rating=5' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "active_page": 1, "count": 18, "next": null, "previous": null, "offset": 0, "limit": 5, "total_pages": 4, "results": [ { "feedback_for": { "username": "satoshi_au", "local_currency_symbol": "AUD", "bio": "", "is_staff": false, "user_uuid": "e98f2078-a4e7-4f59-908f-b5513be95bd6", "date_joined": "2021-06-21T05:24:49.500000Z", "primary_language": "en", "non_custodial": true, "hide_from_google": false }, "rating": "5.0", "feedback": "Fast and friendly.", "feedback_by": { "username": "hal_f", "local_currency_symbol": "AUD", "bio": "", "is_staff": false, "user_uuid": "11ae74df-3dcb-4752-9114-c8b7774faa49", "date_joined": "2024-02-03T11:02:41.118204Z", "primary_language": "en", "non_custodial": true, "hide_from_google": false }, "id": 7780, "rating_percentage": 100.0, "time_created": 1793832100 } ] } ``` ## Notifications ### List your notifications `GET /api/v2/notifs/`. Scope: `read`. Newest first, at most 20 per page. `inbox` picks a tab: `unread`, or `trades`, `swaps` and `account` by `event`; the default `all` includes every event. `has_unseen` says whether any notification, in any tab, is still unseen. `metadata` carries the related object, such as `trade_uuid` for trade events. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `inbox` | query | `account` | `all` | `swaps` | `trades` | `unread` | | | | `limit` | query | integer | | Number of results to return per page. | | `offset` | query | integer | | The initial index from which to return the results. | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/notifs/?inbox=trades&limit=20' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "count": 18, "offset": 0, "limit": 5, "has_unseen": true, "inbox": "all", "results": [ { "id": 318825, "unread": true, "title": "Trade Chat #f3c6120b | hal_f | 250.00 AUD", "description": "Paid by bank transfer, reference LCS-4821.", "event": "TRADE_MSG", "metadata": { "trade_uuid": "f3c6120b-d63a-4a1f-9d18-f181c4be29c2" }, "since": "5 minutes" } ] } ``` ### Mark all notifications read `POST /api/v2/notifs/read/`. Scope: `trade`. Sets `unread` to false on every notification. It doesn't change `has_unseen`; mark them seen for that. ```bash curl --request POST 'https://api.localcoinswap.com/api/v2/notifs/read/' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "status": true } ``` ### Mark one notification read `POST /api/v2/notifs/read/{notif_id}/`. Scope: `trade`. Sets its `unread` to false. 404 if it isn't one of yours. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `notif_id` | path | string | yes | | ```bash curl --request POST 'https://api.localcoinswap.com/api/v2/notifs/read/318825/' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "status": true } ``` ### Mark all notifications seen `POST /api/v2/notifs/seen/`. Scope: `trade`. Clears `has_unseen` (the website's red dot on the bell). Notifications stay `unread` until you mark them read. ```bash curl --request POST 'https://api.localcoinswap.com/api/v2/notifs/seen/' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "status": true } ``` ## Swaps ### List your swaps `GET /api/v2/swaps/`. Scope: `read`. Only swaps you created. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `limit` | query | integer | | Number of results to return per page. | | `offset` | query | integer | | The initial index from which to return the results. | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/swaps/' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "active_page": 1, "count": 18, "next": null, "previous": null, "offset": 0, "limit": 5, "total_pages": 4, "results": [ { "provider": "CHANGENOW", "swap_id": "7fb484616da1e8", "user": { "username": "satoshi_au", "activity_status": "active", "activity_tooltip": "online", "is_email_verified": true, "is_phone_verified": true, "phone_country_code": "AU", "avg_response_time": 4, "completed_trades": 182, "platform_volume": 96000, "feedback_score": "99.20000", "last_seen": 1793817600, "is_legacy": false, "bio": "", "user_uuid": "e98f2078-a4e7-4f59-908f-b5513be95bd6", "on_holiday": false, "hide_from_google": false, "date_joined": "2021-06-21T05:24:49.500000Z", "profile_image": "https://pwa-cdn.localcoinswap.com/default_user.jpg", "is_kyc_verified": true, "xp_level": "EXPERT" }, "status": "WAITING", "from_crypto": { "title": "Ethereum", "symbol": "ETH", "token_standard": null, "symbol_filename": "eth.svg", "is_crypto": true, "slug": "ETH" }, "to_currency": { "title": "Bitcoin", "symbol": "BTC", "token_standard": null, "symbol_filename": "btc.svg", "is_crypto": true, "slug": "BTC" }, "from_amount": "0.100000000000000000", "initial_to_amount": "0.003134120000000000", "addresses_json": { "payout_address": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq", "refund_address": "0x8456D17ef805E5B75dB839275356973E757f5a3E", "payin_address": "0x85b481F4e3691AD6aFF51Bf8e919dC1C3c0B6D5D" }, "uuid": "e96433ff-9b9d-4c05-a98e-8bf726318efd", "tx_json": {}, "final_to_amount": null, "created": "2026-11-02T09:14:03.512000Z", "provider_created_at": "2026-11-02T09:14:02Z" } ] } ``` ### Create swap `POST /api/v2/swaps/`. Scope: `trade`. Create a swap trade. This can be done only by authenticated users. Request body: | Field | Type | Required | Description | | --- | --- | --- | --- | | `uuid` | string | | | | `status` | `NEW` | `WAITING` | `FUNDING` | `CONFIRMING` | `EXCHANGING` | `SENDING` | `FINISHED` | `FAILED` | `REFUNDED` | `VERIFYING` | `EXPIRED` | | * `NEW` - Swap created * `WAITING` - Waiting on user to fund * `FUNDING` - User funds sent * `CONFIRMING` - Confirming transaction * `EXCHANGING` - Exchanging on market * `SENDING` - Sending swap exchange to user * `FINISHED` - Swap finished * `FAILED` - Swap failed * `REFUNDED` - Swap refunded * `VERIFYING` - Swap verifying * `EXPIRED` - Swap expired | | `provider` | `CHANGENOW` | yes | * `CHANGENOW` - ChangeNOW | | `from_crypto` | string | yes | Crypto you want to swap from. | | `to_currency` | string | yes | Crypto you want to swap to. | | `from_amount` | string | yes | | | `addresses_json` | object | yes | | | `initial_to_amount` | string | yes | Initial expected amount to be recieved | | `provider_created_at` | string | null | | | ```bash curl --request POST 'https://api.localcoinswap.com/api/v2/swaps/' \ --header "Authorization: ApiKey $LCS_API_KEY" \ --header 'Content-Type: application/json' \ --data-raw '{"from_crypto": "ETH", "to_currency": "BTC", "from_amount": "0.1", "initial_to_amount": "0.00313412", "provider": "CHANGENOW", "addresses_json": {"payout_address": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq", "refund_address": "0x8456D17ef805E5B75dB839275356973E757f5a3E"}}' ``` Response 201: ```json { "uuid": "e96433ff-9b9d-4c05-a98e-8bf726318efd", "status": "NEW", "provider": "CHANGENOW", "from_crypto": "ETH", "to_currency": "BTC", "from_amount": "0.100000000000000000", "addresses_json": { "payout_address": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq", "refund_address": "0x8456D17ef805E5B75dB839275356973E757f5a3E" }, "initial_to_amount": "0.003134120000000000", "provider_created_at": null } ``` ### Get swap by UUID `GET /api/v2/swaps/{uuid}/`. Scope: `read`. Only the swap's creator can read it. Once the swap is `WAITING`, `addresses_json.payin_address` holds the address to send funds to. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `uuid` | path | string | yes | | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/swaps/e96433ff-9b9d-4c05-a98e-8bf726318efd/' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "provider": "CHANGENOW", "swap_id": "7fb484616da1e8", "user": { "username": "satoshi_au", "activity_status": "active", "activity_tooltip": "online", "is_email_verified": true, "is_phone_verified": true, "phone_country_code": "AU", "avg_response_time": 4, "completed_trades": 182, "platform_volume": 96000, "feedback_score": "99.20000", "last_seen": 1793817600, "is_legacy": false, "bio": "", "user_uuid": "e98f2078-a4e7-4f59-908f-b5513be95bd6", "on_holiday": false, "hide_from_google": false, "date_joined": "2021-06-21T05:24:49.500000Z", "profile_image": "https://pwa-cdn.localcoinswap.com/default_user.jpg", "is_kyc_verified": true, "xp_level": "EXPERT" }, "status": "WAITING", "from_crypto": { "title": "Ethereum", "symbol": "ETH", "token_standard": null, "symbol_filename": "eth.svg", "is_crypto": true, "slug": "ETH" }, "to_currency": { "title": "Bitcoin", "symbol": "BTC", "token_standard": null, "symbol_filename": "btc.svg", "is_crypto": true, "slug": "BTC" }, "from_amount": "0.100000000000000000", "initial_to_amount": "0.003134120000000000", "addresses_json": { "payout_address": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq", "refund_address": "0x8456D17ef805E5B75dB839275356973E757f5a3E", "payin_address": "0x85b481F4e3691AD6aFF51Bf8e919dC1C3c0B6D5D" }, "uuid": "e96433ff-9b9d-4c05-a98e-8bf726318efd", "tx_json": {}, "final_to_amount": null, "created": "2026-11-02T09:14:03.512000Z", "provider_created_at": "2026-11-02T09:14:02Z" } ``` ### Mark swap as funded `PATCH /api/v2/swaps/{uuid}/`. Scope: `trade`. After sending the funds to `addresses_json.payin_address`, move the swap from `WAITING` to `FUNDING` and record the pay-in transaction: `{"status": "FUNDING", "tx_json": {"payin_transaction_hash": "..."}}`. Optional: the swap also progresses once the provider sees the deposit. Only the swap's creator can do this. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `uuid` | path | string | yes | | Request body: | Field | Type | Required | Description | | --- | --- | --- | --- | | `status` | object | | #### The status in which you want to move the swap into. Currently users only need to move their swap to: - `FUNDING` - When you have sent the funds to be swapped to the pay-in address. - Only can be called when swap is in `CREATED` state. * `NEW` - Swap created * `WAITING` - Waiting on user to fund * `FUNDING` - User funds sent * `CONFIRMING` - Confirming transaction * `EXCHANGING` - Exchanging on market * `SENDING` - Sending swap exchange to user * `FINISHED` - Swap finished * `FAILED` - Swap failed * `REFUNDED` - Swap refunded * `VERIFYING` - Swap verifying * `EXPIRED` - Swap expired | | `tx_json` | object | | Optional. `{"payin_transaction_hash": ""}` | ```bash curl --request PATCH 'https://api.localcoinswap.com/api/v2/swaps/e96433ff-9b9d-4c05-a98e-8bf726318efd/' \ --header "Authorization: ApiKey $LCS_API_KEY" \ --header 'Content-Type: application/json' \ --data-raw '{"status": "FUNDING", "tx_json": {"payin_transaction_hash": "0x9c1e4b7f0d2a6e83f5c1b2a49d7e0f36a8c5b1e2d4f6a7b8"}}' ``` Response 200: ```json { "provider": "CHANGENOW", "swap_id": "7fb484616da1e8", "user": { "username": "satoshi_au", "activity_status": "active", "activity_tooltip": "online", "is_email_verified": true, "is_phone_verified": true, "phone_country_code": "AU", "avg_response_time": 4, "completed_trades": 182, "platform_volume": 96000, "feedback_score": "99.20000", "last_seen": 1793817600, "is_legacy": false, "bio": "", "user_uuid": "e98f2078-a4e7-4f59-908f-b5513be95bd6", "on_holiday": false, "hide_from_google": false, "date_joined": "2021-06-21T05:24:49.500000Z", "profile_image": "https://pwa-cdn.localcoinswap.com/default_user.jpg", "is_kyc_verified": true, "xp_level": "EXPERT" }, "status": "FUNDING", "from_crypto": { "title": "Ethereum", "symbol": "ETH", "token_standard": null, "symbol_filename": "eth.svg", "is_crypto": true, "slug": "ETH" }, "to_currency": { "title": "Bitcoin", "symbol": "BTC", "token_standard": null, "symbol_filename": "btc.svg", "is_crypto": true, "slug": "BTC" }, "from_amount": "0.100000000000000000", "initial_to_amount": "0.003134120000000000", "addresses_json": { "payout_address": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq", "refund_address": "0x8456D17ef805E5B75dB839275356973E757f5a3E", "payin_address": "0x85b481F4e3691AD6aFF51Bf8e919dC1C3c0B6D5D" }, "uuid": "e96433ff-9b9d-4c05-a98e-8bf726318efd", "tx_json": { "payin_transaction_hash": "0x9c1e4b7f0d2a6e83f5c1b2a49d7e0f36a8c5b1e2d4f6a7b8" }, "final_to_amount": null, "created": "2026-11-02T09:14:03.512000Z", "provider_created_at": "2026-11-02T09:14:02Z" } ``` ### List your swaps in progress `GET /api/v2/swaps/active-swaps/`. Scope: `read`. Swaps from `WAITING` through `SENDING`: waiting for your deposit or being exchanged. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `limit` | query | integer | | Number of results to return per page. | | `offset` | query | integer | | The initial index from which to return the results. | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/swaps/e96433ff-9b9d-4c05-a98e-8bf726318efd/' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "active_page": 1, "count": 18, "next": null, "previous": null, "offset": 0, "limit": 5, "total_pages": 4, "results": [ { "provider": "CHANGENOW", "swap_id": "7fb484616da1e8", "user": { "username": "satoshi_au", "activity_status": "active", "activity_tooltip": "online", "is_email_verified": true, "is_phone_verified": true, "phone_country_code": "AU", "avg_response_time": 4, "completed_trades": 182, "platform_volume": 96000, "feedback_score": "99.20000", "last_seen": 1793817600, "is_legacy": false, "bio": "", "user_uuid": "e98f2078-a4e7-4f59-908f-b5513be95bd6", "on_holiday": false, "hide_from_google": false, "date_joined": "2021-06-21T05:24:49.500000Z", "profile_image": "https://pwa-cdn.localcoinswap.com/default_user.jpg", "is_kyc_verified": true, "xp_level": "EXPERT" }, "status": "WAITING", "from_crypto": { "title": "Ethereum", "symbol": "ETH", "token_standard": null, "symbol_filename": "eth.svg", "is_crypto": true, "slug": "ETH" }, "to_currency": { "title": "Bitcoin", "symbol": "BTC", "token_standard": null, "symbol_filename": "btc.svg", "is_crypto": true, "slug": "BTC" }, "from_amount": "0.100000000000000000", "initial_to_amount": "0.003134120000000000", "addresses_json": { "payout_address": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq", "refund_address": "0x8456D17ef805E5B75dB839275356973E757f5a3E", "payin_address": "0x85b481F4e3691AD6aFF51Bf8e919dC1C3c0B6D5D" }, "uuid": "e96433ff-9b9d-4c05-a98e-8bf726318efd", "tx_json": {}, "final_to_amount": null, "created": "2026-11-02T09:14:03.512000Z", "provider_created_at": "2026-11-02T09:14:02Z" } ] } ``` ### Estimated swap amount `POST /api/v2/swaps/estimate-swap-amount/`. Scope: `read`. Endpoint to return estimated swap amount for the exchange. Also returns time estimate for trade. Request body: | Field | Type | Required | Description | | --- | --- | --- | --- | | `amount` | string | yes | Amount of crypto you want to swap from. | | `to_currency` | string | yes | Currency you want to swap to. | | `from_crypto` | string | yes | Crypto you want to swap from. | ```bash curl --request POST 'https://api.localcoinswap.com/api/v2/swaps/estimate-swap-amount/' \ --header 'Content-Type: application/json' \ --data-raw '{"from_crypto": "ETH", "to_currency": "BTC", "amount": "1"}' ``` Response 200: ```json { "estimatedAmount": "0.0313412", "transactionSpeedForecast": "10-60", "warningMessage": null } ``` ### Minimal swap amount `GET /api/v2/swaps/min-swap-amount/{from_crypto}/{to_currency}/`. Scope: `read`. Endpoint to return minimal payment amount required to make a swap. If you try to swap less, the transaction will most likely fail. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `from_crypto` | path | string | yes | | | `to_currency` | path | string | yes | | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/swaps/min-swap-amount/ETH/BTC/' ``` Response 200: ```json { "minAmount": "0.0726799" } ``` ### List your finished swaps `GET /api/v2/swaps/past-swaps/`. Scope: `read`. Swaps that ended: `FINISHED`, `FAILED`, `REFUNDED` or `EXPIRED`. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `limit` | query | integer | | Number of results to return per page. | | `offset` | query | integer | | The initial index from which to return the results. | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/swaps/e96433ff-9b9d-4c05-a98e-8bf726318efd/' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "active_page": 1, "count": 18, "next": null, "previous": null, "offset": 0, "limit": 5, "total_pages": 4, "results": [ { "provider": "CHANGENOW", "swap_id": "7fb484616da1e8", "user": { "username": "satoshi_au", "activity_status": "active", "activity_tooltip": "online", "is_email_verified": true, "is_phone_verified": true, "phone_country_code": "AU", "avg_response_time": 4, "completed_trades": 182, "platform_volume": 96000, "feedback_score": "99.20000", "last_seen": 1793817600, "is_legacy": false, "bio": "", "user_uuid": "e98f2078-a4e7-4f59-908f-b5513be95bd6", "on_holiday": false, "hide_from_google": false, "date_joined": "2021-06-21T05:24:49.500000Z", "profile_image": "https://pwa-cdn.localcoinswap.com/default_user.jpg", "is_kyc_verified": true, "xp_level": "EXPERT" }, "status": "WAITING", "from_crypto": { "title": "Ethereum", "symbol": "ETH", "token_standard": null, "symbol_filename": "eth.svg", "is_crypto": true, "slug": "ETH" }, "to_currency": { "title": "Bitcoin", "symbol": "BTC", "token_standard": null, "symbol_filename": "btc.svg", "is_crypto": true, "slug": "BTC" }, "from_amount": "0.100000000000000000", "initial_to_amount": "0.003134120000000000", "addresses_json": { "payout_address": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq", "refund_address": "0x8456D17ef805E5B75dB839275356973E757f5a3E", "payin_address": "0x85b481F4e3691AD6aFF51Bf8e919dC1C3c0B6D5D" }, "uuid": "e96433ff-9b9d-4c05-a98e-8bf726318efd", "tx_json": {}, "final_to_amount": null, "created": "2026-11-02T09:14:03.512000Z", "provider_created_at": "2026-11-02T09:14:02Z" } ] } ``` ## Wallet ### Get your old wallet `GET /api/v2/legacy-wallets/non-custodial/{currency_slug}/`. Scope: `wallet`. Rate limit: 30 per minute. After a wallet reset your previous addresses and their encrypted keys stay here, with the archived account data (`profile_crypto_data_history`) that decrypts them, so you can move what's left to `encrypted_wallet_address`, your current address. 404 if your wallets were never reset. **Rate limit:** 30 per minute Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `currency_slug` | path | string | yes | | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/legacy-wallets/non-custodial/ETH/' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "crypto_balance": "0.420000000000000000", "crypto_balance_base_unit": "420000000000000000", "confirmed_balance_base_unit": "420000000000000000", "fiat_balance": "2730.0000", "crypto_slug": "ETH", "local_currency_symbol": "AUD", "unit_amount_in_local_currency": "6500.0000", "address_balance_map": { "0x7D1f14c29825b052004A5eF02d8F0BC7E2c9A2A0": "0.42" }, "address_list": [ "0x7D1f14c29825b052004A5eF02d8F0BC7E2c9A2A0" ], "address_enc_keys": [ { "address": "0x7D1f14c29825b052004A5eF02d8F0BC7E2c9A2A0", "encrypted_private_key": "3b9f6c...", "encrypted_private_key_iv": "a41c09e2b7d35f18c6e04a92d1f7b305" } ], "network_fees": { "min": "1.4", "max": "5.2", "recommended": "4.4" }, "can_withdraw_free": true, "free_withdrawal_reset_seconds": 0, "encrypted_wallet_address": "0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF", "profile_crypto_data_history": { "id": 812, "created": "2026-04-20T08:11:02.118204Z", "modified": "2026-04-20T08:11:02.118204Z", "salt": "9d2c...", "iterations": 100000, "initialization_vector": "5e8a...", "encrypted_account_key": "c41f...", "public_identity_key": "04ab...", "encrypted_mnemonic": "77d0...", "encrypted_mnemonic_256": "1a9e...", "encrypted_mnemonic_iv": "f03b..." } } ``` ### List BTC trade UTXOs `GET /api/v2/trade-utxos/BTC/`. Scope: `wallet`. BTC that finished escrows paid to you and that you haven't spent yet, at most 500, with the keys and fee rates needed to sweep them to your wallet. Your client builds and signs that transaction and sends it to `publish/`. ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/trade-utxos/BTC/' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json [ { "results": [ { "secret_uid": "7f3a...", "prev_tx": "0200000001...", "tx_hash": "b6f6991d03df0e2e04dafffcd6bc418aac66049e2cd74b80f14ac86db1e3f0da", "tx_pos": 0, "value": 82000, "witnessScript": "6382012088a8...", "trade": "f3c6120b-d63a-4a1f-9d18-f181c4be29c2", "trade_secret_enc": "04ebbc...", "tradeInstruction": "01", "type": "escrow" } ], "from_address": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq", "address_enc_keys": [ { "address": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq", "encrypted_private_key": "8c21...", "encrypted_private_key_iv": "0d6e4f1a92b37c58e1a0f4d2b6c93e71" } ], "network_fees": { "min": "4.00", "avg": "4.00", "max": "12.00", "recommended": "6.60" }, "local_currency_symbol": "AUD", "unit_amount_in_local_currency": "158000.0000" } ] ``` ### List BTC transactions `GET /api/v2/tx-history/non-custodial/BTC/`. Scope: `read`. Deposits, withdrawals and escrow movements on your BTC wallet, newest first. Self-transfers are left out. Filter with `txtype`: `DEPOSIT`, `WITHDRAW`, `ESCROW`, `ESCROW_RELEASE`, `ESCROW_REFUND` or `ESCROW_FEE`. `value` is in satoshis. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `limit` | query | integer | | Number of results to return per page. | | `offset` | query | integer | | The initial index from which to return the results. | | `txtype` | query | `DEPOSIT` | `ESCROW` | `ESCROW_FEE` | `ESCROW_REFUND` | `ESCROW_RELEASE` | `WITHDRAW` | | * `ESCROW` - Escrow * `ESCROW_RELEASE` - Escrow Release * `ESCROW_FEE` - Escrow Fee * `ESCROW_REFUND` - Escrow Refund * `WITHDRAW` - Withdraw * `DEPOSIT` - Deposit | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/tx-history/non-custodial/BTC/?txtype=DEPOSIT' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "active_page": 1, "count": 18, "next": null, "previous": null, "offset": 0, "limit": 5, "total_pages": 4, "results": [ { "id": 55102, "tx": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b", "txtype": "DEPOSIT", "value": 250000, "is_confirmed": true, "first_seen_at": 1793830445, "confirmed_at": 1793831012, "ref_data": {} } ] } ``` ### Unlock your wallet keys `POST /api/v2/wallets/account-rsa-keys/`. Scope: `wallet`. Rate limit: 5 per minute. Send your 6-digit wallet PIN to get your account RSA key pair. The private key decrypts the wallet private keys returned by the wallet endpoints. Treat it like the wallet keys themselves: keep it in memory, never log or store it. Wrong PINs are rate limited. Set or reset the PIN on the website; API keys can't. **Rate limit:** 5 per minute Request body: | Field | Type | Required | Description | | --- | --- | --- | --- | | `pin` | string | yes | | ```bash curl --request POST 'https://api.localcoinswap.com/api/v2/wallets/account-rsa-keys/' \ --header "Authorization: ApiKey $LCS_API_KEY" \ --header 'Content-Type: application/json' \ --data-raw '{"pin": "'"$LCS_WALLET_PIN"'"}' ``` Response 200: ```json { "account_rsa_keys": { "public_key_pem": "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----\n", "private_key_pem": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n" } } ``` ### Prepare a USDT allowance reset `POST /api/v2/wallets/allowance-reset/`. Scope: `wallet`. Rate limit: 30 per minute. USDT-ERC20 refuses to change one non-zero allowance to another, so an escrow approval fails while an old allowance is left over. This returns an unsigned transaction that sets your allowance for the LocalCoinSwap escrow contract back to 0; sign it and send it to `publish/`, then retry the approval. The response is `[unsigned_tx, true]`. **Rate limit:** 30 per minute Request body: | Field | Type | Required | Description | | --- | --- | --- | --- | | `currency` | string | yes | | | `from_address` | string | yes | | ```bash curl --request POST 'https://api.localcoinswap.com/api/v2/wallets/allowance-reset/' \ --header "Authorization: ApiKey $LCS_API_KEY" \ --header 'Content-Type: application/json' \ --data-raw '{"currency": "USDT-ERC20", "from_address": "0x7D1f14c29825b052004A5eF02d8F0BC7E2c9A2A0"}' ``` Response 200: ```json [ { "chainId": 1, "to": "0xdAC17F958D2ee523a2206206994597C13D831ec7", "data": "0x095ea7b3...", "gas": 60000, "gasPrice": 4400000000, "nonce": 28, "value": 0 }, true ] ``` ### Get a coin balance `GET /api/v2/wallets/balance/{currency_slug}/`. Scope: `read`. Rate limit: 30 per minute. Your balance in one coin across all your addresses for it, in whole coins, base units and your local currency. Only needs the `read` scope. **Rate limit:** 30 per minute Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `currency_slug` | path | string | yes | | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/wallets/balance/USDT-ERC20/' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "crypto_balance": "1250.500000000000000000", "crypto_balance_base_unit": "1250500000", "confirmed_balance_base_unit": "1250500000", "fiat_balance": "1915.7660", "crypto_slug": "USDT-ERC20", "local_currency_symbol": "AUD", "unit_amount_in_local_currency": "1.5320" } ``` ### Publish a signed Tron transaction `POST /api/v2/wallets/broadcast-trx-tx/`. Scope: `wallet`. Broadcasts a signed TRX or TRC20 transaction, as the JSON object Tron signing libraries produce, and returns its `txID` as `tx`. Request body: | Field | Type | Required | Description | | --- | --- | --- | --- | | `signed_tx` | object | yes | The signed Tron transaction object, with its `txID`. | ```bash curl --request POST 'https://api.localcoinswap.com/api/v2/wallets/broadcast-trx-tx/' \ --header "Authorization: ApiKey $LCS_API_KEY" \ --header 'Content-Type: application/json' \ --data-raw '{"signed_tx": {"txID": "8e1c...", "raw_data": {"...": "..."}, "raw_data_hex": "0a02...", "signature": ["c6f2..."]}}' ``` Response 200: ```json { "tx": "8e1c..." } ``` ### Get a wallet `GET /api/v2/wallets/non-custodial/{currency_slug}/`. Scope: `wallet`. Rate limit: 30 per minute. Your addresses for one coin with their balances, each address's encrypted private key, and current network fees (`network_fees`: sat/vB for BTC, gwei for ETH and ERC20). Decrypt the keys with the RSA private key from `account-rsa-keys` to sign transactions. ERC20 and BEP20 coins share your ETH addresses, TRC20 coins your TRX ones. **Rate limit:** 30 per minute Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `currency_slug` | path | string | yes | | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/wallets/non-custodial/ETH/' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "crypto_balance": "0.420000000000000000", "crypto_balance_base_unit": "420000000000000000", "confirmed_balance_base_unit": "420000000000000000", "fiat_balance": "2730.0000", "crypto_slug": "ETH", "local_currency_symbol": "AUD", "unit_amount_in_local_currency": "6500.0000", "address_balance_map": { "0x7D1f14c29825b052004A5eF02d8F0BC7E2c9A2A0": "0.42" }, "address_list": [ "0x7D1f14c29825b052004A5eF02d8F0BC7E2c9A2A0" ], "address_enc_keys": [ { "address": "0x7D1f14c29825b052004A5eF02d8F0BC7E2c9A2A0", "encrypted_private_key": "3b9f6c...", "encrypted_private_key_iv": "a41c09e2b7d35f18c6e04a92d1f7b305" } ], "network_fees": { "min": "1.4", "max": "5.2", "recommended": "4.4" }, "can_withdraw_free": true, "free_withdrawal_reset_seconds": 0 } ``` ### Publish a signed transaction `POST /api/v2/wallets/publish/`. Scope: `wallet`. Broadcasts a signed BTC, LTC, ETH, ERC20 or BEP20 transaction (hex) and returns its hash. TRX and TRC20 go to `broadcast-trx-tx/` instead. Request body: | Field | Type | Required | Description | | --- | --- | --- | --- | | `currency` | string | yes | | | `signed_tx` | string | | | ```bash curl --request POST 'https://api.localcoinswap.com/api/v2/wallets/publish/' \ --header "Authorization: ApiKey $LCS_API_KEY" \ --header 'Content-Type: application/json' \ --data-raw '{"currency": "ETH", "signed_tx": "0xf86b1b8504a817c80082520894d337..."}' ``` Response 200: ```json { "error": false, "tx": "0x9c1e4b7f0d2a6e83f5c1b2a49d7e0f36a8c5b1e2d4f6a7b8c9d0e1f2a3b4c5d6" } ``` ### Prepare a transaction to sign `POST /api/v2/wallets/unsigned/`. Scope: `wallet`. Rate limit: 1 per 10 seconds. Builds an unsigned transaction from one of your wallet addresses, for ETH, ERC20, BEP20 and TRC20 coins. Sign it with that address's private key (decrypt it with the keys from `account-rsa-keys`), then send it to `publish/`, or `broadcast-trx-tx/` for TRX and TRC20. BTC and LTC transactions are built and signed by your client from its UTXOs. `gas_price` (wei) and `gas_limit` are optional for ETH and ERC20; the server picks them otherwise. TRC20 sends can be free of network fees once you have completed a trade (see `can_withdraw_free` on the wallet). **Rate limit:** 1 per 10 seconds Request body: | Field | Type | Required | Description | | --- | --- | --- | --- | | `currency` | string | yes | Coin slug: ETH, ERC20, BEP20 and TRC20 coins. Build BTC and LTC transactions yourself and publish them. | | `amount` | string | yes | In whole coins, not base units. | | `from_address` | string | yes | One of your wallet addresses for this coin. | | `to_address` | string | yes | | | `swap_uuid` | string | | TRC20 only: one of your swaps, when sending to its pay-in address. | | `gas_price` | string | | Gas price in wei. Only for transactions on the ethereum blockchain | | `gas_limit` | string | | Only for transactions on the ethereum blockchain | ```bash curl --request POST 'https://api.localcoinswap.com/api/v2/wallets/unsigned/' \ --header "Authorization: ApiKey $LCS_API_KEY" \ --header 'Content-Type: application/json' \ --data-raw '{"currency": "ETH", "from_address": "0x7D1f14c29825b052004A5eF02d8F0BC7E2c9A2A0", "to_address": "0xD337f60a6589f56c44f72937Dc7b5C84dac2c14e", "amount": "0.05"}' ``` Response 200: ```json { "chainId": 1, "to": "0xD337f60a6589f56c44f72937Dc7b5C84dac2c14e", "value": 50000000000000000, "gas": 21000, "gasPrice": 4400000000, "nonce": 27 } ``` ## Referrals ### List your commission payouts `GET /api/v2/referrals/commission-payments/list/`. Scope: `read`. BTC payouts sent to your payout address, newest first, with their transaction hash. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `limit` | query | integer | | Number of results to return per page. | | `offset` | query | integer | | The initial index from which to return the results. | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/referrals/commission-payments/list/' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "active_page": 1, "count": 18, "next": null, "previous": null, "offset": 0, "limit": 5, "total_pages": 4, "results": [ { "id": 77, "uuid": "1e037200-8b42-4d78-affc-4b6f76ccf479", "to_address": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq", "tx_hash": "b6f6991d03df0e2e04dafffcd6bc418aac66049e2cd74b80f14ac86db1e3f0da", "amount": "0.003500000000000000", "created": "2026-10-01T02:00:00Z" } ] } ``` ### List the users you referred `GET /api/v2/referrals/my-referrals/`. Scope: `read`. Newest first, with the trades each completed and the BTC you earned from them. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `limit` | query | integer | | Number of results to return per page. | | `offset` | query | integer | | The initial index from which to return the results. | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/referrals/my-referrals/?limit=20' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "active_page": 1, "count": 18, "next": null, "previous": null, "offset": 0, "limit": 5, "total_pages": 4, "results": [ { "completed_trades": 14, "country_code": "AU", "date_joined": "2026-02-03T11:02:41.118204Z", "username": "hal_f", "user_uuid": "11ae74df-3dcb-4752-9114-c8b7774faa49", "earnings": "0.00084000" } ] } ``` ### Get your referral overview `GET /api/v2/referrals/overview/`. Scope: `read`. Your lifetime, pending and paid referral commission in BTC (and in your local currency under `fiat_values`), how many users you referred and how many of their trades earned you commission, and your payout settings. Changing the payout settings needs the `wallet` scope. ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/referrals/overview/' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "id": 412, "user": { "username": "satoshi_au", "user_uuid": "e98f2078-a4e7-4f59-908f-b5513be95bd6", "referral_code": "satoshi_au", "local_currency_symbol": "AUD", "hide_from_google": false }, "total_amount": "0.004120000000000000", "pending_amount": "0.000620000000000000", "paid_amount": "0.003500000000000000", "opt_in_next_payout": true, "btc_payout_address": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq", "show_on_leaderboard": false, "label": null, "fiat_values": { "total_amount": 650.96, "pending_amount": 97.96, "paid_amount": 553.0 }, "total_referred_users": 9, "total_referred_trades": 37 } ``` ### List your trade commissions `GET /api/v2/referrals/trade-commissions/list/`. Scope: `read`. One row per trade by a user you referred, newest first: the BTC commission, its `percent` of the trade fee, and whether it has been paid out yet. Parameters: | Name | In | Type | Required | Description | | --- | --- | --- | --- | --- | | `limit` | query | integer | | Number of results to return per page. | | `offset` | query | integer | | The initial index from which to return the results. | ```bash curl --request GET 'https://api.localcoinswap.com/api/v2/referrals/trade-commissions/list/?limit=20' \ --header "Authorization: ApiKey $LCS_API_KEY" ``` Response 200: ```json { "active_page": 1, "count": 18, "next": null, "previous": null, "offset": 0, "limit": 5, "total_pages": 4, "results": [ { "id": 9021, "ref_user": { "username": "hal_f", "timezone": "Australia/Adelaide", "local_currency_symbol": "AUD", "bio": "", "is_staff": false, "is_email_verified": true, "last_seen": 1793817600, "cached_last_seen": 1793817600, "profile_image": "https://pwa-cdn.localcoinswap.com/default_user.jpg", "activity_status": "active", "activity_tooltip": "online", "feedback_score": "100.00000", "completed_trades": 14, "trades_30d": 3, "platform_volume": 3600, "platform_volume_30d": 750, "avg_response_time": 6, "user_uuid": "11ae74df-3dcb-4752-9114-c8b7774faa49", "date_joined": "2026-02-03T11:02:41.118204Z", "is_phone_verified": true, "is_legacy": false, "primary_language": "en", "lang_list": "en", "times_blocked": 0, "times_followed": 0, "imported_total_trades": null, "imported_volume": null, "on_holiday": false, "non_custodial": true, "xp_level": "APPRENTICE", "xp": 14, "stats": { "trades_started": 16, "trades_started_completed": 14 } }, "trade": { "uuid": "f3c6120b-d63a-4a1f-9d18-f181c4be29c2", "time_created": 1793830445, "coin_currency": { "title": "Ethereum", "symbol": "ETH", "token_standard": null, "symbol_filename": "eth.svg", "is_crypto": true, "slug": "ETH" }, "fiat_currency": { "title": "Australian Dollar", "symbol": "AUD", "token_standard": null, "symbol_filename": null, "is_crypto": false, "slug": "australian-dollar" } }, "amount": "0.000120000000000000", "percent": "20.000000000000000000", "is_paid": false, "created": "2026-11-03T09:41:55.120000Z" } ] } ```