Platform

Overview

How It Works

Beneficiary Identity

Policy Corridors

Deterministic Finality

Architecture

Security Model

Governance

Integration

Solutions

Corridors Overview

Institutional Overview

Pricing

All Scenarios

Humanitarian Impact Fund

Assurance

Technical Assurance

Verify Receipt

Receipt Example

Developers

Documentation

APIs & Bridges

Architecture Docs

Glossary

BID API

Company

About

Team

Partners

Roadmap

Investors

Contact

Blog

All Documentation

Schedule Consultation
API Reference v1.0 Documentation →

Settlement API Specification

Complete API reference for atomic settlement, compliance validation, finality proofs, and cross-jurisdictional clearing. Programmatic access to the JIL Sovereign settlement engine.

Published: February 2026 Version: 1.0 JIL Sovereign Technologies, Inc.

Overview

The JIL Sovereign Institutional Settlement API provides programmatic access to the settlement engine for banks, payment processors, custodians, and other financial institutions. All settlements are processed through the JIL Sovereign L1 ledger with compliance checks, cryptographic finality proofs, and full audit trails.

Base URLs

EnvironmentBase URL
Productionhttps://settlement.jilsovereign.com
Devnethttps://devnet-settlement.jilsovereign.com
Local (Docker)http://settlement-api:8050

Protocol

PropertyValue
TransportHTTPS (TLS 1.3 required in production)
Content Typeapplication/json
Character EncodingUTF-8
Date FormatISO 8601 (2026-02-09T14:30:00.000Z)
Amount PrecisionString-encoded decimals (e.g. "1500.00")
IdempotencyBy (client_id, external_id) pair
Devnet Access: Contact developers@jilsovereign.com to provision your API key and sandbox credentials before integrating.

Authentication

All API requests must include a valid API key. Enterprise clients may additionally enable HMAC request signing for enhanced security.

API Key Authentication

Include your API key in the x-api-key header with every request.

GET /v1/settlements/stl_abc123 HTTP/1.1 Host: settlement.jilsovereign.com x-api-key: sk_live_9f1c4a2b... Content-Type: application/json

HMAC Request Signing (Optional)

For enhanced security, enterprise clients can enable HMAC-SHA256 request signing. When enabled, every request must include two additional headers: x-timestamp and x-signature.

Signature Formula

// Signature = HMAC-SHA256(secret, method + path + timestamp + sha256(body)) const crypto = require('crypto'); function signRequest(secret, method, path, timestamp, body) { const bodyHash = crypto.createHash('sha256') .update(body || '') .digest('hex'); const payload = method + path + timestamp + bodyHash; return crypto.createHmac('sha256', secret) .update(payload) .digest('hex'); }

Signed Request Headers

x-api-key: sk_live_9f1c4a2b... x-timestamp: 1739097600000 x-signature: a3f2c8d1e5b7... Content-Type: application/json
Timestamp Validation: The x-timestamp must be within 5 minutes of server time. Requests with stale timestamps are rejected with HTTP 401.

Rate Limit Tiers

TierRequests/minProvisioning
Standard60Default for all API keys
Premium300Available on request
Enterprise6,000Dedicated onboarding required

Settlement Submission

POST /v1/settlements

Submit a single settlement for processing. The settlement is validated, checked for compliance, and submitted to the L1 ledger. Idempotent by (client_id, external_id).

Request Body

FieldTypeRequiredDescription
external_idstringrequiredYour unique identifier for this settlement (max 128 chars)
settlement_typestringoptionalSettlement type: SIMPLE, DVP, or PVP. Defaults to SIMPLE.
lanestringoptionalSettlement lane: FI_TO_FI, FI_TO_CRYPTO, or CRYPTO_TO_CRYPTO. Auto-detected from account types if omitted.
from_accountstringrequiredSource account address or JIL handle
to_accountstringrequiredDestination account address or JIL handle
assetstringrequiredAsset symbol (e.g. JIL, USDC, BTC)
amountstringrequiredAmount as decimal string (e.g. "1500.00")
zone_idstringoptionalTarget settlement zone. Defaults to auto-routing.
memostringoptionalArbitrary memo field (max 256 chars)
Settlement Types: SIMPLE is a single-leg transfer. DVP (Delivery vs Payment) links an asset leg with a payment leg - both commit atomically or neither does. PVP (Payment vs Payment) links two payment legs for FX settlement. DVP/PVP settlements require both legs to attest readiness before finalization.

