This guide walks through the complete lifecycle of a Delivery vs. Payment (DvP) settlement, from instruction to finalization.
What we’re building
A tokenized private credit settlement where:
Seller delivers 100 tokens of a private credit fund
Buyer pays 50,000 USDC
Both legs settle atomically - either both complete or neither does
1. Set up your template
Templates define the settlement workflow. You typically create these once and reuse them.
curl -X POST https://api.keystoneos.xyz/v1/settlement-templates \
-H "Authorization: Bearer $TOKEN " \
-H "Content-Type: application/json" \
-d '{
"name": "Standard DvP",
"config": {
"initial_state": "INSTRUCTED",
"terminal_states": ["FINALIZED"],
"failure_states": ["ROLLED_BACK", "TIMED_OUT"],
"transitions": {
"INSTRUCTED": ["COMPLIANCE_CHECKING"],
"COMPLIANCE_CHECKING": ["COMPLIANCE_CLEARED", "ROLLED_BACK"],
"COMPLIANCE_CLEARED": ["REGISTERING_ESCROW"],
"REGISTERING_ESCROW": ["AWAITING_DEPOSITS", "ROLLED_BACK"],
"AWAITING_DEPOSITS": ["EXECUTING_SWAP", "ROLLED_BACK", "TIMED_OUT"],
"EXECUTING_SWAP": ["SETTLED", "ROLLED_BACK"],
"SETTLED": ["FINALIZED"]
},
"actions": {
"INSTRUCTED": {
"type": "compliance_check",
"provider": "internal",
"resolution": "immediate"
},
"COMPLIANCE_CLEARED": {
"type": "register_escrow",
"provider": "escrow",
"resolution": "immediate"
},
"AWAITING_DEPOSITS": {
"type": "monitor_deposits",
"provider": "escrow",
"resolution": "webhook"
},
"EXECUTING_SWAP": {
"type": "execute_escrow",
"provider": "escrow",
"resolution": "immediate"
},
"SETTLED": {
"type": "finalize",
"provider": "internal",
"resolution": "immediate"
}
},
"required_roles": ["buyer", "seller"],
"required_leg_types": ["asset", "payment"],
"compliance_providers": {
"worldcheck": {"type": "entity_screening"},
"cipherowl": {"type": "wallet_screening"}
},
"payment_providers": {
"escrow": {"type": "smart_contract"}
}
}
}'
2. Initiate the settlement
Party details are provided inline - no separate registration step is needed.
curl -X POST https://api.keystoneos.xyz/v1/settlements \
-H "Authorization: Bearer $TOKEN " \
-H "Content-Type: application/json" \
-d '{
"idempotency_key": "my-first-dvp",
"template_id": "TEMPLATE_ID",
"timeout_at": "2026-03-17T00:00:00Z",
"parties": [
{
"role": "buyer",
"external_reference": "buyer-001",
"name": "Beta Capital",
"wallet_address": "0xBuyerWallet...",
"chain_id": 11155111
},
{
"role": "seller",
"external_reference": "seller-001",
"name": "Acme Securities",
"wallet_address": "0xSellerWallet...",
"chain_id": 11155111
}
],
"legs": [
{
"leg_type": "asset",
"instrument_id": "0xTokenAddress",
"quantity": "100",
"direction": "deliver",
"party_role": "seller"
},
{
"leg_type": "payment",
"instrument_id": "USDC",
"quantity": "50000",
"direction": "deliver",
"party_role": "buyer"
}
]
}'
The idempotency_key ensures safe retries. If you send the same key twice, the API returns the existing settlement instead of creating a duplicate.
3. Watch the state machine
After creation, the settlement engine automatically processes each state. You’ll see the settlement advance through:
INSTRUCTED --> COMPLIANCE_CHECKING --> COMPLIANCE_CLEARED
--> REGISTERING_ESCROW --> AWAITING_DEPOSITS
--> EXECUTING_SWAP --> SETTLED --> FINALIZED
Track progress in the KeyStone Dashboard under Settlements (click a settlement to see its timeline and events), or via the API:
# Poll settlement status
curl https://api.keystoneos.xyz/v1/settlements/ $SETTLEMENT_ID \
-H "Authorization: Bearer $TOKEN "
# View event history
curl https://api.keystoneos.xyz/v1/settlements/ $SETTLEMENT_ID /events \
-H "Authorization: Bearer $TOKEN "
4. Handle compliance flags
If the compliance check flags a party, the settlement pauses at COMPLIANCE_CHECKING. A compliance officer reviews and submits a decision:
curl -X POST https://api.keystoneos.xyz/v1/settlements/ $SETTLEMENT_ID /compliance-decision \
-H "Authorization: Bearer $TOKEN " \
-H "Content-Type: application/json" \
-d '{"decision": "approve"}'
If rejected, the settlement transitions to ROLLED_BACK.
5. Deposit to escrow
When the settlement reaches AWAITING_DEPOSITS, both parties deposit their assets to the escrow smart contract on-chain. KeyStone monitors deposits via Alchemy webhooks (real-time) with a fallback poller.
Once all deposits are confirmed, the engine automatically advances to EXECUTING_SWAP.
6. Settlement complete
The escrow contract executes the atomic swap - tokens to the buyer, USDC to the seller - in a single transaction. The settlement transitions through SETTLED to FINALIZED.
What if something goes wrong?
Compliance rejection - Settlement rolls back, no deposits affected.
Deposit timeout - If deposits aren’t received by timeout_at, the settlement transitions to TIMED_OUT and the escrow contract returns any partial deposits.
Execution failure - The escrow contract rolls back, returning all deposits to their original owners.
Every failure path is deterministic and recorded in the event history.
Core Concepts Deep dive into settlements, templates, and the state machine.
Cross-platform guide Settle across multiple platforms.