> ## Documentation Index
> Fetch the complete documentation index at: https://docs.quantumapi.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Transactions

> Transaction lifecycle, signing flow, and state machine

Transactions are the core operation of the Custody API. Every transfer moves through a deterministic state machine from creation to on-chain confirmation.

## Creating a transaction

Submit a transfer with source, destination, amount, and asset:

```bash theme={null}
curl -X POST "$BASE_URL/transactions" \
  -H "Authorization: Bearer $CUSTODY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "asset_id": "QUANTUM",
    "source": {
      "type": "VAULT_ACCOUNT",
      "id": "va_def456"
    },
    "destination": {
      "type": "ONE_TIME_ADDRESS",
      "one_time_address": {
        "address": "0x5678...efgh"
      }
    },
    "amount": "10.0",
    "note": "Payment"
  }'
```

### Source and destination types

| Type               | Description                                    |
| ------------------ | ---------------------------------------------- |
| `VAULT_ACCOUNT`    | A vault account managed by the Custody API     |
| `ONE_TIME_ADDRESS` | An external address used for a single transfer |

## State machine

Transactions move through a deterministic state machine of **14 states**. The diagram below shows the most common path; see [Transaction state machine](/concepts/state-machine) for the full transition table.

```mermaid theme={null}
stateDiagram-v2
    [*] --> SUBMITTED: POST /v1/transactions
    SUBMITTED --> PENDING_AUTHORIZATION: Policy requires approval
    SUBMITTED --> PENDING_AML_SCREENING: Screening required
    SUBMITTED --> PENDING_SIGNATURE: Auto-approved
    SUBMITTED --> REJECTED: Policy denied

    PENDING_AUTHORIZATION --> APPROVED: POST /approve
    PENDING_AUTHORIZATION --> REJECTED: POST /reject
    PENDING_AUTHORIZATION --> CANCELLED: POST /cancel

    APPROVED --> PENDING_SIGNATURE: Authorization complete

    PENDING_AML_SCREENING --> PENDING_SIGNATURE: Cleared
    PENDING_AML_SCREENING --> BLOCKED: Flagged / blocked

    PENDING_SIGNATURE --> SIGNED: Signature submitted
    PENDING_SIGNATURE --> FAILED: Invalid signature
    PENDING_SIGNATURE --> CANCELLED: POST /cancel

    SIGNED --> BROADCASTING: Assembling tx
    BROADCASTING --> CONFIRMING: Broadcast success
    BROADCASTING --> FAILED: Broadcast rejected

    CONFIRMING --> COMPLETED: Confirmed
    CONFIRMING --> FAILED: Reverted/dropped

    COMPLETED --> [*]
    FAILED --> [*]
    REJECTED --> [*]
    CANCELLED --> [*]
    BLOCKED --> [*]
```

### States

| State                   | Description                                                   | Duration                |
| ----------------------- | ------------------------------------------------------------- | ----------------------- |
| `SUBMITTED`             | Accepted by the API; awaiting policy and screening evaluation | Instant                 |
| `QUEUED`                | Held briefly because of an idempotency conflict or rate limit | Seconds                 |
| `PENDING_AUTHORIZATION` | Awaiting manual approval per policy                           | Until approved/rejected |
| `PENDING_AML_SCREENING` | Compliance screening in flight                                | Until provider responds |
| `APPROVED`              | Authorization granted, transitioning to signing               | Instant                 |
| `PENDING_SIGNATURE`     | Awaiting external post-quantum signature                      | Until you sign          |
| `SIGNED`                | Signature received and verified                               | Seconds                 |
| `BROADCASTING`          | Submitted to Quantum Chain nodes                              | Seconds                 |
| `CONFIRMING`            | In a block, waiting for confirmation depth                    | \~15–60 seconds         |
| `COMPLETED`             | Confirmed with sufficient block depth                         | Final                   |
| `FAILED`                | Reverted, broadcast failure, or invalid signature             | Final                   |
| `REJECTED`              | Denied by policy or approver                                  | Final                   |
| `CANCELLED`             | Cancelled by the caller before broadcast                      | Final                   |
| `BLOCKED`               | Compliance screening flagged or blocked the transaction       | Final                   |

## Signing flow

<Steps>
  <Step title="Get the signing payload">
    ```bash theme={null}
    curl "$BASE_URL/transactions/{id}/signing_payload" \
      -H "Authorization: Bearer $CUSTODY_API_KEY"
    ```

    Returns a hex-encoded byte array representing the unsigned transaction digest.
  </Step>

  <Step title="Sign with your quantum-safe key">
    Use your external key management system to produce a post-quantum signature over the digest bytes.
  </Step>

  <Step title="Submit the signature">
    ```bash theme={null}
    curl -X POST "$BASE_URL/transactions/{id}/signature" \
      -H "Authorization: Bearer $CUSTODY_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "signature": "<base64-signature>",
        "signer_public_key": "<base64-public-key>"
      }'
    ```

    The API verifies the signature against the registered wallet's public key before accepting it.
  </Step>
</Steps>

## Approval and rejection

If a policy requires manual approval, the transaction enters a `PENDING_AUTHORIZATION` state.

```bash theme={null}
# Approve
curl -X POST "$BASE_URL/transactions/{id}/approve" \
  -H "Authorization: Bearer $CUSTODY_API_KEY"

# Reject
curl -X POST "$BASE_URL/transactions/{id}/reject" \
  -H "Authorization: Bearer $CUSTODY_API_KEY"
```

## Cancellation

Cancel a transaction before it has been broadcast:

```bash theme={null}
curl -X POST "$BASE_URL/transactions/{id}/cancel" \
  -H "Authorization: Bearer $CUSTODY_API_KEY"
```

<Warning>
  You can only cancel transactions in `SUBMITTED`, `PENDING_AUTHORIZATION`, `APPROVED`, or `PENDING_SIGNATURE`. Once a transaction is `SIGNED`, `BROADCASTING`, or `CONFIRMING`, it cannot be cancelled.
</Warning>

## Idempotency

Include an `Idempotency-Key` header to safely retry requests without creating duplicate transactions:

```bash theme={null}
curl -X POST "$BASE_URL/transactions" \
  -H "Authorization: Bearer $CUSTODY_API_KEY" \
  -H "Idempotency-Key: unique-request-id-123" \
  -H "Content-Type: application/json" \
  -d '{...}'
```

Idempotency keys expire after 24 hours.

## Listing and filtering

```bash theme={null}
# List all transactions
curl "$BASE_URL/transactions" \
  -H "Authorization: Bearer $CUSTODY_API_KEY"

# Get a specific transaction
curl "$BASE_URL/transactions/{id}" \
  -H "Authorization: Bearer $CUSTODY_API_KEY"
```
