Endpoint Index

Every public endpoint of the Folio Lab REST API in one place, grouped by purpose. The credential column answers the first question an integration asks: can a server-to-server API key call this, or does it need a person signed in to the web app?

Three Kinds of Credential

See Authentication for how to obtain each one.

  • API key. Sent as Authorization: Bearer <key> or X-API-Key: <key>. A key carries scopes: jobs:read, jobs:write (which also grants read), jobs:* or *. A key created without scopes gets jobs:read and jobs:write. A key without the scope a route needs receives 403 API key lacks required scope.
  • Web session. The access token the web app receives at sign-in. The account's email must be verified, or most routes answer 403 email_not_verified. An API key sent to a session-only route receives 403 JWT user required.
  • None. Public catalogue routes that read no account data.

The practical consequence: an integration that holds only an API key can submit optimization runs (with an inline rolling backtest), and can poll, read, cancel, rename and delete runs, simulations and backtests. It cannot submit a Monte Carlo simulation or a standalone backtest, read the plan usage at GET /billing/me, run the constraints preflight, manage classification lists or templates, import holdings, or tag runs. Those need a signed-in user.

Optimization runs

Details: Optimization

EndpointCredentialPurpose
POST
/jobs
API key jobs:write, or sessionSubmit an optimization run, optionally with an inline rolling backtest. A chained monte_carlo block is refused for an API key with 403 mc_api_key_not_supported.
GET
/jobs/history
API key jobs:read, or sessionYour runs, newest first, cursor paginated, with search, status, tag, market, mode and constraints filters.
GET
/jobs/active
API key jobs:read, or sessionEvery job still queued, running or uploading, across all three kinds.
GET
/jobs/{run_id}
API key jobs:read, or sessionLifecycle status of one run.
GET
/jobs/{run_id}/result
API key jobs:read, or sessionWeights, metrics and per-asset statistics of a succeeded run.
GET
/jobs/{run_id}/config
API key jobs:read, or sessionThe request the run was submitted with.
GET
/jobs/{run_id}/artifacts
API key jobs:read, or sessionStored files of the run, with signed download URLs.
GET
/jobs/{run_id}/rolling_backtest
API key jobs:read, or sessionThe inline rolling backtest section of one run.
POST
/jobs/{run_id}/report/pdf
API key jobs:write, or sessionStart PDF generation for a report kind.
GET
/jobs/{run_id}/report/status
API key jobs:read, or sessionabsent, queued, rendering, ready or failed, with the reason on failure.
PATCH
/jobs/{run_id}
API key jobs:write, or sessionRename a run. The body takes name; any other field is refused with 400.
POST
/jobs/{run_id}/cancel
API key jobs:write, or sessionCancel an in-flight job of any kind. A finished job returns 409.
DELETE
/jobs/{run_id}
API key jobs:write, or sessionPermanently delete a run and everything attached to it. Returns 409 while the run is in flight. Quota is not returned.

Monte Carlo and backtests

Details: Monte Carlo

EndpointCredentialPurpose
POST
/runs/{run_id}/monte_carlo
Web session onlySubmit a simulation on a succeeded run. Returns 202. An API key passes the scope check and is then refused with 403 mc_api_key_not_supported.
GET
/runs/{run_id}/monte_carlo
API key jobs:read, or sessionThe simulations of one parent run.
GET
/mc
API key jobs:read, or sessionEvery simulation on the account, cursor paginated.
GET
/mc/{mc_run_id}
API key jobs:read, or sessionOne simulation: status, summary and a signed detail URL.
POST
/runs/{run_id}/backtest
Web session onlySubmit a standalone walk-forward backtest on a succeeded run. Returns 202. An API key is refused with 403 backtest_api_key_not_supported.
GET
/runs/{run_id}/backtests
API key jobs:read, or sessionThe standalone backtests of one parent run.
GET
/backtests
API key jobs:read, or sessionEvery standalone backtest on the account, cursor paginated.
GET
/backtests/{backtest_run_id}
API key jobs:read, or sessionOne standalone backtest, with signed report links once it succeeds.

Catalogue and method requirements

