Download OpenAPI specification:
API for exchanges to report fiat deposit and withdrawal transactions to CACI for reconciliation and compliance tracking.
This API allows cryptocurrency exchanges to report completed fiat transactions to CACI in real-time or batch mode.
Key Features:
API Key Authentication:
X-Api-Key headerTo generate the HMAC-SHA512 signature, follow these steps:
import hmac
import hashlib
import json
def generate_signature(method, path, raw_body, timestamp, client_secret):
"""
Generate HMAC-SHA512 signature for CACI API authentication
Args:
method: HTTP method (e.g., 'POST', 'GET')
path: API endpoint path (e.g., '/v1/transactions/fiat')
raw_body: Raw request body JSON string (empty string for GET/DELETE)
timestamp: Unix timestamp in milliseconds
client_secret: Your API secret key
Returns:
Hexadecimal signature string
"""
# Create canonical JSON with sorted keys
if raw_body:
try:
# Parse and re-sort JSON to ensure canonical ordering
body_dict = json.loads(raw_body)
canonical_body = json.dumps(body_dict, sort_keys=True, separators=(',', ':'))
except json.JSONDecodeError:
canonical_body = raw_body
else:
canonical_body = ""
# Build payload
payload = f"{method}|{path}|{canonical_body}|{timestamp}"
# Generate HMAC-SHA512 signature
signature = hmac.new(
client_secret.encode("utf-8"),
payload.encode("utf-8"),
hashlib.sha512
).hexdigest()
return signature
# Example usage
if __name__ == "__main__":
# Sample request data
method = "POST"
path = "/v1/transactions/fiat"
timestamp = 1763474667930
client_secret = "your_api_secret_here"
# Sample request body
request_data = {
"exchange_id": "EXCHANGE-001",
"request_id": "3ed3502d-321b-4b84-b1b1-df45629bd46f",
"request_ts_ms": 1763474667930,
"transactions": [
{
"transaction_id": "5023ed3d-321b-4b84-b1b1-d29bd4f4566f",
"user_id": "USER-001",
"transaction_type": "DEPOSIT",
"amount": "10000000",
"currency": "IDR",
"transaction_ts_ms": 1763474667930,
"status": "COMPLETED",
"bank_code": "BCA",
"bank_account_number": "1234567890",
"bank_account_name": "John Doe",
"reference_number": "REF-001",
"fee_amount": "5000",
"fee_currency": "IDR",
"metadata": [
{
"key": "payment_channel",
"value_type": "string",
"value": "bank_transfer"
},
{
"key": "verification_required",
"value_type": "boolean",
"value": False
}
]
}
]
}
# Convert to canonical JSON
raw_body = json.dumps(request_data, sort_keys=True, separators=(',', ':'))
# Generate signature
signature = generate_signature(method, path, raw_body, timestamp, client_secret)
print(f"Payload: {method}|{path}|{raw_body}|{timestamp}")
print(f"Signature: {signature}")
# Headers to include in request
headers = {
"X-Api-Key": "your_api_key_here",
"X-Signature": signature,
"X-Timestamp": str(timestamp)
}
Use Cases:
Report fiat deposit and withdrawal transactions from exchange to CACI for reconciliation and compliance tracking.
Functionality:
Use Cases:
Authentication:
Rate Limits:
Metadata Support:
Note: Trade report submission is processed asynchronously. The API will accept the payload and enqueue it for processing. You can check the processing status of a trade report from the ICEx dashboard.
| X-Api-Key required | string Example: 42a5eef831b2df8cb4a1106c1d6e623df7424322324afe73 Exchange API key for authentication |
| X-Signature required | string Example: 4b2f8a0e6c3c1a9d5f8b2c4e7a1d3f9b0c2e4a6d8f0b1c3d5e7f9a1b2c3d4e5f HMAC-SHA512 signature in lowercase hex format generated using the exchange's clientSecret. Payload format: "METHOD|PATH|BODY|X-Timestamp" where METHOD is the HTTP method, PATH is the request path (no host/query), BODY is the raw request body, and X-Timestamp is the same header value. |
| X-Timestamp required | string Example: 1760599371260 Unix timestamp in milliseconds used in signature payload |
| request_id | string Optional unique identifier generated by client for idempotency |
| payload_type required | string Value: "transactions-fiat-v1" Payload type identifier, must be "transactions-fiat-v1" |
| request_ts_ms required | integer <int64> UNIX timestamp in milliseconds when client initiates request |
required | Array of objects (FiatTransactionPayload) [ 1 .. 100 ] items Array of transaction objects (maximum 100 per request) |
{- "request_id": "05ca8afa-3912-4e2c-bdbb-5cb254b2b6db",
- "payload_type": "transactions-fiat-v1",
- "request_ts_ms": 1760599371260,
- "payload": {
- "transactions": [
- {
- "tx_id": "503fb0c9-9e7b-46cb-87c1-ccac697215f7",
- "user_id": "user-12345",
- "currency": "IDR",
- "tx_type": "DEPOSIT",
- "tx_channel": "TRANSFER",
- "tx_provider": "MANDIRI",
- "fiat_partner": "XENDIT",
- "amount": "100000.00",
- "transfer_fee": "0",
- "include_fee": false,
- "tx_ts_ms": 1760599371260,
- "fiat_partner_trx_id": "xendit-trx-abc123"
}
]
}
}{- "timestamp": 1760662221648,
- "request_id": "5023ed3d-321b-4b84-b1b1-d29bd4f4566f",
- "code": 200,
- "message": "SUCCESS",
- "data": { }
}include_fee boolean field to FiatTransactionPayload to indicate whether the transaction amount already includes the transfer feefiat_partner field to capture the fiat payment partner used by the exchange (e.g. XENDIT, DOKU)fiat_partner_trx_id field for payment partner transaction reference trackingprovider_trx_id field clarification — use fiat_partner_trx_id for partner-level referencetransactions-fiat-v1 envelope payload format with payload_type discriminatorTRANSFER, VIRTUAL_ACCOUNT, EWALLET, and QRIS transaction channelsX-Api-Key, X-Signature, X-Timestamp)request_id