# Live Operations And Controls

> How to submit deposits, withdrawals, conversions, and internal transfers, and read operation lifecycle and approval state.

Source: https://business-api-docs.youhodler.com/docs/workflows/live-operations-and-controls

Execute deposits, withdrawals, conversions, and ramp sessions under control.

This workflow is the runtime operating path for client-scoped and
enterprise-scoped money movement, including previews, approval checks, status
tracking, and asynchronous observation.

> **Business impact:** Financial execution calls act on `AccountRef`. Governance and lifecycle controls can still introduce approvals, event emissions, or action-token steps around the same operation.

## Operational Sequence

### 1. Preview and validate

Prices and fee previews. Inspect execution inputs before creating a real operation when the integration needs to show costs or conversion direction up front. This reduces operational surprises without mutating balances.

Preview endpoints should be treated as advisory preflight surfaces. The authoritative state still begins when a real operation resource is created.

[API Reference: Create fee preview (POST)](/docs/api/reference/fee-previews/fee-previews-create)

**Request URL — POST**
```http
POST https://business-api.youhodler.com/fee-previews
```
**Request Body — application/json**
```json
{
  "subject_ref": "client-accounts/aaaaaaa1-aaaa-4aaa-8aaa-aaaaaaaaaaa1",
  "operation_type": "withdrawal",
  "service_type": "settlement",
  "principal_amount": {
    "amount": "1250.00",
    "currency": "USDC"
  },
  "requested_at": "2026-04-28T13:40:00.000Z"
}
```
**Request URL — GET**
```http
GET https://business-api.youhodler.com/prices/indicative?base_currency=USDC&quote_currency=EUR&amount=1250.00
```
**200 Fee Preview**

```json
{
  "fee_preview": {
    "fee_components": [
      {
        "code": "platform_fee",
        "amount": {
          "amount": "7.50",
          "currency": "USDC"
        }
      }
    ],
    "summary": {
      "total_fees": {
        "amount": "7.50",
        "currency": "USDC"
      }
    }
  }
}
```

**200 Indicative Price**

```json
{
  "base_currency": "USDC",
  "quote_currency": "EUR",
  "rate": "0.9224",
  "amount": "1250.00",
  "quoted_amount": "1153.00",
  "as_of": "2026-04-28T13:40:00.000Z"
}
```

### 2. Create the operation

Withdrawal, conversion, deposit, or ramp. Once the caller has an execution decision, create the real operation on the target `AccountRef`. The same lifecycle model powers withdrawals, conversions, deposits, and ramp sessions.

Use idempotency on every mutating execution request. The operation id becomes the durable handle for later approval, tracking, and event correlation.

[API Reference: Create withdrawal (POST)](/docs/api/reference/withdrawals/withdrawals-create)

**Request URL — POST**
```http
POST https://business-api.youhodler.com/withdrawals
```
**Request Headers — required**
```json
Authorization: Bearer <token>
Idempotency-Key: 5d17b978-e8ee-4f55-a313-7fe0f31f8535
Content-Type: application/json
```
**Request Body — application/json**
```json
{
  "amount": {
    "amount": "1250.00",
    "currency": "USDC"
  },
  "account_ref": "client-accounts/aaaaaaa1-aaaa-4aaa-8aaa-aaaaaaaaaaa1",
  "destination": {
    "withdrawal_destination_id": "bbbbbbb2-bbbb-4bbb-8bbb-bbbbbbbbbbb2"
  },
  "rail": "crypto"
}
```
**202 Withdrawal Accepted**

```json
{
  "id": "eeeeeee5-eeee-4eee-8eee-eeeeeeeeeee5",
  "family": "withdrawal",
  "status": "processing",
  "account_ref": "client-accounts/aaaaaaa1-aaaa-4aaa-8aaa-aaaaaaaaaaa1",
  "principal_amount": {
    "amount": "1250.00",
    "currency": "USDC"
  },
  "fee_summary": {
    "total_fees": {
      "amount": "7.50",
      "currency": "USDC"
    }
  },
  "fill_rate": null,
  "failure_reason": null,
  "approval_ref": null,
  "subject_attribution": {
    "subject_ref": "clients/88888888-8888-4888-8888-888888888888"
  },
  "family_params": {
    "rail": "crypto",
    "destination": {
      "withdrawal_destination_id": "bbbbbbb2-bbbb-4bbb-8bbb-bbbbbbbbbbb2"
    }
  },
  "created_at": "2026-04-28T13:44:20.000Z",
  "updated_at": "2026-04-28T13:44:20.000Z"
}
```

**422 Not Admissible**

```json
{
  "code": "not_admissible",
  "message": "The requested withdrawal is blocked by current policy posture or account state."
}
```

### 3. Resolve approvals when required

Governed execution path. Some operations enter approval review instead of continuing immediately. Read the approval queue, then resolve the approval with an explicit approval or rejection action.

Treat approval resources as first-class control-plane objects. They are not just side effects of an operation page; they are part of runtime governance.

[API Reference: List approvals (GET)](/docs/api/reference/approvals/approvals-list)

**Request URL — GET**
```http
GET https://business-api.youhodler.com/approvals?status=pending&operation_id=eeeeeee5-eeee-4eee-8eee-eeeeeeeeeee5
```
**Request Body — application/json**
```json
{
  "reason": "Reviewed by treasury operations and approved for release."
}
```
**200 Pending Approval Page**

