Batch processing

Use batch processing for large portfolios or high-volume workloads that should be processed asynchronously in the background.

The batch API accepts the same payload as POST /portfolios, returns a batch_id, and lets you track progress until processing completes.

Overview

The typical flow is:

  1. Submit a portfolio to POST /portfolios/batch
  2. Poll GET /portfolios/batch/{batch_id} until the batch reaches a terminal state
  3. Fetch the resulting account outputs from GET /results/accounts
  4. Filter those results to the account codes that belonged to the submitted batch

This workflow is useful when:

  • the portfolio is large
  • you want background processing instead of waiting on a synchronous response
  • you want queueing and progress tracking

How It Works

Batch submission returns:

{
  "batch_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}

You then poll the batch status endpoint until status becomes one of:

  • completed
  • failed
  • completed_with_errors

Once the batch completes, the results are written into the user's live portfolio store. The updated public Python example then retrieves the latest per-account results using GET /results/accounts.

Submit the batch

POST /portfolios/batch accepts the same JSON payload as POST /portfolios.

Example request:

{
  "calculation_type": "margins",
  "vendor_symbology": "clearing",
  "portfolio": [
    {
      "account_code": "account_0000",
      "exchange_code": "ICE.EU",
      "contract_code": "B",
      "contract_type": "FUT",
      "contract_expiry": "203212",
      "net_position": "100",
      "account_type": "H"
    }
  ]
}

The batch endpoint also supports the x-processing-mode header:

  • fifo
  • priority
  • replace_all

Poll batch status

Use GET /portfolios/batch/{batch_id} to check progress.

Example response:

{
  "batch_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "processing",
  "queue_position": 0,
  "created_at": "2025-01-03T09:31:14Z",
  "completed_at": null,
  "runtime_ms": 4523,
  "completed_pct": 67.5
}

Poll until status is:

  • completed
  • failed
  • completed_with_errors

If the batch fails, stop there and do not attempt to fetch results.

Fetch results

The updated public Python example shows the next step after completion:

results_response = requests.get(f"{C9_API_ENDPOINT}/results/accounts", headers=HEADERS)
results_response.raise_for_status()
accounts = results_response.json()

submitted = set(account_codes)
batch_accounts = [a for a in accounts if a["account_code"] in submitted]

This means:

  • GET /results/accounts returns the latest calculation for every live account owned by the caller
  • your client should keep track of the submitted account_code values
  • after the batch completes, filter the returned accounts down to the ones from that batch

The public example then:

  • prints how many account results were fetched
  • calculates total initial margin across the batch
  • lists the top 5 accounts by initial margin

Was this page helpful?