Skip to content
Rigel docs
Open Rigel

Add an event to the calendar

calendar.event.create

POST/api/v1/households/{household_id}/commands/calendar.event.create

  • Command
  • Rigel runs it
  • Applies offline

Adds one event, or a repeating one when recurrence is given. Timed events give starts_at and ends_at; all-day events give start_date and end_date (the last day, inclusive). Times without an offset are wall-clock time in time_zone, which defaults to the household's, so 2026-11-11T15:30 is 3:30pm there. Without calendar_id the event goes on the default calendar (Family is made first if the household has no calendars). A busy-only calendar stores it as 'Busy' with no details. Prefer one repeating event to many copies. Errors: calendar_not_found, person_not_found, invalid_time_range, invalid_recurrence.

Parameters#

Add an event to the calendar: parameters
FieldDescription
household_idpathstringrequired

The household's ID.

Idempotency-Keyheaderstringoptional

The command's ID. Reuse it when retrying the same command.

Request body#

JSON, as application/json.

Add an event to the calendar: request body fields
FieldDescription
calendar_idstringoptional

Defaults to the default calendar.

titlestringrequired

The event's title, as written, 1–200 characters.

1 to 200 characters
descriptionstring or nulloptional

Notes about the event, as written, up to 8,000 characters.

at most 8,000 characters
locationstring or nulloptional

Where it is, as written, up to 500 characters.

at most 500 characters
kindone of: event, appointment, activity, chore, meal, trip, birthday, holiday, reminder, busyoptional

What sort of thing it is: event (the default), appointment (a doctor, a contractor), activity (swim, practice), chore, meal, trip, birthday, holiday, reminder, or busy (time blocked with no details).

statusone of: confirmed, tentativeoptional

confirmed (the default), or tentative for a plan that isn't settled.

starts_atstringoptional

When a timed event starts. ISO 8601: with an offset it's that instant, without one it's wall-clock time in time_zone, so 2026-11-11T15:30 means 3:30pm there.

ends_atstringoptional

When a timed event ends, in the same form as starts_at.

start_datestringoptional

The first day of an all-day event, YYYY-MM-DD.

end_datestringoptional

The last day of an all-day event, YYYY-MM-DD, inclusive. The same as start_date for a one-day event.

time_zonestringoptional

The IANA zone the event happens in, such as America/New_York. Defaults to the household's zone.

recurrencestring or nulloptional

An RFC 5545 repeat rule without the "RRULE:" prefix, such as FREQ=WEEKLY;BYDAY=SA;UNTIL=20270328. Supports FREQ DAILY, WEEKLY, MONTHLY and YEARLY with INTERVAL, COUNT, UNTIL, BYDAY (with positions), BYMONTHDAY, BYMONTH, BYSETPOS and WKST.

1 to 500 characters
person_idsarray of stringsoptional

The family members the event involves. Duplicates are ignored.

at most 50 items
remindersarray of objectsoptional

Reminders before the event or each occurrence, at most 5. Replaces the event's current reminders.

at most 5 items
reminders[].minutes_beforeintegerrequired

How long before the event starts, 0 to 40,320 (4 weeks).

0 to 40,320
reminders[].person_idstring or nulloptional

