Plan a meal for some people
meals.meal.plan
POST/api/v1/households/{household_id}/commands/meals.meal.plan
- Command
- Rigel runs it
- Applies offline
Plans one meal: a date, a slot, who it is for and its dishes. Dishes are { dish_id } for an existing dish, { name } to use the dish with that name (ignoring case) or create it, or { recipe_id } to plan a recipe: the dish already made from that recipe is used, or one named after the recipe is created and linked to it (recipe_not_found if there is no such recipe). Check meals.dish.search first to reuse dishes. A person has at most one meal per date and slot, so everyone named is first taken out of any other meal at that date and slot (a meal left with no one is removed). Use meals.week.fill instead to plan many meals without disturbing existing ones.
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 |
|---|---|
datestring (date)required | The day of the meal, YYYY-MM-DD. |
slotone of: breakfast, lunch, dinner, snackrequired | Which meal of the day: breakfast, lunch, dinner or snack. |
person_idsarray of stringsrequired | Who the meal is for, 1 to 20 people from the household. Naming someone twice counts once. |
dishesarray of one of 3 shapesrequired | The dishes in the meal, in order, 1 to 20. Naming the same dish twice keeps it once. |
| Shape 1, with dish_id | |
dishes[].dish_idstringrequired | A dish ID, such as dsh_01JC0000000000000000000000. |
| Shape 2, with name | |
dishes[].namestringrequired | A dish name. An existing dish with this name (ignoring case) is used; otherwise a new dish is created. |
| Shape 3, with recipe_id | |
dishes[].recipe_idstringrequired | A recipe from the recipe box. The dish already made from it is used; otherwise a dish named after the recipe is created and linked to it. |
notestringoptional | A kitchen note on the meal, as written: "use the leftover rice", "Nia's friend is over". |
Response#
200 The command was applied.
| Field | Description |
|---|---|
resultobjectrequired | What the command returned, such as the IDs it created. |
result.meal_idstringrequired | The new meal. |
result.dish_idsarray of stringsrequired | The meal's dishes, in order, including any just created. |
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 missing person. |
404 | dish_not_found | A missing dish by ID. |
404 | recipe_not_found | A missing recipe. |
404 | not_found | The household doesn't exist, or you aren't a member of it. |
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.
A new dish is created by name, then the meal, its people and its dishes
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"date": "2026-11-09",
"slot": "dinner",
"person_ids": [
"per_01JC000000000000000000000A",
"per_01JC000000000000000000000C"
],
"dishes": [
{
"name": "Chicken quesadilla"
}
],
"note": "use the leftover rice"
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
date: "2026-11-09",
slot: "dinner",
person_ids: [
"per_01JC000000000000000000000A",
"per_01JC000000000000000000000C",
],
dishes: [
{
name: "Chicken quesadilla",
},
],
note: "use the leftover rice",
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"date": "2026-11-09",
"slot": "dinner",
"person_ids": [
"per_01JC000000000000000000000A",
"per_01JC000000000000000000000C"
],
"dishes": [
{
"name": "Chicken quesadilla"
}
],
"note": "use the leftover rice"
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R080RN24QS5TAABCTF
{
"result": {
"meal_id": "mel_01JC4N0000VGW1STJ6TGXRB7FY",
"dish_ids": [
"dsh_01JC4N0000MBGE5RJ6Q7V6V6T8"
]
},
"version": 1
}Existing dishes by ID and by name (ignoring case), in order, with repeats dropped
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"date": "2026-11-09",
"slot": "lunch",
"person_ids": [
"per_01JC000000000000000000000B",
"per_01JC000000000000000000000B"
],
"dishes": [
{
"name": "rice"
},
{
"dish_id": "dsh_01JC000000000000000000000A"
},
{
"dish_id": "dsh_01JC000000000000000000000B"
}
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
date: "2026-11-09",
slot: "lunch",
person_ids: [
"per_01JC000000000000000000000B",
"per_01JC000000000000000000000B",
],
dishes: [
{
name: "rice",
},
{
dish_id: "dsh_01JC000000000000000000000A",
},
{
dish_id: "dsh_01JC000000000000000000000B",
},
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"date": "2026-11-09",
"slot": "lunch",
"person_ids": [
"per_01JC000000000000000000000B",
"per_01JC000000000000000000000B"
],
"dishes": [
{
"name": "rice"
},
{
"dish_id": "dsh_01JC000000000000000000000A"
},
{
"dish_id": "dsh_01JC000000000000000000000B"
}
]
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0FZKW8KW1ZBC2D0KS
{
"result": {
"meal_id": "mel_01JC4N0000MBGE5RJ6Q7V6V6T8",
"dish_ids": [
"dsh_01JC000000000000000000000B",
"dsh_01JC000000000000000000000A"
]
},
"version": 1
}People are taken out of other meals at that date and slot; a meal left empty is removed
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"date": "2026-11-09",
"slot": "dinner",
"person_ids": [
"per_01JC000000000000000000000A",
"per_01JC000000000000000000000C"
],
"dishes": [
{
"dish_id": "dsh_01JC000000000000000000000C"
}
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
date: "2026-11-09",
slot: "dinner",
person_ids: [
"per_01JC000000000000000000000A",
"per_01JC000000000000000000000C",
],
dishes: [
{
dish_id: "dsh_01JC000000000000000000000C",
},
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"date": "2026-11-09",
"slot": "dinner",
"person_ids": [
"per_01JC000000000000000000000A",
"per_01JC000000000000000000000C"
],
"dishes": [
{
"dish_id": "dsh_01JC000000000000000000000C"
}
]
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R037FGQ6D4ZVWNDB36
{
"result": {
"meal_id": "mel_01JC4N0000MBGE5RJ6Q7V6V6T8",
"dish_ids": [
"dsh_01JC000000000000000000000C"
]
},
"version": 1
}A recipe ref creates a dish named after the recipe, linked to it
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"date": "2026-11-09",
"slot": "dinner",
"person_ids": [
"per_01JC000000000000000000000A",
"per_01JC000000000000000000000B"
],
"dishes": [
{
"recipe_id": "rcp_01JC000000000000000000000A"
}
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
date: "2026-11-09",
slot: "dinner",
person_ids: [
"per_01JC000000000000000000000A",
"per_01JC000000000000000000000B",
],
dishes: [
{
recipe_id: "rcp_01JC000000000000000000000A",
},
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"date": "2026-11-09",
"slot": "dinner",
"person_ids": [
"per_01JC000000000000000000000A",
"per_01JC000000000000000000000B"
],
"dishes": [
{
"recipe_id": "rcp_01JC000000000000000000000A"
}
]
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0JAATVRMRHG01Y9MQ
{
"result": {
"meal_id": "mel_01JC4N0000VGW1STJ6TGXRB7FY",
"dish_ids": [
"dsh_01JC4N0000MBGE5RJ6Q7V6V6T8"
]
},
"version": 1
}A recipe ref uses the dish already made from that recipe
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"date": "2026-11-09",
"slot": "dinner",
"person_ids": [
"per_01JC000000000000000000000A"
],
"dishes": [
{
"recipe_id": "rcp_01JC000000000000000000000A"
}
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
date: "2026-11-09",
slot: "dinner",
person_ids: [
"per_01JC000000000000000000000A",
],
dishes: [
{
recipe_id: "rcp_01JC000000000000000000000A",
},
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"date": "2026-11-09",
"slot": "dinner",
"person_ids": [
"per_01JC000000000000000000000A"
],
"dishes": [
{
"recipe_id": "rcp_01JC000000000000000000000A"
}
]
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0DQ3HG44FSNPJ1DTS
{
"result": {
"meal_id": "mel_01JC4N0000MBGE5RJ6Q7V6V6T8",
"dish_ids": [
"dsh_01JC000000000000000000000A"
]
},
"version": 1
}A recipe ref links a same-name dish that has no recipe, and its ingredients go
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"date": "2026-11-09",
"slot": "dinner",
"person_ids": [
"per_01JC000000000000000000000A"
],
"dishes": [
{
"recipe_id": "rcp_01JC000000000000000000000A"
}
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
date: "2026-11-09",
slot: "dinner",
person_ids: [
"per_01JC000000000000000000000A",
],
dishes: [
{
recipe_id: "rcp_01JC000000000000000000000A",
},
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"date": "2026-11-09",
"slot": "dinner",
"person_ids": [
"per_01JC000000000000000000000A"
],
"dishes": [
{
"recipe_id": "rcp_01JC000000000000000000000A"
}
]
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R08PZM7RE08CTS6H51
{
"result": {
"meal_id": "mel_01JC4N0000MBGE5RJ6Q7V6V6T8",
"dish_ids": [
"dsh_01JC000000000000000000000A"
]
},
"version": 1
}A same-name dish with another recipe is not reused: the new dish gets a number
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"date": "2026-11-09",
"slot": "dinner",
"person_ids": [
"per_01JC000000000000000000000A"
],
"dishes": [
{
"recipe_id": "rcp_01JC000000000000000000000A"
}
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
date: "2026-11-09",
slot: "dinner",
person_ids: [
"per_01JC000000000000000000000A",
],
dishes: [
{
recipe_id: "rcp_01JC000000000000000000000A",
},
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"date": "2026-11-09",
"slot": "dinner",
"person_ids": [
"per_01JC000000000000000000000A"
],
"dishes": [
{
"recipe_id": "rcp_01JC000000000000000000000A"
}
]
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R03T6PRB5CEF2JYGQJ
{
"result": {
"meal_id": "mel_01JC4N0000VGW1STJ6TGXRB7FY",
"dish_ids": [
"dsh_01JC4N0000MBGE5RJ6Q7V6V6T8"
]
},
"version": 1
}A missing person
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"date": "2026-11-09",
"slot": "dinner",
"person_ids": [
"per_01JC000000000000000000000A",
"per_01JC000000000000000000000Z"
],
"dishes": [
{
"dish_id": "dsh_01JC000000000000000000000A"
}
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
date: "2026-11-09",
slot: "dinner",
person_ids: [
"per_01JC000000000000000000000A",
"per_01JC000000000000000000000Z",
],
dishes: [
{
dish_id: "dsh_01JC000000000000000000000A",
},
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"date": "2026-11-09",
"slot": "dinner",
"person_ids": [
"per_01JC000000000000000000000A",
"per_01JC000000000000000000000Z"
],
"dishes": [
{
"dish_id": "dsh_01JC000000000000000000000A"
}
]
}HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0VDQ87SCW2H20GNQN
{
"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_01K9D9S2R0VDQ87SCW2H20GNQN"
}
}A missing dish by ID
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"date": "2026-11-09",
"slot": "dinner",
"person_ids": [
"per_01JC000000000000000000000A"
],
"dishes": [
{
"dish_id": "dsh_01JC000000000000000000000Z"
}
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
date: "2026-11-09",
slot: "dinner",
person_ids: [
"per_01JC000000000000000000000A",
],
dishes: [
{
dish_id: "dsh_01JC000000000000000000000Z",
},
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"date": "2026-11-09",
"slot": "dinner",
"person_ids": [
"per_01JC000000000000000000000A"
],
"dishes": [
{
"dish_id": "dsh_01JC000000000000000000000Z"
}
]
}HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R00GH1RBH9D1BDJ0V6
{
"error": {
"code": "dish_not_found",
"message": "That dish isn't there any more. No changes were applied.",
"details": {
"dish_id": "dsh_01JC000000000000000000000Z"
},
"recovery": "Read the current state, then send a command that fits it.",
"request_id": "req_01K9D9S2R00GH1RBH9D1BDJ0V6"
}
}A missing recipe
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"date": "2026-11-09",
"slot": "dinner",
"person_ids": [
"per_01JC000000000000000000000A"
],
"dishes": [
{
"recipe_id": "rcp_01JC000000000000000000000A"
}
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
date: "2026-11-09",
slot: "dinner",
person_ids: [
"per_01JC000000000000000000000A",
],
dishes: [
{
recipe_id: "rcp_01JC000000000000000000000A",
},
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/meals.meal.plan HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"date": "2026-11-09",
"slot": "dinner",
"person_ids": [
"per_01JC000000000000000000000A"
],
"dishes": [
{
"recipe_id": "rcp_01JC000000000000000000000A"
}
]
}HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0RQRC252MQKHC5W0D
{
"error": {
"code": "recipe_not_found",
"message": "That recipe isn't in the recipe box any more. No changes were applied.",
"details": {
"recipe_id": "rcp_01JC000000000000000000000A"
},
"recovery": "Read the current state, then send a command that fits it.",
"request_id": "req_01K9D9S2R0RQRC252MQKHC5W0D"
}
}Record a meal that's already happened
Dates in the past are fine; they're how Rigel learns what the family eats.
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/meals.meal.plan' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01M6V9CSFPCNFT5RVFSM3CQMY6' \
-d '{
"date": "2026-11-06",
"slot": "dinner",
"person_ids": [
"per_01M6V9CS6RX26JK5KVYGRN22D2",
"per_01M6V9CS744BQQH188FS6CXY9W",
"per_01M6V9CS79TMYHDAM7FTA9ZK3Z",
"per_01M6V9CS7CDAEP5VDA5T8R9TG6"
],
"dishes": [
{
"recipe_id": "rcp_01M6V9CSDDZVYFRVFNA4X5BSMZ"
}
],
"note": "Breakfast for dinner."
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/meals.meal.plan", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01M6V9CSFPCNFT5RVFSM3CQMY6",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
date: "2026-11-06",
slot: "dinner",
person_ids: [
"per_01M6V9CS6RX26JK5KVYGRN22D2",
"per_01M6V9CS744BQQH188FS6CXY9W",
"per_01M6V9CS79TMYHDAM7FTA9ZK3Z",
"per_01M6V9CS7CDAEP5VDA5T8R9TG6",
],
dishes: [
{
recipe_id: "rcp_01M6V9CSDDZVYFRVFNA4X5BSMZ",
},
],
note: "Breakfast for dinner.",
}),
});
const data = await response.json();POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/meals.meal.plan HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CSFPCNFT5RVFSM3CQMY6
{
"date": "2026-11-06",
"slot": "dinner",
"person_ids": [
"per_01M6V9CS6RX26JK5KVYGRN22D2",
"per_01M6V9CS744BQQH188FS6CXY9W",
"per_01M6V9CS79TMYHDAM7FTA9ZK3Z",
"per_01M6V9CS7CDAEP5VDA5T8R9TG6"
],
"dishes": [
{
"recipe_id": "rcp_01M6V9CSDDZVYFRVFNA4X5BSMZ"
}
],
"note": "Breakfast for dinner."
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CSFP6YN8PH2F8GTYNZDG
{
"result": {
"meal_id": "mel_01M6V9CSFPK69RRZZ3DHRR53T4",
"dish_ids": [
"dsh_01M6V9CSFPC1X45XZ3A8P6N25F"
]
},
"version": 76
}Plan a dinner from a recipe
A recipe becomes a dish that buys the recipe's ingredients, scaled to the people eating.
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/meals.meal.plan' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01M6V9CSFSW5B74VDM47A34KTT' \
-d '{
"date": "2026-11-09",
"slot": "dinner",
"person_ids": [
"per_01M6V9CS6RX26JK5KVYGRN22D2",
"per_01M6V9CS744BQQH188FS6CXY9W",
"per_01M6V9CS79TMYHDAM7FTA9ZK3Z",
"per_01M6V9CS7CDAEP5VDA5T8R9TG6"
],
"dishes": [
{
"recipe_id": "rcp_01M6V9CSD8VZYF11AC568Y7QPZ"
}
],
"note": "Make extra for lunches."
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/meals.meal.plan", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01M6V9CSFSW5B74VDM47A34KTT",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
date: "2026-11-09",
slot: "dinner",
person_ids: [
"per_01M6V9CS6RX26JK5KVYGRN22D2",
"per_01M6V9CS744BQQH188FS6CXY9W",
"per_01M6V9CS79TMYHDAM7FTA9ZK3Z",
"per_01M6V9CS7CDAEP5VDA5T8R9TG6",
],
dishes: [
{
recipe_id: "rcp_01M6V9CSD8VZYF11AC568Y7QPZ",
},
],
note: "Make extra for lunches.",
}),
});
const data = await response.json();POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/meals.meal.plan HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CSFSW5B74VDM47A34KTT
{
"date": "2026-11-09",
"slot": "dinner",
"person_ids": [
"per_01M6V9CS6RX26JK5KVYGRN22D2",
"per_01M6V9CS744BQQH188FS6CXY9W",
"per_01M6V9CS79TMYHDAM7FTA9ZK3Z",
"per_01M6V9CS7CDAEP5VDA5T8R9TG6"
],
"dishes": [
{
"recipe_id": "rcp_01M6V9CSD8VZYF11AC568Y7QPZ"
}
],
"note": "Make extra for lunches."
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CSFSYWSYHXP41NJHYF0T
{
"result": {
"meal_id": "mel_01M6V9CSFSFH4859KG4NM47HF2",
"dish_ids": [
"dsh_01M6V9CSFS845RH6KG1MJJPG63"
]
},
"version": 77
}Plan a snack
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/meals.meal.plan' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01M6V9CSGP039EKRR6FQYHN1MY' \
-d '{
"date": "2026-11-10",
"slot": "snack",
"person_ids": [
"per_01M6V9CS79TMYHDAM7FTA9ZK3Z"
],
"dishes": [
{
"name": "Apple slices"
}
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/meals.meal.plan", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01M6V9CSGP039EKRR6FQYHN1MY",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
date: "2026-11-10",
slot: "snack",
person_ids: [
"per_01M6V9CS79TMYHDAM7FTA9ZK3Z",
],
dishes: [
{
name: "Apple slices",
},
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/meals.meal.plan HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CSGP039EKRR6FQYHN1MY
{
"date": "2026-11-10",
"slot": "snack",
"person_ids": [
"per_01M6V9CS79TMYHDAM7FTA9ZK3Z"
],
"dishes": [
{
"name": "Apple slices"
}
]
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CSGP70S2R4FDA6NP78RB
{
"result": {
"meal_id": "mel_01M6V9CSGPM55HPSDSNY45G67K",
"dish_ids": [
"dsh_01M6V9CSGPVJ41AWDSRZ6Q07GJ"
]
},
"version": 82
}For Rigel#
Rigel's tool for this command is meals_meal_plan. Rigel runs this on its own, then says what it did. The agent guide has the rest.