Skills openmarlin

Use OpenMarlin from OpenClaw to answer questions, run tasks, and manage OpenMarlin account setup and billing flows.

install
source · Clone the upstream repo
git clone https://github.com/openclaw/skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/alex4506/openmarlin" ~/.claude/skills/clawdbot-skills-openmarlin && rm -rf "$T"
manifest: skills/alex4506/openmarlin/SKILL.md
source content

OpenMarlin

Use this skill when a user explicitly wants to use OpenMarlin from inside OpenClaw.

This skill covers four main jobs:

  • account registration and API key bootstrap
  • native execution requests through
    /v1/executions
  • asynchronous long-running jobs through
    /v1/tasks
  • billing, balance, and
    402 Payment Required
    recovery

When To Activate

Activate this skill for requests such as:

  • "use openmarlin to answer this"
  • "ask openmarlin to summarize this page"
  • "use openmarlin to find today's USD/CNY exchange rate"
  • "use openmarlin to execute this task"
  • "register OpenMarlin"
  • "check OpenMarlin balance"

When routing the request:

  • treat "use openmarlin ..." as an OpenMarlin intent, not generic chat
  • prefer
    /v1/executions
    for normal tasks such as answering, searching, summarizing, extracting, or translating
  • do not reject activation just because the user did not provide
    provider_id
    , labels, or an exact model ref in the first sentence

Core Constraints

  • Keep the flow OpenClaw-first by default.
  • Do not collect passwords, magic links, MFA secrets, or raw credentials in chat.
  • Prefer the
    device
    auth flow unless the deployment specifically requires
    workos_callback
    .
  • Treat browser use as a narrow external step for identity or Stripe checkout, not the main control plane.
  • After browser handoff begins, keep polling the registration session in OpenClaw until it becomes
    completed
    or
    expired
    .
  • Treat browser callback or landing pages as user-facing only. Machine-readable registration state must come from the registration session.
  • Treat
    OPENMARLIN_SERVER_URL
    as the only trusted API origin and keep it as a bare origin without
    /v1
    .
  • Use server-provided
    handoff.authorization_url
    directly. Do not reconstruct WorkOS or browser URLs locally.
  • Store platform API keys in OpenClaw auth-profile storage when available, not in ordinary skill config.
  • Treat
    OPENMARLIN_PLATFORM_API_KEY
    as a temporary override for debugging, not the preferred steady-state storage path.
  • When balance information is incomplete, label local billing state as last-known or estimated instead of pretending it is authoritative.

Installation

This skill is distributed as a directory, not as a standalone Markdown file. If you install it manually, copy both

SKILL.md
and the sibling
scripts/
directory.

Required files:

  • SKILL.md
  • scripts/registration_session.py
  • scripts/platform_request.py
  • scripts/billing.py
  • scripts/openclaw_billing_state.py
  • scripts/openclaw_platform_auth.py
  • scripts/openclaw_skill_config.py

Runtime expectations:

  • python3
    is available in
    PATH
  • OPENMARLIN_SERVER_URL
    defaults to
    https://api.openmarlin.ai
  • OPENMARLIN_SERVER_URL
    must be a bare origin, not a URL ending in
    /v1

First Run

For a new user, the shortest safe path is:

  1. Confirm
    OPENMARLIN_SERVER_URL
    if you need to override the default.
  2. Start registration with
    python3 scripts/registration_session.py create
    .
  3. Complete external auth in the browser if the server returns a handoff URL.
  4. Poll the registration session with
    watch
    until it becomes
    completed
    .
  5. Bootstrap and store the first workspace API key with
    bootstrap --store
    .
  6. Optionally call
    python3 scripts/platform_request.py models
    .
  7. Send the first execution request.

After setup, the most common next actions are:

  • send a routed execution request
  • submit a long-running task and poll for completion
  • inspect available models
  • recover from a
    402 Payment Required
    response
  • inspect balance or recent billing activity

Request Model

Registration

Registration flows are built on:

  • POST /v1/registration/sessions
  • GET /v1/registration/sessions/:sessionId
  • POST /v1/registration/sessions/:sessionId/api-keys

Registration session states:

  • pending_external_auth
  • completed
  • expired

When a session completes, OpenClaw should continue from the machine-readable registration session state, not from browser callback output.

Executions

Native execution uses:

  • POST /v1/executions

Execution requests may include:

  • instruction
  • kind = agent_run
  • stream
  • provider_id
  • labels
  • agent_id
  • session_key
  • timeout_ms
  • model
  • metadata

Execution routing rules:

  • with neither
    model
    nor
    provider_id
    , let the server choose both
  • with only
    model
    , use an exact full ref and let the server choose a provider
  • with only
    provider_id
    , let the server choose an eligible model on that provider
  • with both
    model
    and
    provider_id
    , the server enforces both constraints

If

model
is provided, it must be an exact full ref such as
openai-codex/gpt-5.4
.

If you provide both

provider_id
and
model
, first confirm from
python3 scripts/platform_request.py models
that the provider advertises that same exact model ref.

Tasks

Long-running jobs use:

  • POST /v1/tasks
  • GET /v1/tasks/:taskId

Task requests follow the same routing shape as

/v1/executions
, but they are intended for work that should not wait on a synchronous response stream.

Prefer

