How do I use MultiOn sessions so my agent can continue a workflow using the same session_id across multiple calls?
On-Device Mobile AI Agents

How do I use MultiOn sessions so my agent can continue a workflow using the same session_id across multiple calls?

11 min read

Most teams hit the same wall the first time they try to move from “single-shot” web actions to real workflows: they realize they need the exact same browser session to stay alive across multiple API calls. That’s what MultiOn sessions are for, and the session_id is the handle you use to keep that workflow continuous.

This guide walks through how to use MultiOn sessions so your agent can continue a workflow using the same session_id across multiple calls, with concrete examples for Amazon checkout, posting on X, and extracting a product catalog.


Why sessions matter for real workflows

If you’re coming from Playwright/Selenium, you already know the failure pattern:

  • Login happens in one place.
  • The next step runs in a fresh browser, so the login cookie is gone.
  • Bot protection flares up, or you get bounced to the homepage.

MultiOn’s Sessions + Step mode avoids that by:

  • Running your workflow in a secure remote session.
  • Giving you a session_id you can reuse across calls.
  • Letting you “step” through a task: navigate, act, verify, then continue.

The mental model is:

Intent in (cmd + url) → actions executed in a real browser → session_id out → reuse session_id to continue the same browser session.


The core pattern: create, reuse, close

At the API level, using MultiOn sessions with a consistent session_id is a three-step pattern:

  1. Create a session

    • Send a POST https://api.multion.ai/v1/web/browse with your initial cmd and url.
    • MultiOn spins up a secure remote browser session and returns a session_id.
  2. Reuse the same session_id across multiple calls

    • For every subsequent step in the workflow, call the same endpoint.
    • Include the same session_id in the request body to continue in that exact browser session.
  3. Optionally close or let the session expire

    • When you’re done (checkout completed, post published), you can drop the session_id or call a cleanup endpoint if exposed in your environment.
    • MultiOn handles session timeout according to platform limits (treat it like any remote browser lease).

Everything else—login persistence, cart state, CSRF tokens, dynamic UI—is handled inside that remote session.


Minimal call shape with session_id

Here’s the smallest useful shape for using sessions via the Agent API (V1 Beta).

First call: start a new session

curl -X POST https://api.multion.ai/v1/web/browse \
  -H "Content-Type: application/json" \
  -H "X_MULTION_API_KEY: $MULTION_API_KEY" \
  -d '{
    "url": "https://www.amazon.com/",
    "cmd": "Search for a Nintendo Switch OLED and open the product page of the top result."
  }'

What to look for in the response:

  • A session_id field (string) — this is your session handle.
  • A description of what the agent did (e.g., navigation, clicks).
  • Optional screenshot and/or DOM snippet depending on your integration.

Example (simplified):

{
  "session_id": "sess_91db8e7a8e0344c5b0c3fad2e6e4b317",
  "status": "success",
  "result": {
    "description": "Opened the product page for 'Nintendo Switch OLED' on Amazon.",
    "url": "https://www.amazon.com/dp/XXXXXXXXX"
  }
}

Save session_id somewhere you control (DB row, cache, or in-memory if it’s a short-lived backend call chain).

Subsequent calls: continue the same session

On the next step, you don’t want a new browser. You want to continue:

curl -X POST https://api.multion.ai/v1/web/browse \
  -H "Content-Type: application/json" \
  -H "X_MULTION_API_KEY: $MULTION_API_KEY" \
  -d '{
    "session_id": "sess_91db8e7a8e0344c5b0c3fad2e6e4b317",
    "cmd": "Add this item to cart, then proceed to checkout until the payment page."
  }'

Because you passed the same session_id, the agent:

  • Uses the same logged-in state.
  • Uses the same cart.
  • Stays inside the same secure remote session.

You can keep repeating this pattern, adjusting the cmd each time while reusing that session_id.


Example 1: Multi-step Amazon checkout with a shared session_id

Let’s walk a realistic flow built on top of Sessions + Step mode.

Step 1: Login and navigate to the product

curl -X POST https://api.multion.ai/v1/web/browse \
  -H "Content-Type: application/json" \
  -H "X_MULTION_API_KEY: $MULTION_API_KEY" \
  -d '{
    "url": "https://www.amazon.com/",
    "cmd": "Log in using the saved browser profile if available, search for 'AirPods Pro', and open the first product page."
  }'

Your backend does:

  • Parse the session_id from the response.
  • Persist it to your “task run” or “order attempt” record.

Step 2: Add to cart in the same session

