Ubyx Platform Settlement AsyncAPI
Event-driven API documentation for the Ubyx Clearing Platform.
Overview
This AsyncAPI specification describes the event-driven architecture for clearing transaction events between the Ubyx Settlement Platform and external partner institutions.
Key Features
- CloudEvents v1.0 Format: All events follow the CloudEvents specification for standardized metadata
- Event-based Messaging: Secure, scalable event streaming with mTLS authentication
- Bidirectional Communication: Outbound (platform → partners) and Inbound (partners → platform) channels
- Schema Versioning: URN-based versioning (e.g.,
urn:ubyx:clearing:schema:1.0-beta)
Contact: Ubyx Platform Team (platform@ubyx.xyz)
License: Proprietary
External Docs: https://developers.ubyx.xyz
Servers
| Environment | URL | Protocol | Description |
|---|---|---|---|
| Sandbox | broker-sandbox.ubyx-platform.com:9092 |
secure-protocol | Sandbox Broker Server |
| Production | broker.ubyx-platform.com:9092 |
secure-protocol | Production Broker Server |
All servers require mTLS (Mutual TLS) authentication.
Channels
ubyx.outbound — Platform → Partners
Outbound channel for clearing transaction events emitted by the platform.
Consumer Configuration:
groupId: Use your institutionId (UUID format)clientId: Use your institutionId (UUID format)topic:ubyx.outbound
Broker Configuration:
- Replicas: 3
- Retention: 7 days
- Cleanup Policy: delete
Consumed Event: ClearingCloudEvent
CloudEvents v1.0 envelope containing clearing transaction event data.
Event Types Published:
ubyx.clearing.CONVERSION_CREATED— New conversion initiatedubyx.clearing.ISSUER_APPROVED— Issuer approved the conversionubyx.clearing.CONVERSION_COMPLETED— Conversion completed successfullyubyx.clearing.CONVERSION_FAILED— Conversion failed
ubyx.inbound — Partners → Platform
Inbound channel for clearing events published by partner institutions.
Producer Configuration:
clientId: Use your institutionId (UUID format)topic:ubyx.inbound
Supported Inbound Event Types
| Event Type | Message | Description |
|---|---|---|
ubyx.clearing.conversion.conversion-request |
ConversionRequestCloudEvent | New conversion request from institution |
ubyx.clearing.conversion.issuer-approval |
IssuerApprovalCloudEvent | Issuer approved the conversion |
ubyx.clearing.conversion.issuer-reject |
IssuerRejectCloudEvent | Issuer rejected the conversion |
ubyx.clearing.conversion.asset-settler-approval |
AssetSettlerApprovalCloudEvent | Asset settler approved |
ubyx.clearing.conversion.cash-settler-approval |
CashSettlerApprovalCloudEvent | Cash settler approved |
ubyx.clearing.conversion.asset-settler-confirm |
AssetSettlerConfirmCloudEvent | Asset settler confirmed settlement |
ubyx.clearing.conversion.cash-settler-confirm |
CashSettlerConfirmCloudEvent | Cash settler confirmed settlement |
ubyx.clearing.conversion.asset-settler-reject-confirm |
AssetSettlerRejectConfirmCloudEvent | Asset settler rejected at confirmation |
ubyx.clearing.conversion.cash-settler-reject-confirm |
CashSettlerRejectConfirmCloudEvent | Cash settler rejected at confirmation |
ubyx.clearing.conversion.asset-settler-reject-approve |
AssetSettlerRejectApproveCloudEvent | Asset settler rejected at approval |
ubyx.clearing.conversion.cash-settler-reject-approve |
CashSettlerRejectApproveCloudEvent | Cash settler rejected at approval |
CloudEvents Structure
All events follow the CloudEvents v1.0 specification:
{
"specversion": "1.0",
"id": "550e8400-e29b-41d4-a716-446655440000",
"type": "ubyx.clearing.CONVERSION_CREATED",
"source": "ubyx-platform-settlement",
"subject": "workflow-abc123",
"time": "2024-12-12T10:30:00Z",
"datacontenttype": "application/json",
"dataschema": "urn:ubyx:clearing:schema:1.0-beta",
"data": {
"clearingTransactionId": "request-conversion-123e4567",
"institutionId": "123e4567-e89b-12d3-a456-426614174000",
"workflowId": "settlement-wf-987654321",
"transactionType": "CONVERSION",
"status": "INITIATED"
}
}
CloudEvent Fields
| Field | Required | Description |
|---|---|---|
specversion |
Yes | Always "1.0" |
id |
Yes | Unique event identifier (UUID) |
type |
Yes | Event type (e.g., ubyx.clearing.CONVERSION_CREATED) |
source |
Yes | Source system (e.g., ubyx-platform-settlement) |
subject |
No | Correlation ID for tracing (typically workflow ID) |
time |
No | ISO 8601 UTC timestamp |
datacontenttype |
No | Always application/json |
dataschema |
No | URN schema version (e.g., urn:ubyx:clearing:schema:1.0-beta) |
data |
No | Business-specific payload |
Schemas
Transaction Types
| Type | Description |
|---|---|
CONVERSION |
Token-to-fiat or fiat-to-token conversion |
REDEMPTION |
Asset redemption within clearing |
MINTING |
Asset minting within clearing |
ERROR |
Error notification for failed transactions |
Transaction Statuses
| Status | Description |
|---|---|
INITIATED |
Transaction initiated |
PENDING |
Awaiting processing |
PROCESSING |
Currently being processed |
COMPLETED |
Successfully completed |
FAILED |
Processing failed |
REJECTED |
Rejected by participant |
Integration Examples
JavaScript Consumer (Outbound Events)
const { Kafka } = require('kafkajs');
const kafka = new Kafka({
clientId: 'your-institution-id',
brokers: ['broker-sandbox.ubyx-platform.com:9092'],
ssl: {
rejectUnauthorized: true,
cert: fs.readFileSync('./client-cert.pem'),
key: fs.readFileSync('./client-key.pem'),
ca: [fs.readFileSync('./ca-cert.pem')]
}
});
const consumer = kafka.consumer({ groupId: 'your-institution-id' });
await consumer.connect();
await consumer.subscribe({ topic: 'ubyx.outbound', fromBeginning: false });
await consumer.run({
eachMessage: async ({ topic, partition, message }) => {
const event = JSON.parse(message.value.toString());
console.log('Received CloudEvent:', event.type, event.id);
switch (event.type) {
case 'ubyx.clearing.CONVERSION_CREATED':
handleConversionCreated(event.data);
break;
case 'ubyx.clearing.ISSUER_APPROVED':
handleIssuerApproved(event.data);
break;
case 'ubyx.clearing.CONVERSION_COMPLETED':
handleSettlementCompleted(event.data);
break;
}
}
});
JavaScript Producer (Inbound Events)
const producer = kafka.producer();
await producer.connect();
// Send a conversion request
const conversionEvent = {
specversion: '1.0',
id: crypto.randomUUID(),
type: 'ubyx.clearing.conversion-request',
source: 'https://your-institution.example.com',
subject: `conversion-${Date.now()}`,
time: new Date().toISOString(),
datacontenttype: 'application/json',
data: {
conversionRequest: {
conversionType: 'REDEMPTION',
receivingInstitutionID: 'your-institution-id',
issuerID: 'issuer-001',
cashSettlerID: 'settler-cash-001',
assetSettlerID: 'settler-asset-001',
assetID: 'USDC',
quantity: 10000,
currency: 'USD',
ownerMeta: {
fullName: 'John Doe',
address: '123 Main Street, New York, NY 10001'
},
RIaccountNumber: 'US12345678901234'
}
}
};
await producer.send({
topic: 'ubyx.inbound',
messages: [{ value: JSON.stringify(conversionEvent) }]
});
Event Flow Diagram
Best Practices
Event Validation
Always validate incoming CloudEvents:
function validateCloudEvent(event) {
const required = ['specversion', 'id', 'type', 'source'];
for (const field of required) {
if (!event[field]) {
throw new Error(`Missing required field: ${field}`);
}
}
if (event.specversion !== '1.0') {
throw new Error('Unsupported CloudEvents version');
}
return true;
}
Idempotency
Use the event id field to ensure idempotent processing:
const processedEvents = new Set();
async function processEvent(event) {
if (processedEvents.has(event.id)) {
console.log('Duplicate event, skipping:', event.id);
return;
}
// Process the event...
processedEvents.add(event.id);
}
Error Handling
Implement robust error handling with retries:
consumer.on('consumer.crash', async ({ error }) => {
console.error('Consumer crashed:', error);
// Implement reconnection logic
await consumer.disconnect();
await consumer.connect();
});