> Solana Developer Platform docs, served as Markdown. The [docs index](https://platform-beta.solana.com/docs.md) lists every page and [llms.txt](https://platform-beta.solana.com/docs/ai/llms.txt) the key ones; [SKILL.md](https://platform-beta.solana.com/SKILL.md) has the rules for building on SDP.

# Get a movement

Gets one deposit or withdrawal and refreshes its onchain status when it can.

> **Earn is under active development.** Features, API endpoints, and docs may change.

`GET /v1/earn/external-wallet/movements/{movementId}`

Use it to track a movement after submit, or to recover a submit whose response was lost. If the chain read fails, you get the last recorded status while SDP keeps reconciling in the background. An atomic movement can show as done at `confirmed`, but only `finalized` and `failed` are final. For `settlement: provider_order`, chain confirmation is not payout: the provider still has to complete the order.

Requires an [API key](/docs/developing-with-sdp/authentication) with the `earn.read` action.

## Path parameters

- **`movementId`** · `string` · required · min length 1 · max length 128 · example `earn_movement_a6aed3f5-4f89-4dc6-9d4b-0864021bd80d`

  The `movementId` a submit returned.

## Headers

- **`x-project-id`** · `string` · min length 1 · example `prj_example`

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

## Responses

- **`200`** Recorded movement

  - **`data`** · `object` · required

    - **`movement`** · `object` · required

      One recorded external-wallet vault movement.

      - **`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.

  - **`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`.

- **`404`** Not Found

  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

```bash tab="cURL"
curl 'https://api.solana.com/v1/earn/external-wallet/movements/earn_movement_a6aed3f5-4f89-4dc6-9d4b-0864021bd80d' \
  -H "Authorization: Bearer $SDP_API_KEY"
```

```ts tab="TypeScript"
const res = await fetch("https://api.solana.com/v1/earn/external-wallet/movements/earn_movement_a6aed3f5-4f89-4dc6-9d4b-0864021bd80d", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.SDP_API_KEY}`
  }
});
```

```python tab="Python"
import os, requests

r = requests.get("https://api.solana.com/v1/earn/external-wallet/movements/earn_movement_a6aed3f5-4f89-4dc6-9d4b-0864021bd80d",
  headers={"Authorization": f"Bearer {os.environ['SDP_API_KEY']}"})
```

## Example responses

```json tab="200"
{
  "data": {
    "movement": {
      "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"
    }
  },
  "meta": {
    "requestId": "req_example",
    "timestamp": "2025-01-01T00:00:00.000Z"
  }
}
```

```json tab="403"
{
  "error": {
    "code": "INSUFFICIENT_PERMISSIONS",
    "message": "Missing action: earn.read",
    "details": {
      "action": "earn.read"
    }
  },
  "meta": {
    "requestId": "req_example"
  }
}
```

Error responses use the [standard error shape](/docs/reference/conventions/errors).
