configure-user-alarm

Read, create, update, snooze, and delete alarms on a user's iPhone running ClawAlarm. Use when the user asks to set an alarm, change an existing alarm's time/recurrence/label, snooze or disable an alarm, list their current alarms, or pair a new device. The skill talks to the ClawAlarm cloud-sync API and a silent APNS push reconciles the change onto the phone.

Safety Notice

This listing is from the official public ClawHub registry. Review SKILL.md and referenced scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "configure-user-alarm" with this command: npx skills add anglinb/claw-alarm

Configure User Alarm

Overview

This skill lets you set and manage alarms on a user's iPhone running the ClawAlarm app.

ClawAlarm is a cloud-synced alarm clock. Each install registers a per-device Durable Object on a Cloudflare Worker (api.claw-alarm.com), and any change made through the API is fanned out to the phone over a silent APNS push. The phone then re-fetches the alarm list and reconciles it into AlarmKit (the iOS native alarm framework). End result: when you POST /v1/account/alarms from this skill, the phone rings on schedule — no app foreground required.

You can use this skill to:

  • List the user's current alarms.
  • Create a new alarm (one-off, daily, weekdays, weekends, or arbitrary weekday mask).
  • Update an existing alarm's time, label, recurrence, sound, or enabled state.
  • Snooze a currently-ringing alarm (intent-driven snoozes only).
  • Delete an alarm.
  • Inspect device status (last sync time, push health, pending revision).

All interaction goes through scripts/alarm-api.sh, a thin curl wrapper over the API. The CLI fetches the live OpenAPI spec from /openapi.json so the available routes, request bodies, and responses always reflect the deployed worker — there is no separately-versioned client to drift.

The full machine-readable spec lives at:

  • Spec: https://api.claw-alarm.com/openapi.json
  • Reference UI: https://api.claw-alarm.com/reference (Scalar-rendered)

Pairing & authentication

Before this skill can configure anything, the phone has to hand the CLI a bearer token. ClawAlarm uses a one-time pairing-code handshake to do that.

How the pairing handshake works

  1. On the phone: the user opens the ClawAlarm app and taps "Connect Claude" (or whatever the equivalent setting is in the current build). The app calls POST /v1/pairing/init, which mints a fresh accountId, a long-lived bearer token, and a 6-letter code of the form ABC-DEF. The phone stores the token locally and displays the code to the user.

  2. In this skill: the user pastes the code into the chat. You exchange it for the same token by running:

    scripts/alarm-api.sh pair ABC-DEF
    

    Internally, that runs POST /v1/pairing/exchange with {"code":"ABC-DEF"}, validates the returned token by hitting GET /v1/account/status, and writes it to .env next to the skill (or ~/.claw-alarm-cli/.env with --location=global).

  3. From here on, every API request from alarm-api.sh carries Authorization: Bearer <token> and lands on the same Durable Object as the phone's own writes.