Who to remind. Leave out or null for the people on the event (or the calendar's owner, or everyone).

Response#

200 The command was applied.

Add an event to the calendar: response fields
FieldDescription
resultobjectrequired

What the command returned, such as the IDs it created.

result.event_idstringrequired

The new event.

versionintegerrequired

The household version after the command.

Errors#

Every error has the same envelope: error.code, error.message, error.details, error.recovery and error.request_id.

Add an event to the calendar: errors
StatusCodeWhen
400validation_failedA field is missing, misspelled or out of range. details.fields lists each problem.
401unauthenticatedThe request has no valid session.
404calendar_not_found
  • The calendar doesn't exist in this household.
  • The calendar must exist.
404person_not_found
  • The person doesn't exist in this household.
  • The people must exist.
  • A reminder's person must exist.
404not_foundThe household doesn't exist, or you aren't a member of it.
409invalid_time_range
  • Ending before starting is refused.
  • An all-day event can't end before its first day.
409invalid_recurrenceA rule Rigel can't read is refused.
409idempotency_key_reusedThe Idempotency-Key was already used for a different command.

Examples#

These are real. Each scenario is one of the command's test cases, run on a household when this site was built, and the response is what the API returned.

A timed event on the default calendar, with people

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "title": "Dentist (Nia)",
  "starts_at": "2025-11-11T15:30",
  "ends_at": "2025-11-11T16:30",
  "kind": "appointment",
  "location": "Dr. Lee, 12 Main St",
  "description": "Bring the insurance card",
  "person_ids": [
    "per_01JC000000000000000000000C",
    "per_01JC000000000000000000000A",
    "per_01JC000000000000000000000C"
  ]
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    title: "Dentist (Nia)",
    starts_at: "2025-11-11T15:30",
    ends_at: "2025-11-11T16:30",
    kind: "appointment",
    location: "Dr. Lee, 12 Main St",
    description: "Bring the insurance card",
    person_ids: [
      "per_01JC000000000000000000000C",
      "per_01JC000000000000000000000A",
      "per_01JC000000000000000000000C",
    ],
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "title": "Dentist (Nia)",
  "starts_at": "2025-11-11T15:30",
  "ends_at": "2025-11-11T16:30",
  "kind": "appointment",
  "location": "Dr. Lee, 12 Main St",
  "description": "Bring the insurance card",
  "person_ids": [
    "per_01JC000000000000000000000C",
    "per_01JC000000000000000000000A",
    "per_01JC000000000000000000000C"
  ]
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0W83J9JWG7RBEWJXP

{
  "result": {
    "event_id": "evt_01JC4N0000MBGE5RJ6Q7V6V6T8"
  },
  "version": 1
}

An offset in the time is that exact instant

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "title": "Call with Gran",
  "starts_at": "2025-11-12T20:00:00Z",
  "ends_at": "2025-11-12T20:30:00Z",
  "calendar_id": "cal_01JC000000000000000000000B",
  "status": "tentative"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    title: "Call with Gran",
    starts_at: "2025-11-12T20:00:00Z",
    ends_at: "2025-11-12T20:30:00Z",
    calendar_id: "cal_01JC000000000000000000000B",
    status: "tentative",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "title": "Call with Gran",
  "starts_at": "2025-11-12T20:00:00Z",
  "ends_at": "2025-11-12T20:30:00Z",
  "calendar_id": "cal_01JC000000000000000000000B",
  "status": "tentative"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0VYM84W4BGG0X588V

{
  "result": {
    "event_id": "evt_01JC4N0000MBGE5RJ6Q7V6V6T8"
  },
  "version": 1
}

A time zone on the event is where its wall-clock times are

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "title": "Flight home",
  "starts_at": "2025-11-20T18:00",
  "ends_at": "2025-11-20T21:00",
  "time_zone": "America/Los_Angeles",
  "kind": "trip"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    title: "Flight home",
    starts_at: "2025-11-20T18:00",
    ends_at: "2025-11-20T21:00",
    time_zone: "America/Los_Angeles",
    kind: "trip",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "title": "Flight home",
  "starts_at": "2025-11-20T18:00",
  "ends_at": "2025-11-20T21:00",
  "time_zone": "America/Los_Angeles",
  "kind": "trip"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R06T7EJAZRAYJT46MT

{
  "result": {
    "event_id": "evt_01JC4N0000MBGE5RJ6Q7V6V6T8"
  },
  "version": 1
}

An all-day event ends on its last day

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "title": "Leo'\''s party",
  "start_date": "2025-11-14",
  "end_date": "2025-11-14",
  "calendar_id": "cal_01JC000000000000000000000A"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    title: "Leo's party",
    start_date: "2025-11-14",
    end_date: "2025-11-14",
    calendar_id: "cal_01JC000000000000000000000A",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "title": "Leo's party",
  "start_date": "2025-11-14",
  "end_date": "2025-11-14",
  "calendar_id": "cal_01JC000000000000000000000A"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0VQP9T3TAMP7T0N15

{
  "result": {
    "event_id": "evt_01JC4N0000MBGE5RJ6Q7V6V6T8"
  },
  "version": 1
}

A repeating event is stored as a canonical rule

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "title": "Swim",
  "starts_at": "2025-11-08T09:00",
  "ends_at": "2025-11-08T10:00",
  "recurrence": "RRULE:FREQ=WEEKLY;BYDAY=SA;UNTIL=20260328",
  "kind": "activity"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    title: "Swim",
    starts_at: "2025-11-08T09:00",
    ends_at: "2025-11-08T10:00",
    recurrence: "RRULE:FREQ=WEEKLY;BYDAY=SA;UNTIL=20260328",
    kind: "activity",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "title": "Swim",
  "starts_at": "2025-11-08T09:00",
  "ends_at": "2025-11-08T10:00",
  "recurrence": "RRULE:FREQ=WEEKLY;BYDAY=SA;UNTIL=20260328",
  "kind": "activity"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0NJAW5E2V91G6QJJJ

{
  "result": {
    "event_id": "evt_01JC4N0000MBGE5RJ6Q7V6V6T8"
  },
  "version": 1
}

The Family calendar is made first when the household has no calendars

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "title": "Dinner out",
  "starts_at": "2025-11-11T18:00",
  "ends_at": "2025-11-11T20:00"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    title: "Dinner out",
    starts_at: "2025-11-11T18:00",
    ends_at: "2025-11-11T20:00",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "title": "Dinner out",
  "starts_at": "2025-11-11T18:00",
  "ends_at": "2025-11-11T20:00"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0J4F6052EHJPVSVK6

{
  "result": {
    "event_id": "evt_01JC4N0000VGW1STJ6TGXRB7FY"
  },
  "version": 1
}

A busy-only calendar stores only that the time is busy

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "title": "Quarterly review",
  "description": "secret",
  "location": "HQ",
  "kind": "appointment",
  "person_ids": [
    "per_01JC000000000000000000000A"
  ],
  "starts_at": "2025-11-12T10:00",
  "ends_at": "2025-11-12T11:00",
  "calendar_id": "cal_01JC000000000000000000000C"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    title: "Quarterly review",
    description: "secret",
    location: "HQ",
    kind: "appointment",
    person_ids: [
      "per_01JC000000000000000000000A",
    ],
    starts_at: "2025-11-12T10:00",
    ends_at: "2025-11-12T11:00",
    calendar_id: "cal_01JC000000000000000000000C",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "title": "Quarterly review",
  "description": "secret",
  "location": "HQ",
  "kind": "appointment",
  "person_ids": [
    "per_01JC000000000000000000000A"
  ],
  "starts_at": "2025-11-12T10:00",
  "ends_at": "2025-11-12T11:00",
  "calendar_id": "cal_01JC000000000000000000000C"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0PNT7QDS05PZGSVBH

{
  "result": {
    "event_id": "evt_01JC4N0000MBGE5RJ6Q7V6V6T8"
  },
  "version": 1
}

A reminder at the start (zero minutes) goes to the people on the event who sign in, including me

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "title": "Pickup",
  "starts_at": "2025-11-07T15:00",
  "ends_at": "2025-11-07T15:30",
  "person_ids": [
    "per_01JC000000000000000000000A",
    "per_01JC000000000000000000000B",
    "per_01JC000000000000000000000C"
  ],
  "reminders": [
    {
      "minutes_before": 0
    },
    {
      "minutes_before": 60,
      "person_id": "per_01JC000000000000000000000B"
    }
  ]
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    title: "Pickup",
    starts_at: "2025-11-07T15:00",
    ends_at: "2025-11-07T15:30",
    person_ids: [
      "per_01JC000000000000000000000A",
      "per_01JC000000000000000000000B",
      "per_01JC000000000000000000000C",
    ],
    reminders: [
      {
        minutes_before: 0,
      },
      {
        minutes_before: 60,
        person_id: "per_01JC000000000000000000000B",
      },
    ],
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "title": "Pickup",
  "starts_at": "2025-11-07T15:00",
  "ends_at": "2025-11-07T15:30",
  "person_ids": [
    "per_01JC000000000000000000000A",
    "per_01JC000000000000000000000B",
    "per_01JC000000000000000000000C"
  ],
  "reminders": [
    {
      "minutes_before": 0
    },
    {
      "minutes_before": 60,
      "person_id": "per_01JC000000000000000000000B"
    }
  ]
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R025VJMC6WNA0296T8

{
  "result": {
    "event_id": "evt_01JC4N0000MBGE5RJ6Q7V6V6T8"
  },
  "version": 1
}

A reminder whose time has passed is skipped

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "title": "Soon",
  "starts_at": "2025-11-06T14:30",
  "ends_at": "2025-11-06T15:00",
  "reminders": [
    {
      "minutes_before": 30
    },
    {
      "minutes_before": 5
    }
  ]
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    title: "Soon",
    starts_at: "2025-11-06T14:30",
    ends_at: "2025-11-06T15:00",
    reminders: [
      {
        minutes_before: 30,
      },
      {
        minutes_before: 5,
      },
    ],
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "title": "Soon",
  "starts_at": "2025-11-06T14:30",
  "ends_at": "2025-11-06T15:00",
  "reminders": [
    {
      "minutes_before": 30
    },
    {
      "minutes_before": 5
    }
  ]
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0PYFNQC4DKFRERDRF

{
  "result": {
    "event_id": "evt_01JC4N0000MBGE5RJ6Q7V6V6T8"
  },
  "version": 1
}

An all-day reminder counts back from 9am on the first day

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "title": "Leo'\''s party",
  "start_date": "2025-11-14",
  "end_date": "2025-11-15",
  "person_ids": [
    "per_01JC000000000000000000000B"
  ],
  "reminders": [
    {
      "minutes_before": 1440
    }
  ]
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    title: "Leo's party",
    start_date: "2025-11-14",
    end_date: "2025-11-15",
    person_ids: [
      "per_01JC000000000000000000000B",
    ],
    reminders: [
      {
        minutes_before: 1440,
      },
    ],
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "title": "Leo's party",
  "start_date": "2025-11-14",
  "end_date": "2025-11-15",
  "person_ids": [
    "per_01JC000000000000000000000B"
  ],
  "reminders": [
    {
      "minutes_before": 1440
    }
  ]
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R087GQJ60PA1DQZE0N

{
  "result": {
    "event_id": "evt_01JC4N0000MBGE5RJ6Q7V6V6T8"
  },
  "version": 1
}

An event can end when it starts

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "title": "Deadline",
  "starts_at": "2025-11-11T17:00",
  "ends_at": "2025-11-11T17:00"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    title: "Deadline",
    starts_at: "2025-11-11T17:00",
    ends_at: "2025-11-11T17:00",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "title": "Deadline",
  "starts_at": "2025-11-11T17:00",
  "ends_at": "2025-11-11T17:00"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R07Z3VDX2NNFNFWWMG

{
  "result": {
    "event_id": "evt_01JC4N0000MBGE5RJ6Q7V6V6T8"
  },
  "version": 1
}

Ending before starting is refused

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "title": "Backwards",
  "starts_at": "2025-11-11T17:00",
  "ends_at": "2025-11-11T16:59"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    title: "Backwards",
    starts_at: "2025-11-11T17:00",
    ends_at: "2025-11-11T16:59",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "title": "Backwards",
  "starts_at": "2025-11-11T17:00",
  "ends_at": "2025-11-11T16:59"
}
Response, 409
HTTP/1.1 409 Conflict
Content-Type: application/json
X-Request-Id: req_01K9D9S2R07D84P0Z3RJX17R30

