Record a trip from a receipt or an order
shopping.trip.record
POST/api/v1/households/{household_id}/commands/shopping.trip.record
- Command
- Rigel runs it
- Applies offline
Records what a receipt or order email says was bought. Give trip_id to add the receipt to a trip already saved (usually one just finished): lines for products the trip already has fill in that item's price and brand (and its amount, if it had none), and other lines are added to the trip. Without trip_id, a new trip is made; shopped_on is then required. Name the store by store_id, or by store_name to use the existing store with that name (ignoring case) or make a new one (an online one, for an order); a trip that already has a store keeps it. total_minor, currency and receipt_file_id are set when given. currency is required with total_minor or any price_minor. For an order, give order_number: without trip_id, the trip at that store with that order number is used when there is one, so the order's confirmation, shipping and delivery emails all land on one trip (items may then be empty); fails with order_not_found when there's none and no shopped_on to start one. Give arrived_on when it arrived and email_message_id for the email it came from. Newly added lines are put away in inventory a moment later, like a finished trip's items; an order's are put away once it has arrived, all at once. Any item still on the list for those products is taken off it.
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 |
|---|---|
trip_idstringoptional | A trip already recorded (usually one just finished), to add this receipt to. Leave out to record a new trip. |
store_idstringoptional | The store, when you know its ID. Give this or store_name for a new trip. |
store_namestringoptional | The store's name, when you don't have its ID: an existing store with this name (ignoring case) is used, or a new one is made. |
shopped_onstring (date)optional | The day on the receipt. Required for a new trip. |
itemsarray of objectsrequired | What the receipt or order says was bought. Items already on the trip get their price and brand. |
items[].product_idstringoptional | The product, when you know its ID. Give this or product_name. |
items[].product_namestringoptional | The product's name, when you don't have its ID: an existing product with this name (ignoring case) is used, or a new one is made. Search with |
items[].quantitynumber or nulloptional | How many, when said. Leave out when no amount was given. |
items[].unitone of: mg, g, kg, oz, lb, ml, l, tsp, tbsp, fl_oz, cup, pint, quart, gallon, pinch, dash, clove, slice, stick, sprig, head, bunch, stalk, can, jar, bottle, box, bag, package, carton, roll, null or nulloptional | A unit. Mass: mg, g, kg, oz, lb. Volume (US sizes): ml, l, tsp, tbsp, fl_oz, cup, pint, quart, gallon. Items, for a count of something other than the thing itself (2 cloves of garlic, 1 can of beans): pinch, dash, clove, slice, stick, sprig, head, bunch, stalk, can, jar, bottle, box, bag, package, carton, roll. Leave it out or null for a plain count of the things themselves (3 eggs). |
items[].price_minorinteger or nulloptional | The line's price from the receipt, in minor units. |
items[].brandstring or nulloptional | The brand from the receipt: "Cabot", as written, 1–120 characters. |
total_minorinteger or nulloptional | The receipt's total, in minor units. |
currencystring or nulloptional | Required with total_minor or any price_minor. |
receipt_file_idstring or nulloptional | The receipt photo, already uploaded as a file. |
order_numberstringoptional | For an order: the store's order number. Without trip_id, the trip at this store with this order number is used if there is one, so an order's confirmation, shipping and delivery emails all record onto one trip. |
arrived_onstring (date)optional | For an order: the day it arrived, from a delivery email or a person saying so. An order's things are put away in inventory only once it has arrived. |
email_message_idstringoptional | The email this was read from, so the trip links to it. Give it whenever you record from an email. |
Response#
200 The command was applied.
| Field | Description |
|---|---|
resultobjectrequired | What the command returned, such as the IDs it created. |
result.trip_idstringrequired | The trip: the one given or found by order number, or the new one. |
result.addedintegerrequired | How many lines were new to the trip. |
result.updatedintegerrequired | How many lines filled in an item the trip already had. |
result.removed_from_listintegerrequired | How many unchecked list items were taken off because their product was just bought. |
result.put_awayobjectrequired | What happened to the newly added lines, or to all of an order's lines when this records its arrival. |
result.put_away.to_put_awayintegerrequired | How many bought things Rigel will put away in inventory, a moment after the trip is saved. |
result.put_away.untrackedintegerrequired | How many weren't put away because the household doesn't track them. |
result.put_away.no_usual_placeintegerrequired | How many are tracked but have no usual place yet, so Rigel should ask or decide where they go. |
result.put_away.on_arrivalintegerrequired | How many Rigel will put away once the order arrives (an order that hasn't arrived yet). |
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 | trip_not_found | An unknown trip is refused. |
404 | store_not_found | An unknown store is refused. |
404 | file_not_found | An unknown receipt file is refused. |
404 | product_not_found | An unknown product is refused. |
404 | order_not_found | An order number with no trip and no shopped_on is refused. |
404 | message_not_found | An unknown email is refused. |
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 receipt with no trip makes a new unfinished trip, a store by name, and removes bought items from the list
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"store_name": "Amazon",
"shopped_on": "2025-11-06",
"currency": "USD",
"total_minor": 1234,
"items": [
{
"product_id": "prd_01JC000000000000000000000A",
"quantity": 1,
"unit": "gallon",
"price_minor": 499,
"brand": "Cabot"
},
{
"product_name": "Paper towels",
"quantity": 6,
"price_minor": 735
}
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
store_name: "Amazon",
shopped_on: "2025-11-06",
currency: "USD",
total_minor: 1234,
items: [
{
product_id: "prd_01JC000000000000000000000A",
quantity: 1,
unit: "gallon",
price_minor: 499,
brand: "Cabot",
},
{
product_name: "Paper towels",
quantity: 6,
price_minor: 735,
},
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"store_name": "Amazon",
"shopped_on": "2025-11-06",
"currency": "USD",
"total_minor": 1234,
"items": [
{
"product_id": "prd_01JC000000000000000000000A",
"quantity": 1,
"unit": "gallon",
"price_minor": 499,
"brand": "Cabot"
},
{
"product_name": "Paper towels",
"quantity": 6,
"price_minor": 735
}
]
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R03DHCA6E4QN61RQD6
{
"result": {
"trip_id": "trp_01JC4N0000JVP6PWJ6S8P7WZ6B",
"added": 2,
"updated": 0,
"removed_from_list": 1,
"put_away": {
"to_put_away": 0,
"untracked": 0,
"no_usual_place": 2,
"on_arrival": 0
}
},
"version": 1
}A store name matches an existing store ignoring case
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"store_name": "market BASKET",
"shopped_on": "2025-11-06",
"items": [
{
"product_id": "prd_01JC000000000000000000000B"
}
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
store_name: "market BASKET",
shopped_on: "2025-11-06",
items: [
{
product_id: "prd_01JC000000000000000000000B",
},
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"store_name": "market BASKET",
"shopped_on": "2025-11-06",
"items": [
{
"product_id": "prd_01JC000000000000000000000B"
}
]
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R00MX15PEYMTJBHW5A
{
"result": {
"trip_id": "trp_01JC4N0000MBGE5RJ6Q7V6V6T8",
"added": 1,
"updated": 0,
"removed_from_list": 0,
"put_away": {
"to_put_away": 0,
"untracked": 0,
"no_usual_place": 1,
"on_arrival": 0
}
},
"version": 1
}A store ID sets the store
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"store_id": "sto_01JC000000000000000000000B",
"shopped_on": "2025-11-06",
"items": []
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
store_id: "sto_01JC000000000000000000000B",
shopped_on: "2025-11-06",
items: [],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"store_id": "sto_01JC000000000000000000000B",
"shopped_on": "2025-11-06",
"items": []
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R01524MJN522Q6YZKD
{
"result": {
"trip_id": "trp_01JC4N0000MBGE5RJ6Q7V6V6T8",
"added": 0,
"updated": 0,
"removed_from_list": 0,
"put_away": {
"to_put_away": 0,
"untracked": 0,
"no_usual_place": 0,
"on_arrival": 0
}
},
"version": 1
}A receipt on a finished trip fills prices and brands, adds new lines, and takes them off the list
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"trip_id": "trp_01JC0000000000000000000001",
"currency": "USD",
"total_minor": 2150,
"items": [
{
"product_id": "prd_01JC000000000000000000000A",
"quantity": 2,
"unit": "gallon",
"price_minor": 499,
"brand": "Cabot"
},
{
"product_id": "prd_01JC000000000000000000000B",
"quantity": 12,
"price_minor": 350
},
{
"product_id": "prd_01JC000000000000000000000C",
"quantity": 1,
"price_minor": 399
}
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
trip_id: "trp_01JC0000000000000000000001",
currency: "USD",
total_minor: 2150,
items: [
{
product_id: "prd_01JC000000000000000000000A",
quantity: 2,
unit: "gallon",
price_minor: 499,
brand: "Cabot",
},
{
product_id: "prd_01JC000000000000000000000B",
quantity: 12,
price_minor: 350,
},
{
product_id: "prd_01JC000000000000000000000C",
quantity: 1,
price_minor: 399,
},
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"trip_id": "trp_01JC0000000000000000000001",
"currency": "USD",
"total_minor": 2150,
"items": [
{
"product_id": "prd_01JC000000000000000000000A",
"quantity": 2,
"unit": "gallon",
"price_minor": 499,
"brand": "Cabot"
},
{
"product_id": "prd_01JC000000000000000000000B",
"quantity": 12,
"price_minor": 350
},
{
"product_id": "prd_01JC000000000000000000000C",
"quantity": 1,
"price_minor": 399
}
]
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0PD1YJS187D4MAAAG
{
"result": {
"trip_id": "trp_01JC0000000000000000000001",
"added": 1,
"updated": 2,
"removed_from_list": 1,
"put_away": {
"to_put_away": 0,
"untracked": 0,
"no_usual_place": 1,
"on_arrival": 0
}
},
"version": 1
}Each trip item takes at most one line, so a second line for the product is a new item
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"trip_id": "trp_01JC0000000000000000000001",
"currency": "USD",
"items": [
{
"product_id": "prd_01JC000000000000000000000A",
"price_minor": 499
},
{
"product_id": "prd_01JC000000000000000000000A",
"price_minor": 520
}
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
trip_id: "trp_01JC0000000000000000000001",
currency: "USD",
items: [
{
product_id: "prd_01JC000000000000000000000A",
price_minor: 499,
},
{
product_id: "prd_01JC000000000000000000000A",
price_minor: 520,
},
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"trip_id": "trp_01JC0000000000000000000001",
"currency": "USD",
"items": [
{
"product_id": "prd_01JC000000000000000000000A",
"price_minor": 499
},
{
"product_id": "prd_01JC000000000000000000000A",
"price_minor": 520
}
]
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0VY5DYP6ZDN0SGAS7
{
"result": {
"trip_id": "trp_01JC0000000000000000000001",
"added": 1,
"updated": 1,
"removed_from_list": 0,
"put_away": {
"to_put_away": 0,
"untracked": 0,
"no_usual_place": 1,
"on_arrival": 0
}
},
"version": 1
}A line without a price leaves the item's price and brand alone
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"trip_id": "trp_01JC0000000000000000000001",
"items": [
{
"product_id": "prd_01JC000000000000000000000A"
}
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
trip_id: "trp_01JC0000000000000000000001",
items: [
{
product_id: "prd_01JC000000000000000000000A",
},
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"trip_id": "trp_01JC0000000000000000000001",
"items": [
{
"product_id": "prd_01JC000000000000000000000A"
}
]
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0YB541GKQHJHNJXTM
{
"result": {
"trip_id": "trp_01JC0000000000000000000001",
"added": 0,
"updated": 1,
"removed_from_list": 0,
"put_away": {
"to_put_away": 0,
"untracked": 0,
"no_usual_place": 0,
"on_arrival": 0
}
},
"version": 1
}The trip's store is set only when it has none
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"trip_id": "trp_01JC0000000000000000000001",
"store_id": "sto_01JC000000000000000000000B",
"items": []
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
trip_id: "trp_01JC0000000000000000000001",
store_id: "sto_01JC000000000000000000000B",
items: [],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"trip_id": "trp_01JC0000000000000000000001",
"store_id": "sto_01JC000000000000000000000B",
"items": []
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0Z1P4N2A4WQZ1QT4R
{
"result": {
"trip_id": "trp_01JC0000000000000000000001",
"added": 0,
"updated": 0,
"removed_from_list": 0,
"put_away": {
"to_put_away": 0,
"untracked": 0,
"no_usual_place": 0,
"on_arrival": 0
}
},
"version": 1
}A trip with no store takes the one named
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"trip_id": "trp_01JC0000000000000000000001",
"store_name": "trader joe'\''s",
"items": []
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
trip_id: "trp_01JC0000000000000000000001",
store_name: "trader joe's",
items: [],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"trip_id": "trp_01JC0000000000000000000001",
"store_name": "trader joe's",
"items": []
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R034XQE7NZ30VMDCXD
{
"result": {
"trip_id": "trp_01JC0000000000000000000001",
"added": 0,
"updated": 0,
"removed_from_list": 0,
"put_away": {
"to_put_away": 0,
"untracked": 0,
"no_usual_place": 0,
"on_arrival": 0
}
},
"version": 1
}A receipt photo is attached
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"trip_id": "trp_01JC0000000000000000000001",
"receipt_file_id": "fil_01JC000000000000000000000A",
"items": []
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
trip_id: "trp_01JC0000000000000000000001",
receipt_file_id: "fil_01JC000000000000000000000A",
items: [],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"trip_id": "trp_01JC0000000000000000000001",
"receipt_file_id": "fil_01JC000000000000000000000A",
"items": []
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0B5WPH0JMCB0EJS7K
{
"result": {
"trip_id": "trp_01JC0000000000000000000001",
"added": 0,
"updated": 0,
"removed_from_list": 0,
"put_away": {
"to_put_away": 0,
"untracked": 0,
"no_usual_place": 0,
"on_arrival": 0
}
},
"version": 1
}Items checked on the list are not taken off it
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"shopped_on": "2025-11-06",
"items": [
{
"product_id": "prd_01JC000000000000000000000A"
}
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
shopped_on: "2025-11-06",
items: [
{
product_id: "prd_01JC000000000000000000000A",
},
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"shopped_on": "2025-11-06",
"items": [
{
"product_id": "prd_01JC000000000000000000000A"
}
]
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0ABZDMXVCV4SFJ220
{
"result": {
"trip_id": "trp_01JC4N0000MBGE5RJ6Q7V6V6T8",
"added": 1,
"updated": 0,
"removed_from_list": 0,
"put_away": {
"to_put_away": 0,
"untracked": 0,
"no_usual_place": 1,
"on_arrival": 0
}
},
"version": 1
}An order makes a trip with its order number at a new online store, links the email, and waits for it to arrive to put things away
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"store_name": "Amazon",
"shopped_on": "2025-11-05",
"order_number": "112-4839201-5551234",
"email_message_id": "emm_01JC0000000000000000000001",
"currency": "USD",
"total_minor": 2398,
"items": [
{
"product_id": "prd_01JC000000000000000000000A",
"quantity": 12,
"price_minor": 2398,
"brand": "Bounty"
}
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
store_name: "Amazon",
shopped_on: "2025-11-05",
order_number: "112-4839201-5551234",
email_message_id: "emm_01JC0000000000000000000001",
currency: "USD",
total_minor: 2398,
items: [
{
product_id: "prd_01JC000000000000000000000A",
quantity: 12,
price_minor: 2398,
brand: "Bounty",
},
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"store_name": "Amazon",
"shopped_on": "2025-11-05",
"order_number": "112-4839201-5551234",
"email_message_id": "emm_01JC0000000000000000000001",
"currency": "USD",
"total_minor": 2398,
"items": [
{
"product_id": "prd_01JC000000000000000000000A",
"quantity": 12,
"price_minor": 2398,
"brand": "Bounty"
}
]
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0B3066BYBANHB0GDK
{
"result": {
"trip_id": "trp_01JC4N0000VGW1STJ6TGXRB7FY",
"added": 1,
"updated": 0,
"removed_from_list": 1,
"put_away": {
"to_put_away": 0,
"untracked": 0,
"no_usual_place": 0,
"on_arrival": 1
}
},
"version": 1
}A later email for the same order records onto its trip, and its delivery puts everything away on the day it arrived
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"store_name": "amazon",
"order_number": "112-4839201-5551234",
"arrived_on": "2025-11-07",
"email_message_id": "emm_01JC0000000000000000000002",
"items": []
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
store_name: "amazon",
order_number: "112-4839201-5551234",
arrived_on: "2025-11-07",
email_message_id: "emm_01JC0000000000000000000002",
items: [],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"store_name": "amazon",
"order_number": "112-4839201-5551234",
"arrived_on": "2025-11-07",
"email_message_id": "emm_01JC0000000000000000000002",
"items": []
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R05GYQ6EWF2PCQSY1V
{
"result": {
"trip_id": "trp_01JC000000000000000000000A",
"added": 0,
"updated": 0,
"removed_from_list": 0,
"put_away": {
"to_put_away": 1,
"untracked": 0,
"no_usual_place": 0,
"on_arrival": 0
}
},
"version": 1
}An email already linked to the trip is linked once
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"store_id": "sto_01JC000000000000000000000A",
"order_number": "112-4839201-5551234",
"email_message_id": "emm_01JC0000000000000000000001",
"items": []
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
store_id: "sto_01JC000000000000000000000A",
order_number: "112-4839201-5551234",
email_message_id: "emm_01JC0000000000000000000001",
items: [],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"store_id": "sto_01JC000000000000000000000A",
"order_number": "112-4839201-5551234",
"email_message_id": "emm_01JC0000000000000000000001",
"items": []
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0Y6ZSDFR5G97KQ8K0
{
"result": {
"trip_id": "trp_01JC000000000000000000000A",
"added": 0,
"updated": 0,
"removed_from_list": 0,
"put_away": {
"to_put_away": 0,
"untracked": 0,
"no_usual_place": 0,
"on_arrival": 0
}
},
"version": 1
}A line added to an order that has arrived is put away straight away
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"store_id": "sto_01JC000000000000000000000A",
"order_number": "112-4839201-5551234",
"currency": "USD",
"items": [
{
"product_id": "prd_01JC000000000000000000000B",
"price_minor": 399
}
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
store_id: "sto_01JC000000000000000000000A",
order_number: "112-4839201-5551234",
currency: "USD",
items: [
{
product_id: "prd_01JC000000000000000000000B",
price_minor: 399,
},
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"store_id": "sto_01JC000000000000000000000A",
"order_number": "112-4839201-5551234",
"currency": "USD",
"items": [
{
"product_id": "prd_01JC000000000000000000000B",
"price_minor": 399
}
]
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0NT2CJJCR4RXRYFJY
{
"result": {
"trip_id": "trp_01JC000000000000000000000A",
"added": 1,
"updated": 0,
"removed_from_list": 0,
"put_away": {
"to_put_away": 1,
"untracked": 0,
"no_usual_place": 0,
"on_arrival": 0
}
},
"version": 1
}An unknown trip is refused
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"trip_id": "trp_01JC0000000000000000000001",
"items": []
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
trip_id: "trp_01JC0000000000000000000001",
items: [],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"trip_id": "trp_01JC0000000000000000000001",
"items": []
}HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0GJEDRG39J4D9HZYV
{
"error": {
"code": "trip_not_found",
"message": "That trip isn't there any more. No changes were applied.",
"details": {
"trip_id": "trp_01JC0000000000000000000001"
},
"recovery": "Read the current state, then send a command that fits it.",
"request_id": "req_01K9D9S2R0GJEDRG39J4D9HZYV"
}
}An unknown store is refused
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"store_id": "sto_01JC000000000000000000000Z",
"shopped_on": "2025-11-06",
"items": []
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
store_id: "sto_01JC000000000000000000000Z",
shopped_on: "2025-11-06",
items: [],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"store_id": "sto_01JC000000000000000000000Z",
"shopped_on": "2025-11-06",
"items": []
}HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R01S1TFASM9JQJEBMQ
{
"error": {
"code": "store_not_found",
"message": "That store isn't there any more. No changes were applied.",
"details": {
"store_id": "sto_01JC000000000000000000000Z"
},
"recovery": "Read the current state, then send a command that fits it.",
"request_id": "req_01K9D9S2R01S1TFASM9JQJEBMQ"
}
}An unknown receipt file is refused
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"trip_id": "trp_01JC0000000000000000000001",
"receipt_file_id": "fil_01JC000000000000000000000Z",
"items": []
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
trip_id: "trp_01JC0000000000000000000001",
receipt_file_id: "fil_01JC000000000000000000000Z",
items: [],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"trip_id": "trp_01JC0000000000000000000001",
"receipt_file_id": "fil_01JC000000000000000000000Z",
"items": []
}HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0CBGP3G8YQVTQEQ5R
{
"error": {
"code": "file_not_found",
"message": "That file isn't there any more. No changes were applied.",
"details": {
"file_id": "fil_01JC000000000000000000000Z"
},
"recovery": "Read the current state, then send a command that fits it.",
"request_id": "req_01K9D9S2R0CBGP3G8YQVTQEQ5R"
}
}An unknown product is refused
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"shopped_on": "2025-11-06",
"items": [
{
"product_id": "prd_01JC000000000000000000000Z"
}
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
shopped_on: "2025-11-06",
items: [
{
product_id: "prd_01JC000000000000000000000Z",
},
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"shopped_on": "2025-11-06",
"items": [
{
"product_id": "prd_01JC000000000000000000000Z"
}
]
}HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R00JFKRREVNQ18ZNSF
{
"error": {
"code": "product_not_found",
"message": "That product isn't there any more. No changes were applied.",
"details": {
"product_id": "prd_01JC000000000000000000000Z"
},
"recovery": "Read the current state, then send a command that fits it.",
"request_id": "req_01K9D9S2R00JFKRREVNQ18ZNSF"
}
}An order number with no trip and no shopped_on is refused
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"store_id": "sto_01JC000000000000000000000A",
"order_number": "112-4839201-5551234",
"arrived_on": "2025-11-07",
"items": []
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
store_id: "sto_01JC000000000000000000000A",
order_number: "112-4839201-5551234",
arrived_on: "2025-11-07",
items: [],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"store_id": "sto_01JC000000000000000000000A",
"order_number": "112-4839201-5551234",
"arrived_on": "2025-11-07",
"items": []
}HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0E4Q5512FJ36F3QGG
{
"error": {
"code": "order_not_found",
"message": "There's no trip for that order yet. Give shopped_on, the day it was ordered, to record it. No changes were applied.",
"details": {
"order_number": "112-4839201-5551234"
},
"recovery": "Read the current state, then send a command that fits it.",
"request_id": "req_01K9D9S2R0E4Q5512FJ36F3QGG"
}
}An unknown email is refused
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"store_id": "sto_01JC000000000000000000000A",
"shopped_on": "2025-11-05",
"order_number": "112-4839201-5551234",
"email_message_id": "emm_01JC000000000000000000000Z",
"items": []
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
store_id: "sto_01JC000000000000000000000A",
shopped_on: "2025-11-05",
order_number: "112-4839201-5551234",
email_message_id: "emm_01JC000000000000000000000Z",
items: [],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.trip.record HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"store_id": "sto_01JC000000000000000000000A",
"shopped_on": "2025-11-05",
"order_number": "112-4839201-5551234",
"email_message_id": "emm_01JC000000000000000000000Z",
"items": []
}HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R098JK1BXSPJ4EV842
{
"error": {
"code": "message_not_found",
"message": "That email isn't here any more. No changes were applied.",
"details": {
"email_message_id": "emm_01JC000000000000000000000Z"
},
"recovery": "Read the current state, then send a command that fits it.",
"request_id": "req_01K9D9S2R098JK1BXSPJ4EV842"
}
}Add a receipt to a trip
Lines for products the trip has fill in their price and brand. Other lines, such as the bananas, are added to the trip.
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/shopping.trip.record' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01M6V9CT8P5MTRPKTF0CB11DWM' \
-d '{
"trip_id": "trp_01M6V9CT8JBJVJK865ZH4D2ZZD",
"items": [
{
"product_name": "Milk",
"price_minor": 778,
"brand": "Hillside"
},
{
"product_name": "Crushed tomatoes",
"price_minor": 258
},
{
"product_name": "Bananas",
"quantity": 6,
"price_minor": 189
}
],
"total_minor": 1225,
"currency": "USD"
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/shopping.trip.record", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01M6V9CT8P5MTRPKTF0CB11DWM",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
trip_id: "trp_01M6V9CT8JBJVJK865ZH4D2ZZD",
items: [
{
product_name: "Milk",
price_minor: 778,
brand: "Hillside",
},
{
product_name: "Crushed tomatoes",
price_minor: 258,
},
{
product_name: "Bananas",
quantity: 6,
price_minor: 189,
},
],
total_minor: 1225,
currency: "USD",
}),
});
const data = await response.json();POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/shopping.trip.record HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CT8P5MTRPKTF0CB11DWM
{
"trip_id": "trp_01M6V9CT8JBJVJK865ZH4D2ZZD",
"items": [
{
"product_name": "Milk",
"price_minor": 778,
"brand": "Hillside"
},
{
"product_name": "Crushed tomatoes",
"price_minor": 258
},
{
"product_name": "Bananas",
"quantity": 6,
"price_minor": 189
}
],
"total_minor": 1225,
"currency": "USD"
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CT8PH67G0VVD7WM3VTBZ
{
"result": {
"trip_id": "trp_01M6V9CT8JBJVJK865ZH4D2ZZD",
"added": 1,
"updated": 2,
"removed_from_list": 0,
"put_away": {
"to_put_away": 0,
"untracked": 0,
"no_usual_place": 1,
"on_arrival": 0
}
},
"version": 286
}Record an online order
Naming the store by store_name uses the existing store, or makes one. order_number ties later emails about the order to the same trip.
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/shopping.trip.record' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01M6V9CT8S2QVPNFGGPDJBPTG8' \
-d '{
"store_name": "Pantry Direct",
"shopped_on": "2026-11-04",
"order_number": "PD-48213",
"items": [
{
"product_name": "Paper towels",
"quantity": 12,
"unit": "roll",
"price_minor": 2899,
"brand": "Softcore"
},
{
"product_name": "Dish soap",
"price_minor": 449
}
],
"total_minor": 3348,
"currency": "USD"
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/shopping.trip.record", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01M6V9CT8S2QVPNFGGPDJBPTG8",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
store_name: "Pantry Direct",
shopped_on: "2026-11-04",
order_number: "PD-48213",
items: [
{
product_name: "Paper towels",
quantity: 12,
unit: "roll",
price_minor: 2899,
brand: "Softcore",
},
{
product_name: "Dish soap",
price_minor: 449,
},
],
total_minor: 3348,
currency: "USD",
}),
});
const data = await response.json();POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/shopping.trip.record HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CT8S2QVPNFGGPDJBPTG8
{
"store_name": "Pantry Direct",
"shopped_on": "2026-11-04",
"order_number": "PD-48213",
"items": [
{
"product_name": "Paper towels",
"quantity": 12,
"unit": "roll",
"price_minor": 2899,
"brand": "Softcore"
},
{
"product_name": "Dish soap",
"price_minor": 449
}
],
"total_minor": 3348,
"currency": "USD"
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CT8S6ENS1JWK7QNFE9XE
{
"result": {
"trip_id": "trp_01M6V9CT8S4T83B9C9T7FBKE1N",
"added": 2,
"updated": 0,
"removed_from_list": 0,
"put_away": {
"to_put_away": 0,
"untracked": 0,
"no_usual_place": 1,
"on_arrival": 1
}
},
"version": 287
}For Rigel#
Rigel's tool for this command is shopping_trip_record. Rigel runs this on its own, then says what it did. The agent guide has the rest.