# Quickstart: Make your first withdrawal

Product: Account API
Guides follow API reference 0.3.0 and event reference 0.2.0.
Canonical page: https://docs.axiym.io/account-api/integration-guide/quick-start

Use provisioned sandbox resources to authenticate, create and review a
withdrawal, confirm it, and reconcile the outcome.

## Integration tools

* **[Postman collection](/account-api/api-reference#downloads)** — Try requests in
  Sandbox. Set `clientId` and `clientSecret`, then send the Auth token request;
  the collection saves the token for subsequent requests.
* **[Integrate using AI](/account-api/integration-guide/integrate-with-ai)** —
  Documentation formats and an optional integration prompt for your coding agent.

## Before you start

You need sandbox OAuth credentials with the `ACCOUNT` scope, an `ACTIVE`
Axiym account with test balance, and an `ACTIVE` address book entry owned by
your organization in the same currency.

Complete [Access setup](/account-api/integration-guide/access-setup) and read
[Sandbox testing](/account-api/integration-guide/sandbox-testing). Bank withdrawal
progression requires Axiym's help; wallet withdrawals use the configured testnet.

Set `AXIYM_CLIENT_ID` and `AXIYM_CLIENT_SECRET` in your shell to your sandbox
OAuth credentials. All requests below use the sandbox base URL.

## 1. Authenticate

```sh
curl --request POST "https://partner-api.sandbox.axiym.io/api/v1/oauth/token" \
  --header "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "client_id=$AXIYM_CLIENT_ID" \
  --data-urlencode "client_secret=$AXIYM_CLIENT_SECRET" \
  --data-urlencode "grant_type=client_credentials" \
  --data-urlencode "scope=ACCOUNT"
```

Set `AXIYM_ACCESS_TOKEN` to the returned `access_token`. Keep it secure; the
remaining requests send it as a bearer token.

## 2. Configure webhooks

Register and test your HTTPS receiver using
[Webhook Registration and Management](/account-api/webhooks/registration-management).
Verify signatures, persist or queue deliveries, and deduplicate by event `id`.
Subscriptions receive account, address book, and test events as well as withdrawals.

## 3. Select the source account

```sh
curl "https://partner-api.sandbox.axiym.io/api/v1/accounts" \
  --header "Authorization: Bearer $AXIYM_ACCESS_TOKEN"
```

Choose an `ACTIVE` account with sufficient test balance. Set `ACCOUNT_ID` to
its returned `accountId` and `WITHDRAWAL_CURRENCY` to its currency. Set
`WITHDRAWAL_AMOUNT` to the decimal string you intend to debit, within the
account balance.

## 4. Select the destination

```sh
curl "https://partner-api.sandbox.axiym.io/api/v1/address-book" \
  --header "Authorization: Bearer $AXIYM_ACCESS_TOKEN"
```

Choose an `ACTIVE` entry owned by your organization with the same currency.
For a wallet, confirm the intended network. Set `DESTINATION_ID` to the
returned `destinationId`. Follow pagination if the entry is not on the first
page.

Register missing entries through the Axiym Dashboard and wait for activation.
See [Select an address book entry](/account-api/integration-guide/register-external-account).

## 5. Create and review the withdrawal

Generate separate keys once for this new withdrawal:

```sh
CREATE_IDEMPOTENCY_KEY=$(uuidgen)
CONFIRM_IDEMPOTENCY_KEY=$(uuidgen)
```

Keep both keys for this attempt. After a timeout or lost response, retry only
the relevant request with its original key, path, and body. Generate fresh
keys when starting another withdrawal.

The example below omits documents. If the destination corridor requires
evidence, include `supportingDocuments` in the body. Each document contains
`documentType`, `name`, and raw file bytes encoded as base64 in `data`, without
a data-URL prefix. Use synthetic documents agreed for sandbox testing.

```sh
curl --request POST "https://partner-api.sandbox.axiym.io/api/v1/withdrawals" \
  --header "Authorization: Bearer $AXIYM_ACCESS_TOKEN" \
  --header "Idempotency-Key: $CREATE_IDEMPOTENCY_KEY" \
  --header "Content-Type: application/json" \
  --data @- <<EOF_BODY
{
  "sourceAccountId": "$ACCOUNT_ID",
  "sourceAmount": { "amount": "$WITHDRAWAL_AMOUNT", "currency": "$WITHDRAWAL_CURRENCY" },
  "destinationId": "$DESTINATION_ID",
  "reference": "Sandbox withdrawal",
  "externalReference": "sandbox-$CREATE_IDEMPOTENCY_KEY"
}
EOF_BODY
```

Creation returns `PENDING_CONFIRMATION`; execution has not started. Set
`WITHDRAWAL_ID` to the returned `withdrawalId` and retain the response for review.

Before confirming, check:

| Returned field      | Check                                                                                  |
| ------------------- | -------------------------------------------------------------------------------------- |
| `sourceAccount`     | The intended funding account and currency.                                             |
| `destination`       | The intended bank account or wallet and network. This is a snapshot taken at creation. |
| `sourceAmount`      | The total amount to debit.                                                             |
| `fee`               | The deduction from `sourceAmount`.                                                     |
| `destinationAmount` | The recipient amount, equal to `sourceAmount` less `fee`.                              |

## 6. Confirm the reviewed instruction

After accepting those details, confirm using the separate key generated above.
The request has no body.

```sh
curl --request POST \
  "https://partner-api.sandbox.axiym.io/api/v1/withdrawals/$WITHDRAWAL_ID/confirm" \
  --header "Authorization: Bearer $AXIYM_ACCESS_TOKEN" \
  --header "Idempotency-Key: $CONFIRM_IDEMPOTENCY_KEY"
```

The response has status `PENDING`: execution is queued, not completed.
For a bank scenario, share `WITHDRAWAL_ID` with Axiym to coordinate subsequent
progression and events.

## 7. Track the outcome

```sh
curl \
  "https://partner-api.sandbox.axiym.io/api/v1/withdrawals/$WITHDRAWAL_ID" \
  --header "Authorization: Bearer $AXIYM_ACCESS_TOKEN"
```

Use signed events for notification and this read for current state.

| Status                   | Meaning                                   |
| ------------------------ | ----------------------------------------- |
| `PENDING_CONFIRMATION`   | Awaiting explicit confirmation.           |
| `PENDING`                | Confirmed and awaiting execution.         |
| `HELD`                   | Temporarily on hold; continue monitoring. |
| `COMPLETED`              | Completed successfully.                   |
| `CANCELED` or `REJECTED` | Not completed; inspect `reasonCode`.      |

If still pending or held, retrieve it again later. For an unsuccessful outcome,
resolve the cause before starting a new withdrawal.

For a completed wallet withdrawal, use the returned `transactionHash` to
verify receipt on testnet. For a bank scenario, validate the simulated
external outcome with Axiym.

## 8. Verify the account movement

Once the withdrawal is `COMPLETED`, retrieve the source account statement:

```sh
curl \
  "https://partner-api.sandbox.axiym.io/api/v1/accounts/$ACCOUNT_ID/statement" \
  --header "Authorization: Bearer $AXIYM_ACCESS_TOKEN"
```

Find the entry with `relatedResourceType: WITHDRAWAL` and `relatedResourceId`
equal to `WITHDRAWAL_ID`. Verify `type: DEBIT` and an `amount` and `currency`
matching the withdrawal's `sourceAmount`. The fee is already included in that
debit. A current account balance alone does not identify this withdrawal.

If the entry is not on the first page, use `pageInfo.endCursor` as `after`
while `pageInfo.hasNextPage` is true. Keep the account and filters unchanged.

The quickstart is complete when the withdrawal reaches `COMPLETED`, its debit
matches the statement, and the external test outcome is verified. Continue
with [Reconcile activity](/account-api/integration-guide/reconcile-activity)
for period totals and handling other account movements.
