# Create withdrawal

Source: https://business-api-docs.youhodler.com/docs/api/reference/withdrawals/withdrawals-create

Creates a withdrawal operation. For crypto requests, bind either a stored withdrawal destination (`destination_id`) or a one-time inline `destination` (`{address, memo}` plus `network`) — exactly one crypto destination path must be present. For fiat requests, bind a stored fiat withdrawal destination by its `withdrawal_destination_id`, resolved within the supplied `account_ref` scope; the canonical bank routing and the authoritative owner topology are sourced from the stored destination, never from the request body. Both rails flow through the same create path: a fiat withdrawal is admitted here and gated downstream solely by fiat-rails runtime readiness at dispatch time (it is no longer short-circuited at the edge). Successful responses return the operation snapshot — for an immediately admitted withdrawal the response may carry `status = "executing"` once operation-flow has written that state. Idempotent on `Idempotency-Key` or `client_idempotency_key`. Human callers must obtain a step-up confirmation via `POST /action-tokens` and submit it in the `X-Action-Token` header; service principals are exempt.

## Request

**Request URL — POST**
```http
POST /withdrawals
```

**Request Body — application/json**
```json
{
  "account_ref": "client-accounts/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
  "amount": {
    "currency": "EUR",
    "value": "100.00"
  },
  "rail": "fiat",
  "withdrawal_destination_id": "b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b"
}
```

## Responses

**202 Request accepted for asynchronous processing**

Request accepted for asynchronous processing. Poll the returned operation ID to track status transitions.

```json
{
  "account_ref": "client-accounts/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
  "approval_ref": null,
  "created_at": "2026-05-01T10:00:00Z",
  "failure_reason": null,
  "family": "withdrawal",
  "family_params": {},
  "fee_summary": {
    "components": [
      {
        "amount": {
          "currency": "USDC",
          "value": "1.00"
        },
        "kind": "network_fee"
      }
    ],
    "total": {
      "currency": "USDC",
      "value": "1.00"
    }
  },
  "fill_rate": null,
  "id": "b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
  "principal_amount": {
    "currency": "USDC",
    "value": "250.00"
  },
  "settled_at": null,
  "status": "executing",
  "subject_attribution": {
    "actor": null,
    "approved_by": null,
    "authenticated_principal": {
      "id": "b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
      "kind": "user",
      "tenant_ref": "enterprises/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b"
    },
    "enterprise_binding": {
      "tenant_type": "enterprise",
      "topology_ref": "enterprises/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b"
    },
    "federation": null,
    "identity_source": "platform-managed",
    "initiated_by": null,
    "subject": {
      "id": "b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b",
      "kind": "user",
      "tenant_ref": "enterprises/b8e2f1a0-4c3d-4e5f-9a1b-2c3d4e5f6a7b"
    }
  },
  "updated_at": "2026-05-01T10:00:00Z"
}
```

**400 Step-up confirmation failed for a money-movement operation**

Step-up confirmation failed for a money-movement operation. `code` is one of: `action_token_required` (X-Action-Token header missing), `action_token_rejected` (token is unknown, expired, already consumed, or its server-canonical command binding does not match the current request). For withdrawals, obtain a fresh token via `POST /action-tokens` with structured `withdrawal.create` preview details and retry.

```json
{
  "code": "invalid_request",
  "details": {
    "reason": "missing_required_field"
  },
  "message": "The withdrawal request payload is invalid."
}
```

**401 Caller is not authenticated or the bearer token is invalid**

Caller is not authenticated or the bearer token is invalid.

```json
{
  "code": "unauthorized",
  "message": "Authentication required."
}
```

**403 Caller lacks the required capability or permitted scope**

Caller lacks the required capability or permitted scope.

```json
{
  "code": "forbidden_capability_scope",
  "details": {
    "reason": "missing_capability"
  },
  "message": "Insufficient capability for this operation."
}
```

**409 State conflict — the request cannot be applied to the current resource state**

State conflict — the request cannot be applied to the current resource state.

```json
{
  "code": "idempotency_conflict",
  "details": {
    "reason": "key_payload_mismatch"
  },
  "message": "The idempotency key was already used with a different request payload."
}
```

**422 Operation is not admissible — it violates a business rule**

Operation is not admissible — it violates a business rule, policy constraint, or lifecycle precondition specific to this resource.

```json
{
  "code": "not_admissible",
  "details": {
    "reason": "Blocked by RBAC policy.",
    "source": "rbac"
  },
  "message": "The withdrawal was rejected by an admissibility policy."
}
```

**429 Request rate limit exceeded**

Request rate limit exceeded. Retry after the delay indicated in the `details.retry_after_ms` field.

```json
{
  "code": "rate_limited",
  "details": {
    "retry_after_ms": 5000
  },
  "message": "Too many requests."
}
```

**502 Upstream service returned an unexpected error**

Upstream service returned an unexpected error.

```json
{
  "code": "upstream_error",
  "message": "An upstream service returned an unexpected error."
}
```

**503 Service is temporarily unavailable**

Service is temporarily unavailable; retry with backoff.

```json
{
  "code": "temporarily_unavailable",
  "details": {
    "reason": "service_unavailable"
  },
  "message": "The withdrawal service is temporarily unavailable. Retry after a short delay."
}
```

**Related endpoints:**

- `POST` [Register withdrawal destination](/docs/api/reference/withdrawal-destinations/withdrawal-destinations-create) — Register a destination first
- `POST` [Enable withdrawal destination](/docs/api/reference/withdrawal-destinations/withdrawal-destinations-enable) — Destination must be enabled
- `POST` [Preview a fee](/docs/api/reference/fee-previews/fee-previews-create) — Preview fees before initiating
- `GET` [Get withdrawal](/docs/api/reference/withdrawals/withdrawals-get) — Poll withdrawal status after creation
- `GET` [List approvals](/docs/api/reference/approvals/approvals-list) — Check pending approvals if awaiting approval
