Knightsbridge Financial
@account

REST API

The KnightsVault REST API provides programmatic access to accounts, statements, and transfers. All endpoints require an API key issued by a platform administrator.

Base URL & Authentication

Base URL

https://chain.kxco.ai/wallet/api/v1

Option A — Bearer token

Include an Authorization header with a Bearer token issued by a platform administrator. The raw token is shown once at creation and cannot be recovered.

Authorization: Bearer kxco_<your-api-key>

Option B — ML-DSA-65 signed request (post-quantum)

Institutional API clients may authenticate using per-request ML-DSA-65 signatures (NIST FIPS 204). The client generates a keypair locally, registers only the public key with a platform administrator, and signs each request with the private key. The server stores no secret — only the public key.

# Header format
Authorization: KXCO-MLDSA <pubkey_hex>.<timestamp_ms>.<sig_hex>

# Signed message (UTF-8 encoded)
"<timestamp_ms>:<METHOD>:<request_path>"

# Example (Node.js, using @noble/post-quantum)
import { ml_dsa65 } from '@noble/post-quantum/ml-dsa'

const ts  = Date.now().toString()
const msg = Buffer.from(`${ts}:GET:/api/v1/accounts/clxxxx`, 'utf8')
const sig = ml_dsa65.sign(secretKey, msg)

// Authorization: KXCO-MLDSA <pubkey_hex>.<ts>.<hex(sig)>

Timestamp must be within ±30 seconds of server time. Public keys are registered via the Back Office (Back Office → API Keys → Register ML-DSA Key).

All endpoints are served over HTTPS with hybrid post-quantum TLS (X25519MLKEM768). HTTP connections are rejected.

Errors

All errors return JSON with an error field.

StatusMeaning
401Missing or invalid API key
403Key does not have permission for this operation
404Resource not found
400Bad request — see error field for detail
429Rate limit exceeded (10 req/s per IP)
500Internal error

Accounts

GET/accounts/{id}Retrieve account details

Returns account details for the given account ID. id is the internal CUID (returned in the reference field of list responses).

curl -s "https://chain.kxco.ai/wallet/api/v1/accounts/clxxxx" \
  -H "Authorization: Bearer kxco_<key>"
{
  "id":          "clxxxx",
  "reference":   "KXCO-ABCD-1234",
  "email":       "client@institution.com",
  "status":      "approved",
  "dailyLimit":  50000,
  "singleLimit": 10000,
  "address":     "0xabc...def",
  "balance":     "12450.00"
}
GET/accounts/{id}/statementPaginated transaction statement

Returns a paginated transaction history for the account.

ParameterTypeDescription
pageintegerPage number, 1-based. Default: 1
limitintegerRecords per page. Max 200. Default: 50
{
  "total": 142,
  "page":  1,
  "limit": 50,
  "transactions": [
    {
      "txRef":       "TXN20260515-A1B2C3D4",
      "txHash":      "0xabc...",
      "direction":   "out",
      "amount":      "1000.00",
      "toAddress":   "0xdef...",
      "status":      "confirmed",
      "blockNumber": 40120,
      "timestamp":   1778900000,
      "createdAt":   "2026-05-15T10:00:00.000Z"
    }
  ]
}

Transfers

GET/transfersList transfers

Returns a paginated list of transfers. Optionally filtered by account.

ParameterTypeDescription
accountIdstringFilter by account ID. Optional.
pageintegerPage number, 1-based. Default: 1
limitintegerRecords per page. Max 200. Default: 50
POST/transfersInitiate a transfer

Initiates an ARMR transfer from the specified account. Signing is performed server-side using the account's encrypted private key — no password or key material is required in the request.

{
  "fromAccountId": "clxxxx",
  "to":            "0xRecipientAddress",
  "amount":        "1000.00",
  "memo":          "INV-2026-001"
}

memo is optional (max 512 chars). When the recipient is on the KnightsVault platform, the memo is encrypted with their ML-KEM-768 public key before being embedded in the transaction data field — chain observers cannot read it.

{
  "ok":        true,
  "txRef":     "TXN20260515-A1B2C3D4",
  "txHash":    "0xabc...",
  "status":    "pending"
}
The transfer record is persisted to the database before broadcast. If broadcast fails, the record is marked failed — it will not be retried automatically. Check the transfer status before re-submitting.
GET/transfers/{reference}Get transfer by reference

Retrieves a single transfer by its txRef (format: TXNYYYYMMDD-XXXXXXXX).

curl -s "https://chain.kxco.ai/wallet/api/v1/transfers/TXN20260515-A1B2C3D4" \
  -H "Authorization: Bearer kxco_<key>"
{
  "txRef":       "TXN20260515-A1B2C3D4",
  "txHash":      "0xabc...",
  "fromAddress": "0xsender...",
  "toAddress":   "0xrecipient...",
  "amount":      "1000.00",
  "direction":   "out",
  "status":      "confirmed",
  "blockNumber": 40120,
  "timestamp":   1778900000,
  "createdAt":   "2026-05-15T10:00:00.000Z"
}

Webhooks

KXCO delivers real-time payment events to HTTPS endpoints registered by the institution. Each delivery is signed with HMAC-SHA256 using a shared secret set by the platform administrator.

Event types

payment.initiatedPayment instruction received and persisted
payment.rate_lockedExchange rate locked — settlement amount fixed
payment.settledOn-chain settlement confirmed
payment.failedPayment failed — see failRsn in payload
payment.returnedPayment returned to sender

Request headers

X-KXCO-Signature:  sha256=<hmac_hex>
X-KXCO-Event:      payment.settled
X-KXCO-Timestamp:  1778900000
X-KXCO-Delivery:   <job_id>

Signature verification (Node.js)

const crypto = require('crypto')

function verify(secret, timestamp, rawBody, sigHeader) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${timestamp}.${rawBody}`)
    .digest('hex')
  const received = sigHeader.replace('sha256=', '')
  return crypto.timingSafeEqual(
    Buffer.from(expected, 'hex'),
    Buffer.from(received, 'hex')
  )
}

Reject deliveries where the timestamp is more than 5 minutes old to prevent replay attacks. Always use timingSafeEqual — never a string equality check.

Example payload — payment.settled

{
  "event":          "payment.settled",
  "uetr":           "550e8400-e29b-41d4-a716-446655440000",
  "txRef":          "KXCO-PMNT-20260515-A1B2C3",
  "status":         "SETTLED",
  "instrAmtCcy":    "USD",
  "instrAmt":       10000.00,
  "settlAmtCcy":    "ARMR",
  "settlAmt":       42500.00,
  "onChainTxHash":  "0xabc...",
  "sttlmTm":        "2026-05-15T10:00:00.000Z",
  "dbtrInst":       "KXCOBHBH",
  "cdtrInst":       "KXCODKDK"
}

Retry policy

AttemptDelay after failure
1Immediate
230 seconds
35 minutes
430 minutes
52 hours — final attempt, then DEAD

Your endpoint must return a 2xx status within 10 seconds. Any other response or timeout is treated as a failure and retried.

Banking Integration

POST/bank/connectISO 20022 integration

Returns integration instructions for connecting a correspondent banking system via ISO 20022 pacs.008 (FI-to-FI credit transfer). This endpoint documents the expected message format and field mappings for settlement instruction routing.

curl -s -X POST "https://chain.kxco.ai/wallet/api/v1/bank/connect" \
  -H "Authorization: Bearer kxco_<key>" \
  -H "Content-Type: application/json" \
  -d '{"institutionBIC":"XXXXGB2L","accountId":"clxxxx"}'

To request an API key or discuss integration requirements, contact the KXCO engineering team.