> ## 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.

# Transactions API introduction

> Initiate and retrieve transactions on the Uphold platform. Transactions are defined by origin, destination, and direction nodes, with quotes and statuses.

The transactions group of endpoints allows you to initiate and retrieve transactions from the platform.

## Transaction nodes

Every transaction is defined by three fundamental properties:

* `origin`: Defines the origin node of the transaction.
* `destination`: Defines the destination node of the transaction.
* `denomination`: Defines what and how much is being moved.

The `origin` and `destination` are each represented by a node. The following node types are supported across the platform:

<AccordionGroup>
  <Accordion title="Account" icon="wallet">
    Account nodes refer to the user's [accounts](../accounts), which are containers of funds of a given asset, stored in Uphold.
  </Accordion>

  <Accordion title="External Account" icon="link-horizontal">
    External accounts refer to the user's [external accounts](../external-accounts), which allow users to deposit and withdraw funds associated with an external source.
  </Accordion>

  <Accordion title="Crypto Address" icon="bitcoin">
    Crypto addresses enable the use of crypto wallet addresses as transaction nodes within the platform.

    Crypto transactions can be executed in different modes depending on the destination and environment. Most transactions are processed **on-chain**, directly on the blockchain network. However, when both parties are Uphold users, crypto withdrawals can be processed **off-chain** within Uphold's infrastructure, eliminating network fees and reducing processing time.

    For development and testing purposes, transactions can be **simulated** without affecting actual blockchain state (user balances will be affected though). The execution mode applied to each transaction is indicated by the [`execution.mode`](./create-transaction#response-transaction-destination-node-execution) property in the crypto address node of the API response.
  </Accordion>

  <Accordion title="Bank Address" icon="building-columns">
    Bank address nodes represent the originating bank account of a push bank deposit, in the cases when adding the originating bank account as an external account is not supported by the platform. They carry the `network` used for the transfer (e.g. `ach`).
  </Accordion>

  <Accordion title="APM" icon="wallet">
    Alternative Payment Method (APM) nodes represent payment methods such as PayPal. They enable users to deposit and withdraw funds using their preferred payment provider.
  </Accordion>
</AccordionGroup>

## Initiating a quote-based transaction

Most transactions are RFQ (Request for Quote) based. This applies to:

* **Withdrawals**: Moving funds out to external accounts or crypto addresses.
* **Trades**: Converting between different assets.
* **Transfers**: Moving funds between accounts of the same asset.
* **Pull deposits**: Deposits where you initiate the transaction (e.g., credit or debit card deposits).

To create a quote, call the [Create quote](/rest-apis/core-api/transactions/create-quote) endpoint and present the user with the quote details. Quotes have a unique ID and are valid for a limited time. While the user hasn't confirmed the quote, keep refreshing it before it expires.

If the user accepts the quote, execute the transaction by calling the [Create transaction](/rest-apis/core-api/transactions/create-transaction) endpoint, passing the quote ID.

### Anatomy of a quote request

The supported [node types](#transaction-nodes) differ between `origin` and `destination`:

* **Origin**: <Badge icon="wallet" stroke color="gray">account</Badge> <Badge icon="link-horizontal" stroke color="gray">external-account</Badge> <Badge icon="wallet" stroke color="gray">apm</Badge>
* **Destination**: <Badge icon="wallet" stroke color="gray">account</Badge> <Badge icon="link-horizontal" stroke color="gray">external-account</Badge> <Badge icon="bitcoin" stroke color="gray">crypto-address</Badge> <Badge icon="wallet" stroke color="gray">apm</Badge>

This model allows you to create transactions between different types of nodes in a unified manner, such as between an account and an external account, or between an account and a crypto address.

With Uphold's **Anything to Anything** system, you can handle different classes of assets in the origin and destination on a single transaction. For example, you can do a fiat deposit using an external account directly into a BTC account, or you can withdraw from a BTC account directly to an XRP crypto address.

### Requirements

Some transactions need additional information before they can be executed. The `requirements` array in the quote response lists what is needed — if it's empty, no extra information is needed and you can proceed to create the transaction directly.

| Requirement        | How to resolve                                                                                                                                                                                            |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `travel-rule`      | Complete the [Travel Rule Widget](/developer-guides/travel-rule/overview) flow and submit the result when creating the transaction.                                                                       |
| `authorize:paypal` | Run the [Payment Widget's Authorize flow](/developer-guides/apm-transfers/deposit/via-rest-api/paypal#authorize-and-create-the-transaction) to authorize the user's PayPal account.                       |
| `authorize:3ds`    | Pass a `returnUrl` as the requirement when creating the transaction. See [Card deposit](/developer-guides/card-transfers/deposit/via-rest-api#confirm-and-create-transaction) for a detailed walkthrough. |

### Related guides

<CardGroup cols={2}>
  <Card title="Crypto Withdrawal" icon="rotate" href="/developer-guides/crypto-transfers/withdrawal/via-rest-api">
    Withdraw crypto from an account.
  </Card>

  <Card title="Bank Withdrawal" icon="arrow-up-right-from-square" href="/developer-guides/bank-transfers/withdrawal/via-rest-api">
    Payout to a bank via quote-based transfers.
  </Card>

  <Card title="Card Deposit" icon="credit-card" href="/developer-guides/card-transfers/deposit/via-rest-api">
    Fund an account from a credit or debit card.
  </Card>

  <Card title="Card Withdrawal" icon="credit-card" href="/developer-guides/card-transfers/withdrawal/via-rest-api">
    Cash out to a credit or debit card.
  </Card>

  <Card title="APM Deposit" icon="wallet" href="/developer-guides/apm-transfers/deposit/via-rest-api/paypal">
    Fund an account from an alternative payment method.
  </Card>

  <Card title="APM Withdrawal" icon="wallet" href="/developer-guides/apm-transfers/withdrawal/via-rest-api/paypal">
    Pay out to an alternative payment method.
  </Card>
</CardGroup>

## Initiating an external transaction

Some transactions are initiated externally:

* **Crypto deposits**: Occur when crypto is sent to a deposit address generated via [Set up account deposit method](/rest-apis/core-api/accounts/set-up-account-deposit-method).
* **Bank deposits**: Occur when funds are sent to the bank deposit details generated via [Set up account deposit method](/rest-apis/core-api/accounts/set-up-account-deposit-method).
* **Bank disbursements**: Occur when funds are pulled from an unlinked external account (e.g., microdeposit disbursements during bank account ownership verification).

These transactions are created automatically by the platform when incoming funds are detected. You can monitor them via [Webhooks](/rest-apis/core-api/transactions/webhooks) or by polling the transaction endpoints.

The supported [node types](#transaction-nodes) for external transactions are:

* **Origin**: <Badge icon="wallet" stroke color="gray">account</Badge> <Badge icon="link-horizontal" stroke color="gray">external-account</Badge> <Badge icon="bitcoin" stroke color="gray">crypto-address</Badge> <Badge icon="building-columns" stroke color="gray">bank-address</Badge>
* **Destination**: <Badge icon="wallet" stroke color="gray">account</Badge> <Badge icon="link-horizontal" stroke color="gray">external-account</Badge> <Badge icon="bitcoin" stroke color="gray">crypto-address</Badge> <Badge icon="building-columns" stroke color="gray">bank-address</Badge>

### Related guides

<CardGroup cols={2}>
  <Card title="Crypto Deposit" icon="wallet" href="/developer-guides/crypto-transfers/deposit/via-rest-api">
    Fund an account with crypto.
  </Card>

  <Card title="Bank Deposit" icon="building-columns" href="/developer-guides/bank-transfers/deposit/via-rest-api">
    Fund an account via bank transfer.
  </Card>
</CardGroup>

### Requests for information (RFIs)

When a transaction is placed on hold with reason `pending-requests-for-information`, that means it requires additional information to proceed. The pending requests for information (RFIs) can be managed using the [Requests for information](/rest-apis/core-api/transactions/rfis) endpoints.

Check out the [Handle on-hold transactions](/developer-guides/crypto-transfers/deposit/via-rest-api#handle-on-hold-transactions) section of the crypto deposit guide for a detailed walkthrough.

## Transaction lifecycle

Once a transaction is created, it goes through a series of statuses:

* `processing`: The transaction is being processed. This is the initial status of a transaction.
* `on-hold`: The transaction is on hold and requires further action by Uphold agents. Once the hold is resolved, the transaction will continue processing.
* `completed`: The transaction has been successfully completed.
* `failed`: The transaction has failed.

## Transaction types

Transactions do not have a type per se, but they can be classified based on the nodes involved in the transaction. The following are the most common types of transactions:

* **Deposit**: A transaction in which the origin is external, such as an external account or a crypto address.
* **Withdrawal**: A transaction in which the destination is external, such as an external account or a crypto address.
* **Trade**: A transaction in which the origin and destination are accounts of different assets.
* **Transfer**: A transaction in which the origin and destination are accounts of the same asset.

## Relation with capabilities

A transaction can require one or more capabilities to be in a valid state:

* `trades`: Required when the underlying origin and destination assets are different.
* `deposits`: Required when the underlying origin is external, such as an external account of type `card`.
* `receives`: Required when the user receives funds from another user.
* `sends`: Required when the user sends funds to another user.
* `crypto-deposits`: Required when the underlying origin is a crypto address.
* `crypto-withdrawals`: Required when the underlying destination network is of type `crypto`.
* `bank-deposits`: Required when the underlying origin is an external account of type `bank`.
* `bank-withdrawals`: Required when the underlying destination network is of type `bank`.
* `cards`: Required when transacting with a card.
* `card-withdrawals`: Required when the underlying destination network is of type `card`.
* `paypal`: Required when transacting with PayPal.
* `paypal-withdrawals`: Required when the underlying destination network is of type `paypal`.

## Transaction amount errors

The API returns `transaction_amount_invalid` error when the specified amount violates a platform rule. Below is a breakdown of the cases your integration should handle.

### Per-transaction limits

Depending on the type of transaction and the amount on the denomination, you may hit minimum or maximum single limits.

If the amount exceeds the maximum, the error `rule` will be set to  `maximum-limit-exceeded` and the `limit` object provides the maximum allowed amount under `maximumAmount`:

```json theme={null}
{
  "code": "transaction_amount_invalid",
  "message": "The amount maximum limit was exceeded",
  "details": {
    "context": "body",
    "property": "denomination",
    "rule": "maximum-limit-exceeded",
    "limit": {
      "maximumAmount": "150"
    }
  }
}
```

If the amount is below the minimum, the error `rule` will be set to  `minimum-limit-not-met` and the `limit` object provides the minimum allowed amount under `minimumAmount`:

```json theme={null}
{
  "code": "transaction_amount_invalid",
  "message": "The amount minimum limit was not met",
  "details": {
    "context": "body",
    "property": "denomination",
    "rule": "minimum-limit-not-met",
    "limit": {
      "minimumAmount": "0.85"
    }
  }
}
```

### Periodic limits

Users may have periodic spending limits (daily, weekly, or monthly) that are enforced when transacting.

If the transaction amount would exceed the period's allowance, the error `rule` encodes the period that was exceeded. The `limit` object provides the total allowed amount for that period (`maximumAmount`) and how much of it is still available (`remainingAmount`):

```json theme={null}
{
  "code": "transaction_amount_invalid",
  "message": "The amount exceeds the daily limit",
  "details": {
    "context": "body",
    "property": "denomination",
    "rule": "amount-exceeds-daily-limit",
    "limit": {
      "maximumAmount": "100.00",
      "remainingAmount": "80.00"
    }
  }
}
```

Possible rules: `amount-exceeds-daily-limit`, `amount-exceeds-weekly-limit`, `amount-exceeds-monthly-limit`.

### Unsettled funds

Some deposit networks (e.g. ACH) do not settle immediately. While a deposit is pending settlement, the respective funds will be locked for withdrawal. If a transaction that moves funds off the user — such as a withdrawal — relies on those locked funds, the request is rejected with `rule` set to `transacting-unsettled-funds`.

The `unsettledFunds` object provides the settlement timestamp (`settlementAt`) — which indicates when the funds will be unlocked — the amount locked required to perform the transaction (`shortfallAmount`), and the reasons the funds are locked (`reasons`):

```json theme={null}
{
  "code": "transaction_amount_invalid",
  "message": "The amount is invalid due to unsettled funds",
  "details": {
    "context": "body",
    "property": "denomination",
    "rule": "transacting-unsettled-funds",
    "unsettledFunds": {
      "settlementAt": "2024-07-26T13:00:00.000Z",
      "shortfallAmount": "0.95",
      "reasons": [
        "pending-ach-deposit-settlement"
      ]
    }
  }
}
```
