Skip to main content

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.

This guide walks you through a complete integration flow: authenticate, create organizational resources, and submit your first transaction on Quantum Chain.

Prerequisites

  • A Qustody account at app.qustody.io
  • An API key pair. Generate one from the dashboard or contact your tenant administrator
All examples target the production API at https://api.qustody.io. To run against your own deployment, override BASE_URL/base_url — see Configure a development network.

Step 1: Authenticate

Every request requires a Bearer token in the format key_id:secret.
export CUSTODY_API_KEY="your_key_id:your_secret"
export BASE_URL="https://api.qustody.io/v1"

# Test credentials
curl -s "$BASE_URL/healthz" | jq .
{
  "status": "healthy"
}

Step 2: Create a tenant

A tenant is an isolated organizational unit. All vaults, wallets, and transactions belong to a tenant.
curl -s -X POST "$BASE_URL/tenants" \
  -H "Authorization: Bearer $CUSTODY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "My Organization"}' | jq .
{
  "id": "tnt_abc123",
  "name": "My Organization",
  "status": "active",
  "created_at": "2026-03-19T10:00:00Z"
}
Save your tenant ID:
export TENANT_ID="tnt_abc123"

Step 3: Create a vault account

A vault account groups related wallets together.
curl -s -X POST "$BASE_URL/vault/accounts" \
  -H "Authorization: Bearer $CUSTODY_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"name\": \"Treasury\", \"tenant_id\": \"$TENANT_ID\"}" | jq .
{
  "id": "va_def456",
  "name": "Treasury",
  "tenant_id": "tnt_abc123",
  "created_at": "2026-03-19T10:01:00Z"
}

Step 4: Register a wallet

Register an external Quantum Chain wallet address. The custody API does not generate keys. You provide the public key, address, and an ownership proof from your external signer. The ownership proof is a post-quantum signature over the deterministic challenge Keccak256("qustody:register:" + lowercase_address).
curl -s -X POST "$BASE_URL/vault/accounts/va_def456/wallets" \
  -H "Authorization: Bearer $CUSTODY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "address": "0x1234...abcd",
    "publicKey": "<hex-encoded-public-key>",
    "signature": "<hex-encoded-ownership-signature>",
    "label": "Hot Wallet"
  }' | jq .
{
  "id": "wlt_ghi789",
  "address": "0x1234...abcd",
  "vault_account_id": "va_def456",
  "name": "Hot Wallet",
  "created_at": "2026-03-19T10:02:00Z"
}

Step 5: Create a transaction

Submit a transfer. The transaction enters PENDING_SIGNATURE status and waits for your external signer.
curl -s -X POST "$BASE_URL/transactions" \
  -H "Authorization: Bearer $CUSTODY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: first-transfer-001" \
  -d '{
    "asset_id": "QUANTUM",
    "source": {
      "type": "VAULT_ACCOUNT",
      "id": "va_def456"
    },
    "destination": {
      "type": "ONE_TIME_ADDRESS",
      "one_time_address": {
        "address": "0x5678...efgh"
      }
    },
    "amount": "1.5",
    "note": "First transfer"
  }' | jq .
{
  "id": "tx_jkl012",
  "status": "PENDING_SIGNATURE",
  "asset_id": "QUANTUM",
  "amount": "1.5",
  "created_at": "2026-03-19T10:03:00Z"
}

Step 6: Sign the transaction

Retrieve the signing payload and submit the signature from your external signer.
# Get the unsigned digest
curl -s "$BASE_URL/transactions/tx_jkl012/signing_payload" \
  -H "Authorization: Bearer $CUSTODY_API_KEY" | jq .

# Sign the hash in your HSM/key vault, then submit:
curl -s -X POST "$BASE_URL/transactions/tx_jkl012/signature" \
  -H "Authorization: Bearer $CUSTODY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "signature": "<base64-encoded-signature>",
    "signer_public_key": "<base64-encoded-public-key>"
  }' | jq .
The transaction moves through SIGNEDBROADCASTINGCONFIRMINGCOMPLETED.

Step 7: Verify completion

Poll the transaction or set up a webhook to receive status updates.
curl -s "$BASE_URL/transactions/tx_jkl012" \
  -H "Authorization: Bearer $CUSTODY_API_KEY" | jq .status
"COMPLETED"

Next steps

Authentication

Set up credentials and IP allowlisting for production.

Webhooks

Get real-time notifications instead of polling.

Policies

Enforce spending limits and approval workflows.

API reference

Explore all available endpoints.