Skip to content

Plan Summary Skill

This page defines the contract for automatically creating a read-only OpenClaw Skill that queries ClawPilot plan usage.

The goal is simple: reuse the current models.providers.clawpilot-ai.apiKey value from openclaw.json, call the ClawPilot plan summary endpoint, and present the result in a stable user-facing format.

If you are creating this Skill automatically, follow this page exactly. Do not switch to a different endpoint or login flow.

1. What This Skill Must Do

  • Query current plan usage, daily allowance, used amount today, remaining amount today, request count, and token usage.
  • Reuse the existing clawpilot-ai provider API key.
  • Do not ask for a second login flow or a second pasted API key.
  • Do not modify openclaw.json, do not store extra secrets, and do not invent stale results.
  • Prefer this Skill when the user asks about:
    • plan balance
    • plan usage
    • remaining daily credits
    • amount used today
    • whether the current plan is still active

2. Credential Rules

2.1 Reuse the current clawpilot-ai provider key

You must read and parse the local OpenClaw config file directly:

bash
models.providers.clawpilot-ai.apiKey

Do not use this command to read the key:

bash
openclaw config get models.providers.clawpilot-ai.apiKey

Reason:

  • This command returns a masked value.
  • The masked value is not usable for the plan summary endpoint.
  • Therefore the Skill must read the local config file directly and extract the raw models.providers.clawpilot-ai.apiKey value.

Recommended lookup order:

  1. If OPENCLAW_CONFIG_PATH exists, read that file first.
  2. Otherwise, if OPENCLAW_STATE_DIR exists, read OPENCLAW_STATE_DIR/openclaw.json.
  3. Otherwise, read the default file at ~/.openclaw/openclaw.json.

Cross-platform and deployment constraints:

  • Do not assume OpenClaw is running on macOS or Linux only. It may also run on Windows, WSL, or inside Docker.
  • Therefore do not hardcode paths such as /Users/..., /home/..., or C:\\Users\\....
  • Prefer OPENCLAW_CONFIG_PATH or OPENCLAW_STATE_DIR first. Only fall back to the default config file under the runtime user's home directory when both are absent.
  • If OpenClaw runs inside Docker, read the config path visible inside the running container, not the host machine path.
  • The Skill should treat the current OpenClaw runtime environment as the filesystem source of truth, rather than assuming the host OS from user wording.

Resolution rules:

  1. Read the local config file and extract models.providers.clawpilot-ai.apiKey.
  2. Trim the extracted value.
  3. If it is empty, stop and report that the current OpenClaw does not have a configured clawpilot-ai provider API key.
  4. If it looks like ${ENV_NAME}, resolve process.env.ENV_NAME.
  5. If it looks like an environment variable name such as CLAWPILOT_AI_API_KEY and that environment variable exists, use the environment value.
  6. Otherwise use the literal value as the API key.

Additional requirements:

  • Do not duplicate this key into skills.entries.*.apiKey.
  • Do not print the full key in user output.
  • Do not write the key into logs or Markdown content.
  • If local config reading fails, report it as a local config read failure instead of pretending it is an API auth failure.
  • Use a 12 second HTTP timeout.
  • On timeout, say the lookup timed out and suggest retrying later.

3. HTTP Contract

3.1 Request

  • Method: GET
  • URL: https://api.clawpilot.me/api/v1/ai-api/me/summary
  • Headers:
    • Authorization: Bearer <clawpilot-ai provider apiKey>
    • Accept: application/json
  • Query: none
  • Body: none

3.2 Success response

On success the endpoint returns 200 with this structure:

