Run and continue sessions
Run an Agent, retrieve conversation history, restore a Session, and send follow-ups.
On this page
Create a SessionRetry creation safelyFind your Sessions by metadataShare an EnvironmentAuthorize Vault accessSubmit inputFollow progressRetrieve conversation historyAll saved ItemsRestore a conversation after a reloadCancel a TurnClient function deadlineCompact conversation contextCompact from a clientA Session holds its Agent configuration, conversation history, Turns, and an optional Environment reference. Keep the Session ID in your application to continue work later.
Rebyte supports retrieving saved conversation history through the Agents API. Use Retrieve conversation history below to restore messages after a page reload. You do not need the separate Conversations API.
Create a Session
const session = await client.beta.agents.sessions.create({
agent: { model: 'gpt-6-luna', instructions: 'Answer concisely.' },
environment: { type: 'none' },
input: 'Explain what an agent session stores.',
});
A Session without an Environment requires initial input. A managed Session can be created before input is available. See the quickstart for client setup and a complete streaming example.
Retry creation safely
A lost response does not tell you whether the Session was created. Send an
Idempotency-Key header (1 to 256 characters, scoped to your organization) and
retry with the same key and the same request: Rebyte returns the Session the first
attempt created, with 200 instead of 201, and never starts a second Turn for its
input. Derive the key from the record the Session serves, for example
weekly-summary/<summary_id>.
const session = await client.beta.agents.sessions.create({
agent_id: agent.id,
input: 'Summarize this week.',
metadata: { app: 'my-app', user: user.id },
}, { headers: { 'Idempotency-Key': `weekly-summary/${summary.id}` } });
With @rebyteai/agent-extensions@0.8.0, pass 'Idempotency-Key' in the
rebyte.sessions.create() parameters instead. A different request under a used key,
or a key whose Session was deleted, returns 409 idempotency_key_in_use. Requests
without the key always create a new Session.
Find your Sessions by metadata
GET /v1/agents/sessions accepts exact-match metadata[key]=value filters (1 to 16
entries). Rebyte applies them within your organization, so you do not page through
unrelated Sessions:
curl --fail-with-body --silent --show-error -G \
'https://api.rebyte.ai/v1/agents/sessions' \
--data-urlencode 'metadata[app]=my-app' --data-urlencode "metadata[user]=$USER_ID" \
-H "Authorization: Bearer $REBYTE_API_KEY" -H 'OpenAI-Beta: agents=v1'
Share an Environment
Available on the Rebyte API: create an independent Session with
environment: { type: 'reference', environment_id } using the matching local
rebyte.sessions.create extension. The response resolves the hosted Environment;
history, Turns and model settings remain separate. The attachment is fixed at
creation. See Shared environments for the
complete example, lifetime and access rules. This does not create a native subagent.
Authorize Vault access
Session vault_ids selects organization-owned Vaults for credential use.
Service-origin HTTP MCP selects credentials by server URL, optionally narrowed
by credential_id. The Vault guide describes
credential types and application authorization responsibilities.
Rebyte extension, available from October 12, 2026: a hosted Session can also
select exact sandbox_environment credentials with
environment.vault_credentials: [{ vault_id, credential_id }]. Include each
parent Vault in vault_ids; attaching a Vault alone injects no Sandbox secrets.
Bindings are fixed in the Environment configuration, while rotated credential values are resolved
for later process launches. See Sandbox delegation
for the complete contract and SDK type support.
Submit input
import { RebyteExtensions } from '@rebyteai/agent-extensions';
const rebyte = new RebyteExtensions(client);
const { turn_id } = await rebyte.sessions.events.create(session.id, {
'Idempotency-Key': 'followup-1',
events: [{
type: 'agent.session.input.message',
input: [{ role: 'user', content: [
{ type: 'input_text', text: 'Give a concrete example.' },
] }],
}],
});
The response names the Turn the message created ({ "turn_id": "turn_..." }; null
when the request carried no message). Read that Turn with
turns.retrieve(turn_id, { session_id }) and its Items with the turn_id filter below,
instead of listing the whole Session. A retry with the same Idempotency-Key and the
same events returns the same turn_id; the same key with different events returns 409.
Rebyte keeps the 1,000 most recent keys per Session.
Each input submission containing a message creates a new Turn. If another Turn is active or waiting for client functions, the new Turn queues behind it. Turns execute sequentially within the Session; a new message does not automatically resolve or steer the waiting Turn. Return its function results or cancel it to allow queued work to continue. This queuing policy differs from OpenAI's active-Turn steering behavior.
Follow progress
Subscribe to live events before submitting input. A subscription opened afterward starts at the current cursor and may miss earlier events. Retrieve Items and Turns to read persisted results.
A Session can be in_progress, requires_action, idle, or failed. requires_action means your application needs to return a function result. An idle Session may contain a completed, failed, or cancelled Turn; inspect that Turn to determine the outcome.
Retrieve conversation history
To show a conversation, use GET https://api.rebyte.ai/v1/agents/sessions/{session_id}/history.
It returns one entry per Turn with only what the user sent and the final answer, so
your application can render a chat without storing messages or filtering execution
detail:
curl --fail-with-body \
"https://api.rebyte.ai/v1/agents/sessions/${REBYTE_SESSION_ID}/history?order=asc&limit=50" \
-H "Authorization: Bearer ${REBYTE_API_KEY}" \
-H "OpenAI-Beta: agents=v1"
{
"object": "list",
"data": [{
"object": "agent.session.history_entry",
"id": "turn_...",
"status": "completed",
"created_at": 1790640000,
"completed_at": 1790640004,
"error": null,
"input": [{ "type": "input_text", "text": "What is the weather in Paris?" }],
"output_text": "It is sunny and 21°C in Paris."
}],
"has_more": false, "first_id": "turn_...", "last_id": "turn_..."
}
id is the Turn ID and the pagination cursor: pass after=<last_id> with the same
order for the next page. limit accepts 1–100 (default 20); order defaults to
desc. input holds the content parts of the Turn's user message(s) in submitted
order. output_text is the final assistant answer, or null while the Turn is running
or when it failed or was cancelled (see status and error). Tool calls, reasoning,
commands and interim commentary are omitted; add full=true to also receive each
Turn's complete items in stream order.
Stream intermediate progress live with events
while a Turn runs; it remains available through full=true or the Items endpoint.
All saved Items
Use GET https://api.rebyte.ai/v1/agents/sessions/{session_id}/items to read every saved
message and execution output. Your Rebyte organization key needs tasks:read
and must belong to the Session's organization. Keep the key on your server.
Install the official client with pnpm add openai@7.15.0, then save this as
history.mjs. Set REBYTE_API_KEY and REBYTE_SESSION_ID to your existing key
and Session ID; this script only reads history and does not start another run.
import OpenAI from 'openai';
const sessionId = process.env.REBYTE_SESSION_ID;
if (!sessionId) throw new Error('Set REBYTE_SESSION_ID');
const client = new OpenAI({
apiKey: process.env.REBYTE_API_KEY,
baseURL: 'https://api.rebyte.ai/v1',
maxRetries: 0,
});
// Automatically fetch every page, oldest first.
for await (const item of client.beta.agents.sessions.items.list(sessionId, {
order: 'asc', limit: 100,
})) {
console.log(JSON.stringify(item));
}
Run node history.mjs. To request one page directly over HTTP:
curl --fail-with-body \
"https://api.rebyte.ai/v1/agents/sessions/${REBYTE_SESSION_ID}/items?order=asc&limit=100" \
-H "Authorization: Bearer ${REBYTE_API_KEY}" \
-H "OpenAI-Beta: agents=v1"
The HTTP response contains data, has_more, first_id, and last_id. When
has_more is true, pass after=<last_id> with the same order to fetch the
next page. limit accepts 1–100 and defaults to 20; order defaults to desc.
The SDK loop above handles pagination for you; reading one page's data alone
does not retrieve a longer history.
Items include user and assistant messages, tool calls, and saved tool results.
Add turn_id to read one Turn's Items only, for example
rebyte.sessions.items.list(sessionId, { turn_id, order: 'asc' }) or
.../items?turn_id=turn_....
Use each Item's type to render it, its id to avoid duplicates, and turn_id
to associate it with an execution Turn. Call Items carry title, the model's
own one-line description of the call when the Agent enables
tool call titles, else null. Retrieve
Turns for completion, failure,
or cancellation status. Files are retrieved separately through
Artifacts.
Restore a conversation after a reload
- Save the Session ID with your application's user/conversation record.
- Authorize that user's access to the Session on your server.
- Retrieve its Items and Turns, and render the saved history.
- Send follow-up input to the same Session ID to continue with its context.
If execution is still active, subscribe to live events and reconcile the saved Items and Turns by ID. A new stream does not replay missed text deltas; use the reconnection flow. Saved Items restore conversation content, not the original timing of every streamed token.
Rebyte Agent SDK already loads this history when you initialize it with an existing Session ID. Deleting a Session makes its history unavailable through the API, so retain the Session while your application needs to display or continue it.
Cancel a Turn
await client.beta.agents.sessions.events.create(session.id, {
'Idempotency-Key': 'cancel-1',
events: [{ type: 'agent.session.input.cancel' }],
});
Cancellation stops the active work and retains the Session for later input. Closing a stream does not cancel execution. Cancellation cannot undo side effects that a tool has already performed.
Client function deadline
A waiting round has a 24-hour deadline for client results. Expired results are
rejected; an abandoned direct function wait fails the Turn with request_timeout.
Waiting survives service restarts. A nested function inside Dynamic Workflow
instead fails its program on expiry and returns that error to the Agent. The
Agent can then continue its Turn. Ordinary Turns have no fixed overall deadline;
a Schedule also imposes its own total timeout.
Applications should still expose explicit cancellation and their own user-facing
response deadline. See Functions.
Compact conversation context
Rebyte keeps the original Session Items when compacting. Compaction changes the history supplied to subsequent model calls; it does not delete your conversation or create a new Session or environment.
Before the first model call of a new Turn, Rebyte automatically summarizes older
history when estimated input reaches 80% of the model's usable input budget:
floor((context_size - reserved_output_tokens - 1024) * 0.8). The current Turn's
new input is excluded from the summary. The pending request then continues using
the summary and newer messages. UI Agents and API Agents share the tokenizer,
threshold policy and summary generator.
Automatic compaction runs at most once per Turn, before generation. It does not
interrupt a running tool-call sequence. Input that still exceeds the budget fails
with context_length_exceeded; shorten the new input or compact between Turns.
Compact from a client
Send /compact as a standalone message while the Session is idle. Rebyte
recognizes it as a control command and runs the shared summarizer; it is not sent
to the Agent as an ordinary prompt. This also works in the SDK's React chat composer.
Quoted mentions, mixed message batches and messages containing attachments are
ordinary input, not commands.
await client.beta.agents.sessions.events.create(session.id, {
events: [{
type: 'agent.session.input.message',
input: [{ role: 'user', content: [{ type: 'input_text', text: '/compact' }] }],
}],
}, { headers: { 'Idempotency-Key': crypto.randomUUID() } });
For an explicit HTTP operation, Rebyte also provides an extension endpoint:
curl -X POST "https://api.rebyte.ai/v1/agents/sessions/$SESSION_ID/compact" \
-H "OpenAI-Beta: agents=v1" \
-H "Authorization: Bearer $REBYTE_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $REQUEST_ID" \
-d '{}'
This returns 202 and a Session snapshot after command admission. It requires
tasks:write. The endpoint is a Rebyte extension, not an extra method added to
the official OpenAI client. Both entry points use the same durable Turn and
idempotency path. Reuse a request key only when retrying the same command.
Subscribe to Session events before submission.
The summary appears as an assistant commentary Item prefixed Context compacted.;
manual compaction finishes with the normal Turn completion event. Automatic
compaction publishes the summary before the answer to the current request.
Rebyte also emits agent.session.compaction.started with the Turn, trigger and
model-attempt identity; clients can ignore this extension event. Original messages,
tool output and completed summaries remain available through Items after reload.
Summary usage is included in Session and Turn usage and billed using the actual
summary model.
Manual compaction returns 409 if a Turn or client function is still active, or
there is no new history since the previous summary. Finish or cancel active work
first. Failed or cancelled summary attempts preserve the previously effective
history. Cancelling after a summary has committed preserves that successful summary.