{
  "error": {
    "code": "invalid_time_range",
    "message": "An event can't end before it starts. No changes were applied.",
    "details": {},
    "recovery": "Read the current state, then send a command that fits it.",
    "request_id": "req_01K9D9S2R07D84P0Z3RJX17R30"
  }
}

An all-day event can't end before its first day

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "title": "Backwards",
  "start_date": "2025-11-12",
  "end_date": "2025-11-11"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    title: "Backwards",
    start_date: "2025-11-12",
    end_date: "2025-11-11",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "title": "Backwards",
  "start_date": "2025-11-12",
  "end_date": "2025-11-11"
}
Response, 409
HTTP/1.1 409 Conflict
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0VBSTW9P36Y3RK53N

{
  "error": {
    "code": "invalid_time_range",
    "message": "An event can't end before it starts. No changes were applied.",
    "details": {},
    "recovery": "Read the current state, then send a command that fits it.",
    "request_id": "req_01K9D9S2R0VBSTW9P36Y3RK53N"
  }
}

A rule Rigel can't read is refused

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "title": "Often",
  "starts_at": "2025-11-11T17:00",
  "ends_at": "2025-11-11T18:00",
  "recurrence": "FREQ=HOURLY"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    title: "Often",
    starts_at: "2025-11-11T17:00",
    ends_at: "2025-11-11T18:00",
    recurrence: "FREQ=HOURLY",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "title": "Often",
  "starts_at": "2025-11-11T17:00",
  "ends_at": "2025-11-11T18:00",
  "recurrence": "FREQ=HOURLY"
}
Response, 409
HTTP/1.1 409 Conflict
Content-Type: application/json
X-Request-Id: req_01K9D9S2R08BZGMEX8QNSRZ8RT

