Skip to main content
The Core administration API (/core/v1) manages an installation: Projects and their API keys, reads and deletion of Project resources, executor credentials, deployment default models, the sandbox deployment and its nodes, monitoring and audit. Web’s console server calls it for the signed-in administrator (console server); operators call it from scripts on the Core host (script the Core API). The generated schema is core.openapi.yaml, and every error uses the Core error envelope. Applications never call /core/v1. It has no operation that creates or edits Agents, Sessions, templates, Files, Skills or Vaults, starts or cancels work, reads Source File content or streams events; applications do those through the Agents API.

Authentication

Every /core/v1 request, including one for an unknown path, must send Authorization: Bearer <Core key>. Without it Core answers 401 invalid_admin_key with WWW-Authenticate: Bearer; an unknown path answers 404 not_found only after authentication.
  • Core compares the SHA-256 of the bearer with the Core key digest it reads at startup from generated/core-key-digests.json, which oac apply derives from secrets/core.key (Core key). A rotated Core key takes effect when Core restarts. Core serves no /core/v1 route when no digest is configured.
  • The Core key authenticates only /core/v1. Project API keys and machine credentials get 401 here, and the Core key gets 401 on /v1 and /api/v1 (API namespaces and credentials).
  • X-Core-Console-Actor is a label the caller asserts. Core records it as the audit actor_label without checking it. The console server sends console; scripts normally send none, which records an empty label. Never use it for authorization or as proof of origin.
  • A {project_id} in a path selects the target Project, including an archived one; it grants nothing.

Routes

Paths are relative to /core/v1.

Projects and keys

A Project owns one execution tenant; its keys share its principal and assets (Projects own assets). Web’s Projects and keys page uses these routes.
  • A Project has id, name, created_at, nullable archived_at and active_key_count. A key has id, project_id, name, prefix, created_at and nullable revoked_at. IDs are server-generated UUIDs.
  • Project names have 1–128 characters and key names 1–80; names are labels and may repeat, and control characters are rejected.
  • Lists order by ID with order=asc|desc (default desc), limit=1..100 (default 20) and after.
  • Only the issuance response contains the key’s plaintext, in key; Core stores its digest. Show it once and never cache it. After an uncertain issuance response, list the keys and revoke any you cannot use before issuing another.
  • Archive marks the Project archived, revokes all its keys and writes the audit entry in one transaction. Issuing a key in an archived Project returns 409 project_archived. There is no Project deletion, unarchive or key reset.
The /v1 authentication rules define key lookup, revocation visibility, scope headers and authentication errors.

Resource reads and deletion

Paths are relative to /core/v1/projects/{project_id}. Each read returns the same object, pagination and errors as the matching /v1 operation, and each deletion has the same preconditions.
  • Administrator deletion never cancels work: a Session that /v1 could not delete, because a Turn or input is pending, returns the same 409.
  • Deleting a Credential removes Core’s copy only; it does not revoke the authorization at the provider.
  • HEAD on Skill and Artifact content, a Runtime observation, the Runtime observation list and Runtime history returns 405, so it never samples a provider or queries telemetry.
  • Administrator deletions appear in the audit log, not in key write history.

Session archive

POST /projects/{project_id}/sessions/{session_id}/archive with {"expected_generation": N} releases one Core-managed openai_hosted Session’s sandbox without a deployment reset. N is the current generation of the sandbox deployment, a positive integer. The deployment must be configured in Web. One transaction marks the Environment expired (a failed Environment stays failed), requests cancellation of running work, revokes the Runtime’s authority and writes the audit entry. Cleanup of the sandbox and its snapshot follows through the normal lifecycle; a resource whose release is uncertain stays owned until the provider confirms it. The Session is not deleted: its history and persisted Files and Artifacts stay readable, unpersisted workspace contents are lost and the Session cannot resume. POST and GET /projects/{project_id}/sessions/{session_id}/archive return {session_id, environment_id, state}. GET is read-only and needs no generation. state is the resource’s current disposition: active, cleanup_pending or released, whatever released it. released does not mean an active Turn has finished cancelling; read the Turn for that. After an uncertain POST response, GET the archive before writing again. Repeating the POST has the same effect and records one audit entry per accepted request. To clear every hosted Session before changing the deployment, use the deployment reset.

Execution configuration

GET /projects/{project_id}/sessions/{session_id}/execution-configuration reports the model, Harness, native parameters and model provider a Session froze at creation. It reads only stored configuration: it never contacts a provider, starts a Turn or wakes a sandbox. Responses carry Cache-Control: no-store.
Each source is session, agent, deployment or unknown, recorded independently: a Session can override the model and keep its Agent’s Harness and provider. An explicit inline Harness is session; an inline agent.x_agents_core: null resets the Harness to deployment and keeps the inherited provider; a null Session provider inherits normally. harness_config.value is {} when no native parameters apply. Model execution owns how each value is resolved. Core writes this record in the same transaction that creates the Session. Later Agent edits or deletion, deployment default changes, restarts and same-key creation retries never change it. A Session without the record reports its stored model and Harness with source unknown, a null value where none is stored, and an unavailable provider. A missing Session and one in another Project return the same 404. The response never contains keys, ciphertext, secret references, native headers or query parameters.