Example Request

POST /v1/settlements HTTP/1.1 Host: settlement.jilsovereign.com x-api-key: sk_live_9f1c4a2b... Content-Type: application/json { "external_id": "INV-2026-0209-001", "from_account": "jil1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh", "to_account": "jil1grht6d6c4eyqvkde4pjhvmr6s7elggcuqfjmh32", "asset": "USDC", "amount": "50000.00", "settlement_type": "SIMPLE", "lane": "FI_TO_FI", "zone_id": "us-east", "memo": "Q1 vendor payment" }

Response (201 Created)

{ "id": "stl_7f3a9b2c4e1d", "external_id": "INV-2026-0209-001", "status": "received", "created_at": "2026-02-09T14:30:00.123Z" }

POST /v1/settlements/batch

Submit a batch of 1 to 100 settlements in a single request. Each settlement is independently validated and processed.

Request Body

FieldTypeRequiredDescription
external_batch_idstringrequiredYour unique identifier for this batch (max 128 chars)
settlementsarrayrequiredArray of settlement objects (1-100 items)

Example Request

POST /v1/settlements/batch HTTP/1.1 x-api-key: sk_live_9f1c4a2b... Content-Type: application/json { "external_batch_id": "BATCH-2026-0209-PAYROLL", "settlements": [ { "external_id": "PAY-001", "from_account": "jil1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh", "to_account": "jil1grht6d6c4eyqvkde4pjhvmr6s7elggcuqfjmh32", "asset": "USDC", "amount": "12500.00", "memo": "Salary - Feb 2026" }, { "external_id": "PAY-002", "from_account": "jil1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh", "to_account": "jil1w508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4", "asset": "USDC", "amount": "8750.00", "memo": "Salary - Feb 2026" } ] }

Response (201 Created)

{ "batch_id": "bat_e2c8f1a3b5d9", "external_batch_id": "BATCH-2026-0209-PAYROLL", "total": 2, "accepted": 2, "rejected": 0, "results": [ { "index": 0, "id": "stl_a1b2c3d4e5f6", "status": "received" }, { "index": 1, "id": "stl_b2c3d4e5f6a7", "status": "received" } ], "created_at": "2026-02-09T14:30:00.456Z" }

Settlement Actions

POST /v1/settlements/:id/cancel

Cancel a settlement that has not yet reached submitted state. Settlements in received, validated, compliance_check, accepted, or ready states can be cancelled. Returns HTTP 409 if the settlement has already been submitted to the L1 ledger.

Response (200 OK)

{ "id": "stl_7f3a9b2c4e1d", "status": "cancelled", "cancelled_at": "2026-02-09T14:31:00.123Z" }

POST /v1/settlements/:id/attest-ready

Attest that your side of a DVP or PVP settlement is ready for finalization. Both parties must attest readiness before the settlement can proceed to submitted state. Only applicable to DVP/PVP settlement types. Returns HTTP 409 if the settlement is not in accepted state or is a SIMPLE type.

Response (200 OK)

{ "id": "stl_7f3a9b2c4e1d", "status": "ready", "readiness": { "party_a": true, "party_b": true, "both_ready_at": "2026-02-09T14:30:01.456Z" } }

Settlement Status

GET /v1/settlements/:id

Retrieve the full status of a settlement including L1 ledger details, compliance results, and timing information.

Response (200 OK)