{
  "error": {
    "code": "invalid_recurrence",
    "message": "That repeat rule doesn't work: Rigel can't repeat events by the hour. No changes were applied.",
    "details": {
      "problem": "Rigel can't repeat events by the hour."
    },
    "recovery": "Read the current state, then send a command that fits it.",
    "request_id": "req_01K9D9S2R08BZGMEX8QNSRZ8RT"
  }
}

The calendar must exist

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "title": "x",
  "starts_at": "2025-11-11T17:00",
  "ends_at": "2025-11-11T18:00",
  "calendar_id": "cal_01JC000000000000000000000Z"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    title: "x",
    starts_at: "2025-11-11T17:00",
    ends_at: "2025-11-11T18:00",
    calendar_id: "cal_01JC000000000000000000000Z",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "title": "x",
  "starts_at": "2025-11-11T17:00",
  "ends_at": "2025-11-11T18:00",
  "calendar_id": "cal_01JC000000000000000000000Z"
}
Response, 404
HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R01RAP4TKXZKSDSN69

{
  "error": {
    "code": "calendar_not_found",
    "message": "That calendar isn't there any more. No changes were applied.",
    "details": {
      "calendar_id": "cal_01JC000000000000000000000Z"
    },
    "recovery": "Read the current state, then send a command that fits it.",
    "request_id": "req_01K9D9S2R01RAP4TKXZKSDSN69"
  }
}

