# Public API Documentation

Source: https://autoplus.gg/docs/public-api



## API Reference [#api-reference]

The AutoPlus public API uses HTTPS and JSON. It provides public AutoPlus statistics and user-authenticated endpoints for opening and automating escrow trades.

### Base URL [#base-url]

<Block color="gray" padding="p-2" className="mt-2">
  <code>
    [https://api.autoplus.gg/v1](https://api.autoplus.gg/v1)
  </code>
</Block>

Version `v1` is currently the only available API version.

### Authentication [#authentication]

Every trade endpoint requires an API token associated with one Discord user. Send it using the bearer authentication scheme:

<Block color="gray" padding="p-2" className="mt-2">
  <code>
    Authorization: Bearer YOUR_API_TOKEN
  </code>
</Block>

Open a support ticket in the [AutoPlus Discord server](https://discord.gg/autoplus) to request an API token. Keep it private and use it only from a trusted server.

The `/servers`, `/stats`, and `/transactions` endpoints do not require authentication.

### Request format [#request-format]

Requests with a body must include `Content-Type: application/json`.

Discord user IDs, guild IDs, and trade IDs are JSON strings. Timestamps are integer Unix timestamps in seconds. Optional response fields are omitted when they have no value.

### Idempotency [#idempotency]

The following endpoints require an `Idempotency-Key` header:

* `POST /guilds/{guildId}/trades`
* `POST /trades/{id}/confirm-action`
* `POST /trades/{id}/confirm-claim`

The key must contain 8 to 128 characters. Use a unique random value for each new operation. If a request times out, retry the identical request with the same key. Reusing a key with different request data returns `409 Conflict`.

### Crypto type [#crypto]

The `Crypto` type identifies both the asset and, for tokens, its network:

<Block color="gray" padding="p-2" className="mt-2">
  <code>
    "ltc" | "sol" | "eth" | "bnb" | "btc" | "pol" | "sol_usdt" | "sol_usdc" | "eth_usdt" | "eth_usdc" | "bnb_usdt" | "bnb_usdc" | "pol_usdt" | "pol_usdc" | "pol_usdce"
  </code>
</Block>

Availability also depends on the networks currently enabled by AutoPlus.

### Trade automation rules [#trade-automation-rules]

* The authenticated user must be the sender or receiver of every trade they access.
* Route parameter `id` is the Discord trade thread ID returned by trade creation, not the incremental `tradeId`.
* Identification and terms confirmations must repeat the exact values from the latest trade response.
* Only the sender can release funds. Only the receiver can return funds.
* Release, return, and claim operations use short-lived confirmation challenges.
* A successful claim confirmation returns `202 Accepted`; poll trade events for the final result.
* The API can provide a reduction return address when a trade is already in `waitingReduceAmountAddress`, but it cannot initiate a reduction.

## Public Endpoints [#public-endpoints]

### GET /servers \[toc] [#servers-endpoint]

<Endpoint id="servers-endpoint" method="get" endpoint="/servers">
  <p>
    Get the list of Discord servers AutoPlus is in.
  </p>

  <h3 id="servers-response" className="text-xl font-bold inline-block scroll-mt-16">
    Response Structure
  </h3>

  <p className="text-sm italic">
    Each object in the returned array has this structure:
  </p>

  <StructureTable
    data="[
  { field: &#x22;id&#x22;, type: &#x22;string&#x22;, description: &#x22;Discord server ID.&#x22; },
  { field: &#x22;name&#x22;, type: &#x22;string&#x22;, description: &#x22;Discord server name.&#x22; },
  { field: &#x22;icon&#x22;, type: &#x22;string&#x22;, description: &#x22;Server icon URL.&#x22; }
]"
  />
</Endpoint>

### GET /stats \[toc] [#stats-endpoint]

<Endpoint id="stats-endpoint" method="get" endpoint="/stats">
  <p>
    Get global AutoPlus trade statistics.
  </p>

  <h3 id="stats-response" className="text-xl font-bold inline-block scroll-mt-16">
    Response Structure
  </h3>

  <StructureTable
    data="[
  { field: &#x22;trades&#x22;, type: &#x22;number&#x22;, description: &#x22;Total completed and canceled trades.&#x22; },
  { field: &#x22;volume&#x22;, type: &#x22;number&#x22;, description: &#x22;Total completed and canceled volume in USD.&#x22; },
  { field: &#x22;canceledTrades&#x22;, type: &#x22;number&#x22;, description: &#x22;Total canceled trades.&#x22; },
  { field: &#x22;canceledVolume&#x22;, type: &#x22;number&#x22;, description: &#x22;Total canceled volume in USD.&#x22; },
  { field: &#x22;trades24h&#x22;, type: &#x22;number&#x22;, description: &#x22;Trades recorded during the last 24 hours.&#x22; },
  { field: &#x22;volume24h&#x22;, type: &#x22;number&#x22;, description: &#x22;Volume recorded during the last 24 hours in USD.&#x22; }
]"
  />
</Endpoint>

### GET /transactions \[toc] [#transactions-endpoint]

<Endpoint id="transactions-endpoint" method="get" endpoint="/transactions">
  <p>
    Get the 10 most recent public AutoPlus transactions.
  </p>

  <h3 id="transactions-response" className="text-xl font-bold inline-block scroll-mt-16">
    Response Structure
  </h3>

  <p className="text-sm italic">
    Each object in the returned array has this structure:
  </p>

  <StructureTable
    data="[
  { field: &#x22;crypto&#x22;, type: &#x22;Crypto&#x22;, description: &#x22;Crypto used by the trade.&#x22; },
  { field: &#x22;amount&#x22;, type: &#x22;number&#x22;, description: &#x22;Transaction amount in the selected crypto.&#x22; },
  { field: &#x22;amountUsd&#x22;, type: &#x22;number&#x22;, description: &#x22;Transaction amount valued in USD.&#x22; },
  { field: &#x22;txid&#x22;, type: &#x22;string&#x22;, description: &#x22;Incoming escrow transaction ID.&#x22; },
  { field: &#x22;txid2&#x22;, type: &#x22;string&#x22;, description: &#x22;Settlement transaction ID.&#x22; },
  { field: &#x22;receivedAt&#x22;, type: &#x22;number&#x22;, description: &#x22;Timestamp when escrow received the funds.&#x22; },
  { field: &#x22;closedAt&#x22;, type: &#x22;number&#x22;, description: &#x22;Timestamp when the trade closed.&#x22; }
]"
  />
</Endpoint>

## Authenticated Endpoints [#authenticated-endpoints]

All endpoints in this section require bearer authentication.

### POST /guilds/{"{guildId}"}/trades \[toc] [#create-trade-endpoint]

<Endpoint id="create-trade-endpoint" method="post" endpoint="/guilds/{guildId}/trades">
  <p>
    Create a trade in an API-enabled Discord server.
  </p>

  <p className="text-sm italic">
    Requires bearer authentication and an Idempotency-Key header.
  </p>

  <h3 id="create-trade-request" className="text-xl font-bold inline-block scroll-mt-16">
    Request Structure
  </h3>

  <StructureTable
    data="[
  { field: &#x22;crypto&#x22;, type: &#x22;Crypto&#x22;, description: &#x22;Crypto and network used by the trade.&#x22; },
  { field: &#x22;sender&#x22;, type: &#x22;string&#x22;, description: &#x22;Discord user ID of the participant funding escrow.&#x22; },
  { field: &#x22;receiver&#x22;, type: &#x22;string&#x22;, description: &#x22;Discord user ID of the participant receiving released funds.&#x22; }
]"
  />

  <p>
    The authenticated user must be either 

    <code>sender</code>

     or 

    <code>receiver</code>

    . Both participants must be different, non-bot members of the guild.
  </p>

  <h3 id="create-trade-response" className="text-xl font-bold inline-block scroll-mt-16">
    Response Structure — 201 Created
  </h3>

  <StructureTable
    data="[
  { field: &#x22;id&#x22;, type: &#x22;string&#x22;, description: &#x22;Discord thread ID used as {id} in every other trade endpoint.&#x22; },
  { field: &#x22;tradeId&#x22;, type: &#x22;number&#x22;, description: &#x22;Human-readable incremental trade number.&#x22; }
]"
  />
</Endpoint>

### GET /trades/{"{id}"} \[toc] [#get-trade-endpoint]

<Endpoint id="get-trade-endpoint" method="get" endpoint="/trades/{id}">
  <p>
    Get the current public representation of a trade.
  </p>

  <p className="text-sm italic">
    Requires bearer authentication. The caller must be a participant.
  </p>

  <h3 id="get-trade-response" className="text-xl font-bold inline-block scroll-mt-16">
    Response — 200 OK
  </h3>

  <p>
    Returns a 

    <a href="#trade-structure" className="text-primary hover:underline">Trade</a>

    . The escrow deposit address is exposed only to the sender.
  </p>
</Endpoint>

### GET /trades/{"{id}"}/events \[toc] [#trade-events-endpoint]

<Endpoint id="trade-events-endpoint" method="get" endpoint="/trades/{id}/events">
  <p>
    Poll durable trade events using a client-managed offset.
  </p>

  <p className="text-sm italic">
    Requires bearer authentication. Maximum two concurrent polls per token and trade.
  </p>

  <h3 id="trade-events-query" className="text-xl font-bold inline-block scroll-mt-16">
    Query Parameters
  </h3>

  <StructureTable
    data="[
  { field: &#x22;offset?&#x22;, type: &#x22;number&#x22;, description: &#x22;Last processed event ID. Omit to receive a current snapshot.&#x22; },
  { field: &#x22;timeout?&#x22;, type: &#x22;number&#x22;, description: &#x22;Long-poll timeout in seconds. Defaults to 55 and is capped at 60.&#x22; }
]"
  />

  <h3 id="trade-events-response" className="text-xl font-bold inline-block scroll-mt-16">
    Response Structure — 200 OK
  </h3>

  <StructureTable
    data="[
  { field: &#x22;events&#x22;, type: &#x22;TradeEvent[]&#x22;, description: &#x22;Events after the supplied offset, in chronological order.&#x22; },
  { field: &#x22;nextOffset&#x22;, type: &#x22;number&#x22;, description: &#x22;Offset to send with the next poll.&#x22; }
]"
  />

  <p>
    An empty 

    <code>events</code>

     array means the poll timed out without a new event. Repeat the same offset. If retained history expired, the API returns a current 

    <code>trade.snapshot</code>

    .
  </p>
</Endpoint>

### PUT /trades/{"{id}"}/identification \[toc] [#select-identification-endpoint]

<Endpoint id="select-identification-endpoint" method="put" endpoint="/trades/{id}/identification">
  <p>
    Select the authenticated user's role after identification was reset.
  </p>

  <p className="text-sm italic">
    Valid only while the trade is waiting for identification.
  </p>

  <h3 id="select-identification-request" className="text-xl font-bold inline-block scroll-mt-16">
    Request Structure
  </h3>

  <StructureTable
    data="[
  { field: &#x22;role&#x22;, type: '&#x22;sender&#x22; | &#x22;receiver&#x22;', description: &#x22;Role assigned to the authenticated user.&#x22; },
  { field: &#x22;revision&#x22;, type: &#x22;number&#x22;, description: &#x22;Current identificationRevision from the trade.&#x22; }
]"
  />

  <h3 id="select-identification-response" className="text-xl font-bold inline-block scroll-mt-16">
    Response — 200 OK
  </h3>

  <p>
    Returns the updated 

    <a href="#trade-structure" className="text-primary hover:underline">Trade</a>

    .
  </p>
</Endpoint>

### POST /trades/{"{id}"}/identification/confirm \[toc] [#confirm-identification-endpoint]

<Endpoint id="confirm-identification-endpoint" method="post" endpoint="/trades/{id}/identification/confirm">
  <p>
    Confirm the exact current sender and receiver assignment.
  </p>

  <h3 id="confirm-identification-request" className="text-xl font-bold inline-block scroll-mt-16">
    Request Structure
  </h3>

  <StructureTable
    data="[
  { field: &#x22;sender&#x22;, type: &#x22;string&#x22;, description: &#x22;Exact current sender Discord user ID.&#x22; },
  { field: &#x22;receiver&#x22;, type: &#x22;string&#x22;, description: &#x22;Exact current receiver Discord user ID.&#x22; },
  { field: &#x22;revision&#x22;, type: &#x22;number&#x22;, description: &#x22;Current identificationRevision from the trade.&#x22; }
]"
  />

  <h3 id="confirm-identification-response" className="text-xl font-bold inline-block scroll-mt-16">
    Response — 200 OK
  </h3>

  <p>
    Returns the updated 

    <a href="#trade-structure" className="text-primary hover:underline">Trade</a>

    . After both participants confirm the same revision, the trade moves to 

    <code>waitingTermsAcceptance</code>

    .
  </p>
</Endpoint>

### POST /trades/{"{id}"}/identification/reset \[toc] [#reset-identification-endpoint]

<Endpoint id="reset-identification-endpoint" method="post" endpoint="/trades/{id}/identification/reset">
  <p>
    Clear both role assignments and their confirmations.
  </p>

  <h3 id="reset-identification-request" className="text-xl font-bold inline-block scroll-mt-16">
    Request Structure
  </h3>

  <StructureTable
    data="[
  { field: &#x22;sender&#x22;, type: &#x22;null&#x22;, description: &#x22;Must be null.&#x22; },
  { field: &#x22;receiver&#x22;, type: &#x22;null&#x22;, description: &#x22;Must be null.&#x22; },
  { field: &#x22;revision&#x22;, type: &#x22;number&#x22;, description: &#x22;Current identificationRevision from the trade.&#x22; }
]"
  />

  <h3 id="reset-identification-response" className="text-xl font-bold inline-block scroll-mt-16">
    Response — 200 OK
  </h3>

  <p>
    Returns the updated 

    <a href="#trade-structure" className="text-primary hover:underline">Trade</a>

    .
  </p>
</Endpoint>

### PUT /trades/{"{id}"}/terms \[toc] [#set-terms-endpoint]

<Endpoint id="set-terms-endpoint" method="put" endpoint="/trades/{id}/terms">
  <p>
    Set, replace, or clear the authenticated user's terms.
  </p>

  <p className="text-sm italic">
    Valid only while the trade is waiting for terms acceptance.
  </p>

  <h3 id="set-terms-request" className="text-xl font-bold inline-block scroll-mt-16">
    Request Structure
  </h3>

  <StructureTable
    data="[
  { field: &#x22;text&#x22;, type: &#x22;string | null&#x22;, description: &#x22;Terms text, up to 896 characters. Use null to clear it.&#x22; },
  { field: &#x22;version&#x22;, type: &#x22;string&#x22;, description: &#x22;Current terms.version from the trade.&#x22; }
]"
  />

  <p>
    Each update creates a new terms version and clears existing confirmations.
  </p>

  <h3 id="set-terms-response" className="text-xl font-bold inline-block scroll-mt-16">
    Response — 200 OK
  </h3>

  <p>
    Returns the updated 

    <a href="#trade-structure" className="text-primary hover:underline">Trade</a>

    .
  </p>
</Endpoint>

### POST /trades/{"{id}"}/terms/confirm \[toc] [#confirm-terms-endpoint]

<Endpoint id="confirm-terms-endpoint" method="post" endpoint="/trades/{id}/terms/confirm">
  <p>
    Confirm the complete current terms exactly as returned by the API.
  </p>

  <h3 id="confirm-terms-request" className="text-xl font-bold inline-block scroll-mt-16">
    Request Structure
  </h3>

  <StructureTable
    data="[
  { field: &#x22;sender&#x22;, type: &#x22;string | null&#x22;, description: &#x22;Exact current sender terms, or null when absent.&#x22; },
  { field: &#x22;receiver&#x22;, type: &#x22;string | null&#x22;, description: &#x22;Exact current receiver terms, or null when absent.&#x22; },
  { field: &#x22;version&#x22;, type: &#x22;string&#x22;, description: &#x22;Exact current terms version.&#x22; }
]"
  />

  <h3 id="confirm-terms-response" className="text-xl font-bold inline-block scroll-mt-16">
    Response — 200 OK
  </h3>

  <p>
    Returns the updated 

    <a href="#trade-structure" className="text-primary hover:underline">Trade</a>

    . After both participants confirm, the trade moves to 

    <code>waitingReceive</code>

    . The sender's response then includes the escrow deposit address.
  </p>
</Endpoint>

### POST /trades/{"{id}"}/action \[toc] [#request-action-endpoint]

<Endpoint id="request-action-endpoint" method="post" endpoint="/trades/{id}/action">
  <p>
    Request a short-lived confirmation challenge for releasing or returning funds.
  </p>

  <p className="text-sm italic">
    Valid at waitingAction. Sender may release; receiver may return.
  </p>

  <h3 id="request-action-request" className="text-xl font-bold inline-block scroll-mt-16">
    Request Structure
  </h3>

  <StructureTable
    data="[
  { field: &#x22;action&#x22;, type: '&#x22;release&#x22; | &#x22;return&#x22;', description: &#x22;Requested fund action.&#x22; }
]"
  />

  <h3 id="request-action-response" className="text-xl font-bold inline-block scroll-mt-16">
    Response Structure — 201 Created
  </h3>

  <StructureTable
    data="[
  { field: &#x22;action&#x22;, type: '&#x22;release&#x22; | &#x22;return&#x22;', description: &#x22;Action bound to the challenge.&#x22; },
  { field: &#x22;recipient&#x22;, type: &#x22;string&#x22;, description: &#x22;Discord user ID that will receive the funds.&#x22; },
  { field: &#x22;confirmationCode&#x22;, type: &#x22;string&#x22;, description: &#x22;Secret confirmation code valid for 60 seconds.&#x22; },
  { field: &#x22;expiresAt&#x22;, type: &#x22;number&#x22;, description: &#x22;Challenge expiration timestamp.&#x22; }
]"
  />
</Endpoint>

### POST /trades/{"{id}"}/confirm-action \[toc] [#confirm-action-endpoint]

<Endpoint id="confirm-action-endpoint" method="post" endpoint="/trades/{id}/confirm-action">
  <p>
    Confirm a release or return challenge.
  </p>

  <p className="text-sm italic">
    Requires an Idempotency-Key header.
  </p>

  <h3 id="confirm-action-request" className="text-xl font-bold inline-block scroll-mt-16">
    Request Structure
  </h3>

  <StructureTable
    data="[
  { field: &#x22;action&#x22;, type: '&#x22;release&#x22; | &#x22;return&#x22;', description: &#x22;Exact action returned by the challenge.&#x22; },
  { field: &#x22;recipient&#x22;, type: &#x22;string&#x22;, description: &#x22;Exact recipient returned by the challenge.&#x22; },
  { field: &#x22;confirmationCode&#x22;, type: &#x22;string&#x22;, description: &#x22;Confirmation code returned by the challenge.&#x22; }
]"
  />

  <h3 id="confirm-action-response" className="text-xl font-bold inline-block scroll-mt-16">
    Response — 200 OK
  </h3>

  <p>
    Returns the updated 

    <a href="#trade-structure" className="text-primary hover:underline">Trade</a>

    . Release moves the trade to 

    <code>waitingAddress</code>

    ; return moves it to 

    <code>waitingReturnAddress</code>

    .
  </p>
</Endpoint>

### POST /trades/{"{id}"}/claim-funds \[toc] [#claim-funds-endpoint]

<Endpoint id="claim-funds-endpoint" method="post" endpoint="/trades/{id}/claim-funds">
  <p>
    Request a confirmation challenge for a payout, return, or reduction-return address.
  </p>

  <p className="text-sm italic">
    Receiver claims at waitingAddress. Sender claims at waitingReturnAddress or waitingReduceAmountAddress.
  </p>

  <h3 id="claim-funds-request" className="text-xl font-bold inline-block scroll-mt-16">
    Request Structure
  </h3>

  <StructureTable
    data="[
  { field: &#x22;address&#x22;, type: &#x22;string&#x22;, description: &#x22;Destination address valid for the trade crypto.&#x22; },
  { field: &#x22;crypto&#x22;, type: &#x22;Crypto&#x22;, description: &#x22;Exact crypto value from the trade.&#x22; }
]"
  />

  <h3 id="claim-funds-response" className="text-xl font-bold inline-block scroll-mt-16">
    Response Structure — 201 Created
  </h3>

  <StructureTable
    data="[
  { field: &#x22;address&#x22;, type: &#x22;string&#x22;, description: &#x22;Address bound to the challenge.&#x22; },
  { field: &#x22;crypto&#x22;, type: &#x22;Crypto&#x22;, description: &#x22;Crypto bound to the challenge.&#x22; },
  { field: &#x22;confirmationCode&#x22;, type: &#x22;string&#x22;, description: &#x22;Secret confirmation code valid for 60 seconds.&#x22; },
  { field: &#x22;expiresAt&#x22;, type: &#x22;number&#x22;, description: &#x22;Challenge expiration timestamp.&#x22; },
  { field: &#x22;btcFeeOptions?&#x22;, type: &#x22;BtcFeeOption[]&#x22;, description: &#x22;Available fee choices for BTC claims only.&#x22; }
]"
  />
</Endpoint>

### POST /trades/{"{id}"}/confirm-claim \[toc] [#confirm-claim-endpoint]

<Endpoint id="confirm-claim-endpoint" method="post" endpoint="/trades/{id}/confirm-claim">
  <p>
    Confirm the destination and begin the fund transfer.
  </p>

  <p className="text-sm italic">
    Requires an Idempotency-Key header.
  </p>

  <h3 id="confirm-claim-request" className="text-xl font-bold inline-block scroll-mt-16">
    Request Structure
  </h3>

  <StructureTable
    data="[
  { field: &#x22;address&#x22;, type: &#x22;string&#x22;, description: &#x22;Exact original address returned by the challenge.&#x22; },
  { field: &#x22;crypto&#x22;, type: &#x22;Crypto&#x22;, description: &#x22;Exact crypto returned by the challenge.&#x22; },
  { field: &#x22;confirmationCode&#x22;, type: &#x22;string&#x22;, description: &#x22;Confirmation code returned by the challenge.&#x22; },
  { field: &#x22;btcFee?&#x22;, type: &#x22;BtcFee&#x22;, description: &#x22;One unchanged BTC fee option. Omit for non-BTC trades.&#x22; }
]"
  />

  <h3 id="confirm-claim-response" className="text-xl font-bold inline-block scroll-mt-16">
    Response Structure — 202 Accepted
  </h3>

  <StructureTable
    data="[
  { field: &#x22;executionId&#x22;, type: &#x22;string&#x22;, description: &#x22;Fund execution identifier.&#x22; },
  { field: &#x22;status&#x22;, type: '&#x22;pending&#x22;', description: &#x22;The transfer was accepted for asynchronous processing.&#x22; }
]"
  />

  <p>
    Continue polling trade events. 

    <code>trade.fund.execution.updated</code>

     reports execution progress and 

    <code>trade.closed</code>

     reports the final release or return.
  </p>
</Endpoint>

## Response Structures [#response-structures]

### Trade [#trade-structure]

<StructureTable
  data="[
{ field: &#x22;id&#x22;, type: &#x22;string&#x22;, description: &#x22;Discord trade thread ID used in API routes.&#x22; },
{ field: &#x22;tradeId&#x22;, type: &#x22;number&#x22;, description: &#x22;Human-readable incremental trade number.&#x22; },
{ field: &#x22;revision&#x22;, type: &#x22;number&#x22;, description: &#x22;Current public trade revision.&#x22; },
{ field: &#x22;openedAt&#x22;, type: &#x22;number&#x22;, description: &#x22;Timestamp when the trade opened.&#x22; },
{ field: &#x22;crypto&#x22;, type: &#x22;Crypto&#x22;, description: &#x22;Crypto and network selected for the trade.&#x22; },
{ field: &#x22;status&#x22;, type: &#x22;TradeStatus&#x22;, description: &#x22;Current trade lifecycle status.&#x22; },
{ field: &#x22;sender?&#x22;, type: &#x22;string&#x22;, description: &#x22;Sender Discord user ID. Omitted while identification is reset.&#x22; },
{ field: &#x22;receiver?&#x22;, type: &#x22;string&#x22;, description: &#x22;Receiver Discord user ID. Omitted while identification is reset.&#x22; },
{ field: &#x22;identificationRevision&#x22;, type: &#x22;number&#x22;, description: &#x22;Revision used for identification updates and confirmations.&#x22; },
{ field: &#x22;identificationConfirmedBy&#x22;, type: &#x22;string[]&#x22;, description: &#x22;Participant IDs that confirmed the current identification.&#x22; },
{ field: &#x22;terms?&#x22;, type: &#x22;TradeTerms&#x22;, description: &#x22;Current terms and confirmation state.&#x22; },
{ field: &#x22;address?&#x22;, type: &#x22;string&#x22;, description: &#x22;Escrow deposit address. Exposed only to the sender.&#x22; },
{ field: &#x22;fees?&#x22;, type: &#x22;number&#x22;, description: &#x22;Network fees in the selected crypto.&#x22; },
{ field: &#x22;feesUsd?&#x22;, type: &#x22;number&#x22;, description: &#x22;Estimated network fees in USD.&#x22; },
{ field: &#x22;amount?&#x22;, type: &#x22;number&#x22;, description: &#x22;Amount received by escrow in the selected crypto.&#x22; },
{ field: &#x22;amountUsd?&#x22;, type: &#x22;number&#x22;, description: &#x22;Received amount valued in USD.&#x22; },
{ field: &#x22;receivedAt?&#x22;, type: &#x22;number&#x22;, description: &#x22;Timestamp when the deposit was received.&#x22; },
{ field: &#x22;txid?&#x22;, type: &#x22;string&#x22;, description: &#x22;Incoming deposit transaction ID.&#x22; },
{ field: &#x22;settlementTxid?&#x22;, type: &#x22;string&#x22;, description: &#x22;Final payout or return transaction ID.&#x22; },
{ field: &#x22;fundControlsLocked?&#x22;, type: &#x22;boolean&#x22;, description: &#x22;True when fund actions are temporarily locked.&#x22; }
]"
/>

### TradeStatus [#trade-status-structure]

<Block color="gray" padding="p-2" className="mt-2">
  <code>
    "waitingIdentification" | "waitingTermsAcceptance" | "waitingReceive" | "waitingConfirmations" | "waitingAction" | "waitingReduceAmountAddress" | "waitingReturnAddress" | "waitingAddress" | "completed"
  </code>
</Block>

### TradeTerms [#trade-terms-structure]

<StructureTable
  data="[
{ field: &#x22;version&#x22;, type: &#x22;string&#x22;, description: &#x22;Opaque version required for terms updates and confirmations.&#x22; },
{ field: &#x22;sender&#x22;, type: &#x22;TradeTermsSide&#x22;, description: &#x22;Sender terms and confirmation state.&#x22; },
{ field: &#x22;receiver&#x22;, type: &#x22;TradeTermsSide&#x22;, description: &#x22;Receiver terms and confirmation state.&#x22; }
]"
/>

Each `TradeTermsSide` contains:

<StructureTable
  data="[
{ field: &#x22;text?&#x22;, type: &#x22;string&#x22;, description: &#x22;Terms text. Omitted when no terms were set.&#x22; },
{ field: &#x22;confirmed&#x22;, type: &#x22;boolean&#x22;, description: &#x22;Whether this participant confirmed the current version.&#x22; },
{ field: &#x22;confirmedAt?&#x22;, type: &#x22;number&#x22;, description: &#x22;Confirmation timestamp.&#x22; }
]"
/>

### TradeEvent [#trade-event-structure]

<StructureTable
  data="[
{ field: &#x22;id&#x22;, type: &#x22;number&#x22;, description: &#x22;Monotonically increasing event ID within the trade.&#x22; },
{ field: &#x22;type&#x22;, type: &#x22;TradeEventType&#x22;, description: &#x22;Event category.&#x22; },
{ field: &#x22;occurredAt&#x22;, type: &#x22;number&#x22;, description: &#x22;Timestamp when the event occurred.&#x22; },
{ field: &#x22;changes&#x22;, type: &#x22;TradeEventChanges&#x22;, description: &#x22;Changed public fields and optional status or outcome information.&#x22; },
{ field: &#x22;trade&#x22;, type: &#x22;Trade&#x22;, description: &#x22;Complete API trade snapshot at this event.&#x22; }
]"
/>

<Block color="gray" padding="p-2" className="mt-2">
  <code>
    "trade.snapshot" | "trade.created" | "trade.identification.updated" | "trade.terms.updated" | "trade.status.changed" | "trade.fund.execution.updated" | "trade.support.updated" | "trade.closed"
  </code>
</Block>

Events are retained for at least one hour. A closed trade may no longer be returned by `GET /trades/{id}`, but its retained event stream remains available to its participants.

### BTC fee types [#btc-fee-structure]

<StructureTable
  data="[
{ field: &#x22;priority&#x22;, type: '&#x22;high&#x22; | &#x22;medium&#x22; | &#x22;none&#x22;', description: &#x22;Fee priority returned by AutoPlus.&#x22; },
{ field: &#x22;satPerVbyte&#x22;, type: &#x22;number&#x22;, description: &#x22;Fee rate that must be returned unchanged.&#x22; },
{ field: &#x22;estimatedCostUsd&#x22;, type: &#x22;number&#x22;, description: &#x22;Estimated transfer cost. Present in BtcFeeOption responses only.&#x22; }
]"
/>

## Errors [#errors]

API errors use the HTTP status code as the primary result and return:

<StructureTable
  data="[
{ field: &#x22;code&#x22;, type: &#x22;string&#x22;, description: &#x22;Stable machine-readable error code.&#x22; },
{ field: &#x22;message&#x22;, type: &#x22;string&#x22;, description: &#x22;Human-readable error description.&#x22; },
{ field: &#x22;requestId&#x22;, type: &#x22;string&#x22;, description: &#x22;Request identifier to provide when contacting support.&#x22; },
{ field: &#x22;details?&#x22;, type: &#x22;object&#x22;, description: &#x22;Optional safe machine-readable context.&#x22; }
]"
/>

Common status codes:

<StructureTable
  data="[
{ field: &#x22;400&#x22;, type: &#x22;Bad Request&#x22;, description: &#x22;Malformed JSON, missing field, or invalid field type.&#x22; },
{ field: &#x22;401&#x22;, type: &#x22;Unauthorized&#x22;, description: &#x22;Bearer token is missing, invalid, expired, or revoked.&#x22; },
{ field: &#x22;403&#x22;, type: &#x22;Forbidden&#x22;, description: &#x22;The authenticated user or guild cannot perform the operation.&#x22; },
{ field: &#x22;404&#x22;, type: &#x22;Not Found&#x22;, description: &#x22;Trade does not exist or the caller is not a participant.&#x22; },
{ field: &#x22;409&#x22;, type: &#x22;Conflict&#x22;, description: &#x22;Wrong state, stale revision, confirmation mismatch, or idempotency conflict.&#x22; },
{ field: &#x22;410&#x22;, type: &#x22;Gone&#x22;, description: &#x22;Confirmation challenge expired. Request a new challenge.&#x22; },
{ field: &#x22;422&#x22;, type: &#x22;Unprocessable Content&#x22;, description: &#x22;Invalid address, crypto, or semantic request data.&#x22; },
{ field: &#x22;429&#x22;, type: &#x22;Too Many Requests&#x22;, description: &#x22;A rate or concurrent polling limit was exceeded.&#x22; },
{ field: &#x22;500&#x22;, type: &#x22;Internal Server Error&#x22;, description: &#x22;Unexpected internal failure.&#x22; },
{ field: &#x22;503&#x22;, type: &#x22;Service Unavailable&#x22;, description: &#x22;A required AutoPlus dependency is unavailable.&#x22; }
]"
/>

On `stale_revision` or `confirmation_mismatch`, fetch the trade again and compare the new values before asking the user to confirm them. Never automatically confirm changed roles, terms, recipients, crypto, or addresses.
