List movements

Lists one customer wallet's deposits and withdrawals, newest first, one page at a time.

GET/v1/earn/external-wallet/movements

Movement statuses are requested, submitted, confirmed, finalized and failed; only finalized and failed are final. ownerAddress is required, and a wallet with no movements returns an empty movements list, not 404. Show tokenAmount in tokenMint units: on a withdrawal it is the observed payout once finalized, while amount and denomination carry the onchain quantity, which is shares. Reads keep working after a provider stops taking deposits.

Requires an API key with the earn.read action.

Query parameters

  • ownerAddress · string · required · min length 32 · max length 44 · pattern ^[1-9A-HJ-NP-Za-km-z]{32,44}$ · example 9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM

    The customer's wallet address: an external wallet, so SDP holds no key for it. It signs, owns the shares, and pays the network fee unless the build names a feePayer. It must decode to a 32-byte public key; a base58 string that matches the pattern but does not decode returns 400.

  • direction · string · one of deposit, withdrawal

  • status · string · min length 1 · max length 64

    Return only movements in this status, such as finalized. Takes one value; an unknown value matches nothing.

  • limit · integer · min 1 · max 100 · default 20

    Page size, from 1 to 100. Defaults to 20.

  • before · string · min length 1

    The previous page's nextCursor. Omit it for the first page.

Headers

  • x-project-id · string · min length 1 · example prj_example

    Required for dashboard sessions. API keys use their assigned project.

Responses

  • 200 One page of movements

    • data · object · required

      • ownerAddress · string · required · example 9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM

        The customer's wallet address.

      • movements · object[] · required

        The wallet's recorded movements, newest first.

        • settlementOutcome · string · one of delivered, cancelled

        • movementId · string · required · example earn_movement_a6aed3f5-4f89-4dc6-9d4b-0864021bd80d

        • positionId · string · required · example earn_position_2f8b6b04-7147-487e-b760-b1caa4fbcb8b

        • provider · string · required · example kamino

        • providerReference · string · required · example 7uib8xGAwkaPz4ZGCA6t8sSEid5Yp9ty13PHUweTypx

        • direction · string · required · one of deposit, withdrawal

        • status · string · required · one of requested, submitted, confirmed, finalized, failed

          The movement's status. requested means SDP recorded the signed transaction but has not yet seen it on the network. confirmed is optimistic and can still be rolled back; only finalized and failed are final.

        • settlement · string · required · one of atomic, provider_order

          How the movement settles. atomic completes in one transaction, so you may show it as done at confirmed while SDP tracks finality. provider_order pays out later through the provider, so chain confirmation alone is not payout: the movement stays confirmed until the provider completes it, and only finalized means it is done.

        • signature · string · required

          The transaction signature, for explorers.

        • ownerAddress · string · required · example 9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM

          The customer's wallet address.

        • amount · string · required · max length 128 · pattern ^(?=.*[1-9])\d+(\.\d+)?$ · example 25

          Requested quantity, denominated in denomination.

        • denomination · string · required · example 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU

          Token mint for a deposit; share mint for a withdrawal.

        • tokenMint · string · required · example 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU

          The position's deposit-token mint. Show tokenAmount in these units; amount and denomination carry the onchain quantity, which is shares on a withdrawal.

        • tokenAmount · string | null · required · max length 128 · pattern ^(?=.*[1-9])\d+(\.\d+)?$ · example 25

          Quantity in tokenMint units. Kamino deposits and all withdrawals require a finalized observation; null beforehand or when the actual debit/payout cannot be observed. Other deposits report their fixed input amount.

        • failureReason · string | null · required

        • createdAt · string · required · format date-time · example 2025-01-01T00:00:00.000Z

          ISO 8601 timestamp.

        • confirmedAt · string | null · required · format date-time · example 2025-01-01T00:00:00.000Z

          ISO 8601 timestamp.

        • settledAt · string | null · required · format date-time · example 2025-01-01T00:00:00.000Z

          ISO 8601 timestamp.

        • replayed · boolean

          True when the idempotency key already produced this movement and nothing was re-sent.

      • hasMore · boolean · required

      • nextCursor · string | null · required

    • meta · object · required

      Response metadata.

      • requestId · string · required · min length 1 · example req_example

        Request identifier for tracing.

      • timestamp · string · required · format date-time · example 2025-01-01T00:00:00.000Z

        ISO 8601 timestamp.

  • 400 Bad Request

    • error · object · required

      Standard error payload.

      • code · string · required

        Machine-readable error code.

      • message · string · required

        Human-readable error message.

      • details · object

        Optional error details for debugging.

        • * · any
    • meta · object

      • requestId · string · min length 1 · example req_example

        Request identifier for tracing.

  • 401 Unauthorized

    Same fields as 400.

  • 403 Forbidden. Requires the earn.read action: an API key must hold it (a module's manage or execute also covers its read), and a signed-in member's organization role must include it. Without it the error is INSUFFICIENT_PERMISSIONS and error.details.action names the action. Any other 403 names its own reason.

    Same fields as 400.

  • 429 Too Many Requests

    Same fields as 400.

  • 500 Internal Server Error

    Same fields as 400.

  • 503 Service Unavailable

    Same fields as 400.

Example request

curl 'https://api-beta.solana.com/v1/earn/external-wallet/movements?ownerAddress=9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM' \
  -H "Authorization: Bearer $SDP_API_KEY"
const res = await fetch("https://api-beta.solana.com/v1/earn/external-wallet/movements?ownerAddress=9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.SDP_API_KEY}`
  }
});
import os, requests

r = requests.get("https://api-beta.solana.com/v1/earn/external-wallet/movements?ownerAddress=9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",
  headers={"Authorization": f"Bearer {os.environ['SDP_API_KEY']}"})

Example responses

JSON
{
  "data": {
    "ownerAddress": "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",
    "movements": [
      {
        "movementId": "earn_movement_a6aed3f5-4f89-4dc6-9d4b-0864021bd80d",
        "positionId": "earn_position_2f8b6b04-7147-487e-b760-b1caa4fbcb8b",
        "provider": "kamino",
        "providerReference": "C7N2fqV2GvhFghDf5PJSwstyjedjLNCY1cm2Ak7TeU83",
        "direction": "deposit",
        "settlement": "atomic",
        "signature": "3dhkSPLiQZQPXL96fWzMdWJtdbtAffkBKXw2xhsYbV3VNSnYrVAcdx1czsnLsE1ou4SvLecGdSYe4QpAuZdfjJAf",
        "ownerAddress": "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",
        "amount": "25",
        "denomination": "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",
        "tokenMint": "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",
        "failureReason": null,
        "createdAt": "2026-11-06T17:57:30.817Z",
        "status": "finalized",
        "tokenAmount": "25",
        "confirmedAt": "2026-11-06T17:57:32.517Z",
        "settledAt": "2026-11-06T17:57:35.623Z"
      }
    ],
    "hasMore": false,
    "nextCursor": null
  },
  "meta": {
    "requestId": "req_example",
    "timestamp": "2025-01-01T00:00:00.000Z"
  }
}
JSON
{
  "error": {
    "code": "INSUFFICIENT_PERMISSIONS",
    "message": "Missing action: earn.read",
    "details": {
      "action": "earn.read"
    }
  },
  "meta": {
    "requestId": "req_example"
  }
}

Error responses use the standard error shape.