{ "id": "stl_7f3a9b2c4e1d", "external_id": "INV-2026-0209-001", "status": "final", "from_account": "jil1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh", "to_account": "jil1grht6d6c4eyqvkde4pjhvmr6s7elggcuqfjmh32", "asset": "USDC", "amount": "50000.00", "zone_id": "us-east", "l1": { "tx_hash": "0x8a2f3c...b9e1d4", "block_number": 1847293, "block_hash": "0x4e7f1a...c3d8b2", "confirmations": 6, "gas_used": 42150 }, "compliance": { "status": "passed", "checks": ["sanctions", "aml", "jurisdiction"], "receipt_hash": "0x5b9c2d...a1e3f7" }, "settlement_type": "SIMPLE", "lane": "FI_TO_FI", "timestamps": { "received_at": "2026-02-09T14:30:00.123Z", "validated_at": "2026-02-09T14:30:00.234Z", "compliance_check_at": "2026-02-09T14:30:00.456Z", "accepted_at": "2026-02-09T14:30:00.512Z", "ready_at": "2026-02-09T14:30:00.678Z", "submitted_at": "2026-02-09T14:30:00.789Z", "confirmed_at": "2026-02-09T14:30:02.345Z", "final_at": "2026-02-09T14:30:11.012Z" }, "fee": { "amount": "20.00", "bps": 4, "calculated_at": "2026-02-09T14:30:11.012Z", "note": "Fee calculated at finality" } }

GET /v1/settlements/:id/proof

Retrieve the cryptographic finality proof for a completed settlement. Only available when the settlement status is final. Returns HTTP 409 if the settlement has not yet reached finality.

Response (200 OK)

{ "settlement_id": "stl_7f3a9b2c4e1d", "proof": { "block_hash": "0x4e7f1a...c3d8b2", "block_number": 1847293, "tx_hash": "0x8a2f3c...b9e1d4", "merkle_root": "0x3c1d8a...f2e7b9", "merkle_proof": ["0xa1...", "0xb2...", "0xc3..."], "validator_signatures": { "threshold": "14-of-20", "signers": 14, "signatures": [ { "validator": "val_us_east_01", "jurisdiction": "US", "signature": "0xed25519..." } ] }, "compliance_receipt": { "hash": "0x5b9c2d...a1e3f7", "checks_passed": ["sanctions", "aml", "jurisdiction"], "timestamp": "2026-02-09T14:30:00.456Z" } }, "finalized_at": "2026-02-09T14:30:11.012Z" }

GET /v1/settlements/:id/receipt

Retrieve the full settlement receipt including fee breakdown, compliance attestation, and reconciliation data. Only available when the settlement status is final.

Response (200 OK)

{ "settlement_id": "stl_7f3a9b2c4e1d", "receipt": { "settlement_type": "SIMPLE", "lane": "FI_TO_FI", "asset": "USDC", "amount": "50000.00", "fee": { "amount": "20.00", "bps": 4, "calculated_at": "2026-02-09T14:30:11.012Z" }, "compliance_receipt": { "hash": "0x5b9c2d...a1e3f7", "checks_passed": ["sanctions", "aml", "jurisdiction", "travel_rule"] }, "beneficiary_binding_hash": "0x7d4e2a...b8c1f3", "beneficiary_verified_at": "2026-02-09T14:29:58.234Z", "bec_check_result": "PASS", "proof_hash": "0x3c1d8a...f2e7b9", "quorum_attestation": "14-of-20" }, "finalized_at": "2026-02-09T14:30:11.012Z" }
BEC Prevention: In addition to DVP/PVP readiness attestations, JIL enforces beneficiary identity binding at submission and runs a BEC prevention gate prior to finalization. The settlement_receipt includes beneficiary_binding_hash, beneficiary_verified_at, and bec_check_result.

GET /v1/settlements/batch/:batch_id

Retrieve the summary and individual results for a batch settlement.

Response (200 OK)

{ "batch_id": "bat_e2c8f1a3b5d9", "total": 2, "summary": { "received": 0, "validated": 0, "compliance_check": 0, "accepted": 0, "ready": 0, "submitted": 0, "confirmed": 0, "final": 2, "rejected": 0, "failed": 0, "cancelled": 0, "expired": 0 }, "settlements": [ { "id": "stl_a1b2c3d4e5f6", "status": "final" }, { "id": "stl_b2c3d4e5f6a7", "status": "final" } ] }

Settlement Lifecycle

Every settlement follows a deterministic state machine from submission through finality. The lifecycle ensures compliance validation, L1 ledger confirmation, and cryptographic proof generation.

State Machine (9 States)

received
validated
compliance_check
accepted
ready
ready
submitted
confirmed
final
compliance denied
compliance_check
rejected
 
