Skip to main content

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.

This guide walks you through supporting card deposits using the REST API.

Prerequisites

Walkthrough


Check available rails

Call List Rails to verify card deposit is available.
GET /core/rails?type=card
{
  "rails": [
    {
      "type": "card",
      "network": "visa",
      "method": "debit-card",
      "asset": "GBP",
      "decimals": 2,
      "features": [
        "deposit",
        "withdraw"
      ]
    }
  ]
}

Select a card account

Let the user pick an existing card or add a new one.

Find an existing card account

Call List external accounts to fetch the user’s saved cards.
GET /core/external-accounts
Make sure the selected card has status: "ok" and in features.
{
  "externalAccounts": [
    {
      "id": "7d5928c5-8ac4-4b0d-8b45-f332ba6a9de7",
      "ownerId": "e4ce04dc-67b7-4e9f-af91-482cb6f9fc4a",
      "type": "card",
      "status": "ok",
      "label": "My Visa Card",
      "asset": "GBP",
      "network": "visa",
      "features": [
        "deposit",
        "withdraw"
      ],
      "details": {
        "type": "debit",
        "last4Digits": "5119",
        "expiryDate": {
          "month": 12,
          "year": 2028
        },
        "octSupport": "supported"
      }
    }
  ]
}
If the user wants to use a card not yet on file, call Create external account with the card details.
POST /core/external-accounts
{
  "type": "card",
  "label": "My Visa Card",
  "number": "4921817844445119",
  "securityCode": "123",
  "expiryDate": {
    "month": 12,
    "year": 2028
  }
}
The response initially returns status: "processing" while the card is validated.
{
  "externalAccount": {
    "id": "7d5928c5-8ac4-4b0d-8b45-f332ba6a9de7",
    "type": "card",
    "status": "processing",
    "label": "My Visa Card"
  }
}
Once validated, the status transitions to ok and the full details are available.
{
  "externalAccount": {
    "id": "7d5928c5-8ac4-4b0d-8b45-f332ba6a9de7",
    "ownerId": "e4ce04dc-67b7-4e9f-af91-482cb6f9fc4a",
    "type": "card",
    "status": "ok",
    "label": "My Visa Card",
    "asset": "GBP",
    "network": "visa",
    "features": [
      "deposit",
      "withdraw"
    ],
    "details": {
      "type": "debit",
      "last4Digits": "5119",
      "expiryDate": {
        "month": 12,
        "year": 2028
      },
      "octSupport": "supported"
    }
  }
}
Monitor the external account status via Get external account or the external-account.status-changed webhook until status is ok before proceeding.

EMD disclaimer

This disclaimer is required to comply with FCA regulations. Display it to users based in GB, the first time they link a credit/debit card or generate bank deposit details — it only needs to be shown once:
Uphold Europe Limited is an EMD Agent of Optimus Cards UK Limited (FRN: 902034). All received funds are held in a designated safekeeping account with a regulated bank and kept separate from Uphold’s own assets. These funds are not protected by the UK Financial Services Compensation Scheme.

Select destination account

Card deposits can target any account. If the selected account is not in the card’s currency, the amount will be converted at settlement using Uphold’s prevailing rate. Make sure the destination asset has the necessary features enabled.

Find an existing account

Call List accounts to retrieve the user’s accounts and let them pick the one they want to fund.
GET /core/accounts
{
  "accounts": [
    {
      "id": "a00507fe-628c-4f27-ae81-e1c40b2a8fb8",
      "ownerId": "e4ce04dc-67b7-4e9f-af91-482cb6f9fc4a",
      "label": "My GBP account",
      "asset": "GBP",
      "balance": {
        "total": "500.00",
        "available": "500.00"
      }
    }
  ]
}

Create a new account

If the user has no accounts, create one with Create account before proceeding.
POST /core/accounts
{
  "label": "My GBP account",
  "asset": "GBP"
}
{
  "account": {
    "id": "a00507fe-628c-4f27-ae81-e1c40b2a8fb8",
    "ownerId": "e4ce04dc-67b7-4e9f-af91-482cb6f9fc4a",
    "label": "My GBP account",
    "asset": "GBP",
    "balance": {
      "total": "0",
      "available": "0"
    }
  }
}

Create a quote

