| title | API Access |
|---|---|
| description | Generated REST APIs, authentication, and API keys for integrations. |
Every object declared in the artifact is exposed through a generated REST API. The same endpoints power the UI, integrations, and customer ETL scripts — there is no separate "integration API" to maintain.
https://<project-domain>/api/v1
Notable surfaces:
| Path | Purpose |
|---|---|
/api/v1/data/<object> |
Generated CRUD for each object (e.g. /api/v1/data/account) |
/api/v1/data/<object>/{id} |
Read/update/delete a single record |
/api/v1/actions/<object>/<action> |
Invoke a declarative action (POST) |
/api/v1/auth/* |
Authentication (sign-in, sessions, OAuth, OIDC) |
/api/v1/meta/* |
Metadata APIs (objects, fields, views) when enabled |
/api/v1/keys |
Mint a show-once sys_api_key for the calling user (POST) |
/api/v1/mcp |
Model Context Protocol server over Streamable HTTP, when OS_MCP_SERVER_ENABLED=true |
/api/v1/health |
Liveness/readiness probe (no auth) |
The prefix defaults to /api/v1 (the API basePath of /api plus the
version of v1) and is configurable on the ObjectOS stack.
API exposure is governed per object in the artifact, not at the gateway:
- Set
apiEnabled: falseon an object to keep it off the REST surface entirely (its routes 404). - Set an
apiMethodswhitelist (e.g.['get', 'list']) to make an object read-only or otherwise restrict which operations are reachable.
Both are enforced at the REST layer — see REST API → Restricting the API surface.
Callers can authenticate in three ways:
| Method | Best for | How |
|---|---|---|
| Session cookie | Browser/UI traffic | Sign in through /api/v1/auth/*; cookies are scoped to the project hostname |
| Bearer access token | Mobile, SPA, short-lived server jobs | Exchange credentials at /api/v1/auth/sign-in/email and pass Authorization: Bearer <token> |
| API key | Server-to-server, ETL, long-lived integrations | Create a sys_api_key, pass it as a bearer token |
All three pass through the same AuthPlugin and resolve to a sys_user
context that the SecurityPlugin evaluates against permissions and
record access.
API keys are first-class sys_api_key records. The key value itself is
stored hashed — only the prefix and metadata remain queryable, so a
leaked key cannot be reconstructed from the database.
Issue a key in either of two ways:
-
Console — sign in to Console → API Keys as an administrator, choose the owning user, optionally set an expiration date, and copy the displayed secret once.
-
Self-serve endpoint —
POST /api/v1/keysmints a key for the authenticated caller and returns the raw secret exactly once. The key is pinned to the caller's own user, so it cannot be used to impersonate another identity:curl -X POST https://app.example.com/api/v1/keys \ -H "Authorization: Bearer <session-or-access-token>" \ -H "Content-Type: application/json" \ -d '{"name": "etl-pipeline"}' # → { "id": "...", "name": "etl-pipeline", "prefix": "os_pk_…", "key": "os_pk_live_…" }
Pass the key on subsequent requests as a bearer token, an x-api-key
header, or Authorization: ApiKey. The REST data and metadata APIs all
authenticate it through the same verifier as MCP, under the key owner's
permissions and record-level security:
curl https://app.example.com/api/v1/data/account \
-H "x-api-key: os_pk_live_…"To revoke a key, run the revoke_api_key action on the corresponding
sys_api_key record (also available in the Console UI). Revocation takes
effect immediately on the next request.
Generated list endpoints accept the standard ObjectStack query parameters:
| Parameter | Meaning |
|---|---|
?limit= |
Page size (subject to a server-side ceiling) |
?offset= or ?cursor= |
Pagination |
?filter= |
Server-side filtering using the ObjectQL filter syntax |
?sort= |
Sort expression (e.g. -created_at) |
?fields= |
Sparse field selection |
Refer to the framework documentation for the full filter grammar — the runtime grammar is the source of truth.
Use the framework's RateLimiter primitive (or your ingress / API
gateway) to apply per-IP and per-identity limits. Recommended starting
buckets are documented in Production readiness.
If callers run in a browser on a different origin, configure CORS at the ingress or via the runtime's middleware. Do not combine wildcard origins with credentialed requests.
The runtime can serve an OpenAPI document for the generated REST API when the corresponding capability is included in the image. Customer integrations should generate clients from the per-deployment OpenAPI document rather than hand-rolling URLs, because object names and generated routes follow the deployed artifact.