L1 error / timeout
submitted
failed
 
user action / timeout
any pre-submit
cancelled
 
TTL exceeded
any state
expired

State Descriptions

StateDescriptionTerminal?
receivedSettlement accepted by the API and queued for structural validation.No
validatedStructural validation passed (fields, formats, accounts). Queued for compliance.No
compliance_checkCompliance validation in progress (sanctions, AML, jurisdiction, travel rule evaluation).No
acceptedCompliance passed. Awaiting readiness attestation (for DVP/PVP) or auto-promoted to ready (for SIMPLE).No
readyAll parties have attested readiness. Queued for L1 ledger submission.No
submittedSubmitted to the L1 ledger for inclusion in a block.No
confirmedIncluded in a block. Awaiting finality (6 confirmations, ~9 seconds at 1.5s block time).No
finalSettlement is complete with a cryptographic finality proof. Fees calculated at this state. Irreversible.Yes
rejectedCompliance denied the settlement. Review compliance receipt for details.Yes
failedL1 ledger error or timeout. Can be resubmitted with same external_id.Yes
cancelledCancelled by the submitting party before reaching submitted state.Yes
expiredTime-to-live (TTL) exceeded without reaching a terminal state.Yes
Time to Finality: Under normal conditions, a settlement reaches final status within 10-15 seconds. Compliance checks complete in under 500ms. The L1 ledger confirms in 1.5-second blocks with finality after 6 confirmations (~9 seconds).

Settlement Types

TypeLegsReadinessUse Case
SIMPLESingle leg (one-way transfer)Auto-promoted from accepted to readyStandard transfers, payroll, distributions
DVPAsset leg + Payment legBoth parties must call /attest-ready. Per-leg compliance applied.Securities settlement, tokenized asset trades
PVPPayment A + Payment BBoth parties must call /attest-ready. Per-leg compliance applied.FX settlement, cross-currency swaps

Settlement Lanes

Every settlement is routed through one of three lanes. The lane determines compliance depth, fee tier, and reconciliation format.

LaneDescriptionComplianceTypical Fee
FI_TO_FIFinancial Institution to Financial Institution. Full regulatory compliance corridor between LEI-identified participants.Sanctions, AML, jurisdiction, travel rule evaluation, cross-border checks3-4 bps
FI_TO_CRYPTOFinancial Institution to crypto-native account. Bridge between regulated and on-chain ecosystems.Sanctions, AML, jurisdiction, travel rule evaluation, address screening4-5 bps
CRYPTO_TO_CRYPTOOn-chain account to on-chain account. Permissionless settlement with baseline compliance.Sanctions screening, address risk scoring3-5 bps
Fee Timing: Settlement fees are calculated at the final state, not at submission. The fee is based on the settlement notional at the time of finality. Settlements that do not reach finality incur no fee.

Reconciliation

GET /v1/reconciliation/transactions

Query settlement transactions for reconciliation. Supports cursor-based pagination, date ranges, and filtering by status, asset, and account.

Query Parameters

ParameterTypeRequiredDescription
cursorstringoptionalCursor for pagination. Omit for first page.
limitintegeroptionalResults per page, 1-200. Default: 50.
statusstringoptionalFilter by status (e.g. final, failed).
assetstringoptionalFilter by asset symbol (e.g. USDC).
accountstringoptionalFilter by from or to account address.
from_datestringoptionalStart date (ISO 8601). Inclusive.
to_datestringoptionalEnd date (ISO 8601). Exclusive.

Response (200 OK)

{ "transactions": [ { "id": "stl_7f3a9b2c4e1d", "external_id": "INV-2026-0209-001", "status": "final", "asset": "USDC", "amount": "50000.00", "created_at": "2026-02-09T14:30:00.123Z", "final_at": "2026-02-09T14:30:11.012Z" } ], "pagination": { "cursor": "eyJpZCI6InN0bF83ZjN...", "has_more": true, "limit": 50 } }
Cursor Pagination: Use the cursor value from the response to fetch the next page. When has_more is false, you have reached the end of the result set.

Webhooks

Subscribe to real-time settlement events via webhooks. All webhook payloads are signed with HMAC-SHA256 so you can verify authenticity before processing.

