Developers · PRISM Optimization API

The API reference.

Firm-wide, tax-aware portfolio optimization, exposed as a black-box REST API. Bring accounts, lots, and constraints (or use our demo data); get back optimized weights, timings, and a hash-chained audit trail. Need a key first? Get a free trial key →

01 · Overview

Base URL & how it fits together.

All requests go to the versioned base path. The engine itself is a GPU-native, proprietary factor-structured optimization core — the API surface is intentionally simple: submit a job, poll it, fetch the result.

base url
https://asymmetrycomputing.com/api/prism

The typical flow is: PUT a dataset (optional, for your own data) → POST /v1/jobs → poll GET /v1/jobs/{id} until status is completed → fetch GET /v1/jobs/{id}/result and, if needed, GET /v1/jobs/{id}/weights.

02 · Authentication

An API key on every request.

Pass your key in the X-API-Key header. /v1/health, /v1/capabilities, and /v1/access-requests do not require a key — everything else does.

header
X-API-Key: YOUR_API_KEY

Don't have a key yet? Request a free trial key on the API product page — keys are manually approved and emailed, typically within 24–48 hours.

03 · Endpoint reference

Every endpoint.

GET /v1/health GET /v1/capabilities POST /v1/access-requests PUT /v1/datasets/{name} GET /v1/datasets POST /v1/jobs GET /v1/jobs/{id} GET /v1/jobs/{id}/result GET /v1/jobs/{id}/weights

GET /v1/health

Liveness check. No API key required.

bash
curl https://asymmetrycomputing.com/api/prism/v1/health

GET /v1/capabilities

Returns supported task types and their current limits. No API key required — use it to introspect what your key tier (or an unauthenticated caller) can do before submitting a job.

bash
curl https://asymmetrycomputing.com/api/prism/v1/capabilities

POST /v1/access-requests

Request a trial key. No API key required. Trial keys are manually approved and emailed — this endpoint just files the request and returns a tracking ID.

json · request body
{
  "name": "Jane Doe",
  "email": "jane@fund.example",
  "company": "Example Capital",
  "use_case": "Testing book_rebalance on a 10k-account taxable book"
}
json · response
{
  "request_id": "req_8f2a1c90",
  "status": "pending_review"
}

PUT /v1/datasets/{name}

Upload a dataset as the raw request body — a .npz archive matching the schema for the task you intend to run (see book_rebalance or portfolio below). Trial keys are capped at 200MB per dataset.

bash
curl -X PUT https://asymmetrycomputing.com/api/prism/v1/datasets/my_book \
  -H "X-API-Key: $KEY" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @my_book.npz

GET /v1/datasets

List datasets uploaded under your key.

bash
curl https://asymmetrycomputing.com/api/prism/v1/datasets \
  -H "X-API-Key: $KEY"

GET /v1/jobs/{id}

Poll job status: queued, running, completed, or failed.

json · response
{ "job_id": "job_a91fe0", "status": "running" }

GET /v1/jobs/{id}/result

Fetch the full result once the job is completed: solve timings, a summary of the book (turnover, positions, per-segment breakdown), an optional independent-validation block, and the audit chain with its final hash.

json · response (abridged)
{
  "job_id": "job_a91fe0",
  "status": "completed",
  "timings": {
    "solve_wall_s": 47.2,
    "us_per_account": 94.4
  },
  "summary": {
    "n_accounts": 500000,
    "n_names": 1000,
    "turnover": 0.083,
    "positions": 481932,
    "segments": [
      { "profile": "taxable", "accounts": 320000, "turnover": 0.091 },
      { "profile": "tax_deferred", "accounts": 180000, "turnover": 0.068 }
    ]
  },
  "validation": {
    "reference": "open-source interior-point (CLARABEL), 1e-9 tolerance",
    "sample_size": 50,
    "max_weight_error_pct": 0.00025,
    "gate_pct": 0.05,
    "passed": true,
    "reference_ms_per_account": 65.0
  },
  "audit": {
    "stages": 6,
    "final_hash": "3f1a9c2e7b4d0851f6a2c9de4b7108c3e5f9a1d2b6c847e0f193a5d7c2b8e410"
  }
}

GET /v1/jobs/{id}/weights

