System One
System One
DocumentationAPI referenceSDK documentationSDK on GitHubSystem One

SDK

API

Credits and billing

Shared guides

Decision primitivesIntegrate with an agentData handlingDeploy on Cloudflare Workers

Integrate with an agent

Choose bounded decision tasks, authenticate on the server, and recover requests without losing control of actions or charges.

This guide uses the SDK with System One hosted API to add a decision step to an Agent. For SDK connections to other services, see SDK documentation; those connections use the selected service's credentials and billing.

When to use System One

Use the decision interface when your application can state the question and its possible outcomes: route a message, choose among allowed workflow steps, score a candidate against an ordered rubric, or estimate whether a condition holds. A shared state with several named questions lets the application inspect related decisions together.

For open-ended planning, new information gathering, or ambiguous choices, hand control to a separate reasoning model or a person. Include an explicit review or think outcome when useful. A probability is a model estimate, not permission to execute a tool. Your application remains responsible for action allowlists, authorization, and any confirmation required by that action.

The hosted API currently provides Jev-compatible decisions. Evaluate its accuracy and latency on your own tasks; this guide makes no universal quality or response-time claim. Independent SDK adapters for other models are not a hosted model catalog.

Authenticate outside the model context

Create a platform API key in the signed-in console and store it in a server secret or environment variable. Use Authorization: Bearer with the hosted https://system-one.dev/v1 API. The docs host does not serve inference. Keep credentials out of prompts, tool descriptions, browser bundles, URLs, and logs. The upstream operator key is not the caller's platform key.

GET /v1/models also requires your platform key. Browser management endpoints and Playground instead use the Better Auth session; a Bearer key does not replace that session. API keys belong to an account and share its balance, rate limit, and idempotency namespace.

Add one decision step

Install the independent packages on your server:

npm install @system-one-ai/core@0.6.0 @system-one-ai/transport-fetch@0.6.0 @system-one-ai/adapter-system-one@0.6.0

This TypeScript example selects a proposed next step. It does not execute any tool:

import { createSystemOne, choice } from '@system-one-ai/core';
import { createFetchTransport } from '@system-one-ai/transport-fetch';
import { systemOneAdapter } from '@system-one-ai/adapter-system-one';

const apiKey = process.env.SYSTEM_ONE_API_KEY;
if (!apiKey) throw new Error('Set SYSTEM_ONE_API_KEY on the server.');
const client = createSystemOne({
  apiKey,
  baseURL: 'https://system-one.dev/v1',
  adapter: systemOneAdapter,
  transport: createFetchTransport(),
  model: 'jev-latest',
  timeoutMs: 30_000,
  maxRetries: 0,
});

const operation = {
  idempotencyKey: crypto.randomUUID(),
  request: {
    state: { message: 'Can you explain how credits are calculated?' },
    questions: {
      next: choice('Choose the next review step.', {
        answer: 'The request can be answered from the available documentation',
        think: 'More reasoning or information is needed',
        review: 'A person should review this request',
      }),
    },
  },
};
// Persist this operation before sending; reuse it to recover an uncertain result.
const result = await client.evaluate(operation.request, {
  headers: { 'Idempotency-Key': operation.idempotencyKey },
});
console.log({ proposedStep: result.answers.next.choice });

Running this example makes a billable request. Save the operation in your own durable job state before sending; recreating it with a fresh UUID is a new operation. A client timeout or cancellation does not prove that the server failed to complete. Select your own total deadline and retry budget.

Keep state limited to the information needed for the decision. Do not include API keys or unrelated private history. A state array is one shared input, not a batch of independent evaluations. The SDK maps booleanQuestion to native noul, but core 0.6 has stricter nullable inputs than raw HTTP; see primitives.

Recover before creating a new operation

Start with maxRetries: 0. Core APIError provides status, request ID, and retry delay; it does not expose the platform's classification headers. For a recovery controller, use raw HTTP and read X-System-One-Error-Code, X-System-One-Error-Source, X-Request-Id, Retry-After, and X-System-One-Credits. Do not classify a provider failure by arbitrary error-body text.

Observed resultApplication response
Connection lost, timeout, or unknown outcomeRecover using the saved key and identical effective request within the retention window. Do not infer a refund.
409 request_in_progressRespect Retry-After, then use the same key and body.
Successful replayUse the answer. X-Idempotency-Replayed: true and a zero charge header identify the replay; no new inference ran.
409 idempotency_failedThe previous attempt failed and was refunded. A deliberate new attempt needs a new key.
409 idempotency_conflictRestore the original request or assign a new key only to a genuinely different operation.
429 rate_limit_exceededWait for the account limit to reset, then retry the same operation. Provider provider_busy has separate refund and retry behavior.
503 request_reconciliation_pending, 410 idempotency_expired, or an unresolved internal failurePreserve the original identifiers and inspect account usage before attempting another operation. Missing credit headers do not mean zero charge.
Authentication, input, or insufficient-credit errorCorrect the cause before another attempt. An upstream 401 is not evidence that the platform account session expired.

Respect Retry-After as either seconds or an HTTP date. Bound retries by your application's deadline and attempt limit, and use backoff with jitter when no delay is supplied. Preserve the request's effective model, rubric order, extensions, and numeric values. A new key can cause another charge; a changed body under the old key is a conflict.

Completed keys and answers are retained for 24 hours from request creation. After expiry, the same key can start a new operation; this is not permanent deduplication. Application-side tool execution needs its own durable operation state and idempotency because the decision API does not perform or deduplicate those actions. See API retries, versioning, and data handling.

Decision primitives

Preserve the meaning of choices, weighted rubric scores, and boolean probabilities.

Data handling

Where requests go, what this service stores, and how retention works.

On this page

When to use System OneAuthenticate outside the model contextAdd one decision stepRecover before creating a new operation