Install
openclaw skills install @alex4506/openmarlinUse OpenMarlin from OpenClaw to answer questions, run tasks, and manage OpenMarlin account setup and billing flows.
openclaw skills install @alex4506/openmarlinUse this skill when a user explicitly wants to use OpenMarlin from inside OpenClaw.
This skill covers four main jobs:
/v1/executions/v1/tasks402 Payment Required recoveryActivate this skill for requests such as:
When routing the request:
/v1/executions for normal tasks such as answering, searching,
summarizing, extracting, or translating/v1/tasks for video generation and other artifact-oriented jobs even
when the user did not explicitly say "async"/v1/tasks by default unless the user explicitly
asks for synchronous executiondevice auth flow unless the deployment specifically requires
workos_callback.completed or expired.OPENMARLIN_SERVER_URL as the only trusted API origin and keep it as a
bare origin without /v1.https://openmarlin.ai as OPENMARLIN_SERVER_URL; that is the
browser-facing website. Use https://api.openmarlin.ai unless the user is
targeting a custom deployment.handoff.authorization_url directly. Do not reconstruct
WorkOS or browser URLs locally.OPENMARLIN_PLATFORM_API_KEY as a temporary override for debugging,
not the preferred steady-state storage path.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.pyRuntime expectations:
python3 is available in PATHOPENMARLIN_SERVER_URL defaults to https://api.openmarlin.aiOPENMARLIN_SERVER_URL must be a bare origin, not a URL ending in /v1For a new user, the shortest safe path is:
OPENMARLIN_SERVER_URL if you need to override the default.python3 scripts/registration_session.py create.watch until it becomes completed.bootstrap --store.python3 scripts/platform_request.py models.After setup, the most common next actions are:
402 Payment Required responseRegistration flows are built on:
POST /v1/registration/sessionsGET /v1/registration/sessions/:sessionIdPOST /v1/registration/sessions/:sessionId/api-keysRegistration session states:
pending_external_authcompletedexpiredWhen a session completes, OpenClaw should continue from the machine-readable registration session state, not from browser callback output.
Native execution uses:
POST /v1/executionsExecution requests may include:
instructionkind = agent_runstreamprovider_idlabelsagent_idsession_keytimeout_msmodelmetadataExecution routing rules:
model nor provider_id, let the server choose bothmodel, use an exact full ref and let the server choose a providerprovider_id, let the server choose an eligible model on that
providermodel and provider_id, the server enforces both constraintsIf 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.
Long-running jobs use:
POST /v1/tasksGET /v1/tasks/:taskIdTask requests do not use the same routing shape as /v1/executions.
Task requests use:
kind = videoinput.prompt requiredinput.media_urls optionalinput.media_ids optionalinput.duration_ms optionalinput.aspect_ratio optionalmetadata optionalTask requests do not accept:
instructionprovider_idlabelsmodelstreamPrefer /v1/tasks when:
artifact_url/v1/tasks from inside OpenClaw, default to submitting with
watch-and-wait behavior instead of stopping after returning a task_idTask states:
queuedrunningsucceededfailedBilling and recovery flows use:
GET /v1/balanceGET /v1/usage-eventsGET /v1/ledgerPOST /v1/topup/sessionsGET /v1/topup/sessions/:sessionIdStructured balance failures may return:
error_code = insufficient_balancemessageworkspace_idcurrent_balance.amount / unitrequired_balance.amount / unitTreat that 402 shape as workflow input, not a generic transport failure.
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
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}'
Submit a long-running job:
python3 scripts/platform_request.py tasks-submit \
--watch \
--body-json '{"kind":"video","input":{"prompt":"Generate a short plane 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>
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
Fetch the caller's referral code, invite link, and attribution summary:
python3 scripts/billing.py referral-link
Translate common routing errors into plain language:
provider_unavailable: the selected provider is not currently connectedprovider_label_mismatch: the selected provider does not satisfy the
requested routing hintsexecution_provider_not_found: no eligible execution provider matched the
current requestexecution_provider_ambiguous: more than one execution provider matched and
the server needs narrower labels or an explicit provider overrideexecution_kind_not_available: the selected provider does not support the
requested execution kindtask_executor_not_found: no configured task executor matched the current
long-running task requestinvalid_routing_labels: labels were malformedWhen these happen:
For /v1/tasks specifically:
kind = video and the input payload shape insteadFor long-running jobs:
tasks-submit --watch over asking the user to manually follow up with
tasks-watchtasks-submit --watch as the default
completion path unless the user explicitly asks for fire-and-forget behavioridempotency_key so the server
returns the original task instead of creating a second /v1/tasks requesttask_id is returnedoutput and metadata when the task reaches succeededWhen the server returns a structured 402 insufficient_balance response:
GET /v1/balance reads when availableWhen guiding a top-up flow:
pending_payment, credit_applied, and
payment_failedcheckout_url is the only required
external billing stepThe returned secret from API key bootstrap is the steady-state platform
credential for OpenClaw.
--store is usedopenmarlin.ai appears blocked by browser or Cloudflare protection,
verify that helpers are targeting https://api.openmarlin.ai before
suggesting manual browser actions