Download the optimized weights as a .npz archive — one row per account, one column per name, aligned to the input dataset's ordering.

bash
curl https://asymmetrycomputing.com/api/prism/v1/jobs/job_a91fe0/weights \
  -H "X-API-Key: $KEY" -o weights.npz
04 · Submitting jobs

POST /v1/jobs

Every job is asynchronous: submit, get a job_id back immediately, then poll. There are two task types today — book_rebalance for multi-account books and portfolio for single-portfolio optimization.

json · response
{ "job_id": "job_a91fe0", "status": "queued" }
Engine. PRISM is a GPU-native, proprietary factor-structured optimization engine. The API is a black box by design: inputs in, weights + timings + audit trail out. There is no internal algorithm surface exposed.
05 · task: book_rebalance

Rebalance a whole book of accounts.

The core, book-scale task. Use it to rebalance thousands to hundreds of thousands of accounts against a target model in one call.

json · request
{
  "task": "book_rebalance",
  "source": "demo | stress_demo | dataset",
  "n_accounts": 25000,
  "n_names": 1000,
  "dataset_id": "my_book",
  "precision": "fast | high",
  "chunk_size": 5000,
  "include_warm_lane": true,
  "validate_sample": 50,
  "position_max": 0.08
}
FieldTypeNotes
sourcestringdemo, stress_demo, or dataset — see below
n_accountsintrequired for demo / stress_demo
n_namesint≤ 1,000
dataset_idstringrequired when source is dataset
precisionstringfast or high
chunk_sizeintaccounts processed per internal batch
include_warm_laneboolinclude a warm-started fast lane in the run
validate_sampleintaccounts to independently validate in-job against the reference solver
position_maxfloatper-name position cap, as a weight fraction

Source: demo

Real historical price history, with synthesized accounts and holdings layered on top. Fast way to smoke-test the endpoint and see result shape.

Source: stress_demo

Full-difficulty, realistic book: multi-lot HIFO cost basis built from real price history, sparse model holdings, concentrated legacy positions, a taxable/tax-deferred account mix, wash-sale blocks, and heterogeneous per-account position caps. This is the honest stress test — the 47-second, 500,000-account headline number was measured on this mode.

Source: dataset — .npz schema

Upload your own book via PUT /v1/datasets/{name}, then reference it by dataset_id.

KeyShapeRequiredNotes
prices(T, n)yesprice history, T periods × n names
W_cur(m, n)nocurrent weights, m accounts × n names
gain_frac(m, n)nounrealized gain as a fraction of position value
is_short_term(m, n) boolnoshort-term vs. long-term lot flag
wash_blocked(m, n) boolnopositions currently wash-sale blocked
profile(m,) intnoaccount profile: 0, 1, or 2 (e.g. taxable / deferred / mixed)
w_index(n,)notarget model / index weights
06 · task: portfolio

Optimize a single portfolio.

For single-portfolio (not book-scale) optimization — a standard allocation problem over an asset universe.

json · request
{
  "task": "portfolio",
  "source": "demo | dataset",
  "n_assets": 5000,
  "dataset_id": "my_universe"
}
KeyShapeRequiredNotes
returns(T, n)one of returns / B+Dhistorical returns, T periods × n assets
B(n, k)one of returns / B+Dfactor loadings, paired with D
D(n,)paired with Bidiosyncratic variances
mu(n,)noexpected returns
w_current(n,)nocurrent portfolio weights
07 · Limits & errors

Trial-tier limits.

LimitValue
Accounts per job25,000
Assets per job20,000
Jobs per day10
Total jobs (trial key lifetime)40
Dataset upload size200 MB

Need more? A production key removes these caps — talk to us about pricing.

Error semantics

StatusMeaning
401Invalid or missing API key
403Request exceeds your key's limits (accounts, assets, or dataset size)
429Quota reached (jobs/day or lifetime job cap)
500Generic failure — response detail reads "Optimization interrupted on host."
Deterministic by design. Every completed job returns a hash-chained audit trail so results are re-derivable and verifiable — useful for both debugging and compliance review.

Get a free trial key.

Manually approved, rate-limited, and enough to run a real book-scale test — up to 25,000 accounts per job, 10 jobs a day.

Request a trial key →