Installation facts

GET /installation reports what an administrator needs to call and change this installation. It answers before any sandbox deployment exists and calls no provider or model. configuration has:
  • path: the absolute host path of config.json, by default ~/.oac/core/config.json;
  • apply_command: the command that applies changes, by default ~/.oac/core/oac apply;
  • applied_at: when the snapshot was last applied;
  • settings: one entry per setting, with its dotted key, applied value, default, whether it is changeable after installation, whether it is sensitive, and the services it restarts (core, web, database).
A sensitive setting has null value and default and a boolean configured instead; only sensitive settings have configured. Core refuses to start when the snapshot breaks this rule, repeats a key or has an unknown member. Core only reports the snapshot; configuration describes each setting.

Write provenance

Core records which Project API key made each successful public write, in the same transaction as the write; if the record fails, the write fails. Reads, rejected requests and Core’s own maintenance, such as OAuth token refresh and cleanup, are not recorded.
  • A write is recorded when it commits. Session input counts once admitted, including input reserved for an Environment that is still preparing; a later execution failure or a lost response does not remove the record. An explicit empty input batch and a repeated creation or deletion are recorded without changing ownership.
  • An Environment file upload is recorded when the Runtime confirms the write. Core saves the key, request and trace before sending the file, and records only confirmed uploads.
  • Creating a resource also records its creation owner. Updates, retries and no-op writes never change it. A new Skill’s first version and a new Session’s Environment share the creating operation. Artifacts come from the Runtime and have no creation owner; deleting one is recorded.
  • Revoking a key stops new writes but keeps its history. Deleting a resource keeps its creation owner and operation history.
  • Each record holds its ID, time, key metadata, action, resource type and ID, parent ID, request_id and trace_id. request_id is server-generated per request; a shared trace_id is not an idempotency key. Records never hold request or response bodies, secrets, model credentials, tokens, file paths or file contents.
Both routes accept only the parameters listed; an unknown, repeated or empty parameter returns 400, and a missing Project 404. GET /projects/{project_id}/resource-owners?resource_type=agent&resource_ids=id1,id2 returns the creating key of 1–100 resources of one type, in request order. resource_type is agent, session, environment, environment_template, skill, skill_version, file, vault, credential or artifact.
api_key and source are null when Core has no creation record, including for resources in another Project. source: "admin_copy" with an admin_audit_id marks a resource recorded by a copy entry in the audit log; no current route writes one. GET /projects/{project_id}/write-operations lists writes newest first by (created_at, id). Filters: key_id, resource_type, resource_id, inclusive created_after and exclusive created_before (RFC 3339). limit is 1–100, default 50. Pass the previous next_cursor as after with unchanged filters. The response is {data, has_more, next_cursor}; each entry has id, created_at, api_key, action, resource_type, resource_id, parent_id (empty when absent), request_id and trace_id. Creation records are kept for good, including after the resource is deleted. Other records are kept for core.write_audit_retention, 90 days by default; every minute Core deletes up to 1,000 expired records, so a backlog drains over several passes. Revoking a key or deleting a resource never deletes records.

Summary

GET /summary counts Sessions and usage. The response is {data, has_more, next_cursor}. Each row has project_id, nullable agent_id and key_id, current assets counts (null for Agent and key groups), sessions counts (total, idle, in_progress, requires_action, failed), summed usage, coverage (measured_sessions, total_sessions, nullable ratio) and nullable Unix last_active_at.
  • A key group counts each Session under the key that created it, even when another key later sends input. Sessions without a recorded creator form a group with a null key_id.
  • A Session whose public usage is null adds no tokens but counts in the coverage denominator.
  • Each Project is read in one database snapshot; a page is not one snapshot of the whole deployment. Totals are operational counts, not billing records.

Runtime observations

The Runtime telemetry API owns current observations, the list-only disk field, Session history and node host observations and history.

Audit log

GET /audit-log lists administrator writes newest first. Filters: project_id, resource_type, resource_id, action, inclusive created_after and exclusive created_before (RFC 3339). limit is 1–100, default 50, with the opaque after cursor. The response is {data, has_more, next_cursor}. Each entry has id, created_at, admin_credential_id (the first 8 hex characters of the Core key digest), actor_label, action, project_id, resource_type, resource_id, result_ids, request_id and trace_id. result_ids is an empty array except on copy entries. Deployment-wide entries have project_id: null, and a project_id filter excludes them. An administrator write and its audit entry commit in one transaction; if the entry fails, the write fails. A reset’s background archives and its reset_deadline and reset_complete entries carry the requester’s credential, actor label, request and trace, and each archive keeps its Session’s Project. Cancelling a reset does not undo archives already committed. Rejected provider verifications and no-op updates write no entry. Entries never contain credential values, request bodies or provider response text, and they survive the deletion of their resource and the revocation of keys.