Skip to main content
This guide walks you through ingesting transactional data - Deposits, Withdrawals, and Trades - into Corsa. In Corsa, transactions are modeled as Operations. Full API reference is available in the API Reference.
Before ingesting operations, make sure the related clients have already been ingested. See the Ingesting Clients guide.

Step 1: Ingest Deposits

Deposits represent incoming funds (crypto or fiat) into client accounts. Endpoint: POST /v1/operations/deposits
POST /v1/operations/deposits?upsert=true
Content-Type: application/json

{
  "referenceId": "DEP-2024-001",
  "initiatedBy": "123e4567-e89b-12d3-a456-426614174000",
  "initiatedAt": "2024-01-15T08:30:00Z",
  "depositTransaction": {
    "referenceId": "TX-BLOCK-888",
    "txHash": "0x123abc...",
    "amount": {
      "amount": 1.5,
      "currency": "BTC",
      "netAmount": 1.5
    },
    "convertedAmount": {
      "amount": 65000.00,
      "currency": "USD"
    },
    "from": {
      "walletAddress": "0xSourceWalletAddress..."
    },
    "to": {
      "walletAddress": "0xYourDepositAddress..."
    },
    "blockchainNetworkId": "bitcoin-mainnet",
    "statusHistory": [
      {
        "type": "SUCCESS",
        "timestamp": "2024-01-15T08:30:00Z"
      }
    ]
  }
}
The initiatedBy field should reference the Corsa client id of the client who initiated the deposit.

Step 2: Ingest Withdrawals

Withdrawals represent outgoing funds (crypto or fiat) from client accounts. Endpoint: POST /v1/operations/withdrawals

Fiat Withdrawal

POST /v1/operations/withdrawals?upsert=true
Content-Type: application/json

{
  "referenceId": "WDR-FIAT-2024-005",
  "initiatedBy": "123e4567-e89b-12d3-a456-426614174000",
  "initiatedAt": "2024-01-16T14:20:00Z",
  "withdrawTransaction": {
    "referenceId": "TX-BANK-999",
    "amount": {
      "amount": 5000,
      "currency": "USD"
    },
    "to": {
      "bankAccountNumber": "1234567890"
    },
    "paymentMethod": "WIRE_TRANSFER",
    "statusHistory": [
      {
        "type": "PENDING",
        "timestamp": "2024-01-16T14:20:00Z"
      }
    ]
  }
}

Crypto Withdrawal

POST /v1/operations/withdrawals?upsert=true
Content-Type: application/json

{
  "referenceId": "WDR-2024-005",
  "initiatedBy": "123e4567-e89b-12d3-a456-426614174000",
  "initiatedAt": "2024-01-16T14:20:00Z",
  "withdrawTransaction": {
    "referenceId": "TX-BLOCK-999",
    "txHash": "0x456def...",
    "amount": {
      "amount": 5000,
      "currency": "USDC"
    },
    "to": {
      "walletAddress": "0xDestWalletAddress..."
    },
    "blockchainNetworkId": "ethereum-mainnet",
    "statusHistory": [
      {
        "type": "PENDING",
        "timestamp": "2024-01-16T14:20:00Z"
      }
    ]
  }
}

Step 3: Ingest Trades

Trades represent exchange operations between two assets. They can be ingested in two ways:
  • Atomic Ingestion - Send the entire trade with all its transactions in a single request.
  • Incremental Ingestion (Fills) - Send parts of the trade as separate requests that get grouped into the same trade entity.
Endpoint: POST /v1/operations/trades

Atomic Ingestion

Send the full trade with all transactions at once:
POST /v1/operations/trades
Content-Type: application/json

{
  "referenceId": "TRADE-100",
  "initiatedBy": "123e4567-e89b-12d3-a456-426614174000",
  "initiatedAt": "2024-01-17T10:00:00Z",
  "tradeType": "BUY",
  "instrumentBaseAsset": "BTC",
  "instrumentQuoteAsset": "USD",
  "price": 60000,
  "quantity": 1,
  "status": "SUCCESS",
  "transactions": [
    {
      "referenceId": "TX-FILL-1",
      "initiatedAt": "2024-01-17T10:00:00Z",
      "amount": { "amount": 0.4, "currency": "BTC" },
      "paymentMethod": "CRYPTO_TRANSFER",
      "statusHistory": [{ "type": "SUCCESS", "timestamp": "2024-01-17T10:00:00Z" }]
    },
    {
      "referenceId": "TX-FILL-2",
      "initiatedAt": "2024-01-17T10:00:05Z",
      "amount": { "amount": 0.6, "currency": "BTC" },
      "paymentMethod": "CRYPTO_TRANSFER",
      "statusHistory": [{ "type": "SUCCESS", "timestamp": "2024-01-17T10:00:05Z" }]
    }
  ]
}