curl -X POST https://api.multion.ai/v1/web/browse \
  -H "Content-Type: application/json" \
  -H "X_MULTION_API_KEY: $MULTION_API_KEY" \
  -d '{
    "session_id": "sess_91db8e7a8e0344c5b0c3fad2e6e4b317",
    "cmd": "Add this item to the cart, then navigate to the cart page."
  }'

The agent does:

  • A click on “Add to Cart”.
  • Follows the UI flow to the cart page.
  • Returns you updated state (URL, description, maybe a summary of cart contents).

Step 3: Proceed to checkout and stop at payment

curl -X POST https://api.multion.ai/v1/web/browse \
  -H "Content-Type: application/json" \
  -H "X_MULTION_API_KEY: $MULTION_API_KEY" \
  -d '{
    "session_id": "sess_91db8e7a8e0344c5b0c3fad2e6e4b317",
    "cmd": "Proceed to checkout, confirm the existing shipping address, and stop when you reach the payment selection page. Do not place the order."
  }'

Because all steps share the same session_id, you don’t fight:

  • Lost login state.
  • New-device challenges every step.
  • Cart desyncs.

From a platform perspective, “session continuity” is your real SLA; keeping the session_id consistent is how you get it.


Example 2: Posting on X with two-step confirmation

Another common pattern is API → human approval → API.

  1. Agent drafts the post in X with a session_id.
  2. You present a preview to the user.
  3. If they approve, you reuse the same session_id to click “Post”.

Step 1: Draft a post

curl -X POST https://api.multion.ai/v1/web/browse \
  -H "Content-Type: application/json" \
  -H "X_MULTION_API_KEY: $MULTION_API_KEY" \
  -d '{
    "url": "https://x.com/",
    "cmd": "Log in if necessary and draft a new post saying: \"Launching our new feature today!\" but do not publish yet."
  }'

Store the returned session_id. Show the user a screenshot/preview.

Step 2: Publish in the same session after approval

curl -X POST https://api.multion.ai/v1/web/browse \
  -H "Content-Type: application/json" \
  -H "X_MULTION_API_KEY: $MULTION_API_KEY" \
  -d '{
    "session_id": "sess_xxx_approved",
    "cmd": "Click the button to publish the drafted post."
  }'

The same session_id means:

  • The draft is still loaded in that browser tab.
  • The user is still logged in.
  • No re-auth or “you’re posting from a new device” prompts.

Example 3: Extract, then act (sessions + Retrieve)

Sometimes you need structured JSON out and actions in the same workflow. The pattern is:

  1. Use the Agent API to navigate in a session.
  2. Use Retrieve (with the same session context) to turn the dynamic page into a JSON array of objects.
  3. Optionally act again in the same session_id.

Assume you used POST /v1/web/browse to reach an H&M category page in a session:

# Step 1: navigate via Agent API
curl -X POST https://api.multion.ai/v1/web/browse \
  -H "Content-Type: application/json" \
  -H "X_MULTION_API_KEY: $MULTION_API_KEY" \
  -d '{
    "url": "https://www2.hm.com/en_us/men/products/jeans.html",
    "cmd": "Open the H&M men jeans category page and scroll to load products."
  }'

You get:

{
  "session_id": "sess_hm_jeans_123",
  "status": "success",
  "result": { "url": "https://www2.hm.com/en_us/men/products/jeans.html" }
}

Step 2: Retrieve structured JSON using the same session

Retrieve is designed to produce JSON arrays of objects and handle dynamic pages with controls like renderJs, scrollToBottom, and maxItems.

Example call shape (your environment may expose this as POST https://api.multion.ai/v1/web/retrieve):

curl -X POST https://api.multion.ai/v1/web/retrieve \
  -H "Content-Type: application/json" \
  -H "X_MULTION_API_KEY: $MULTION_API_KEY" \
  -d '{
    "session_id": "sess_hm_jeans_123",
    "renderJs": true,
    "scrollToBottom": true,
    "maxItems": 50,
    "schema": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": { "type": "string" },
          "price": { "type": "string" },
          "url": { "type": "string" },
          "image": { "type": "string" }
        },
        "required": ["name", "price", "url"]
      }
    }
  }'

Return shape (simplified):

[
  {
    "name": "Slim Fit Jeans",
    "price": "$39.99",
    "url": "https://www2.hm.com/en_us/productpage.1234567890.html",
    "image": "https://image.hm.com/assets/hm1234567890.jpg"
  },
  { "...": "..." }
]

Because Retrieve uses the same session_id, you inherit:

  • Any prior scrolling the agent has done.
  • Any location/locale selection.
  • Any login-based personalization, if relevant.

You can then pass that session_id back into web/browse again to act on a specific product.


Handling errors and session expiry