The people must exist

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "title": "x",
  "starts_at": "2025-11-11T17:00",
  "ends_at": "2025-11-11T18:00",
  "person_ids": [
    "per_01JC000000000000000000000Z"
  ]
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    title: "x",
    starts_at: "2025-11-11T17:00",
    ends_at: "2025-11-11T18:00",
    person_ids: [
      "per_01JC000000000000000000000Z",
    ],
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "title": "x",
  "starts_at": "2025-11-11T17:00",
  "ends_at": "2025-11-11T18:00",
  "person_ids": [
    "per_01JC000000000000000000000Z"
  ]
}
Response, 404
HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0DARVS5VQNTRS7F0E

{
  "error": {
    "code": "person_not_found",
    "message": "That person isn't in the household any more. No changes were applied.",
    "details": {
      "person_id": "per_01JC000000000000000000000Z"
    },
    "recovery": "Read the current state, then send a command that fits it.",
    "request_id": "req_01K9D9S2R0DARVS5VQNTRS7F0E"
  }
}

A reminder's person must exist

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "title": "x",
  "starts_at": "2025-11-11T17:00",
  "ends_at": "2025-11-11T18:00",
  "reminders": [
    {
      "minutes_before": 5,
      "person_id": "per_01JC000000000000000000000Z"
    }
  ]
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    title: "x",
    starts_at: "2025-11-11T17:00",
    ends_at: "2025-11-11T18:00",
    reminders: [
      {
        minutes_before: 5,
        person_id: "per_01JC000000000000000000000Z",
      },
    ],
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/calendar.event.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "title": "x",
  "starts_at": "2025-11-11T17:00",
  "ends_at": "2025-11-11T18:00",
  "reminders": [
    {
      "minutes_before": 5,
      "person_id": "per_01JC000000000000000000000Z"
    }
  ]
}
Response, 404
HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0MMEB9W1072ES5MP9

{
  "error": {
    "code": "person_not_found",
    "message": "That person isn't in the household any more. No changes were applied.",
    "details": {
      "person_id": "per_01JC000000000000000000000Z"
    },
    "recovery": "Read the current state, then send a command that fits it.",
    "request_id": "req_01K9D9S2R0MMEB9W1072ES5MP9"
  }
}

Add a repeating event