Codes are single-use and expire 10 minutes after issue. If the user takes too long, ask them to refresh on the phone (or — if you're already paired and just want to add another non-iOS client — run scripts/alarm-api.sh refresh, which mints a new code on the existing account).

One token = one device

A token is bound to exactly one ClawAlarm install. The Durable Object key is derived from the accountId baked into the token; there is no notion of "account with multiple devices" in the current API.

That means:

  • To configure alarms on one phone, do the pairing handshake once.
  • To configure alarms on a second phone, do the pairing handshake again from a separate location. There's no shared state — each device has its own alarm list and its own token.
  • The token does not expire on a timer. It's invalidated only by the user explicitly resetting pairing on the device.

Storing the token

The bearer token is a secret in the cryptographic sense — anyone holding it can read and rewrite the alarm list on the paired device. However:

  • It can only configure alarms. It cannot read contacts, location, photos, payment info, or anything else on the phone.
  • Its blast radius is one device.
  • It does not roll. Re-pairing is cheap (one tap on the phone).

Given that, it is safe to commit the token to a project-local CLAUDE.md, an .env, or any other config file you'd normally pin to a repo for personal-project use. You do not need a secrets manager. The default alarm-api.sh pair command writes the token to <skill>/.env, which the skill .gitignores, but you can also paste it into your CLAUDE.md so future sessions auto-load it without re-pairing:

# In ~/.claude/CLAUDE.md or project CLAUDE.md
CLAW_ALARM_API_TOKEN=<paste-token-here>

The CLI resolves credentials in this order:

  1. CLAW_ALARM_API_TOKEN from the current shell environment.
  2. Local saved token at <skill>/.env.
  3. Global saved token at ~/.claw-alarm-cli/.env.

Use scripts/alarm-api.sh auth status to see which one is active.

Listing & updating alarms

Once authenticated, the CLI is a generic curl wrapper. Every endpoint on the deployed worker is reachable through it — the help text is generated from the live OpenAPI spec, so anything documented there is callable here.

Discover available routes

# All routes, with example payloads inferred from the spec.
scripts/alarm-api.sh --help

# Full schema for one route (params, request body, responses).
scripts/alarm-api.sh --help /v1/account/alarms
scripts/alarm-api.sh --help /v1/account/alarms/{id}

Common workflows

List alarms:

scripts/alarm-api.sh /v1/account/alarms

Returns { object: "list", data: [Alarm, ...], device_revision: <int> }. The device_revision is the per-device monotonic counter — clients can short-circuit a refresh when it hasn't changed.

Create a daily 7:30 am alarm:

scripts/alarm-api.sh -m POST -d '{
  "label": "Wake up",
  "local_time": { "hour": 7, "minute": 30 },
  "recurrence": { "type": "daily" },
  "time_zone": "America/Los_Angeles"
}' /v1/account/alarms

Create a weekdays-only alarm:

scripts/alarm-api.sh -m POST -d '{
  "label": "Stand-up",
  "local_time": { "hour": 9, "minute": 0 },
  "recurrence": { "type": "weekdays" },
  "time_zone": "America/Los_Angeles"
}' /v1/account/alarms

Create an arbitrary-weekday alarm (e.g. Mon/Wed/Fri):

recurrence.weekday_mask is a 7-bit bitmask. Bit 0 = Sunday, bit 1 = Monday, …, bit 6 = Saturday. Mon (2) | Wed (8) | Fri (32) = 42.

scripts/alarm-api.sh -m POST -d '{
  "label": "Gym",
  "local_time": { "hour": 6, "minute": 15 },
  "recurrence": { "type": "weekly_mask", "weekday_mask": 42 },
  "time_zone": "America/Los_Angeles"
}' /v1/account/alarms

Create a one-off alarm:

scripts/alarm-api.sh -m POST -d '{
  "label": "Flight",
  "local_time": { "hour": 4, "minute": 45 },
  "recurrence": { "type": "none" },
  "one_off_local_date": { "year": 2026, "month": 5, "day": 12 },
  "time_zone": "America/Los_Angeles"
}' /v1/account/alarms

Update an alarm:

PATCH only the fields you want to change. Pass the alarm's current revision as If-Match to detect concurrent edits from the phone.

scripts/alarm-api.sh -m PATCH -d '{
  "local_time": { "hour": 8, "minute": 0 }
}' /v1/account/alarms/<id>

To use optimistic concurrency, add the header manually with curl, or omit it for a last-write-wins update on a known-stable alarm.

Disable / re-enable an alarm:

scripts/alarm-api.sh -m PATCH -d '{ "enabled": false }' /v1/account/alarms/<id>

Snooze a ringing alarm (intent-driven only):

The body is an ISO instant, not a duration — clock skew between client and server otherwise turns a 5-minute snooze into 4:55 or 5:05.

scripts/alarm-api.sh -m POST -d '{
  "snoozed_until": "2026-05-04T07:35:00Z"
}' /v1/account/alarms/<id>/snooze

Delete an alarm:

scripts/alarm-api.sh -m DELETE /v1/account/alarms/<id>

Inspect device status:

scripts/alarm-api.sh /v1/account/status

Includes last_synced_with_device, device_revision, last_push_sent_at, last_push_failure_code, and next_fire_at (server-computed preview of the next scheduled fire across all enabled alarms).

Important schema notes

Authoritative shapes live in the OpenAPI spec — always prefer alarm-api.sh --help <route> over guessing — but a few things are worth highlighting because they're easy to get wrong:

  • local_time is local-clock, not UTC. Recurring alarms store a clock-time spec (hour/minute) plus a recurrence rule plus a time_zone. The device recomputes the next absolute fire date each cycle, which keeps daily and weekday alarms DST- and travel-correct. Do not pretranslate the hour to UTC.
  • time_zone is required and must be an IANA name (America/Los_Angeles, Europe/Zurich, etc.). When the user asks for "7am" without specifying a zone, default to the zone the phone is currently in if you can infer it from /v1/account/status's next_fire_at; otherwise ask.
  • one_off_local_date is required iff recurrence.type === "none". The schema doesn't enforce that pairing — the repository does — so the API will reject the wrong combination with BadRequest.
  • Field names on the wire are snake_case. The rest of the worker codebase is camelCase; the wire uses Stripe-style snake_case so any future non-TS client reads naturally.
  • Mutating endpoints accept an optional If-Match: <revision> header for optimistic concurrency. The CLI's -d shorthand only sets the body, not arbitrary headers — use raw curl if you need it.

Errors you'll see

The error union is declared in src/api/errors.ts on the worker. The shapes are:

  • 400 BadRequest — malformed payload, wrong recurrence/date combination, invalid weekday_mask, etc.
  • 401 Unauthorized — missing/invalid bearer token.
  • 404 NotFound — alarm id doesn't exist on this device.
  • 409 ConflictIf-Match revision didn't match the stored revision.
  • 410 PairingCodeExpired / 404 PairingCodeNotFound — pairing-handshake failures.
  • 500 InternalServerError — bug; report and retry.

Where the docs come from

The ClawAlarm worker is built on @effect/platform's HttpApi, which means the OpenAPI spec is generated from the same HttpApi definitions that produce the request/response handlers. There is no separate spec to keep in sync — they are the same artifact.

If a route exists, it's in /openapi.json. If a route is in /openapi.json, it's callable. The Scalar UI at /reference is a renderer over that spec.

When investigating an unfamiliar route, the right order is:

  1. scripts/alarm-api.sh --help <route> — fast, machine-readable, scoped.
  2. https://api.claw-alarm.com/reference — interactive, full surface, shows examples.
  3. The worker source under cloudflare-worker/src/api/groups/ and cloudflare-worker/src/api/schemas/ — only when behavior is unclear from the schema alone (e.g. cross-field invariants like "one_off_local_date is required iff recurrence.type === 'none'").

Local testing

Point the CLI at a local wrangler dev instance:

CLAW_ALARM_API_BASE_URL=http://127.0.0.1:8787 scripts/alarm-api.sh pair ABC-DEF
CLAW_ALARM_API_BASE_URL=http://127.0.0.1:8787 scripts/alarm-api.sh /v1/account/alarms

The base URL is read fresh on every invocation, so you can flip between local and production by toggling the env var.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

小爱音箱语音播报

小爱音箱语音播报。一句话让小爱说话,无需编写代码,支持定时提醒、远程喊话、家庭传话。

Registry SourceRecently Updated
4110zkfan
General

goplaces-togo

Ask the user for their Google saved places list, look up each place with goplaces, and recommend the single best one to visit today based on their preference...

Registry SourceRecently Updated
General

Pay For Service

Access paid API endpoints and content using the x402 payment protocol. Use when you or the user want to call a paid API, access gated content, make an x402 p...

Registry SourceRecently Updated
General

Portfolio Daily Tracker

Track and report multi-group stock portfolios with daily snapshots, live Yahoo Finance prices, P&L analytics, and push notifications (Feishu/Telegram). Suppo...

Registry SourceRecently Updated