Incremental Ingestion (Fills)

Use shouldAppendToExistingTrade=true and the same referenceId to append transactions to an existing trade. Request 1 (First Fill):
POST /v1/operations/trades?shouldAppendToExistingTrade=true
Content-Type: application/json

{
  "referenceId": "TRADE-100",
  "initiatedBy": "123e4567-e89b-12d3-a456-426614174000",
  "initiatedAt": "2024-01-17T10:00:00Z",
  "tradeType": "BUY",
  "instrumentBaseAsset": "BTC",
  "instrumentQuoteAsset": "USD",
  "price": 60000,
  "quantity": 1,
  "status": "PENDING",
  "transactions": [
    {
      "referenceId": "TX-FILL-1",
      "initiatedAt": "2024-01-17T10:00:00Z",
      "amount": { "amount": 0.4, "currency": "BTC" },
      "paymentMethod": "CRYPTO_TRANSFER",
      "statusHistory": [{ "type": "SUCCESS", "timestamp": "2024-01-17T10:00:00Z" }]
    }
  ]
}
Request 2 (Second Fill):
POST /v1/operations/trades?shouldAppendToExistingTrade=true
Content-Type: application/json

{
  "referenceId": "TRADE-100",
  "initiatedBy": "123e4567-e89b-12d3-a456-426614174000",
  "initiatedAt": "2024-01-17T10:00:00Z",
  "tradeType": "BUY",
  "instrumentBaseAsset": "BTC",
  "instrumentQuoteAsset": "USD",
  "price": 60000,
  "quantity": 1,
  "status": "SUCCESS",
  "transactions": [
    {
      "referenceId": "TX-FILL-2",
      "initiatedAt": "2024-01-17T10:00:05Z",
      "amount": { "amount": 0.6, "currency": "BTC" },
      "paymentMethod": "CRYPTO_TRANSFER",
      "statusHistory": [{ "type": "SUCCESS", "timestamp": "2024-01-17T10:00:05Z" }]
    }
  ]
}

Step 4: Update Operation & Transaction Statuses

As operations progress through their lifecycle, you can update their statuses.

Available Statuses

Operation Statuses (Deposits, Withdrawals, Trades)

StatusDescription
PENDINGThe operation has been initiated but is not yet final.
SUCCESSThe operation completed successfully.
FAILEDThe operation failed.
REJECTEDThe operation was rejected.
EXPIREDThe operation expired (specific to time-bound operations).

Transaction Statuses

StatusDescription
PENDINGThe transaction is processing.
SUCCESSThe transaction was confirmed.
FAILEDThe transaction failed on-chain or during processing.
CANCELLEDThe transaction was cancelled.
FROZENThe transaction has been frozen.

Updating a Trade Status

Endpoint: PUT /v1/operations/trades/{id}/updateStatus
PUT /v1/operations/trades/TRADE-100/updateStatus
Content-Type: application/json

{
  "status": "SUCCESS",
  "timestamp": "2024-01-17T10:05:00Z",
  "reason": "Trade executed successfully",
  "subStatus": "FILLED"
}

Updating a Transaction Status

Endpoint: PUT /v1/transactions/{id}/updateStatus
PUT /v1/transactions/TX-FILL-1/updateStatus
Content-Type: application/json

{
  "type": "SUCCESS",
  "timestamp": "2024-01-17T10:05:00Z",
  "reason": "Blockchain confirmation received",
  "subStatus": "CONFIRMED_6_BLOCKS"
}

What’s Next?

With clients and operations ingested, you can now set up alerting and case management.

Ingest Alerts & Cases

Push external alerts and escalate them to investigation cases.

Ingesting Clients

Review the client ingestion guide.