In a production integration, treat session_id like any other remote resource lease:

  • Check for 4xx/5xx responses on every call.
    • If you see 402 Payment Required, your usage or billing state needs attention before you can continue that session.
  • Handle “session not found” or expiry gracefully.
    • Implement a retry policy that can:
      • Start a new session.
      • Re-run critical steps (e.g., re-login, navigate back to the target page).
  • Store session metadata:
    • session_id
    • Creation time
    • Last-used time
    • Associated user / workflow run

This makes it trivial to decide when to reuse, when to let expire, and when to spawn a new parallel agent.


Using Sessions + Step mode from your app code

Here’s how this looks in a Node backend, with a minimal “orchestrator” that keeps the same session_id across steps.

import fetch from "node-fetch";

const MULTION_API_KEY = process.env.MULTION_API_KEY;
const BASE_URL = "https://api.multion.ai/v1/web/browse";

async function multionStep(payload: any) {
  const res = await fetch(BASE_URL, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X_MULTION_API_KEY": MULTION_API_KEY!
    },
    body: JSON.stringify(payload)
  });

  if (res.status === 402) {
    throw new Error("MultiOn: 402 Payment Required – check billing/quotas.");
  }

  if (!res.ok) {
    const text = await res.text();
    throw new Error(`MultiOn error ${res.status}: ${text}`);
  }

  return res.json();
}

export async function runAmazonFlow() {
  // Step 1: start session
  const first = await multionStep({
    url: "https://www.amazon.com/",
    cmd: "Search for 'Nintendo Switch OLED' and open the top product page."
  });

  const sessionId = first.session_id;
  if (!sessionId) throw new Error("Missing session_id in first MultiOn response");

  // Step 2: continue with same session
  const second = await multionStep({
    session_id: sessionId,
    cmd: "Add this item to cart and go to the cart page."
  });

  // Step 3: another step with the same session
  const third = await multionStep({
    session_id: sessionId,
    cmd: "Proceed to checkout until the payment method selection page, but do not place the order."
  });

  return { first, second, third };
}

Key points:

  • Only the first call supplies url; subsequent calls rely on the current page in that session.
  • Every later call includes session_id and a new cmd.
  • Errors include payment state (e.g., 402 Payment Required) as first-class signals.

Parallel agents with distinct session_ids

Sessions become even more powerful when you scale out:

  • You can have many concurrent session_ids, each representing an independent browser session.
  • Each session can:
    • Log into a different account.
    • Be assigned to a different user or tenant.
    • Run the same workflow template with different parameters.

Pattern:

  • Per user: allocate a new session_id for long-running tasks, store it on their profile, reuse until idle.
  • Per job: allocate a new session_id per batch (e.g., 50 product checks), reuse inside that batch, then let it expire.

This is how you get “infinite scalability with parallel agents”: each session_id is a unit of concurrency, and MultiOn runs those as secure remote sessions behind the scenes.


Practical guidelines for using the same session_id across calls

From years of babysitting brittle Playwright/Selenium flows, this is the operational checklist I’d actually enforce:

  1. Always persist session_id on first response
    Don’t rely on an in-function variable; store it in DB/cache tagged to the workflow or user.

  2. Pass session_id on every subsequent call
    If you forget it once, you’re in a new browser. That’s a silent failure mode if you’re not logging it.

  3. Treat sessions as stateful resources
    Track created_at and last_step_at. If a session is older than your acceptable threshold, consider starting a new one.

  4. Separate “navigation” from “destructive actions”
    Use smaller cmds so you can inspect responses between steps:

    • Step A: get to the page.
    • Step B: perform the action. This gives you better control and observability.
  5. Log session_id with every error
    When something goes wrong, the first question should be:
    “Is this an agent command issue, or did this session die / get challenged?”


How this replaces brittle Playwright/Selenium flows

With Playwright/Selenium, you’ve probably fought:

  • Cookies that don’t persist across workers.
  • Manual proxy juggling to appease bot protection.
  • Hand-rolled “remote Chrome farms” to keep sessions alive.

MultiOn’s Sessions + Step mode and secure remote sessions give you:

  • A stable session_id interface instead of hand-managed browser objects.
  • Native proxy support and infrastructure tuned for “tricky bot protection.”
  • An API surface where “intent in, actions executed in a real browser, and structured JSON out” is the default—not an internal project.

You stop maintaining selector jungles and start orchestrating workflows through a small set of primitives: Agent API, Retrieve, session_id, and stepwise cmds.


Next step

If you want to see MultiOn sessions in action in your own stack, start wiring the pattern above into a small workflow—one Amazon-like checkout or one X posting flow—and watch how much friction disappears once you treat session_id as the core unit of continuity.

Get Started