REST API#
Every Lens Agents surface is built on one REST API. The CLI is a client of it, the admin UI consumes it, and the MCP endpoint delegates to it. All three enforce the same identity, RBAC, policies, and audit.
Base path and OpenAPI#
https://agents.example.com/v1
Each install serves the OpenAPI 3 document for the exact version it is running:
https://agents.example.com/v1/openapi.json
That document is authoritative. Generate a client from it rather than hand-writing one against this page.
Authentication#
Bearer tokens, in an Authorization header. Three kinds are accepted:
| Token | From |
|---|---|
| OIDC JWT | An interactive sign-in through your identity provider. |
| API token | api-token create. |
| Cluster JWT | Issued to a registered cluster relay. |
curl -fsS -H "Authorization: Bearer $LENS_AGENTS_TOKEN" \
https://agents.example.com/v1/auth/me
GET /v1/auth/me returns the identity type behind the token, which is the quickest way to confirm a credential works and is what you think it is.
Two endpoints need no authentication: GET /v1/installation and the activation device flow, because they run before an install has any identities.
Errors#
Failures use RFC 9457 problem details with an application/problem+json content type:
{
"type": "https://api.lens.dev/problems/not-found",
"title": "Not Found",
"status": 404,
"detail": "Sandbox not found"
}
A 429 from an /llm/* route means a spending limit was reached. The sandbox keeps running; only model access stops.
Endpoint groups#
Identity and tenancy#
| Group | Base |
|---|---|
| Current identity | /auth/me |
| Organizations and members | /orgs, /orgs/{orgId}/members/{userId} |
| Teams, membership, project access | /orgs/{orgId}/teams, /teams/{teamId} |
| Projects and keys | /orgs/{orgId}/projects, /projects/{projectId}, /projects/{projectId}/rotate-keys |
| Invitations | /orgs/{orgId}/invitations, /invitations |
| API tokens | /orgs/{orgId}/api-tokens, /api-tokens/{tokenId} |
Projects also publish /projects/{projectId}/public-key and /projects/{projectId}/.well-known/jwks.json, which the cluster relay uses to verify platform-signed requests.
Sandboxes#
| Operation | Endpoint |
|---|---|
| List, create | /projects/{projectId}/sandboxes |
| Get, update, delete | /projects/{projectId}/sandboxes/{sandboxId} |
| Start, stop | .../start, .../stop |
| Revisions, rollback | .../revisions, .../rollback |
| Effective policy | .../effective-policy |
| Sandbox tokens | /projects/{projectId}/sandbox-tokens, /sandbox-tokens/{id} |
| Shell exec | /shell/exec |
| Shell sessions | /projects/{projectId}/shell-sessions |
Interactive exec is a WebSocket, not a REST call:
wss://agents.example.com/v1/projects/{projectId}/sandboxes/{sandboxId}/exec
Query parameters: command, tty, cols, rows.
It multiplexes stdin, stdout, stderr, and terminal resize frames. Use nexusctl sandbox exec unless you are building a terminal.
Governance#
| Group | Base |
|---|---|
| Project policies | /projects/{projectId}/policies |
| Org policies | /orgs/{orgId}/policies |
| Project bindings | /projects/{projectId}/policy-bindings |
| Org bindings | /orgs/{orgId}/policy-bindings |
| Binding drift | /orgs/{orgId}/policy-bindings/drift |
| Credentials | /projects/{projectId}/credentials |
Connections#
| Group | Base |
|---|---|
| Clusters | /projects/{projectId}/clusters, /clusters/{clusterId} |
| Kubernetes proxy | /clusters/{clusterId}/proxy/{path} |
| Tunnel token rotation | /clusters/{clusterId}/rotate-tunnel-token |
| AWS connections | /projects/{projectId}/aws-connections, /aws-connections/{connectionId} |
| AWS proxy | /aws-connections/{connectionId}/aws/{path} |
| Connectors | /projects/{projectId}/mcp-servers, /mcp-servers/{serverId} |
| HTTP connector from OpenAPI | /projects/{projectId}/mcp-servers/http |
| Discovery and preview | .../discover/preview, /mcp-servers/{connectorId}/discover/url |
| Pending specs | /mcp-servers/{connectorId}/specs/pending, .../{specId}/diff, .../promote |
| Connector credentials | /projects/{projectId}/mcp-servers/{serverId}/credentials |
| Tool visibility | /mcp-servers/{connectorId}/entries/{entryName}/visibility |
| Tool call | /mcp-servers/{serverId}/tools/call |
Both proxy groups accept GET, POST, PUT, PATCH, and DELETE, passing the method and path through to the upstream after the policy check.
Inference#
| Provider | Route |
|---|---|
| Configured providers | /inference/providers |
| Bedrock | /llm/bedrock/{region}/{path} |
| Foundry — Claude | /llm/azure/anthropic/{path} |
| Foundry — GPT | /llm/azure/openai/{path} |
| Bedrock Mantle — Claude | /llm/bedrock-mantle/anthropic/{region}/{path} |
| Bedrock Mantle — GPT | /llm/bedrock-mantle/openai/{region}/{path} |
Each has a /projects/{projectId}/llm/... form for callers with access to several projects. The short form resolves the project from the caller's identity. See Models.
Observability#
| Group | Base |
|---|---|
| Audit trail | /orgs/{orgId}/audit-trail, .../stats, .../timeseries |
| Usage costs | /orgs/{orgId}/usage-costs, .../timeseries |
| Spending limits | /orgs/{orgId}/spending-limits, .../status |
The audit trail paginates by cursor — pass the ISO 8601 timestamp from the previous response. See Audit trail.
Installation#
| Operation | Endpoint |
|---|---|
| Status | GET /installation |
| Start device flow | POST /installation/activation |
| Poll device flow | GET /installation/activation/{sessionId} |
Other surfaces#
| Surface | Path |
|---|---|
| Health | /health |
| MCP, org-scoped | /mcp |
| MCP, project-scoped | /projects/{projectId}/mcp |
| Sandbox exposed ports | https://<sandbox-slug>.<sandboxIngress.host> |
The MCP endpoints sit at the root, not under /v1.
Related#
- CLI reference — the same operations from a terminal
- Platform tools — the same operations over MCP
- Set up the CLI — authentication and environment defaults