Install
openclaw skills install skylightInteract with Skylight Calendar frame - manage calendar events, chores, lists, task box items, and rewards. Use when the user wants to view/create calendar events, manage family chores, work with shopping or to-do lists, check reward points, or interact with their Skylight smart display.
openclaw skills install skylightControl Skylight Calendar frame via the unofficial API.
Set environment variables:
SKYLIGHT_URL: Base URL (default: https://app.ourskylight.com)SKYLIGHT_FRAME_ID: Your frame (household) ID — find this by logging into ourskylight.com, clicking your calendar, and copying the number from the URL (e.g., 4197102 from https://ourskylight.com/calendar/4197102)Authentication:
Use either plain env vars or 1Password references:
SKYLIGHT_EMAIL, SKYLIGHT_PASSWORDSKYLIGHT_EMAIL_OP_REF, SKYLIGHT_PASSWORD_OP_REF (op://vault/item/field)SKYLIGHT_TOKEN: Full Authorization header value, usually Bearer <access_token>Use the bundled OAuth helper to get an access token. With 1Password, store only references in env/config. If using a 1Password service-account/access token, make OP_SERVICE_ACCOUNT_TOKEN available to the Gateway process:
export OP_SERVICE_ACCOUNT_TOKEN='ops_...'
export SKYLIGHT_EMAIL_OP_REF='op://AIVault/Skylight/username'
export SKYLIGHT_PASSWORD_OP_REF='op://AIVault/Skylight/password'
export SKYLIGHT_TOKEN="$(./scripts/get-access-token.sh)"
Plain env vars still work:
export SKYLIGHT_EMAIL='you@example.com'
export SKYLIGHT_PASSWORD='...'
export SKYLIGHT_TOKEN="$(./scripts/get-access-token.sh)"
The script follows Skylight's current web/mobile OAuth flow:
SKYLIGHT_EMAIL and SKYLIGHT_PASSWORD; if either value is an op://... reference, or the matching *_OP_REF env var is set, it reads the secret with op read/oauth/authorize with client skylight-mobile and scope everything/auth/session/new and extracts the Rails authenticity_token/auth/sessioncode from the second redirect/oauth/tokenBearer <access_token> for direct use as SKYLIGHT_TOKENOptional overrides:
SKYLIGHT_URL: Base URL, default https://app.ourskylight.comSKYLIGHT_COOKIE_JAR: Path to keep cookies for debugging; by default the script uses and deletes a temp jarSKYLIGHT_DEVICE_FINGERPRINT: OAuth device fingerprint; default matches the observed web flowDo not print or persist Skylight or 1Password tokens unless needed. When using OP_SERVICE_ACCOUNT_TOKEN, never inline it in shell commands such as OP_SERVICE_ACCOUNT_TOKEN='...' op read ...; rely on the process environment so tmux/pane logs do not echo the token. Tokens may expire or rotate; rerun the helper when API calls return 401.
Responses use JSON:API format with data, included, and relationships fields.
curl -s "$SKYLIGHT_URL/api/frames/$SKYLIGHT_FRAME_ID/calendar_events?date_min=2025-01-27&date_max=2025-01-31" \
-H "Authorization: $SKYLIGHT_TOKEN" \
-H "Accept: application/json"
Query params:
date_min (required): Start date YYYY-MM-DDdate_max (required): End date YYYY-MM-DDtimezone: Timezone string (optional)include: CSV of related resources (categories,calendar_account,event_notification_setting)curl -s "$SKYLIGHT_URL/api/frames/$SKYLIGHT_FRAME_ID/source_calendars" \
-H "Authorization: $SKYLIGHT_TOKEN"
curl -s "$SKYLIGHT_URL/api/frames/$SKYLIGHT_FRAME_ID/chores?after=2025-01-27&before=2025-01-31" \
-H "Authorization: $SKYLIGHT_TOKEN"
Query params:
after: Start date YYYY-MM-DDbefore: End date YYYY-MM-DDinclude_late: Include overdue chores (bool)filter: Filter by linked_to_profilecurl -s -X POST "$SKYLIGHT_URL/api/frames/$SKYLIGHT_FRAME_ID/chores" \
-H "Authorization: $SKYLIGHT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"data": {
"type": "chore",
"attributes": {
"summary": "Take out trash",
"status": "pending",
"start": "2025-01-28",
"start_time": "08:00",
"recurring": false
},
"relationships": {
"category": {
"data": {"type": "category", "id": "CATEGORY_ID"}
}
}
}
}'
Chore attributes:
summary: Chore titlestatus: pending or completedstart: Date YYYY-MM-DDstart_time: Time HH:MM (optional)recurring: Booleanrecurrence_set: RRULE string for recurring choresreward_points: Integer (optional)emoji_icon: Emoji (optional)curl -s "$SKYLIGHT_URL/api/frames/$SKYLIGHT_FRAME_ID/lists" \
-H "Authorization: $SKYLIGHT_TOKEN"
curl -s "$SKYLIGHT_URL/api/frames/$SKYLIGHT_FRAME_ID/lists/{listId}" \
-H "Authorization: $SKYLIGHT_TOKEN"
Response includes data.attributes.kind (shopping or to_do) and included array with list items.
List item attributes:
label: Item textstatus: pending or completedsection: Section name (optional)position: Sort ordercurl -s -X POST "$SKYLIGHT_URL/api/frames/$SKYLIGHT_FRAME_ID/task_box/items" \
-H "Authorization: $SKYLIGHT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"data": {
"type": "task_box_item",
"attributes": {
"summary": "Pack lunches"
}
}
}'
Task box attributes:
summary: Task titleemoji_icon: Emoji (optional)routine: Boolean (optional)reward_points: Integer (optional)curl -s "$SKYLIGHT_URL/api/frames/$SKYLIGHT_FRAME_ID/categories" \
-H "Authorization: $SKYLIGHT_TOKEN"
Categories are used to assign chores to family members. Attributes include:
label: Category name (e.g., "Mom", "Dad", "Kids")color: Hex color #RRGGBBprofile_pic_url: Avatar URLcurl -s "$SKYLIGHT_URL/api/frames/$SKYLIGHT_FRAME_ID/rewards" \
-H "Authorization: $SKYLIGHT_TOKEN"
Optional query: redeemed_at_min (datetime) to filter by redemption date.
curl -s "$SKYLIGHT_URL/api/frames/$SKYLIGHT_FRAME_ID/reward_points" \
-H "Authorization: $SKYLIGHT_TOKEN"
curl -s "$SKYLIGHT_URL/api/frames/$SKYLIGHT_FRAME_ID" \
-H "Authorization: $SKYLIGHT_TOKEN"
curl -s "$SKYLIGHT_URL/api/frames/$SKYLIGHT_FRAME_ID/devices" \
-H "Authorization: $SKYLIGHT_TOKEN"
jq to parse JSON:API responses