```json
{
  "items": [
    {
      "id": "fffffff6-ffff-4fff-8fff-fffffffffff6",
      "resource": "approval",
      "status": "pending",
      "operation": "withdrawal",
      "operation_id": "eeeeeee5-eeee-4eee-8eee-eeeeeeeeeee5",
      "decided_by": null,
      "requirement_summary": {
        "required_approvals": 1
      },
      "created_at": "2026-04-28T13:44:21.000Z",
      "updated_at": "2026-04-28T13:44:21.000Z",
      "expires_at": "2026-04-28T14:14:21.000Z"
    }
  ],
  "next_page_token": null
}
```

**200 Approval Approved**

```json
{
  "id": "fffffff6-ffff-4fff-8fff-fffffffffff6",
  "resource": "approval",
  "status": "approved",
  "operation": "withdrawal",
  "operation_id": "eeeeeee5-eeee-4eee-8eee-eeeeeeeeeee5",
  "decided_by": {
    "actor_ref": "users/44444444-4444-4444-8444-444444444444"
  },
  "requirement_summary": {
    "required_approvals": 1
  },
  "created_at": "2026-04-28T13:44:21.000Z",
  "updated_at": "2026-04-28T13:46:01.000Z",
  "expires_at": "2026-04-28T14:14:21.000Z"
}
```

### 4. Track status and final state

Lifecycle visibility. After creation, read the operation resource directly when the caller needs the current status, a failure reason, or the final execution state.

Use polling selectively. In most integrations, direct reads are best for operator inspection or retry handling, while webhooks and events handle normal asynchronous processing.

[API Reference: Get withdrawal (GET)](/docs/api/reference/withdrawals/withdrawals-get)

**Request URL — GET**
```http
GET https://business-api.youhodler.com/withdrawals/eeeeeee5-eeee-4eee-8eee-eeeeeeeeeee5
```
**200 Completed**

```json
{
  "id": "eeeeeee5-eeee-4eee-8eee-eeeeeeeeeee5",
  "family": "withdrawal",
  "status": "completed",
  "account_ref": "client-accounts/aaaaaaa1-aaaa-4aaa-8aaa-aaaaaaaaaaa1",
  "principal_amount": {
    "amount": "1250.00",
    "currency": "USDC"
  },
  "fee_summary": {
    "total_fees": {
      "amount": "7.50",
      "currency": "USDC"
    }
  },
  "fill_rate": null,
  "failure_reason": null,
  "approval_ref": "approvals/fffffff6-ffff-4fff-8fff-fffffffffff6",
  "subject_attribution": {
    "subject_ref": "clients/88888888-8888-4888-8888-888888888888"
  },
  "family_params": {
    "rail": "crypto"
  },
  "created_at": "2026-04-28T13:44:20.000Z",
  "updated_at": "2026-04-28T13:47:18.000Z"
}
```

**200 Failed**

```json
{
  "id": "eeeeeee5-eeee-4eee-8eee-eeeeeeeeeee5",
  "family": "withdrawal",
  "status": "failed",
  "account_ref": "client-accounts/aaaaaaa1-aaaa-4aaa-8aaa-aaaaaaaaaaa1",
  "principal_amount": {
    "amount": "1250.00",
    "currency": "USDC"
  },
  "fee_summary": null,
  "fill_rate": null,
  "failure_reason": "destination_unreachable",
  "approval_ref": null,
  "subject_attribution": {
    "subject_ref": "clients/88888888-8888-4888-8888-888888888888"
  },
  "family_params": {
    "rail": "crypto"
  },
  "created_at": "2026-04-28T13:44:20.000Z",
  "updated_at": "2026-04-28T13:45:04.000Z"
}
```

### 5. Observe events and webhooks

Asynchronous integration. Event and webhook delivery should be the default machine-consumption path for operation progression. Polling is a fallback, not the main contract.

The event stream is also the best cross-cutting surface for audit, replay, and operational traceability across multiple operation families.

[API Reference: List events (GET)](/docs/api)

**Request URL — GET**
```http
GET https://business-api.youhodler.com/events?aggregate_type=operation&aggregate_id=eeeeeee5-eeee-4eee-8eee-eeeeeeeeeee5
```
**200 Event Page**

```json
{
  "items": [
    {
      "id": "12121212-1212-4121-8121-121212121212",
      "resource": "event",
      "event_type": "operation.updated",
      "schema_version": 1,
      "occurred_at": "2026-04-28T13:47:18.000Z",
      "published_at": "2026-04-28T13:47:18.100Z",
      "aggregate": {
        "type": "operation",
        "id": "eeeeeee5-eeee-4eee-8eee-eeeeeeeeeee5"
      },
      "partition_key": "operations/eeeeeee5-eeee-4eee-8eee-eeeeeeeeeee5",
      "trace_id": "23232323-2323-4232-8232-232323232323",
      "subject_attribution": {
        "subject_ref": "clients/88888888-8888-4888-8888-888888888888"
      },
      "enterprise_id": "11111111-1111-4111-8111-111111111111",
      "data": {
        "status": "completed"
      },
      "metadata": null
    }
  ],
  "next_page_token": null
}
```

**Webhook Delivery Shape**

```json
{
  "id": "12121212-1212-4121-8121-121212121212",
  "event_type": "operation.updated",
  "occurred_at": "2026-04-28T13:47:18.000Z",
  "aggregate": {
    "type": "operation",
    "id": "eeeeeee5-eeee-4eee-8eee-eeeeeeeeeee5"
  },
  "data": {
    "status": "completed"
  }
}
```
