Transaction Management API
This document describes the Transaction Management endpoints for Link Core, covering the complete transaction lifecycle including withdrawals, screening, and frozen transaction handling.
Endpoints
- List Transactions -
GET /transactions - Get Transaction -
GET /transactions/:id - Create Withdrawal -
POST /transactions/withdrawal - Complete Screening -
POST /transactions/complete-screening - Reject Frozen Deposit -
POST /transactions/:id/reject-frozen-deposit - Approve Frozen Deposit -
POST /transactions/:id/approve-frozen-deposit - Reject Frozen Withdrawal -
POST /transactions/:id/reject-frozen-withdrawal - Approve Frozen Withdrawal -
POST /transactions/:id/approve-frozen-withdrawal
List Transactions
Retrieves all transactions in the system.
Endpoint: GET /transactions
Response
Status: 200 OK
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"customerId": "customer-123",
"accountId": "account-456",
"assetId": "asset-789",
"type": "DEPOSIT",
"status": "COMPLETED",
"amount": "0.5",
"sourceAddress": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"destinationAddress": null,
"txHash": "0x1234...abcd",
"screeningData": {
"score": 0.95,
"provider": "Chainalysis"
},
"createdAt": "2025-11-20T10:30:00.000Z",
"updatedAt": "2025-11-20T10:35:00.000Z"
}
]
Response Fields
| Field | Type | Description |
|---|---|---|
id | string (UUID) | Transaction identifier |
customerId | string | Customer identifier |
accountId | string | Account identifier |
assetId | string (UUID) | Digital asset identifier |
type | string | Transaction type: DEPOSIT, WITHDRAWAL, TRANSFER |
status | string | Status: PENDING, FROZEN, APPROVED, COMPLETED, REJECTED, FAILED |
amount | string | Transaction amount (decimal string) |
sourceAddress | string | Source blockchain address (for deposits) |
destinationAddress | string | Destination blockchain address (for withdrawals) |
txHash | string | Blockchain transaction hash |
screeningData | object | AML/compliance screening results |
createdAt | string | Creation timestamp (ISO 8601) |
updatedAt | string | Last update timestamp (ISO 8601) |
Example
curl -X GET "https://api.ledgerlink.ai/v1/transactions"
Get Transaction
Retrieves a specific transaction by ID.
Endpoint: GET /transactions/:id
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string (UUID) | Yes | Transaction ID |
Response
Status: 200 OK
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"customerId": "customer-123",
"accountId": "account-456",
"assetId": "asset-789",
"type": "WITHDRAWAL",
"status": "FROZEN",
"amount": "1.5",
"sourceAddress": null,
"destinationAddress": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"txHash": null,
"screeningData": {
"score": 0.45,
"provider": "Chainalysis",
"flags": ["high_risk_address"],
"reason": "Destination address flagged for suspicious activity"
},
"createdAt": "2025-11-20T10:30:00.000Z",
"updatedAt": "2025-11-20T10:31:00.000Z",
"asset": {
"id": "asset-789",
"name": "Bitcoin",
"code": "BTC"
}
}
Example
curl -X GET "https://api.ledgerlink.ai/v1/transactions/550e8400-e29b-41d4-a716-446655440000"
Error Responses
404 Not Found
{
"statusCode": 404,
"message": "Transaction not found",
"error": "Not Found"
}
Create Withdrawal
Initiates a withdrawal request for a customer.
Endpoint: POST /transactions/withdrawal
Request Body
{
"accountId": "string",
"network": "string",
"assetId": "string",
"amount": "string",
"destinationAddress": "string",
"reference": "string"
}
| Field | Type | Required | Description |
|---|---|---|---|
accountId | string | Yes | Account identifier |
network | string | Yes | Blockchain network (e.g., "bitcoin", "ethereum") |
assetId | string (UUID) | Yes | Digital asset identifier |
amount | string | Yes | Withdrawal amount (decimal string) |
destinationAddress | string | Yes | Blockchain destination address |
reference | string | No | Optional reference or memo |
Response
Status: 201 Created
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"accountId": "account-456",
"assetId": "btc-asset-id",
"type": "WITHDRAWAL",
"status": "PENDING",
"amount": "0.5",
"network": "bitcoin",
"destinationAddress": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"reference": null,
"txHash": null,
"screeningData": null,
"createdAt": "2025-11-20T10:30:00.000Z",
"updatedAt": "2025-11-20T10:30:00.000Z"
}
Examples
Basic Withdrawal Request
curl -X POST "https://api.ledgerlink.ai/v1/transactions/withdrawal" \
-H "Content-Type: application/json" \
-d '{
"accountId": "account-456",
"network": "bitcoin",
"assetId": "btc-asset-id",
"amount": "0.5",
"destinationAddress": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh"
}'
Withdrawal with Reference
curl -X POST "https://api.ledgerlink.ai/v1/transactions/withdrawal" \
-H "Content-Type: application/json" \
-d '{
"accountId": "account-456",
"network": "ethereum",
"assetId": "eth-asset-id",
"amount": "2.5",
"destinationAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"reference": "customer-withdrawal-001"
}'
Error Responses
400 Bad Request
{
"statusCode": 400,
"message": ["amount must be a positive number", "destinationAddress must be a valid address"],
"error": "Bad Request"
}
Causes:
- Missing required fields
- Invalid amount (negative, zero, or non-numeric)
- Invalid destination address format
- Insufficient balance
404 Not Found
{
"statusCode": 404,
"message": "Customer or asset not found",
"error": "Not Found"
}
Withdrawal Flow
- Request Created → Status:
PENDING - Awaiting External Screening → External AML/compliance system performs checks
- Screening Callback → External system calls
/transactions/complete-screening- If approved → Blockchain transaction initiated
- If rejected → Status:
FROZEN, requires manual review
- Manual Review (if frozen) → Approve or reject via API
- Blockchain Execution → Wallet Manager processes on-chain transaction
- Completion → Status:
COMPLETED, balance deducted
Complete Screening
Webhook endpoint for external AML/compliance systems to report screening results.
Endpoint: POST /transactions/complete-screening
Request Body
{
"id": "string",
"isApproved": boolean,
"screeningData": {}
}
| Field | Type | Required | Description |
|---|---|---|---|
id | string (UUID) | Yes | Transaction ID |
isApproved | boolean | Yes | Whether screening passed (true) or failed (false) |
screeningData | object | No | Screening details (score, flags, provider, etc.) |
Response
Status: 200 OK
If Approved
{
"enqueued": true
}
The transaction is queued for processing. Balance updates and blockchain execution will occur asynchronously.
If Rejected
{}
The transaction status is updated to FROZEN and awaits manual review.
Examples
Approve Transaction
curl -X POST "https://api.ledgerlink.ai/v1/transactions/complete-screening" \
-H "Content-Type: application/json" \
-d '{
"id": "550e8400-e29b-41d4-a716-446655440000",
"isApproved": true,
"screeningData": {
"score": 0.95,
"provider": "Chainalysis",
"timestamp": "2025-11-20T10:31:00.000Z"
}
}'
Response:
{
"enqueued": true
}
Reject Transaction (Flag for Review)
curl -X POST "https://api.ledgerlink.ai/v1/transactions/complete-screening" \
-H "Content-Type: application/json" \
-d '{
"id": "550e8400-e29b-41d4-a716-446655440000",
"isApproved": false,
"screeningData": {
"score": 0.35,
"provider": "Chainalysis",
"flags": ["high_risk_address", "sanctioned_entity"],
"reason": "Destination address associated with sanctioned entity"
}
}'
Response:
{}
Transaction status updated to FROZEN.
Error Responses
404 Not Found
{
"statusCode": 404,
"message": "Transaction with ID 550e8400... not found.",
"error": "Not Found"
}
Notes
- This endpoint is designed to be called by external AML/compliance systems
- It should be secured with appropriate authentication (API keys, IP whitelisting, etc.)
- Approved transactions are queued for background processing via Bull queues
- Rejected transactions require manual intervention via approval/rejection endpoints
Reject Frozen Deposit
Rejects a deposit transaction that was frozen during screening.
Endpoint: POST /transactions/:id/reject-frozen-deposit
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string (UUID) | Yes | Transaction ID |
Request Body
{
"reason": "string"
}
| Field | Type | Required | Description |
|---|---|---|---|
reason | string | No | Reason for rejection |
Response
Status: 200 OK
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "REJECTED",
"rejectionReason": "AML compliance violation"
}
Example
curl -X POST "https://api.ledgerlink.ai/v1/transactions/550e8400-e29b-41d4-a716-446655440000/reject-frozen-deposit" \
-H "Content-Type: application/json" \
-d '{
"reason": "Customer failed enhanced due diligence"
}'
Error Responses
404 Not Found
{
"statusCode": 404,
"message": "Transaction with ID 550e8400... not found.",
"error": "Not Found"
}
400 Bad Request
{
"statusCode": 400,
"message": "Transaction is not in FROZEN status",
"error": "Bad Request"
}
Approve Frozen Deposit
Approves a deposit transaction that was frozen during screening.
Endpoint: POST /transactions/:id/approve-frozen-deposit
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string (UUID) | Yes | Transaction ID |
Response
Status: 200 OK
{
"enqueued": true
}
The transaction is queued for completion. Balance will be credited asynchronously.
Example
curl -X POST "https://api.ledgerlink.ai/v1/transactions/550e8400-e29b-41d4-a716-446655440000/approve-frozen-deposit"
Error Responses
404 Not Found
{
"statusCode": 404,
"message": "Transaction with ID 550e8400... not found.",
"error": "Not Found"
}
400 Bad Request
{
"statusCode": 400,
"message": "Transaction is not in FROZEN status",
"error": "Bad Request"
}
Reject Frozen Withdrawal
Rejects a withdrawal transaction that was frozen during screening.
Endpoint: POST /transactions/:id/reject-frozen-withdrawal
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string (UUID) | Yes | Transaction ID |
Request Body
{
"reason": "string"
}
| Field | Type | Required | Description |
|---|---|---|---|
reason | string | No | Reason for rejection |
Response
Status: 200 OK
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "REJECTED",
"rejectionReason": "Suspicious activity detected"
}
Example
curl -X POST "https://api.ledgerlink.ai/v1/transactions/550e8400-e29b-41d4-a716-446655440000/reject-frozen-withdrawal" \
-H "Content-Type: application/json" \
-d '{
"reason": "Destination address flagged for money laundering"
}'
Notes
- Rejecting a withdrawal refunds the amount to the customer's balance
- The rejection reason is stored for audit purposes
- Customer should be notified of the rejection
Approve Frozen Withdrawal
Approves a withdrawal transaction that was frozen during screening.
Endpoint: POST /transactions/:id/approve-frozen-withdrawal
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string (UUID) | Yes | Transaction ID |
Response
Status: 200 OK
{
"enqueued": true
}
The transaction is queued for blockchain execution. The Wallet Manager will process the on-chain transaction.
Example
curl -X POST "https://api.ledgerlink.ai/v1/transactions/550e8400-e29b-41d4-a716-446655440000/approve-frozen-withdrawal"
Error Responses
404 Not Found
{
"statusCode": 404,
"message": "Transaction with ID 550e8400... not found.",
"error": "Not Found"
}
Transaction Statuses
| Status | Description |
|---|---|
PENDING | Transaction created, awaiting external screening |
FROZEN | Flagged by screening, requires manual review |
APPROVED | Approved and processing |
COMPLETED | Fully processed and finalized |
REJECTED | Rejected by screening or manual review |
FAILED | Processing failed due to error |
Status Transitions
Deposit Flow:
PENDING → (screening approved) → APPROVED → COMPLETED
PENDING → (screening rejected) → FROZEN → (manual approve) → APPROVED → COMPLETED
PENDING → (screening rejected) → FROZEN → (manual reject) → REJECTED
Withdrawal Flow:
PENDING → (screening approved) → APPROVED → (blockchain) → COMPLETED
PENDING → (screening rejected) → FROZEN → (manual approve) → APPROVED → (blockchain) → COMPLETED
PENDING → (screening rejected) → FROZEN → (manual reject) → REJECTED
Transaction Types
| Type | Description |
|---|---|
DEPOSIT | Customer deposits digital assets from external wallet |
WITHDRAWAL | Customer withdraws digital assets to external wallet |
TRANSFER | Internal transfer between customer accounts |
Integration Notes
External AML/Compliance System Integration
- Webhook Setup: Configure your AML system to call
/transactions/complete-screening - Authentication: Use API keys or IP whitelisting to secure the webhook
- Screening Data: Include detailed screening results in
screeningDatafield - Timeout: Set appropriate timeout (30-60 seconds recommended)
Background Job Processing
Approved transactions are processed asynchronously using Bull queues:
- Queue:
screening-complete-queue - Job:
screening-complete-job - Processing: Balance updates, blockchain transactions, notifications, logging
Event Logging
All transaction events are logged to Link Tracker:
- Transaction creation
- Status changes
- Screening results
- Approvals/rejections
- Completions/failures
Need Help? Contact helpdesk@ledgerlink.ai for assistance.