Times without an offset are wall-clock times in the household's time zone. recurrence is an RFC 5545 rule.

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/calendar.event.create' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01M6V9CSHPF76790NMR0YW7ZX6' \
  -d '{
  "calendar_id": "cal_01M6V9CSHK7NNRTMZQSM1BFD1B",
  "title": "Soccer practice",
  "kind": "activity",
  "location": "Riverside Park",
  "starts_at": "2026-11-10T17:00",
  "ends_at": "2026-11-10T18:00",
  "recurrence": "FREQ=WEEKLY;BYDAY=TU",
  "person_ids": [
    "per_01M6V9CS7CDAEP5VDA5T8R9TG6"
  ],
  "reminders": [
    {
      "minutes_before": 60
    }
  ]
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/calendar.event.create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01M6V9CSHPF76790NMR0YW7ZX6",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    calendar_id: "cal_01M6V9CSHK7NNRTMZQSM1BFD1B",
    title: "Soccer practice",
    kind: "activity",
    location: "Riverside Park",
    starts_at: "2026-11-10T17:00",
    ends_at: "2026-11-10T18:00",
    recurrence: "FREQ=WEEKLY;BYDAY=TU",
    person_ids: [
      "per_01M6V9CS7CDAEP5VDA5T8R9TG6",
    ],
    reminders: [
      {
        minutes_before: 60,
      },
    ],
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/calendar.event.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CSHPF76790NMR0YW7ZX6

