Skills openmarlin
Use OpenMarlin from OpenClaw to answer questions, run tasks, and manage OpenMarlin account setup and billing flows.
git clone https://github.com/openclaw/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"
skills/alex4506/openmarlin/SKILL.mdOpenMarlin
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
recovery402 Payment Required
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
for normal tasks such as answering, searching, summarizing, extracting, or translating/v1/executions - do not reject activation just because the user did not provide
, labels, or an exact model ref in the first sentenceprovider_id
Core Constraints
- Keep the flow OpenClaw-first by default.
- Do not collect passwords, magic links, MFA secrets, or raw credentials in chat.
- Prefer the
auth flow unless the deployment specifically requiresdevice
.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
orcompleted
.expired - Treat browser callback or landing pages as user-facing only. Machine-readable registration state must come from the registration session.
- Treat
as the only trusted API origin and keep it as a bare origin withoutOPENMARLIN_SERVER_URL
./v1 - Use server-provided
directly. Do not reconstruct WorkOS or browser URLs locally.handoff.authorization_url - Store platform API keys in OpenClaw auth-profile storage when available, not in ordinary skill config.
- Treat
as a temporary override for debugging, not the preferred steady-state storage path.OPENMARLIN_PLATFORM_API_KEY - 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.mdscripts/registration_session.pyscripts/platform_request.pyscripts/billing.pyscripts/openclaw_billing_state.pyscripts/openclaw_platform_auth.pyscripts/openclaw_skill_config.py
Runtime expectations:
is available inpython3PATH
defaults toOPENMARLIN_SERVER_URLhttps://api.openmarlin.ai
must be a bare origin, not a URL ending inOPENMARLIN_SERVER_URL/v1
First Run
For a new user, the shortest safe path is:
- Confirm
if you need to override the default.OPENMARLIN_SERVER_URL - Start registration with
.python3 scripts/registration_session.py create - Complete external auth in the browser if the server returns a handoff URL.
- Poll the registration session with
until it becomeswatch
.completed - Bootstrap and store the first workspace API key with
.bootstrap --store - Optionally call
.python3 scripts/platform_request.py models - 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
response402 Payment Required - inspect balance or recent billing activity
Request Model
Registration
Registration flows are built on:
POST /v1/registration/sessionsGET /v1/registration/sessions/:sessionIdPOST /v1/registration/sessions/:sessionId/api-keys
Registration session states:
pending_external_authcompletedexpired
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:
instructionkind = agent_runstreamprovider_idlabelsagent_idsession_keytimeout_msmodelmetadata
Execution routing rules:
- with neither
normodel
, let the server choose bothprovider_id - with only
, use an exact full ref and let the server choose a providermodel - with only
, let the server choose an eligible model on that providerprovider_id - with both
andmodel
, the server enforces both constraintsprovider_id
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/tasksGET /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:
queuedrunningsucceededfailed
Billing
Billing and recovery flows use:
GET /v1/balanceGET /v1/usage-eventsGET /v1/ledgerPOST /v1/topup/sessionsGET /v1/topup/sessions/:sessionId
Structured balance failures may return:
error_code = insufficient_balancemessageworkspace_idcurrent_balance.amount / unitrequired_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:
: the selected provider is not currently connectedprovider_unavailable
: the selected provider does not satisfy the requested routing hintsprovider_label_mismatch
: no eligible execution provider matched the current requestexecution_provider_not_found
: more than one execution provider matched and the server needs narrower labels or an explicit provider overrideexecution_provider_ambiguous
: the selected provider does not support the requested execution kindexecution_kind_not_available
: labels were malformedinvalid_routing_labels
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
over asking the user to manually follow up withtasks-submit --watchtasks-watch - acknowledge acceptance as soon as a
is returnedtask_id - surface final
andoutput
when the task reachesmetadatasucceeded
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
reads when availableGET /v1/balance - 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
, andcredit_appliedpayment_failed - tell the user that opening the Stripe
is the only required external billing stepcheckout_url - 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
is used--store - avoid echoing raw secrets unless the active command explicitly returns them
- when reporting success, show where the key was stored or loaded from