Webhook Events

EventDescription
SETTLEMENT_RECEIVEDSettlement accepted and queued for validation
SETTLEMENT_VALIDATEDStructural validation passed, queued for compliance
SETTLEMENT_COMPLIANCE_CHECKCompliance validation started (sanctions, AML, jurisdiction, travel rule)
SETTLEMENT_ACCEPTEDCompliance passed, awaiting readiness attestation
SETTLEMENT_READYAll parties attested readiness, queued for L1 submission
SETTLEMENT_REJECTEDCompliance denied the settlement
SETTLEMENT_SUBMITTEDSubmitted to L1 ledger
SETTLEMENT_CONFIRMEDIncluded in a block, awaiting finality
SETTLEMENT_FINALSettlement finalized with cryptographic proof. Fee calculated.
SETTLEMENT_FAILEDL1 error or timeout
SETTLEMENT_CANCELLEDSettlement cancelled before L1 submission
SETTLEMENT_EXPIREDSettlement TTL exceeded
BATCH_CREATEDBatch accepted for processing
BATCH_COMPLETEDAll settlements in batch reached terminal state

Managing Webhooks

POST /v1/webhooks

Create a webhook subscription. The signing secret is returned only once in the creation response.

// Request { "url": "https://your-bank.com/api/jil-webhooks", "events": ["SETTLEMENT_FINAL", "SETTLEMENT_FAILED"], "description": "Production settlement notifications" } // Response (201) { "id": "whk_9a3c7d1e5f2b", "url": "https://your-bank.com/api/jil-webhooks", "signing_secret": "whsec_k8m3n7p2q5r9s1t4v6w8x0y3z", "active": true }
Save the signing_secret immediately. It is only returned once during webhook creation. If lost, you must delete and recreate the webhook to receive a new secret.

GET /v1/webhooks

List all webhook subscriptions for your API key.

DELETE /v1/webhooks/:id

Deactivate a webhook subscription. Deactivated webhooks stop receiving events immediately.

Webhook Payload Format

// Webhook delivery headers POST /api/jil-webhooks HTTP/1.1 Content-Type: application/json x-jil-signature: sha256=a3f2c8d1e5b7f9a2c4d6e8f0... x-jil-event: SETTLEMENT_FINAL x-jil-delivery-id: del_f2a8c3d1e5b7 // Webhook payload { "event": "SETTLEMENT_FINAL", "delivery_id": "del_f2a8c3d1e5b7", "timestamp": "2026-02-09T14:30:11.012Z", "data": { "id": "stl_7f3a9b2c4e1d", "status": "final", "asset": "USDC", "amount": "50000.00", "l1_tx_hash": "0x8a2f3c...b9e1d4" } }

Signature Verification

const crypto = require('crypto'); function verifyWebhookSignature(secret, body, signature) { const expected = 'sha256=' + crypto .createHmac('sha256', secret) .update(body) .digest('hex'); return crypto.timingSafeEqual( Buffer.from(expected), Buffer.from(signature) ); }

Retry Policy

Failed webhook deliveries (non-2xx response or timeout after 10 seconds) are retried with exponential backoff. After 8 failed attempts, the delivery is marked as permanently failed.

AttemptDelayCumulative Wait
1 (initial)Immediate0s
230 seconds30s
32 minutes2m 30s
410 minutes12m 30s
530 minutes42m 30s
61 hour1h 42m 30s
72 hours3h 42m 30s
84 hours7h 42m 30s

Health Check

GET /health

Returns the health status of the settlement API including connectivity to downstream dependencies. This endpoint does not require authentication.

Response (200 OK)

{ "ok": true, "service": "settlement-api", "version": "1.0.0", "uptime_seconds": 847293, "dependencies": { "database": { "status": "healthy", "latency_ms": 2 }, "ledger_router": { "status": "healthy", "latency_ms": 8 }, "compliance": { "status": "healthy", "latency_ms": 5 } } }

Code Examples

Complete JavaScript/TypeScript examples for common settlement operations.

1. API Client Setup