/v1/tasks
when:

  • generation may take many minutes
  • stream output is absent or not useful
  • the real result is expected to arrive later as artifact metadata such as an
    artifact_url

Task states:

  • queued
  • running
  • succeeded
  • failed

Billing

Billing and recovery flows use:

  • GET /v1/balance
  • GET /v1/usage-events
  • GET /v1/ledger
  • POST /v1/topup/sessions
  • GET /v1/topup/sessions/:sessionId

Structured balance failures may return:

  • error_code = insufficient_balance
  • message
  • workspace_id
  • current_balance.amount / unit
  • required_balance.amount / unit

Treat that

402
shape as workflow input, not a generic transport failure.

Common Commands

Registration

Create a registration session:

python3 scripts/registration_session.py create

Create a callback-style session when the deployment requires it:

python3 scripts/registration_session.py create --auth-flow workos_callback

Check or poll a registration session:

python3 scripts/registration_session.py status --session-id <session-id>
python3 scripts/registration_session.py watch --session-id <session-id>

Bootstrap and store the first API key:

python3 scripts/registration_session.py bootstrap \
  --session-id <session-id> \
  --store

Executions

List currently available exact models:

python3 scripts/platform_request.py models

Let the server choose model and provider automatically:

python3 scripts/platform_request.py executions \
  --body-json '{"instruction":"say hello"}'

Use an exact model ref with automatic provider routing:

python3 scripts/platform_request.py executions \
  --body-json '{"instruction":"say hello","model":"openai-codex/gpt-5.4"}'

Use an explicit provider override:

python3 scripts/platform_request.py executions \
  --provider node-a \
  --body-json '{"instruction":"say hello"}'

Send a dry run:

python3 scripts/platform_request.py executions \
  --dry-run \
  --server-url https://your-server.example.com \
  --api-key claw_wsk_placeholder \
  --body-json '{"instruction":"say hello"}'

Use streaming execution:

python3 scripts/platform_request.py executions \
  --body-json '{"instruction":"say hello","stream":true}'

Tasks

Submit a long-running job:

python3 scripts/platform_request.py tasks-submit \
  --watch \
  --body-json '{"instruction":"Generate a short plane video.","metadata":{"mode":"video"}}'

Fetch the current task state:

python3 scripts/platform_request.py tasks-status --task-id <task-id>

Poll until the task succeeds or fails:

python3 scripts/platform_request.py tasks-watch --task-id <task-id>

Billing

Explain a structured

402
response:

python3 scripts/billing.py explain-402 \
  --response-json '{"error_code":"insufficient_balance","message":"Workspace balance is insufficient for this request.","workspace_id":"ws_123","current_balance":{"amount":0,"unit":"credits"},"required_balance":{"amount":1,"unit":"credits"}}'

Create a top-up session from the

402
shortfall:

python3 scripts/billing.py create-topup \
  --response-json '{"error_code":"insufficient_balance","message":"Workspace balance is insufficient for this request.","workspace_id":"ws_123","current_balance":{"amount":0,"unit":"credits"},"required_balance":{"amount":1,"unit":"credits"}}'

Check top-up progress:

python3 scripts/billing.py status --session-id <topup-session-id>
python3 scripts/billing.py watch --session-id <topup-session-id>

Show current balance:

python3 scripts/billing.py balance --workspace-id <workspace-id>

Show recent billing activity:

python3 scripts/billing.py activity

Operational Guidance

Routing Failures

Translate common routing errors into plain language:

  • provider_unavailable
    : the selected provider is not currently connected
  • provider_label_mismatch
    : the selected provider does not satisfy the requested routing hints
  • execution_provider_not_found
    : no eligible execution provider matched the current request
  • execution_provider_ambiguous
    : more than one execution provider matched and the server needs narrower labels or an explicit provider override
  • execution_kind_not_available
    : the selected provider does not support the requested execution kind
  • invalid_routing_labels
    : labels were malformed

When these happen:

  • restate the provider and labels you actually sent
  • suggest retrying with different labels, a different provider, or automatic routing
  • do not invent hidden labels or undocumented routing fields

For long-running jobs:

  • prefer
    tasks-submit --watch
    over asking the user to manually follow up with
    tasks-watch
  • acknowledge acceptance as soon as a
    task_id
    is returned
  • surface final
    output
    and
    metadata
    when the task reaches
    succeeded

Balance And Recovery

When the server returns a structured

402 insufficient_balance
response:

  • show the current balance, required balance, and shortfall explicitly
  • explain that this is a recoverable billing state
  • keep the recovery flow inside OpenClaw until the required Stripe checkout step
  • prefer authoritative
    GET /v1/balance
    reads when available
  • keep local billing snapshots only as supporting context

When guiding a top-up flow:

  • create the top-up session inside OpenClaw
  • show the difference between
    pending_payment
    ,
    credit_applied
    , and
    payment_failed
  • tell the user that opening the Stripe
    checkout_url
    is the only required external billing step
  • refresh balance after credit lands

Credential Handling

The returned

secret
from API key bootstrap is the steady-state platform credential for OpenClaw.

  • prefer OpenClaw auth profiles over plain repo files or ordinary config
  • store the key in the default OpenClaw auth profile when
    --store
    is used
  • avoid echoing raw secrets unless the active command explicitly returns them
  • when reporting success, show where the key was stored or loaded from