/core/v1: current Runtime observations, the stored Runtime history of one Session, and the host observations and history of a sandbox node. Reads never create, wake, renew or change compute and never add samples to history. Runtime observability defines how Core collects and keeps these values; Console API usage lists the Web pages that read them.
Every route requires the Core key as the bearer credential; a missing or invalid key returns 401 invalid_admin_key. A Project ID in a path selects the target Project and does not authenticate. Responses carry Cache-Control: no-store, use the Core error envelope and never contain provider responses, native identifiers, paths or credentials.
Current Runtime observations
List observations of every Project
The list has one row for every Session of every Project that is not deleted, including
none, self_hosted and released managed Sessions. Each row carries the owning project_id and an observation: the RuntimeObservation plus disk. Pages use the Session list’s creation-time and ID keyset. The observation ID is the Session ID, so page boundaries do not move when the Runtime behind a Session changes. A page is not an atomic snapshot: each row has its own resolved_at and, when sampled, observed_at. Unknown query keys are ignored.
Retrieve one Session’s observation
RuntimeObservation, without disk. It accepts no query parameters. An environment:none Session returns 200 with status unsupported.
RuntimeObservation
lifecycle_state comes from Core’s allocation records, never from the sample:
RuntimeInstance
cpu
All fields are finite nonnegative numbers or null. Zero is an observed zero; null is unavailable.
memory
usage_bytes and limit_bytes are safe JSON integers or null. Zero usage is observed zero; limit_bytes is at least 1, and an unknown or unlimited limit is null.
disk
Only list rows carry disk: null, or {usage_bytes, limit_bytes} with the rules of memory. E2B fills it when the sandbox reports both its disk usage and a nonzero capacity. Docker and microsandbox return null. A non-null disk appears only on an observed row.
Status and reason
An ownership mismatch, malformed durable identity or invalid provider evidence fails the request instead of becoming an
unavailable row. The generated core.openapi.yaml records each field’s type, nullability and enum but cannot express which combinations of status, mode and fields are valid; this table and the field rules above are normative.
Errors
Client
packages/agents-client exposes AdminClient.listRuntimeObservations({after, limit, order}) and AdminClient.retrieveRuntimeObservation(projectId, sessionId, options). RuntimeObservation in src/types.ts is a union discriminated by status and mode; AdminRuntimeObservation adds disk. The client checks every field, enum, nullability rule, timestamp and number and rejects unknown fields. A malformed observation rejects with a 502 invalid_runtime_observation error and a malformed page with invalid_admin_response; one bad row rejects the whole page.
Session Runtime history
Each parameter may appear once. Core chooses the bucket width: the range divided by
max_points, rounded up to whole seconds, and at least 30 seconds or the sampling interval, whichever is longer. Buckets start at start; the last one ends at end.
Core resolves the Project, then the Session and its Environment, before it reads storage; allocation and provider identities are results, never query inputs. History exists only for openai_hosted Sessions.
source is always durable. resolution_seconds is the bucket width and generated_at the read time. Only buckets that hold at least one sample appear in coverage.buckets, series[].points and token_usage; a gap stays a gap, never a zero.
Coverage
coverage counts every stored sample of the Session in the range, including unavailable ones that belong to no allocation. retained_start is the later of start and seven days before generated_at. expected_sample_count is the number of sampling intervals between retained_start and end, rounded up. Each bucket has start, end, first_observed_at, last_observed_at, observation_count, observed_count and unavailable_count.
Series
There is one series per managed allocation, keyed byallocation_id, so a provider that pauses, restores or replaces compute under the same allocation keeps one series. environment_id and provider_type identify its source. started_at is the earliest retained start of the allocation’s compute, as JSON-safe {seconds, nanoseconds} with nanoseconds 0 to 999,999,999; it is not a per-bucket start, and compute uptime comes only from current observations.
Each point has the bucket bounds, the coverage counts of the allocation’s samples, and nullable cpu and memory objects with a contributor_count of at least 1:
cpu.utilization_ratiocomes from consecutive cumulative CPU counters of one compute incarnation: the CPU seconds consumed divided by the elapsed time multiplied by the capacity, over the intervals that end in the bucket. The baseline resets when the incarnation changes or a counter decreases. E2B reports no cumulative CPU time; its bucket value is the mean of the ratios sampled in it.cpu.capacity_coresis the last capacity in the bucket.memory.usage_bytesandmemory.limit_bytesare the last values observed in the bucket.
Token usage
token_usage belongs to the Session, not to an allocation. Each point holds the last cumulative measured Session usage sampled in its bucket: start, end, sampled_at, input_tokens and output_tokens. Measured Session usage is a Core extension that sums every recorded root Turn snapshot, active Turns included. It differs from public Session usage, which is null while a root Turn runs or after one ends unmeasured. These counters are measured model tokens, not prices or billing records.
Errors and bounds
A response holds at most
max_points buckets per array, 64 series and 10,000 coverage and series points in total. Storage error text is neither returned nor logged.
Client
AdminClient.retrieveRuntimeHistory(projectId, sessionId, {start, end, maxPoints, signal}) validates the query before sending it. It then checks the exact fields, the echoed range and Session, bucket order within the range, coverage totals, allocation identity, contributor counts, token usage order, nullability, numbers and response size. Any violation rejects the whole response with a 502 invalid_admin_response error.
Node host observations and history
range is 1h (the default), 6h or 24h. Another parameter, a repeated or invalid range, or a malformed node ID returns 400 invalid_request; a missing or removed node returns 404 not_found_error. The response is the node object of the node list plus host and history:
host is the node’s last received heartbeat observation; every unavailable value, including an unobserved observed_at, is null. An offline node keeps its last values and their original time, so judge freshness by the node’s online and host.observed_at.
cpu_utilizationis the share of busy ticks in the host’s aggregate/proc/statcounters between two heartbeats, 0 to 1. Idle and I/O-wait ticks are not busy, and guest time is not counted twice. The first heartbeat of a connection, a counter reset and an unreadable baseline give null. It measures the whole visible host, not the node process or its sandboxes.effective_cpu_coresaccounts for the node process’s CPU affinity and cgroup limits; null when those cannot be established.total_memory_bytesandavailable_memory_bytesareMemTotalandMemAvailable.available_disk_bytesis the free space of the node’s state filesystem, not a sandbox quota.
history covers the range in complete UTC buckets: 60 seconds for 1h, 300 for 6h and 900 for 24h. Every bucket of the range is present, and the bucket in progress is left out. cpu_utilization_max and memory_used_bytes_max are the maxima of the recorded observations, where used memory is total minus available memory of the same observation; available_disk_bytes_min is the minimum. Each metric is null for a bucket without a recorded value, including offline periods. Core never interpolates or backfills.
SandboxAdminClient.retrieveNode(nodeId, range, options) in packages/agents-client reads this route and validates the response.