Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.keystoneos.xyz/llms.txt

Use this file to discover all available pages before exploring further.

This guide walks you through a complete DvP (Delivery vs. Payment) settlement using bilateral instruction submission and autonomous on-chain execution.

Prerequisites

  • A KeyStone OS platform account with API credentials (M2M client ID and secret) - find these in the KeyStone Dashboard under Settings > General
  • An active environment (sandbox or production)

Step 1: Authenticate

KeyStone uses Auth0 M2M (client credentials) tokens for platform API access.
curl --request POST \
  --url https://auth.keystoneos.xyz/oauth/token \
  --header 'content-type: application/json' \
  --data '{
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "audience": "https://api.keystoneos.xyz",
    "grant_type": "client_credentials"
  }'
The returned access_token is a JWT valid for 24 hours. Include it in all API requests:
Authorization: Bearer {access_token}

Step 2: Browse available templates

Templates define the settlement workflow and are pre-configured by KeyStone. Browse the available templates to find the right one for your use case.
curl https://api.keystoneos.xyz/v1/settlement-templates \
  -H "Authorization: Bearer $TOKEN"
Pick the template that matches your settlement type. For a standard DvP settlement, use the dvp-standard template. Note the slug field - you will reference it when submitting instructions.

Step 3: Submit the seller instruction

Submit one side of the trade. KeyStone generates a trade reference that your counterparty will use to submit the other side.
curl -X POST https://api.keystoneos.xyz/v1/instructions \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "idempotency_key": "dvp-2026-001",
    "template_slug": "dvp-standard",
    "role": "seller",
    "party": {
      "external_reference": "seller-001",
      "name": "Acme Securities",
      "wallet_address": "0xSellerWallet..."
    },
    "legs": [
      {
        "leg_type": "asset_delivery",
        "instrument_id": "0xTokenContractAddress",
        "quantity": "100",
        "direction": "deliver",
        "chain_id": 11155111
      },
      {
        "leg_type": "payment",
        "instrument_id": "0xUSDCAddress",
        "quantity": "50000",
        "direction": "receive",
        "chain_id": 11155111
      }
    ],
    "timeout_at": "2026-03-20T00:00:00Z"
  }'
The response includes a generated trade reference:
{
  "id": "inst-...",
  "trade_reference": "KS-a1b2c3d4-...",
  "status": "pending_match",
  "settlement_id": null
}

Step 4: Share trade reference with counterparty

Send the trade_reference to your counterparty through your own channels (email, chat, API integration, etc.). They will use it to submit the matching instruction.

Step 5: Counterparty submits matching instruction

The counterparty submits their side with the same trade reference:
curl -X POST https://api.keystoneos.xyz/v1/instructions \
  -H "Authorization: Bearer $COUNTERPARTY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "idempotency_key": "dvp-2026-001-buyer",
    "trade_reference": "KS-a1b2c3d4-...",
    "template_slug": "dvp-standard",
    "role": "buyer",
    "party": {
      "external_reference": "buyer-001",
      "name": "Beta Capital",
      "wallet_address": "0xBuyerWallet..."
    },
    "legs": [
      {
        "leg_type": "asset_delivery",
        "instrument_id": "0xTokenContractAddress",
        "quantity": "100",
        "direction": "receive",
        "chain_id": 11155111
      },
      {
        "leg_type": "payment",
        "instrument_id": "0xUSDCAddress",
        "quantity": "50000",
        "direction": "deliver",
        "chain_id": 11155111
      }
    ],
    "timeout_at": "2026-03-20T00:00:00Z"
  }'
When the instructions match, the response includes the new settlement:
{
  "id": "inst-...",
  "trade_reference": "KS-a1b2c3d4-...",
  "status": "matched",
  "settlement_id": "stl-..."
}

Step 6: Settlement created on-chain

After matching, KeyStone creates the settlement on the SettlementCoordinator contract. The state machine rules are stored on-chain, and the settlement enters INSTRUCTED.

Step 7: Compliance runs automatically

If the template has compliance configured, KeyStone screens all parties through LSEG World-Check (entity) and CipherOwl (wallet), then attests the results to the ComplianceRegistry on-chain. The contract enforces that compliance must pass before the settlement can advance.

Step 8: Both parties deposit to escrow

When the settlement reaches AWAITING_DEPOSITS, the settlement response includes a deposit_secret and deposit_key for each leg. Both parties deposit their assets directly to the escrow smart contract by calling depositLeg(settlementId, legIndex, depositSecret). Your platform uses its custody provider to sign the deposit transaction. KeyStone is not involved in the deposit step.

Step 9: Contracts auto-execute and finalize

The escrow contract detects when all deposits are complete and notifies the SettlementCoordinator. The coordinator verifies the atomicity gate (all legs deposited) and calls executeSettlement(settlementId, recipients[]) on the escrow - revealing recipient addresses only at this point. Tokens go to the buyer, USDC goes to the seller. The settlement transitions to FINALIZED.

Step 10: Check the result

curl https://api.keystoneos.xyz/v1/settlements/$SETTLEMENT_ID \
  -H "Authorization: Bearer $TOKEN"
Or subscribe to webhooks for real-time notifications. Register a webhook endpoint in the KeyStone Dashboard under Settings > Webhooks.

What happened

INSTRUCTED --> COMPLIANCE_CHECKING --> COMPLIANCE_CLEARED
           --> AWAITING_DEPOSITS --> EXECUTING_SWAP --> FINALIZED
PhaseWho drives it
Instruction matchingKeyStone API (off-chain)
On-chain creationKeyStone engine
Compliance screeningKeyStone compliance oracle
Compliance attestationKeyStone compliance oracle
Past compliance gateKeyStone engine (one transition)
DepositsParties deposit directly to escrow
ExecutionContracts (autonomous)
FinalizationContracts (autonomous)
Timeout (if needed)Anyone (permissionless)

Next: Authentication

Learn about M2M tokens, user tokens, scopes, and environment resolution.