Call Create quote with the card external account as origin and the destination account.
POST /core/transactions/quote
{
  "origin": {
    "type": "external-account",
    "id": "7d5928c5-8ac4-4b0d-8b45-f332ba6a9de7"
  },
  "destination": {
    "type": "account",
    "id": "a00507fe-628c-4f27-ae81-e1c40b2a8fb8"
  },
  "denomination": {
    "asset": "GBP",
    "amount": "250.00",
    "target": "origin"
  }
}
Check the origin node in the response for confirmationUrl. If present, card authorization is required — see Handle quote requirements below.
{
  "quote": {
    "id": "623000c8-9bdf-4a2b-aa3d-6a6b44a7f6a0",
    "origin": {
      "amount": "250.00",
      "asset": "GBP",
      "node": {
        "type": "external-account",
        "id": "7d5928c5-8ac4-4b0d-8b45-f332ba6a9de7",
        "ownerId": "e4ce04dc-67b7-4e9f-af91-482cb6f9fc4a"
      },
      "rate": "1"
    },
    "destination": {
      "amount": "250.00",
      "asset": "GBP",
      "node": {
        "type": "account",
        "id": "a00507fe-628c-4f27-ae81-e1c40b2a8fb8",
        "ownerId": "e4ce04dc-67b7-4e9f-af91-482cb6f9fc4a"
      },
      "rate": "1"
    },
    "denomination": {
      "asset": "GBP",
      "amount": "250.00",
      "target": "origin",
      "rate": "1"
    },
    "fees": [],
    "expiresAt": "2024-07-24T15:22:39Z"
  }
}
Quotes typically expire quickly. Prompt for user confirmation within the expiry window and requote if needed.

Handle quote requirements

When the quote is returned, check the origin node for confirmationUrl. If present, resolve it before creating the transaction.

Card authorization

If confirmationUrl is present on the origin node, the card requires authorization. Build a returnUrl — the URL Uphold will redirect the user back to after completing the challenge — and include the quoteId as a query parameter so you can reference it on return. Pass it as params.returnUrl when creating the transaction below.

Confirm and create transaction

Once the user confirms, call Create transaction with the quote ID. If card authorization is required, include params.returnUrl.
POST /core/transactions
{
  "quoteId": "623000c8-9bdf-4a2b-aa3d-6a6b44a7f6a0",
  "params": {
    "returnUrl": "https://example.com/redirect?quoteId=623000c8-9bdf-4a2b-aa3d-6a6b44a7f6a0"
  }
}
If authorization is required, the response will include a confirmationUrl on the origin node. Redirect the user to that URL to complete the challenge. After completion, the user will be redirected back to your returnUrl.
{
  "transaction": {
    "id": "623000c8-9bdf-4a2b-aa3d-6a6b44a7f6a0",
    "status": "processing",
    "origin": {
      "node": {
        "type": "external-account",
        "id": "7d5928c5-8ac4-4b0d-8b45-f332ba6a9de7",
        "confirmationUrl": "https://authentication-devices.sandbox.checkout.com/sessions-interceptor/sid_...",
        "ownerId": "e4ce04dc-67b7-4e9f-af91-482cb6f9fc4a"
      }
    }
  }
}
In a successful card deposit, the origin is the external-account representing the card and the destination is the user’s account.
{
  "transaction": {
    "id": "f5a6b7c8-3d4e-4f7a-b00c-9d8e7f6a5b4c",
    "origin": {
      "asset": "GBP",
      "amount": "250.00",
      "node": {
        "type": "external-account",
        "id": "7d5928c5-8ac4-4b0d-8b45-f332ba6a9de7",
        "ownerId": "e4ce04dc-67b7-4e9f-af91-482cb6f9fc4a"
      }
    },
    "destination": {
      "asset": "GBP",
      "amount": "250.00",
      "node": {
        "type": "account",
        "id": "a00507fe-628c-4f27-ae81-e1c40b2a8fb8",
        "ownerId": "e4ce04dc-67b7-4e9f-af91-482cb6f9fc4a"
      }
    },
    "status": "completed",
    "quotedAt": "2025-01-10T11:02:39Z",
    "createdAt": "2025-01-10T11:12:39Z",
    "updatedAt": "2025-01-10T11:13:08Z",
    "denomination": {
      "asset": "GBP",
      "amount": "250.00",
      "target": "origin"
    }
  }
}

Monitor for settlement

Card deposit transactions may remain in processing while the payment settles. Monitor until the transaction reaches a terminal state.

Notify the user

Display an in-app confirmation when the transaction is completed, and send an email if applicable.
You now support card deposits via the REST API.