Skip to content

Limits & quotas

Production limits for TwinCell (open-deeplife-api). Internal dev environments may differ; this page documents production only.

Source of truth for credits

Your remaining prediction quota is returned by the API and shown in the TwinCell console overview:

GET /v1/usage/predictions/quota

Authenticate with the X-API-Key header (see Errors → Authentication).

Response fields include total_quota_requests, consumed_quota_requests, and remaining_quota_requests. Prefer this endpoint (or the console) over hard-coded numbers when building automation.

Free tier (current)

New accounts currently receive a lifetime cap of 100 billable prediction submissions (POST /v1/predictions). This value may change. Higher tiers are not yet defined publicly — contact Access & Support to extend quota.

Non-billable target-validation failures (for example target_not_in_interactome) do not consume quota once the API marks the run counts_toward_quota=false.

Rate limits

Limit Value Signal
Edge (WAF) requests per client IP 30 requests per 60 seconds HTTP 403 with an HTML body and no X-Deeplife-Error-Code
POST /v1/predictions per API key 60 requests per 60 seconds HTTP 429, header X-Deeplife-Error-Code: rate_limited, optional Retry-After
Concurrent in-flight predictions 1 per account HTTP 429, X-Deeplife-Error-Code: inflight_limit
Lifetime external prediction cap 100 (current free tier) HTTP 429, X-Deeplife-Error-Code: external_prediction_quota_exceeded

The SDK retries GET requests on true throttling (rate_limited) and on unlabelled edge 403s, but never retries POST — a repeated upload would create a duplicate prediction.

The edge limit is per IP, not per key

The first row is the one that bites during polling, and it behaves differently from the others: it is enforced before the request reaches the API, counts every request from your IP (uploads, status polls, health checks, and any colleague behind the same NAT or VPN egress), and reports a 403 with an HTML body rather than a 429 with Retry-After.

Status polling is the easiest way to exhaust it. The SDK defaults poll_interval_seconds to 5 s12 requests/minute, about 40% of the budget — which leaves headroom for the upload and for other traffic from the same address:

from deeplife.twincell import DEFAULT_POLL_INTERVAL_SECONDS

DEFAULT_POLL_INTERVAL_SECONDS  # 5.0

Lowering it is what triggers the failure: a 2 s interval is exactly 30 requests/minute, the entire budget, so any concurrent request tips you into a 403. If you run several waiters at once, raise the interval proportionally — the budget is shared across all of them.

See Errors → Two kinds of 403 for telling an edge block apart from an account-policy 403.

Payload & result caps

Constants below are exported from deeplife.twincell.limits and match production API defaults.

Constant / parameter Value Applies to
TWINCELL_API_MAX_OBSERVATIONS_PER_ANNDATA 1,000 Max n_obs per control or perturbed .h5ad before upload (local validation)
DEFAULT_PREDICTION_MAX_ROWS 15,000 Max protein result rows per GET /v1/predictions/{id} (max_rows)
DEFAULT_PREDICTION_MAX_COLUMNS 512 Max source-influence matrix columns (max_columns)
DEFAULT_SOURCE_INFLUENCE_MAX_ROWS 50,000 Server cap for matrix rows (max_source_influence_rows on the API)
DEFAULT_TOP_N_CAUSAL_DEGS 1,000 Default top-N DEGs for causal analysis / causal-graph requests (range 1–100,000)

The high-level TwinCell class and DeepLifeClient use DEFAULT_PREDICTION_MAX_ROWS and DEFAULT_PREDICTION_MAX_COLUMNS as defaults so client previews match server caps.

Python

from deeplife.twincell.limits import (
    DEFAULT_PREDICTION_MAX_COLUMNS,
    DEFAULT_PREDICTION_MAX_ROWS,
    TWINCELL_API_MAX_OBSERVATIONS_PER_ANNDATA,
)
  • Errors — quota and rate-limit exceptions.
  • Access & Support — trials, academic credits, and quota increases.