{
  "calendar_id": "cal_01M6V9CSHK7NNRTMZQSM1BFD1B",
  "title": "Soccer practice",
  "kind": "activity",
  "location": "Riverside Park",
  "starts_at": "2026-11-10T17:00",
  "ends_at": "2026-11-10T18:00",
  "recurrence": "FREQ=WEEKLY;BYDAY=TU",
  "person_ids": [
    "per_01M6V9CS7CDAEP5VDA5T8R9TG6"
  ],
  "reminders": [
    {
      "minutes_before": 60
    }
  ]
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CSHPZYXRZD4K5Y5BFCNA

{
  "result": {
    "event_id": "evt_01M6V9CSHPG77MMGGKHAEJQ484"
  },
  "version": 89
}

Add an appointment

Reminders go to the people on the event, or to one person you name.

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/calendar.event.create' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01M6V9CSHW9XJJP1FEZ7PWQWPX' \
  -d '{
  "title": "Nia'\''s dentist",
  "kind": "appointment",
  "location": "Lakeview Dental",
  "starts_at": "2026-11-12T15:30",
  "ends_at": "2026-11-12T16:15",
  "person_ids": [
    "per_01M6V9CS79TMYHDAM7FTA9ZK3Z",
    "per_01M6V9CS6RX26JK5KVYGRN22D2"
  ],
  "reminders": [
    {
      "minutes_before": 1440
    },
    {
      "minutes_before": 60,
      "person_id": "per_01M6V9CS6RX26JK5KVYGRN22D2"
    }
  ]
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/calendar.event.create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01M6V9CSHW9XJJP1FEZ7PWQWPX",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    title: "Nia's dentist",
    kind: "appointment",
    location: "Lakeview Dental",
    starts_at: "2026-11-12T15:30",
    ends_at: "2026-11-12T16:15",
    person_ids: [
      "per_01M6V9CS79TMYHDAM7FTA9ZK3Z",
      "per_01M6V9CS6RX26JK5KVYGRN22D2",
    ],
    reminders: [
      {
        minutes_before: 1440,
      },
      {
        minutes_before: 60,
        person_id: "per_01M6V9CS6RX26JK5KVYGRN22D2",
      },
    ],
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/calendar.event.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CSHW9XJJP1FEZ7PWQWPX

{
  "title": "Nia's dentist",
  "kind": "appointment",
  "location": "Lakeview Dental",
  "starts_at": "2026-11-12T15:30",
  "ends_at": "2026-11-12T16:15",
  "person_ids": [
    "per_01M6V9CS79TMYHDAM7FTA9ZK3Z",
    "per_01M6V9CS6RX26JK5KVYGRN22D2"
  ],
  "reminders": [
    {
      "minutes_before": 1440
    },
    {
      "minutes_before": 60,
      "person_id": "per_01M6V9CS6RX26JK5KVYGRN22D2"
    }
  ]
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CSHW157C9ZNMBBKYHWXE

{
  "result": {
    "event_id": "evt_01M6V9CSHWH4PNSMGCX1WKFWDT"
  },
  "version": 90
}

Add a plan that isn't settled yet

status: tentative marks it as a plan.

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/calendar.event.create' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01M6V9CSJ2X2CM31B0BPR5HFZE' \
  -d '{
  "title": "Family movie night",
  "status": "tentative",
  "starts_at": "2026-11-13T19:00",
  "ends_at": "2026-11-13T21:00",
  "person_ids": [
    "per_01M6V9CS6RX26JK5KVYGRN22D2",
    "per_01M6V9CS744BQQH188FS6CXY9W",
    "per_01M6V9CS79TMYHDAM7FTA9ZK3Z",
    "per_01M6V9CS7CDAEP5VDA5T8R9TG6"
  ]
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/calendar.event.create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01M6V9CSJ2X2CM31B0BPR5HFZE",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    title: "Family movie night",
    status: "tentative",
    starts_at: "2026-11-13T19:00",
    ends_at: "2026-11-13T21:00",
    person_ids: [
      "per_01M6V9CS6RX26JK5KVYGRN22D2",
      "per_01M6V9CS744BQQH188FS6CXY9W",
      "per_01M6V9CS79TMYHDAM7FTA9ZK3Z",
      "per_01M6V9CS7CDAEP5VDA5T8R9TG6",
    ],
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/calendar.event.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CSJ2X2CM31B0BPR5HFZE

{
  "title": "Family movie night",
  "status": "tentative",
  "starts_at": "2026-11-13T19:00",
  "ends_at": "2026-11-13T21:00",
  "person_ids": [
    "per_01M6V9CS6RX26JK5KVYGRN22D2",
    "per_01M6V9CS744BQQH188FS6CXY9W",
    "per_01M6V9CS79TMYHDAM7FTA9ZK3Z",
    "per_01M6V9CS7CDAEP5VDA5T8R9TG6"
  ]
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CSJ2KTVRCXRYB27WXN53

{
  "result": {
    "event_id": "evt_01M6V9CSJ21CBFYER5ACBGBM1N"
  },
  "version": 91
}

Add an all-day event

All-day events give start_date and end_date, the last day, inclusive.

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/calendar.event.create' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01M6V9CSJ55R407Y2WC3QS9BNJ' \
  -d '{
  "title": "Grandma Okafor'\''s birthday",
  "kind": "birthday",
  "start_date": "2026-11-28",
  "end_date": "2026-11-28",
  "recurrence": "FREQ=YEARLY"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/calendar.event.create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01M6V9CSJ55R407Y2WC3QS9BNJ",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    title: "Grandma Okafor's birthday",
    kind: "birthday",
    start_date: "2026-11-28",
    end_date: "2026-11-28",
    recurrence: "FREQ=YEARLY",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/calendar.event.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CSJ55R407Y2WC3QS9BNJ

{
  "title": "Grandma Okafor's birthday",
  "kind": "birthday",
  "start_date": "2026-11-28",
  "end_date": "2026-11-28",
  "recurrence": "FREQ=YEARLY"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CSJ5RNG2X5M1FD55AAQC

{
  "result": {
    "event_id": "evt_01M6V9CSJ5S4BPHRJWMF5GA0Y4"
  },
  "version": 92
}

Add an event to the default calendar

Without calendar_id the event goes on the default calendar.

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/calendar.event.create' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01M6V9CSJ8AZ132YGW7ZMK8D6M' \
  -d '{
  "title": "Parent-teacher conferences",
  "starts_at": "2026-11-18T18:00",
  "ends_at": "2026-11-18T19:00"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/calendar.event.create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01M6V9CSJ8AZ132YGW7ZMK8D6M",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    title: "Parent-teacher conferences",
    starts_at: "2026-11-18T18:00",
    ends_at: "2026-11-18T19:00",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/calendar.event.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CSJ8AZ132YGW7ZMK8D6M

{
  "title": "Parent-teacher conferences",
  "starts_at": "2026-11-18T18:00",
  "ends_at": "2026-11-18T19:00"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CSJ8FREQS3SE3YFQC902

{
  "result": {
    "event_id": "evt_01M6V9CSJ8BBY7SAS3VQTA0FCZ"
  },
  "version": 93
}

For Rigel#

Rigel's tool for this command is calendar_event_create. Rigel runs this on its own, then says what it did. The agent guide has the rest.

Rigel is in early access, and sign-up is by invitation. Open Rigel