EndpointCredentialPurpose
GET
/universe
NoneThe live Indian ticker universe. Cached on its content digest: send If-None-Match to receive 304 when nothing changed. Returns 503 rather than a stale copy.
GET
/mutual-funds/search
NoneSearch Indian mutual funds. q of 2 or more characters, limit 1 to 50, optional asset_class (equity, debt, hybrid, other), optional page and page_size.
GET
/us-stocks/search
NoneSearch NYSE and NASDAQ equities. limit 1 to 50.
GET
/methods/requirements
NoneMinimum assets, minimum observations and benchmark need of every method, and the fields enforced at submission.

Constraints, classification lists and holdings

Details: Constraints

EndpointCredentialPurpose
GET
/constraints/capability
Web session onlyWhich constraint families each method enforces. Not plan-gated.
POST
/constraints/preflight
Web session onlyFeasibility and reachable ranges of a set of rules before a run. Enterprise. Uses no run and no quota.
GET
/classification-maps
Web session onlyYour saved classification lists. Enterprise.
POST
/classification-maps
Web session onlySave a classification list. Enterprise.
PUT
/classification-maps/{map_id}
Web session onlyReplace a saved list. A new revision does not change what a past run used. Enterprise.
DELETE
/classification-maps/{map_id}
Web session onlyDelete a saved list. Enterprise.
POST
/holdings/import
Web session onlyRead a Zerodha or Groww .xlsx export, sent as base64 in content_base64, into stock and fund starting portfolios. The file is not stored. An unreadable layout returns 400 HOLDINGS_FILE_UNREADABLE.

Templates, tags and comparisons

Details: Results and Analytics

EndpointCredentialPurpose
GET
/templates
Web session onlyYour saved optimization templates.
POST
/templates
Web session onlySave a template: name (at most 100 characters) and request (an object). At most 20 per account.
PATCH
/templates/{template_id}
Web session onlyRename a template.
DELETE
/templates/{template_id}
Web session onlyDelete a template.
POST
/runs/{run_id}/tags
Web session onlyTag a run.
DELETE
/runs/{run_id}/tags/{tag_name}
Web session onlyRemove a tag.
GET
/analytics/tags
Web session onlyEvery tag in use, with run counts.
GET
/analytics/dashboard
Web session onlyCross-run dashboard statistics.
POST
/analytics/refresh-stats
Web session onlyRecompute the dashboard statistics.
POST
/analytics/comparisons
Web session onlySave a comparison of runs.
GET
/analytics/comparisons
Web session onlyYour saved comparisons.
GET
/analytics/comparisons/{comparison_id}
Web session onlyOne saved comparison.
GET
/analytics/comparisons/{comparison_id}/surface
Web session onlyThe detailed comparison surface of a saved comparison, one page of runs at a time: page_size, cursor, curve_methods, groups.
PATCH
/analytics/comparisons/{comparison_id}
Web session onlyEdit a saved comparison.
DELETE
/analytics/comparisons/{comparison_id}
Web session onlyDelete a saved comparison.
POST
/analytics/insights/{insight_id}/dismiss
Web session onlyDismiss one dashboard insight.

Account, API credentials and connectors

Details: Authentication

EndpointCredentialPurpose
GET
/users/me
Web session onlyYour profile.
PATCH
/users/me
Web session onlySet display_name.
DELETE
/users/me
Web session onlyDelete the account. Returns 204.
GET
/billing/me
Web session onlyPlan and the usage of the three monthly meters.
GET
/auth/api-clients
Web session onlyYour API clients. POST, GET by id, PATCH and DELETE are also available.
GET
/auth/api-keys
Web session onlyYour API keys. POST creates one with scopes; PATCH and DELETE are also available.
GET
/users/me/mcp-grants
Web session onlyAI assistant connectors that hold an active grant on the account.
DELETE
/users/me/mcp-grants?client_id=...
Web session onlyRevoke one connector. The query form accepts a client_id that is an HTTPS URL. Returns 204.

Pagination

The list routes /jobs/history, /mc and /backtests take limit (default 20) and an opaque cursor. Pass the next_cursor of one page to read the next. A cursor is not an offset: do not build one yourself.

bash
curl "https://api.foliolab.ai/backtests?limit=20&cursor=$NEXT_CURSOR" \
  -H "Authorization: Bearer $API_KEY"

Not Listed Here

The sign-up, sign-in, token refresh and password routes are on the Authentication page. The checkout routes serve the web app's billing pages and are not an integration surface. The OAuth routes under /oauth and /.well-known serve AI assistant connectors; see the MCP tool reference.

Not investment advice. Past performance is not indicative of future results.