Develop

Embed Mobius as your agent backend

Mobius can run the agents behind your product while owning durable sessions, turn execution, streaming, and scheduled work. Your product reconciles each agent through an assign-once external_ref; Mobius stores the executable agent configuration so interactive and autonomous runs behave the same way.

Prerequisites

  • An API key with mobius.org.admin for provisioning and mobius.agent.invoke for runtime calls.
  • An agent configured with its instructions, default model, tool selectors, and skills.
  • A durable application key for each conversation.

Set MOBIUS_BASE_URL and MOBIUS_API_KEY for the examples below.

Step 1: Provision or adopt the agent

Use the same external_ref on every retry:

const agentResponse = await fetch(`${process.env.MOBIUS_BASE_URL}/v1/agents`, {
  method: "POST",
  headers: {
    authorization: `Bearer ${process.env.MOBIUS_API_KEY}`,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    name: "Support",
    external_ref: "primary-support-agent",
    if_exists: "adopt",
    model: "claude-sonnet-5",
    system_prompt:
      "You are Acme's support agent. Be concise and cite ticket numbers.",
    thinking_effort: "medium",
    timeout_seconds: 120,
  }),
});
 
const agent = await agentResponse.json();

Mobius returns the new agent or the live agent that already owns the external reference. Adoption does not rewrite mutable fields; use the update-agent API when a deploy intentionally changes the configuration.

This stored configuration is used for direct invocations, routines, and messaging. There is no separate callback that Mobius must reach before an unattended turn can start.

Step 2: Invoke into a durable session

Use an application-owned session_key and idempotency key:

const response = await fetch(
  `${process.env.MOBIUS_BASE_URL}/v1/agents/invoke`,
  {
    method: "POST",
    headers: {
      authorization: `Bearer ${process.env.MOBIUS_API_KEY}`,
      "content-type": "application/json",
      accept: "text/event-stream",
    },
    body: JSON.stringify({
      agent_ref: { id: agent.id },
      session: {
        mode: "continue_or_create",
        session_key: "app:acct_123:user_456:support",
        title: "Support chat",
      },
      input: {
        content: [{ type: "text", text: "Summarize my open tickets." }],
        idempotency_key: "message_01",
      },
    }),
  },
);

Persist your inbound message and idempotency key before invoking. Once Mobius acknowledges the turn, reconnect to the returned session cursor if the stream drops; do not create a second logical message.

Step 3: Let the user choose a session model

If your product exposes a model picker, send the choice as model_override when the session is first created:

{
  "session": {
    "mode": "continue_or_create",
    "session_key": "app:acct_123:user_456:support",
    "model_override": "gpt-5.6-sol"
  }
}

The selected model applies to that session while the agent's instructions, skills, tools, memory policy, reasoning effort, and timeout remain unchanged. Resolving an existing session never replaces its choice; create a new session to switch models. Omit the field to inherit the agent's default. Worker-routed agents cannot use a managed model override.

Step 4: Reconnect and recover

  • Resume the stream using its last durable cursor or Last-Event-ID.
  • Treat turn.completed, turn.failed, and turn.cancelled as terminal for the matching turn.
  • Treat 409 session_turn_active as an application decision: wait, or send an explicit nudge when the user intends to steer the active turn.
  • Retry an invocation only when no acknowledgement was received, using the same idempotency key.

Next