json
{
  "account": {
    "id": 123,
    "email": "[email protected]",
    "status": "active",
    "created_at": "2026-03-01T09:00:00.000Z",
    "updated_at": "2026-03-14T06:21:00.000Z",
    "last_login_at": "2026-03-14T05:10:00.000Z"
  },
  "summary": {
    "has_any_entitlement": true,
    "has_active_entitlement": true,
    "current_total_daily_allowance_usd_micros": 100000000,
    "today_used_amount_usd_micros": 12345678,
    "current_daily_remaining_usd_micros": 87654322,
    "today_used_input_tokens": 123456,
    "today_used_output_tokens": 78901,
    "today_used_total_tokens": 202357,
    "today_request_count": 42,
    "last_request_at": "2026-03-14T06:20:15.000Z",
    "last_entitlement_ends_at": "2026-04-10T16:00:00.000Z",
    "quota_date": "2026-03-14",
    "quota_reset_timezone": "Asia/Shanghai"
  },
  "server_time": "2026-03-14T06:21:02.000Z"
}

Compatibility rules:

  • Ignore unknown fields.
  • Do not depend on fields not listed above.

3.3 Field meanings

FieldMeaningDisplay guidance
has_any_entitlementWhether the account has ever had a planDistinguish “never had a plan” vs “no active plan now”
has_active_entitlementWhether a plan is currently activeMain status flag
current_total_daily_allowance_usd_microsCurrent daily allowance in USD microsDivide by 1_000_000 before display
today_used_amount_usd_microsAmount used today in USD microsDivide by 1_000_000 before display
current_daily_remaining_usd_microsRemaining amount today in USD microsDivide by 1_000_000 before display
today_used_input_tokensInput tokens used todayPrefer compact units such as 1.2K or 3.4M
today_used_output_tokensOutput tokens used todayPrefer compact units such as 1.2K or 3.4M
today_used_total_tokensTotal tokens used todayPrefer compact units such as 1.2K or 3.4M
today_request_countRequest count todayDisplay as integer
last_request_atLast request timestampShow N/A when null; otherwise render it as an absolute time in the user's local timezone
last_entitlement_ends_atLatest active/recent entitlement end timeShow N/A when null; otherwise render it as an absolute time in the user's local timezone
quota_dateCurrent quota date bucketShow together with timezone
quota_reset_timezoneDaily quota reset timezonePreserve the raw timezone value
server_timeServer response timeRecommended to show as fetch time, rendered in the user's local timezone

3.4 Money conversion rule

For every *_usd_micros field:

text
usd = micros / 1_000_000

Display rules:

  • Use up to 2 decimal places for values greater than or equal to 0.01.
  • Use up to 4 decimal places for values between 0 and 0.01.
  • Strip meaningless trailing zeros.
  • Use the $ prefix.

3.5 Token display rule

  • For today_used_input_tokens, today_used_output_tokens, and today_used_total_tokens, prefer compact units.
  • Recommended units:
    • K = thousand
    • M = million
    • B = billion
  • Recommended formatting:
    • 950 -> 950
    • 1_200 -> 1.2K
    • 15_300 -> 15.3K
    • 2_450_000 -> 2.45M
  • Keep at most 2 decimal places and trim trailing zeros.
  • today_request_count should stay as a regular integer.

3.6 Time display rule

  • Convert server_time, last_request_at, and last_entitlement_ends_at into the user's local timezone before presenting them.
  • Use absolute timestamps, not only relative wording such as “today” or “just now”.
  • If available, include a timezone label or abbreviation in the displayed time.
  • quota_reset_timezone is the plan's quota reset timezone, not the user's display timezone. Keep its raw value.
  • If a time field is null, display N/A.

4. Error Contract

For non-2xx responses, the endpoint returns a standard error payload:

json
{
  "code": 401,
  "status": 401,
  "error_code": "UNAUTHORIZED",
  "message": "AI API Key 无效",
  "request_id": "req_xxx"
}

Handling rules:

HTTP statusRequired behavior
401Say the current clawpilot-ai provider key is missing, invalid, or not usable for this plan summary query; include request_id when present
403Say the AI API account is currently unavailable; include request_id when present
429Say the endpoint is rate-limited and should be retried later; include retry_after_seconds when present
5xxSay the service is temporarily unavailable; include request_id when present

