> ## Documentation Index
> Fetch the complete documentation index at: https://developer.uphold.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Execute a send via the REST API

> Move the same asset between two users in the same organization using the Uphold quote → transaction flow, initiated on behalf of the sender.

A **send** transfers an asset from one user's account to another user's account holding the **same asset**, where both users belong to the **same organization** (for example, 50 USD from User A to User B).

Sends follow a simple two-step flow:

1. **Create a quote** on behalf of the sender.
2. **Create a transaction** from that quote.

Because both accounts hold the same asset, the amount sent and the amount received are always identical — there's no conversion or exchange rate involved.

## Prerequisites

Before creating sends:

* The **sender** must have completed onboarding and have the **`sends`** capability enabled.
* The **recipient** must have completed onboarding and have the **`receives`** capability enabled.
* The sender and recipient must belong to the **same organization**.

Recipient discovery is not provided by the Enterprise API and must be implemented by your application (for example through QR codes, contact lists, usernames, or invitation flows).

Verify capabilities using [List capabilities](/rest-apis/core-api/capabilities/list-user-capabilities):

```http theme={null}
GET /core/users/{userId}/capabilities
```

```json theme={null}
{ "code": "sends", "enabled": true, "restrictions": [], "requirements": [] }

{ "code": "receives", "enabled": true, "restrictions": [], "requirements": [] }
```

<Info>
  **Both accounts must be denominated in the same asset.**

  A send moves a single asset between two same-asset accounts (e.g. USD → USD). The recipient does not need an existing balance — a freshly created, zero-balance account in that asset can receive the send.
</Info>

## Walkthrough

<Tip>Prefer to click through the flow? See the [interactive send walkthrough](/developer-guides/trade-and-send/send/interactive-send-flow) for a visual step-by-step guide.</Tip>

## Identify the sender and recipient accounts

A send involves two different users:

* **Origin account** — the sender's account.
* **Destination account** — the recipient's account.

The destination account must belong to a different `ownerId` than the sender.

Before creating a quote, verify the recipient account exists using [Get account](/rest-apis/core-api/accounts/get-account).

```http theme={null}
GET /core/accounts/{accountId}
```

```json theme={null}
{
  "account": {
    "id": "d9f7a3c1-2b8e-4f5d-9c6a-1e2b3c4d5e6f",
    "label": "Jane's USD account",
    "asset": "USD",
    "balance": { "total": "100.00", "available": "100.00" }
  }
}
```

The send quote must be created using:

```http theme={null}
X-On-Behalf-Of: <sender userId>
```

This header identifies the sender and determines which user's balances and permissions are evaluated.

<Info>
  Do not expose recipient `ownerId` values directly to end users.

  Instead, resolve account ownership server-side and display a friendly identifier such as a name, username, or contact entry.
</Info>

## Create a quote

Create a quote on behalf of the sender.

The quote acts as a confirmation handle and validation step before funds move. Because both accounts hold the same asset, the amounts in the quote are always identical.

```http theme={null}
POST /core/transactions/quote
X-On-Behalf-Of: 5feba1e3-3f14-4fd9-b00d-f386df83042f
{
  "origin": {
    "type": "account",
    "id": "11de2405-1f1f-4a6e-8a39-acd97dc7f3ec"
  },
  "destination": {
    "type": "account",
    "id": "d9f7a3c1-2b8e-4f5d-9c6a-1e2b3c4d5e6f"
  },
  "denomination": {
    "asset": "USD",
    "amount": "50"
  }
}
```

```json [expandable] theme={null}
{
  "quote": {
    "id": "b7e4d2c1-9f3a-4b5e-8d7c-2e1f3a4b5c6d",
    "expiresAt": "2026-05-29T14:02:00.000Z",
    "origin": { "asset": "USD", "amount": "50.00", "rate": "1.00" },
    "destination": { "asset": "USD", "amount": "50.00", "rate": "1.00" },
    "denomination": {
      "asset": "USD",
      "amount": "50.00",
      "rate": "1.00",
      "target": "origin"
    },
    "fees": []
  }
}
```

For endpoint details, see [Create a quote](/rest-apis/core-api/transactions/create-quote).

<Note>
  Quotes have a short validity window even at a 1:1 rate. If a quote expires, transaction creation returns `404 entity_not_found` — create a new quote and ask the sender to confirm again.
</Note>

## Create the transaction

Once the sender confirms the transfer, create the transaction from the quote.

As with trades, the `quoteId` becomes the `transactionId`, allowing a single identifier to be used throughout the transfer lifecycle.

Sends settle synchronously. In most cases, by the time the API responds, balances have already been updated.

```http theme={null}
POST /core/transactions
X-On-Behalf-Of: <sender userId>
{
  "quoteId": "b7e4d2c1-9f3a-4b5e-8d7c-2e1f3a4b5c6d"
}
```

```json [expandable] theme={null}
{
  "transaction": {
    "id": "b7e4d2c1-9f3a-4b5e-8d7c-2e1f3a4b5c6d",
    "status": "processing",
    "origin": { "asset": "USD", "amount": "50.00" },
    "destination": { "asset": "USD", "amount": "50.00" }
  }
}
```

## Notify sender and recipient

After the transaction succeeds:

#### Notify the sender

Display a confirmation such as:

> Sent 50.00 USD to Jane Smith.

Refresh balances using [Get account](/rest-apis/core-api/accounts/get-account).

#### Notify the recipient

Send an in-app, push, SMS, or email notification indicating that funds were received.

The recipient webhook payload contains the same transaction `id` returned during transaction creation, allowing notifications to be deduplicated across systems.

<Check>
  You now support peer-to-peer sends using the Uphold Enterprise API Suite.
</Check>

## Common errors

| Status | Code                                                      | Cause                                                                              | Recommended action                                              |
| ------ | --------------------------------------------------------- | ---------------------------------------------------------------------------------- | --------------------------------------------------------------- |
| `409`  | `user_capability_failure` (`capability.code: "sends"`)    | Sender does not have the `sends` capability enabled.                               | Verify onboarding status and sender capability requirements.    |
| `409`  | `user_capability_failure` (`capability.code: "receives"`) | Recipient cannot receive funds.                                                    | Verify recipient onboarding and capability status.              |
| `404`  | `entity_not_found` (`entity: "account"`)                  | Destination account does not exist or is not visible to your partner relationship. | Verify the recipient account ID before retrying.                |
| `404`  | `entity_not_found` (`entity: "quote"`)                    | Quote expired or no longer exists.                                                 | Create a new quote and request confirmation again.              |
| `409`  | `insufficient_balance`                                    | Sender account does not have sufficient available funds.                           | Refresh balances and prompt the sender to enter a lower amount. |