const API_KEY = process.env.JIL_API_KEY; const BASE_URL = 'https://settlement.jilsovereign.com'; async function apiRequest(method, path, body) { const response = await fetch(`${BASE_URL}${path}`, { method, headers: { 'x-api-key': API_KEY, 'Content-Type': 'application/json', }, body: body ? JSON.stringify(body) : undefined, }); if (!response.ok) { const err = await response.json(); throw new Error(`API Error ${response.status}: ${err.message}`); } return response.json(); }

2. Submit a Settlement

const settlement = await apiRequest('POST', '/v1/settlements', { external_id: 'INV-2026-0209-001', from_account: 'jil1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh', to_account: 'jil1grht6d6c4eyqvkde4pjhvmr6s7elggcuqfjmh32', asset: 'USDC', amount: '50000.00', }); console.log('Settlement ID:', settlement.id); // Settlement ID: stl_7f3a9b2c4e1d

3. Poll for Finality

async function waitForFinality(id, timeoutMs = 30000) { const start = Date.now(); while (Date.now() - start < timeoutMs) { const result = await apiRequest('GET', `/v1/settlements/${id}`); if (result.status === 'final') return result; if (['rejected', 'failed', 'cancelled', 'expired'].includes(result.status)) throw new Error(`Settlement ${result.status}`); await new Promise(r => setTimeout(r, 2000)); } throw new Error('Finality timeout'); }

4. Batch Settlement

const batch = await apiRequest('POST', '/v1/settlements/batch', { external_batch_id: 'BATCH-2026-0209-PAYROLL', settlements: [ { external_id: 'PAY-001', from_account: 'jil1qxy...', to_account: 'jil1grht...', asset: 'USDC', amount: '12500.00' }, { external_id: 'PAY-002', from_account: 'jil1qxy...', to_account: 'jil1w508...', asset: 'USDC', amount: '8750.00' }, ], }); console.log(`Batch: ${batch.accepted}/${batch.total} accepted`);

5. Reconciliation Query

const today = new Date().toISOString().split('T')[0]; const params = new URLSearchParams({ status: 'final', asset: 'USDC', from_date: `${today}T00:00:00.000Z`, limit: '200', }); let cursor = null, all = []; do { if (cursor) params.set('cursor', cursor); const page = await apiRequest('GET', `/v1/reconciliation/transactions?${params}`); all = all.concat(page.transactions); cursor = page.pagination.has_more ? page.pagination.cursor : null; } while (cursor); console.log(`Reconciled ${all.length} settlements`);

Error Codes

All error responses include a JSON body with error, message, and optional details fields.

Error Response Format

{ "error": "VALIDATION_ERROR", "message": "Request validation failed", "details": [ { "field": "amount", "code": "invalid_type", "message": "Expected string, received number" } ] }

HTTP Status Codes

StatusError CodeDescription
400VALIDATION_ERRORRequest body failed Zod schema validation.
401UNAUTHORIZEDMissing or invalid API key, expired HMAC timestamp, or invalid signature.
403ZONE_NOT_ALLOWEDAPI key not authorized for the requested settlement zone.
404SETTLEMENT_NOT_FOUNDSettlement ID does not exist or does not belong to your client.
404BATCH_NOT_FOUNDBatch ID does not exist or does not belong to your client.
404WEBHOOK_NOT_FOUNDWebhook ID does not exist or does not belong to your client.
409NOT_YET_FINALIZEDFinality proof requested for non-final settlement.
429RATE_LIMIT_EXCEEDEDToo many requests. Includes retry_after_ms.

Rate Limits

Rate limits are enforced per API key using a sliding window algorithm. Rate limit information is returned in response headers for every request.

Rate Limit Tiers

TierRequests/minBatch SizeConcurrent Batches
Standard60Up to 251
Premium300Up to 505
Enterprise6,000Up to 100Unlimited

Rate Limit Headers

Every response includes the following rate limit headers.

x-ratelimit-limit: 300 x-ratelimit-remaining: 295 x-ratelimit-reset: 1739097660
HeaderDescription
x-ratelimit-limitMaximum requests allowed in the current window
x-ratelimit-remainingRequests remaining in the current window
x-ratelimit-resetUnix timestamp (seconds) when the rate limit window resets
Need higher limits? Contact us at contact@jilsovereign.com for enterprise access with dedicated rate limits and priority support.