Additional requirements:

  • Never invent plan data on failure.
  • Do not fall back to other ClawPilot private endpoints to guess the answer.

5. User-Facing Output Contract

Present successful results in this order:

text
ClawPilot plan usage
- Fetched at: <server_time rendered as an absolute time in the user's local timezone>
- Account: <account.email>
- Current status: <status label>
- Current daily allowance: <$ amount>
- Used today: <$ amount>
- Remaining today: <$ amount>
- Request count today: <integer>
- Token usage today: input <compact unit> / output <compact unit> / total <compact unit>
- Last request: <last_request_at rendered in the user's local timezone, or N/A>
- Latest entitlement end: <last_entitlement_ends_at rendered in the user's local timezone, or N/A>
- Quota bucket: <quota_date> (<quota_reset_timezone>)

Status labels:

  • has_active_entitlement === true Use: Active plan
  • has_active_entitlement === false && has_any_entitlement === true Use: No active plan
  • has_active_entitlement === false && has_any_entitlement === false Use: No plan detected

Required constraints:

  • Use the user's local timezone for displayed server_time, last_request_at, and last_entitlement_ends_at, and show them as absolute timestamps.
  • Do not infer a plan name because the endpoint does not return one.
  • Do not infer remaining days because the endpoint does not return remaining days directly.
  • Do not dump raw micros unless the user explicitly asks for raw fields.
  • Render token usage with compact units such as K and M.
bash
mkdir -p ~/.openclaw/workspace/skills/clawpilot-plan-summary/scripts

Structure:

text
clawpilot-plan-summary/
├── SKILL.md
└── scripts/
    └── fetch_plan_summary.mjs

7. Reference SKILL.md

markdown
---
name: clawpilot-plan-summary
description: Query ClawPilot plan usage and remaining daily credits with the existing clawpilot-ai provider API key.
metadata:
  {
    "openclaw":
      {
        "emoji": "📊",
        "requires": { "bins": ["node", "openclaw"], "config": ["models.providers.clawpilot-ai.apiKey"] },
      },
  }
---

# ClawPilot plan summary

Use this skill when the user asks about ClawPilot plan balance, plan usage, daily credits, remaining quota, or whether the current plan is still active.

## Steps

1. Run `node {baseDir}/scripts/fetch_plan_summary.mjs`.
2. Parse the returned JSON.
3. If `ok !== true`, explain the failure briefly and include `request_id` when present.
4. If `ok === true`, present the result in this exact order:
   - fetched_at
   - account_email
   - status_label
   - current_daily_allowance
   - used_today
   - remaining_today
   - today_request_count
   - today token usage
   - last_request_at (render in the user's local timezone)
   - last_entitlement_ends_at (render in the user's local timezone)
   - quota_date + quota_reset_timezone

## Important rules

- Reuse the existing `clawpilot-ai` provider API key.
- Do not ask the user to paste a second API key if this skill is eligible.
- Do not call `/api/v1/client/ai-api/runtime-status`.
- Do not infer a plan name.
- Do not show raw micros unless the user explicitly asks for raw fields.
- Render displayed timestamps in the user's local timezone.

8. Reference Script

Use the same reference implementation as the Chinese page if you are generating the actual files automatically:

The script should:

  • read the current clawpilot-ai provider key
  • call https://api.clawpilot.me/api/v1/ai-api/me/summary
  • output normalized JSON for the Skill to format

Time note:

  • The script may keep raw ISO timestamps.
  • Final user-facing rendering should convert displayed timestamps into the user's local timezone.
  • The script uses os.homedir() and path.join() specifically to stay compatible with Windows, macOS, Linux, and container paths.

9. Validation Checklist

  1. The Skill works when the current OpenClaw already has a configured clawpilot-ai provider key.
  2. The Skill reports a missing provider key clearly instead of calling the wrong endpoint.
  3. The Skill shows No active plan or No plan detected without inventing a plan name.
  4. The Skill includes request_id on API failures when present.
  5. The Skill never leaks the full API key.

Last updated:

ClawPilot