Set up a routine for Rigel
agent.routine.create
POST/api/v1/households/{household_id}/commands/agent.routine.create
- Command
- Rigel runs it
- Applies offline
Sets up work Rigel does on its own at set times, such as "Wednesdays at 9am, if no new recipe was tried in 3 weeks, suggest one" or "every Sunday, remind me to plan meals". Use it when someone asks for something to happen repeatedly or later, not for a one-time answer. Give a title in plain words for the settings list and a task written for a run with nobody present. It runs with the authority of for_person_id (default: the person asking) and may only tell the family through dashboard cards and notifications. Fails with person_not_found if for_person_id isn't in the household, person_required if nobody is named and the requester has no person, and time_in_past for a once-only time that has passed. Returns the routine's ID and when it runs next.
Parameters#
| Field | Description |
|---|---|
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.
| Field | Description |
|---|---|
titlestringrequired | What the routine does in plain words for the list in settings, 1–120 characters, such as "Suggest a new recipe on Wednesdays". |
taskstringrequired | The instructions Rigel follows each time, up to 4000 characters, written to be read with nobody around: what to check, when to do something, and what to leave alone. |
appone of: meals, recipes, shopping, inventory, calendar, email, tasks, documents, chat, maintenance, null or nulloptional | The app whose guide Rigel reads for this work; null or left out for none. |
for_person_idstringoptional | Whose authority it runs with and who it is for. Defaults to the person asking. |
repeatone of 4 shapesrequired | How often it runs: daily at a time, weekly on some days, monthly on a day (1–28), or once on a date. Example: { "kind": "weekly", "days": ["wed"], "time": "09:00" }. |
| Shape 1 | |
repeat.kindone of: dailyrequired | No description. |
repeat.timestringrequired | The time of day in the household's time zone, 24-hour "HH:MM", such as "09:00". |
| Shape 2, with days | |
repeat.kindone of: weeklyrequired | No description. |
repeat.daysarray, each one of: mon, tue, wed, thu, fri, sat, sunrequired | The days of the week: "mon", "tue", "wed", "thu", "fri", "sat", "sun". |
repeat.timestringrequired | The time of day in the household's time zone, 24-hour "HH:MM", such as "09:00". |
| Shape 3, with day | |
repeat.kindone of: monthlyrequired | No description. |
repeat.dayintegerrequired | The day of the month, 1 to 28, so every month has it. |
repeat.timestringrequired | The time of day in the household's time zone, 24-hour "HH:MM", such as "09:00". |
| Shape 4, with date | |
repeat.kindone of: oncerequired | No description. |
repeat.datestringrequired | A calendar date in the household's time zone, YYYY-MM-DD. |
repeat.timestringrequired | The time of day in the household's time zone, 24-hour "HH:MM", such as "09:00". |
Response#
200 The command was applied.
| Field | Description |
|---|---|
resultobjectrequired | What the command returned, such as the IDs it created. |
result.routine_idstringrequired | The new routine. |
result.next_run_atintegerrequired | When it runs first, UTC milliseconds. |
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.
| Status | Code | When |
|---|---|---|
400 | validation_failed | A field is missing, misspelled or out of range. details.fields lists each problem. |
401 | unauthenticated | The request has no valid session. |
404 | person_not_found | A person who isn't in the household. |
404 | not_found | The household doesn't exist, or you aren't a member of it. |
409 | time_in_past | A once-only time that has passed. |
409 | person_required | Nobody named and the requester has no person. |
409 | idempotency_key_reused | The 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.
Sets up a weekly routine for the person asking
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/agent.routine.create' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"title": "Suggest a new recipe on Wednesdays",
"task": "Suggest a recipe.",
"app": "meals",
"repeat": {
"kind": "weekly",
"days": [
"wed"
],
"time": "09:00"
}
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/agent.routine.create", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
title: "Suggest a new recipe on Wednesdays",
task: "Suggest a recipe.",
app: "meals",
repeat: {
kind: "weekly",
days: [
"wed",
],
time: "09:00",
},
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/agent.routine.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"title": "Suggest a new recipe on Wednesdays",
"task": "Suggest a recipe.",
"app": "meals",
"repeat": {
"kind": "weekly",
"days": [
"wed"
],
"time": "09:00"
}
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0HR64SDQARAVBBWWK
{
"result": {
"routine_id": "rtn_01JC4N0000MBGE5RJ6Q7V6V6T8",
"next_run_at": 1762956000000
},
"version": 1
}For someone else
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/agent.routine.create' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000BBBBBBBBBBBBBBBB' \
-d '{
"title": "Plan meals on Sundays",
"task": "Remind me to plan the week'\''s meals.",
"for_person_id": "per_01JC000000000000000000000A",
"repeat": {
"kind": "weekly",
"days": [
"sun"
],
"time": "18:00"
}
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/agent.routine.create", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000BBBBBBBBBBBBBBBB",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
title: "Plan meals on Sundays",
task: "Remind me to plan the week's meals.",
for_person_id: "per_01JC000000000000000000000A",
repeat: {
kind: "weekly",
days: [
"sun",
],
time: "18:00",
},
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/agent.routine.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000BBBBBBBBBBBBBBBB
{
"title": "Plan meals on Sundays",
"task": "Remind me to plan the week's meals.",
"for_person_id": "per_01JC000000000000000000000A",
"repeat": {
"kind": "weekly",
"days": [
"sun"
],
"time": "18:00"
}
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R02K786HRT7BYH28KD
{
"result": {
"routine_id": "rtn_01JC4N00004J057T2A2FXGZEXG",
"next_run_at": 1762729200000
},
"version": 1
}A daily time that doesn't exist on the spring-forward day runs just after the gap
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/agent.routine.create' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000CCCCCCCCCCCCCCCC' \
-d '{
"title": "Check the pantry",
"task": "Look for things that are running out.",
"for_person_id": "per_01JC000000000000000000000A",
"repeat": {
"kind": "daily",
"time": "02:30"
}
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/agent.routine.create", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000CCCCCCCCCCCCCCCC",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
title: "Check the pantry",
task: "Look for things that are running out.",
for_person_id: "per_01JC000000000000000000000A",
repeat: {
kind: "daily",
time: "02:30",
},
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/agent.routine.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000CCCCCCCCCCCCCCCC
{
"title": "Check the pantry",
"task": "Look for things that are running out.",
"for_person_id": "per_01JC000000000000000000000A",
"repeat": {
"kind": "daily",
"time": "02:30"
}
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01KK4Q9J80CGH64Q0AJ0FY063T
{
"result": {
"routine_id": "rtn_01JC4N0000MF7D5SWWQQ5KK6CM",
"next_run_at": 1772955000000
},
"version": 1
}A once-only routine on a later date, in another time zone
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/agent.routine.create' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000DDDDDDDDDDDDDDDD' \
-d '{
"title": "Renew the car registration",
"task": "Remind us to renew the registration.",
"for_person_id": "per_01JC000000000000000000000B",
"repeat": {
"kind": "once",
"date": "2025-12-01",
"time": "08:00"
}
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/agent.routine.create", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000DDDDDDDDDDDDDDDD",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
title: "Renew the car registration",
task: "Remind us to renew the registration.",
for_person_id: "per_01JC000000000000000000000B",
repeat: {
kind: "once",
date: "2025-12-01",
time: "08:00",
},
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/agent.routine.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000DDDDDDDDDDDDDDDD
{
"title": "Renew the car registration",
"task": "Remind us to renew the registration.",
"for_person_id": "per_01JC000000000000000000000B",
"repeat": {
"kind": "once",
"date": "2025-12-01",
"time": "08:00"
}
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R082TMKC36WF1F6BNR
{
"result": {
"routine_id": "rtn_01JC4N000049NKRJJ4CAP6XY8V",
"next_run_at": 1764604800000
},
"version": 1
}A once-only time that has passed
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/agent.routine.create' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000EEEEEEEEEEEEEEEE' \
-d '{
"title": "Old",
"task": "Old.",
"for_person_id": "per_01JC000000000000000000000B",
"repeat": {
"kind": "once",
"date": "2025-11-06",
"time": "08:00"
}
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/agent.routine.create", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000EEEEEEEEEEEEEEEE",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
title: "Old",
task: "Old.",
for_person_id: "per_01JC000000000000000000000B",
repeat: {
kind: "once",
date: "2025-11-06",
time: "08:00",
},
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/agent.routine.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000EEEEEEEEEEEEEEEE
{
"title": "Old",
"task": "Old.",
"for_person_id": "per_01JC000000000000000000000B",
"repeat": {
"kind": "once",
"date": "2025-11-06",
"time": "08:00"
}
}HTTP/1.1 409 Conflict
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0P859E8EQN263GKSX
{
"error": {
"code": "time_in_past",
"message": "That time has already passed. No changes were applied.",
"details": {},
"recovery": "Read the current state, then send a command that fits it.",
"request_id": "req_01K9D9S2R0P859E8EQN263GKSX"
}
}A person who isn't in the household
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/agent.routine.create' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000FFFFFFFFFFFFFFFF' \
-d '{
"title": "Plan",
"task": "Plan.",
"for_person_id": "per_01JC000000000000000000000Z",
"repeat": {
"kind": "weekly",
"days": [
"wed"
],
"time": "09:00"
}
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/agent.routine.create", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000FFFFFFFFFFFFFFFF",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
title: "Plan",
task: "Plan.",
for_person_id: "per_01JC000000000000000000000Z",
repeat: {
kind: "weekly",
days: [
"wed",
],
time: "09:00",
},
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/agent.routine.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000FFFFFFFFFFFFFFFF
{
"title": "Plan",
"task": "Plan.",
"for_person_id": "per_01JC000000000000000000000Z",
"repeat": {
"kind": "weekly",
"days": [
"wed"
],
"time": "09:00"
}
}HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0T5ZK0ERFKH2WFVWN
{
"error": {
"code": "person_not_found",
"message": "That person isn't in the household. No changes were applied.",
"details": {
"person_id": "per_01JC000000000000000000000Z"
},
"recovery": "Read the current state, then send a command that fits it.",
"request_id": "req_01K9D9S2R0T5ZK0ERFKH2WFVWN"
}
}Nobody named and the requester has no person
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/agent.routine.create' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000GGGGGGGGGGGGGGGG' \
-d '{
"title": "Plan",
"task": "Plan.",
"repeat": {
"kind": "weekly",
"days": [
"wed"
],
"time": "09:00"
}
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/agent.routine.create", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000GGGGGGGGGGGGGGGG",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
title: "Plan",
task: "Plan.",
repeat: {
kind: "weekly",
days: [
"wed",
],
time: "09:00",
},
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/agent.routine.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000GGGGGGGGGGGGGGGG
{
"title": "Plan",
"task": "Plan.",
"repeat": {
"kind": "weekly",
"days": [
"wed"
],
"time": "09:00"
}
}HTTP/1.1 409 Conflict
Content-Type: application/json
X-Request-Id: req_01K9D9S2R09WQNV3YSTHWQQVBR
{
"error": {
"code": "person_required",
"message": "Say who the routine is for. No changes were applied.",
"details": {},
"recovery": "Read the current state, then send a command that fits it.",
"request_id": "req_01K9D9S2R09WQNV3YSTHWQQVBR"
}
}Set up a routine
Work Rigel does on its own at set times, written for a run with nobody present. It runs with the authority of the person it's for.
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/agent.routine.create' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01M6V9CTC5A82R7X6DV70WV7DV' \
-d '{
"title": "Nudge us to plan meals",
"task": "On Sunday evening, if next week has fewer than five dinners planned, post a dashboard card that asks whether to plan the rest.",
"app": "meals",
"repeat": {
"kind": "weekly",
"days": [
"sun"
],
"time": "18:00"
}
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/agent.routine.create", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01M6V9CTC5A82R7X6DV70WV7DV",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
title: "Nudge us to plan meals",
task: "On Sunday evening, if next week has fewer than five dinners planned, post a dashboard card that asks whether to plan the rest.",
app: "meals",
repeat: {
kind: "weekly",
days: [
"sun",
],
time: "18:00",
},
}),
});
const data = await response.json();POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/agent.routine.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CTC5A82R7X6DV70WV7DV
{
"title": "Nudge us to plan meals",
"task": "On Sunday evening, if next week has fewer than five dinners planned, post a dashboard card that asks whether to plan the rest.",
"app": "meals",
"repeat": {
"kind": "weekly",
"days": [
"sun"
],
"time": "18:00"
}
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CTC5QJKJ3SVRFZN0S9ED
{
"result": {
"routine_id": "rtn_01M6V9CTC5VNP0HS02R6Q1BQHB",
"next_run_at": 1794182400000
},
"version": 313
}Set up a monthly routine for one person
for_person_id is whose authority it runs with and who it's for.
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/agent.routine.create' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01M6V9CTC7X6C5FG0VN7JFXQ88' \
-d '{
"title": "Check the filter supply",
"task": "On the first of the month, check that the pantry has a furnace filter. If it doesn'\''t, add a pack to the shopping list and post a card that says so.",
"app": "shopping",
"for_person_id": "per_01M6V9CS6RX26JK5KVYGRN22D2",
"repeat": {
"kind": "monthly",
"day": 1,
"time": "09:00"
}
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/agent.routine.create", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01M6V9CTC7X6C5FG0VN7JFXQ88",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
title: "Check the filter supply",
task: "On the first of the month, check that the pantry has a furnace filter. If it doesn't, add a pack to the shopping list and post a card that says so.",
app: "shopping",
for_person_id: "per_01M6V9CS6RX26JK5KVYGRN22D2",
repeat: {
kind: "monthly",
day: 1,
time: "09:00",
},
}),
});
const data = await response.json();POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/agent.routine.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CTC7X6C5FG0VN7JFXQ88
{
"title": "Check the filter supply",
"task": "On the first of the month, check that the pantry has a furnace filter. If it doesn't, add a pack to the shopping list and post a card that says so.",
"app": "shopping",
"for_person_id": "per_01M6V9CS6RX26JK5KVYGRN22D2",
"repeat": {
"kind": "monthly",
"day": 1,
"time": "09:00"
}
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CTC7H39QQHB5ER3X9RD2
{
"result": {
"routine_id": "rtn_01M6V9CTC7NW649VMCSKRPFYS2",
"next_run_at": 1796137200000
},
"version": 314
}For Rigel#
Rigel's tool for this command is agent_routine_create. Rigel runs this on its own, then says what it did. The agent guide has the rest.