Skip to content
Rigel docs
Open Rigel

Add something we have

inventory.item.add

POST/api/v1/households/{household_id}/commands/inventory.item.add

  • Command
  • Rigel runs it
  • Applies offline

Records a new item: a product in a place, with how much we have, its size, brand, dates and a note. Name the product by product_id, or by product_name, which finds the product ignoring case or creates it (a new product's usual place is this location, and an existing product with no usual place gets this one). Give the amount as quantity (with quantity_unit, or none for a plain count) or as a level, or neither for "we have some". Give expires_on together with expires_source, and say estimated when you worked the date out yourself. Counts as seen now, or at confirmed_at. Errors: product_not_found, location_not_found, file_not_found, person_not_found, recipe_not_found.

Parameters#

Add something we have: 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 something we have: request body fields
FieldDescription
product_idstringoptional

An existing product, from inventory.product.search. Give this or product_name.

product_namestringoptional

The product by name, ignoring case; it is created when there is none. Give this or product_id.

1 to 120 characters
location_idstringrequired

Where the item is kept.

quantitynumber or nulloptional

How many we have, in quantity_unit, such as 2 (cans) or 1.5 (lb). Leave out or null when there is no number. Never give it together with level. Leave both out for "we have some".

greater than 0, at most 1,000,000
quantity_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

The unit of quantity, such as "lb" or "can". Null or left out is a plain count of the things themselves (3 eggs). Only allowed with quantity.

levelone of: full, most, half, low, null or nulloptional

A rough amount when there is no number: full, most, half or low. Never give it together with quantity.

size_valuenumber or nulloptional

The size of one, such as 500 for a 500 g box. Give it together with size_unit; null clears both.

greater than 0, at most 1,000,000
size_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

The unit of size_value, such as g or oz. Give it together with size_value; null clears both.

for_person_idstring or nulloptional

Who it is kept for, such as Theo's yogurt or a cake for Nia's birthday. Null clears it.

recipe_idstring or nulloptional

For homemade food and leftovers, the recipe it was made from. Null clears it.

brandstring or nulloptional

The brand, as written on the package, such as "Barilla". One line, up to 80 characters. Null clears it.

1 to 80 characters
variantstring or nulloptional

A variation of the product, such as "low sodium" or "whole wheat". One line, up to 80 characters. Null clears it.

1 to 80 characters
notestring or nulloptional

A note about this item, as written, such as "for Nia's birthday". Null clears it.

1 to 500 characters
acquired_onstring (date) or nulloptional

The date it was bought or made, YYYY-MM-DD. Null clears it.

opened_onstring (date) or nulloptional

The date it was opened, if that changes how long it lasts (milk, salsa), YYYY-MM-DD. Null clears it.

label_best_bystring (date) or nulloptional

The best-by or use-by date printed on the package, as read, YYYY-MM-DD. Null clears it.

expires_onstring (date) or nulloptional

When to use it by, where it is now, YYYY-MM-DD; the date the app warns about. Give it together with expires_source; null (with a null source) means it does not go bad.

expires_sourceone of: label, person, estimated, null or nulloptional

Where expires_on came from. Give it together with expires_on; null clears both.

confirmed_atstring (date-time)optional

When this was known to be true, if not now: for a photo, when it was taken. A time after the command is treated as now, and an item's confirmation never moves backwards.

photo_file_idstringoptional

A picture of the item, an uploaded file. Optional.

cropobjectoptional

Where the item is in the photo, as fractions of the image; the picture shows just that part. Leave out for the whole image.

crop.xnumberrequired

Left edge of the item in the photo, as a fraction of the image width (0 to 1).

0 to 1
crop.ynumberrequired

Top edge of the item in the photo, as a fraction of the image height (0 to 1).

0 to 1
crop.widthnumberrequired

Width of the item in the photo, as a fraction of the image width (more than 0).

0 to 1greater than 0
crop.heightnumberrequired

Height of the item in the photo, as a fraction of the image height (more than 0).

0 to 1greater than 0

Response#

200 The command was applied.

Add something we have: response fields
FieldDescription
resultobjectrequired

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

result.item_idstringrequired

The new item.

result.product_idstringrequired

Its product, new or existing.

result.created_productbooleanrequired

True when the product did not exist and was created for this item.

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 something we have: errors
StatusCodeWhen
400validation_failedA field is missing, misspelled or out of range. details.fields lists each problem.
401unauthenticatedThe request has no valid session.
404product_not_found
  • The product doesn't exist in this household.
  • An unknown product.
404location_not_found
  • The location doesn't exist in this household.
  • An unknown location.
  • An unknown location, naming a new product.
404file_not_found
  • The file doesn't exist in this household.
  • An unknown photo file.
404person_not_found
  • The person doesn't exist in this household.
  • An unknown person.
404recipe_not_found
  • The recipe doesn't exist in this household.
  • An unknown recipe.
404not_foundThe household doesn't exist, or you aren't a member of it.
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.

Creates the product, with this location as its usual place, and the item

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "location_id": "loc_01JC000000000000000000000A",
  "product_name": "Black beans",
  "quantity": 2,
  "quantity_unit": "can",
  "size_value": 15,
  "size_unit": "oz",
  "brand": "Goya",
  "variant": "low sodium",
  "acquired_on": "2025-11-01",
  "label_best_by": "2027-03-01",
  "expires_on": "2027-03-01",
  "expires_source": "label",
  "note": "for chili"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    location_id: "loc_01JC000000000000000000000A",
    product_name: "Black beans",
    quantity: 2,
    quantity_unit: "can",
    size_value: 15,
    size_unit: "oz",
    brand: "Goya",
    variant: "low sodium",
    acquired_on: "2025-11-01",
    label_best_by: "2027-03-01",
    expires_on: "2027-03-01",
    expires_source: "label",
    note: "for chili",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "location_id": "loc_01JC000000000000000000000A",
  "product_name": "Black beans",
  "quantity": 2,
  "quantity_unit": "can",
  "size_value": 15,
  "size_unit": "oz",
  "brand": "Goya",
  "variant": "low sodium",
  "acquired_on": "2025-11-01",
  "label_best_by": "2027-03-01",
  "expires_on": "2027-03-01",
  "expires_source": "label",
  "note": "for chili"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0XB4WSZZTMRG4YED7

{
  "result": {
    "item_id": "inv_01JC4N0000VGW1STJ6TGXRB7FY",
    "product_id": "prd_01JC4N0000MBGE5RJ6Q7V6V6T8",
    "created_product": true
  },
  "version": 1
}

Finds an existing product by name in another case and leaves its usual place alone

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "location_id": "loc_01JC000000000000000000000A",
  "product_name": "rICE",
  "quantity": 1,
  "quantity_unit": "bag"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    location_id: "loc_01JC000000000000000000000A",
    product_name: "rICE",
    quantity: 1,
    quantity_unit: "bag",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "location_id": "loc_01JC000000000000000000000A",
  "product_name": "rICE",
  "quantity": 1,
  "quantity_unit": "bag"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0CH2N6B8TZ2APXSVB

{
  "result": {
    "item_id": "inv_01JC4N0000MBGE5RJ6Q7V6V6T8",
    "product_id": "prd_01JC000000000000000000000A",
    "created_product": false
  },
  "version": 1
}

Fills an existing product's empty usual place

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "location_id": "loc_01JC000000000000000000000A",
  "product_id": "prd_01JC000000000000000000000A",
  "quantity": 3
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    location_id: "loc_01JC000000000000000000000A",
    product_id: "prd_01JC000000000000000000000A",
    quantity: 3,
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "location_id": "loc_01JC000000000000000000000A",
  "product_id": "prd_01JC000000000000000000000A",
  "quantity": 3
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0CC5A4V42HGSGPHY2

{
  "result": {
    "item_id": "inv_01JC4N0000MBGE5RJ6Q7V6V6T8",
    "product_id": "prd_01JC000000000000000000000A",
    "created_product": false
  },
  "version": 1
}

A level instead of a number

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "location_id": "loc_01JC000000000000000000000A",
  "product_id": "prd_01JC000000000000000000000A",
  "level": "half"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    location_id: "loc_01JC000000000000000000000A",
    product_id: "prd_01JC000000000000000000000A",
    level: "half",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "location_id": "loc_01JC000000000000000000000A",
  "product_id": "prd_01JC000000000000000000000A",
  "level": "half"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0687PP5FW9QDHBSVD

{
  "result": {
    "item_id": "inv_01JC4N0000MBGE5RJ6Q7V6V6T8",
    "product_id": "prd_01JC000000000000000000000A",
    "created_product": false
  },
  "version": 1
}

No amount means we have some

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "location_id": "loc_01JC000000000000000000000A",
  "product_id": "prd_01JC000000000000000000000A"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    location_id: "loc_01JC000000000000000000000A",
    product_id: "prd_01JC000000000000000000000A",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "location_id": "loc_01JC000000000000000000000A",
  "product_id": "prd_01JC000000000000000000000A"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0SMB65NH2AZF8MAP0

{
  "result": {
    "item_id": "inv_01JC4N0000MBGE5RJ6Q7V6V6T8",
    "product_id": "prd_01JC000000000000000000000A",
    "created_product": false
  },
  "version": 1
}

A photo with a crop

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "location_id": "loc_01JC000000000000000000000A",
  "product_id": "prd_01JC000000000000000000000A",
  "photo_file_id": "fil_01JC000000000000000000000A",
  "crop": {
    "x": 0.25,
    "y": 0.5,
    "width": 0.5,
    "height": 0.5
  }
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    location_id: "loc_01JC000000000000000000000A",
    product_id: "prd_01JC000000000000000000000A",
    photo_file_id: "fil_01JC000000000000000000000A",
    crop: {
      x: 0.25,
      y: 0.5,
      width: 0.5,
      height: 0.5,
    },
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "location_id": "loc_01JC000000000000000000000A",
  "product_id": "prd_01JC000000000000000000000A",
  "photo_file_id": "fil_01JC000000000000000000000A",
  "crop": {
    "x": 0.25,
    "y": 0.5,
    "width": 0.5,
    "height": 0.5
  }
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R043WB4Z0HK87T5721

{
  "result": {
    "item_id": "inv_01JC4N0000MBGE5RJ6Q7V6V6T8",
    "product_id": "prd_01JC000000000000000000000A",
    "created_product": false
  },
  "version": 1
}

A photo without a crop uses the whole image

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "location_id": "loc_01JC000000000000000000000A",
  "product_id": "prd_01JC000000000000000000000A",
  "photo_file_id": "fil_01JC000000000000000000000A"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    location_id: "loc_01JC000000000000000000000A",
    product_id: "prd_01JC000000000000000000000A",
    photo_file_id: "fil_01JC000000000000000000000A",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "location_id": "loc_01JC000000000000000000000A",
  "product_id": "prd_01JC000000000000000000000A",
  "photo_file_id": "fil_01JC000000000000000000000A"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0FR9DCRGD3MGXWSRQ

{
  "result": {
    "item_id": "inv_01JC4N0000MBGE5RJ6Q7V6V6T8",
    "product_id": "prd_01JC000000000000000000000A",
    "created_product": false
  },
  "version": 1
}

Confirmed_at in the past dates the item then

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "location_id": "loc_01JC000000000000000000000A",
  "product_name": "Rice",
  "confirmed_at": "2025-11-04T23:46:40.000Z"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    location_id: "loc_01JC000000000000000000000A",
    product_name: "Rice",
    confirmed_at: "2025-11-04T23:46:40.000Z",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "location_id": "loc_01JC000000000000000000000A",
  "product_name": "Rice",
  "confirmed_at": "2025-11-04T23:46:40.000Z"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0YXBRQ9Z19WRWMB14

{
  "result": {
    "item_id": "inv_01JC4N0000MBGE5RJ6Q7V6V6T8",
    "product_id": "prd_01JC000000000000000000000A",
    "created_product": false
  },
  "version": 1
}

Confirmed_at in the future counts as now

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "location_id": "loc_01JC000000000000000000000A",
  "product_name": "Rice",
  "confirmed_at": "2026-11-06T19:20:00.000Z"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    location_id: "loc_01JC000000000000000000000A",
    product_name: "Rice",
    confirmed_at: "2026-11-06T19:20:00.000Z",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "location_id": "loc_01JC000000000000000000000A",
  "product_name": "Rice",
  "confirmed_at": "2026-11-06T19:20:00.000Z"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R06DTJMR80NETKRHPS

{
  "result": {
    "item_id": "inv_01JC4N0000MBGE5RJ6Q7V6V6T8",
    "product_id": "prd_01JC000000000000000000000A",
    "created_product": false
  },
  "version": 1
}

Kept for someone

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "location_id": "loc_01JC000000000000000000000A",
  "product_id": "prd_01JC000000000000000000000A",
  "for_person_id": "per_01JC000000000000000000000A"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    location_id: "loc_01JC000000000000000000000A",
    product_id: "prd_01JC000000000000000000000A",
    for_person_id: "per_01JC000000000000000000000A",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "location_id": "loc_01JC000000000000000000000A",
  "product_id": "prd_01JC000000000000000000000A",
  "for_person_id": "per_01JC000000000000000000000A"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R02M3Q3BHY77CP4JRH

{
  "result": {
    "item_id": "inv_01JC4N0000MBGE5RJ6Q7V6V6T8",
    "product_id": "prd_01JC000000000000000000000A",
    "created_product": false
  },
  "version": 1
}

Leftovers made from a recipe

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "location_id": "loc_01JC000000000000000000000B",
  "product_name": "Tikka masala (leftovers)",
  "level": "half",
  "acquired_on": "2025-11-06",
  "expires_on": "2025-11-09",
  "expires_source": "person",
  "recipe_id": "rcp_01JC000000000000000000000A"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    location_id: "loc_01JC000000000000000000000B",
    product_name: "Tikka masala (leftovers)",
    level: "half",
    acquired_on: "2025-11-06",
    expires_on: "2025-11-09",
    expires_source: "person",
    recipe_id: "rcp_01JC000000000000000000000A",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "location_id": "loc_01JC000000000000000000000B",
  "product_name": "Tikka masala (leftovers)",
  "level": "half",
  "acquired_on": "2025-11-06",
  "expires_on": "2025-11-09",
  "expires_source": "person",
  "recipe_id": "rcp_01JC000000000000000000000A"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R08MYCQWC6SC91RPDQ

{
  "result": {
    "item_id": "inv_01JC4N0000VGW1STJ6TGXRB7FY",
    "product_id": "prd_01JC4N0000MBGE5RJ6Q7V6V6T8",
    "created_product": true
  },
  "version": 1
}

An unknown person

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "location_id": "loc_01JC000000000000000000000A",
  "product_id": "prd_01JC000000000000000000000A",
  "for_person_id": "per_01JC000000000000000000000Z"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    location_id: "loc_01JC000000000000000000000A",
    product_id: "prd_01JC000000000000000000000A",
    for_person_id: "per_01JC000000000000000000000Z",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "location_id": "loc_01JC000000000000000000000A",
  "product_id": "prd_01JC000000000000000000000A",
  "for_person_id": "per_01JC000000000000000000000Z"
}
Response, 404
HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0CA4HRJZWKAZ84PTR

{
  "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_01K9D9S2R0CA4HRJZWKAZ84PTR"
  }
}

An unknown recipe

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "location_id": "loc_01JC000000000000000000000A",
  "product_id": "prd_01JC000000000000000000000A",
  "recipe_id": "rcp_01JC000000000000000000000Z"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    location_id: "loc_01JC000000000000000000000A",
    product_id: "prd_01JC000000000000000000000A",
    recipe_id: "rcp_01JC000000000000000000000Z",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "location_id": "loc_01JC000000000000000000000A",
  "product_id": "prd_01JC000000000000000000000A",
  "recipe_id": "rcp_01JC000000000000000000000Z"
}
Response, 404
HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0S2W31EZ3QWY0H5EE

{
  "error": {
    "code": "recipe_not_found",
    "message": "That recipe isn't in the recipe box any more. No changes were applied.",
    "details": {
      "recipe_id": "rcp_01JC000000000000000000000Z"
    },
    "recovery": "Read the current state, then send a command that fits it.",
    "request_id": "req_01K9D9S2R0S2W31EZ3QWY0H5EE"
  }
}

An unknown product

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "location_id": "loc_01JC000000000000000000000A",
  "product_id": "prd_01JC000000000000000000000Z"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    location_id: "loc_01JC000000000000000000000A",
    product_id: "prd_01JC000000000000000000000Z",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "location_id": "loc_01JC000000000000000000000A",
  "product_id": "prd_01JC000000000000000000000Z"
}
Response, 404
HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0V844ZKMJS0C7R17X

{
  "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_01K9D9S2R0V844ZKMJS0C7R17X"
  }
}

An unknown location

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "location_id": "loc_01JC000000000000000000000Z",
  "product_id": "prd_01JC000000000000000000000A"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    location_id: "loc_01JC000000000000000000000Z",
    product_id: "prd_01JC000000000000000000000A",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "location_id": "loc_01JC000000000000000000000Z",
  "product_id": "prd_01JC000000000000000000000A"
}
Response, 404
HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R01FSM8KVZG5E93ANM

{
  "error": {
    "code": "location_not_found",
    "message": "That place isn't in the inventory any more. No changes were applied.",
    "details": {
      "location_id": "loc_01JC000000000000000000000Z"
    },
    "recovery": "Read the current state, then send a command that fits it.",
    "request_id": "req_01K9D9S2R01FSM8KVZG5E93ANM"
  }
}

An unknown location, naming a new product

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "location_id": "loc_01JC000000000000000000000Z",
  "product_name": "Oats"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    location_id: "loc_01JC000000000000000000000Z",
    product_name: "Oats",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "location_id": "loc_01JC000000000000000000000Z",
  "product_name": "Oats"
}
Response, 404
HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0RTNBY3FVERNQJ3B3

{
  "error": {
    "code": "location_not_found",
    "message": "That place isn't in the inventory any more. No changes were applied.",
    "details": {
      "location_id": "loc_01JC000000000000000000000Z"
    },
    "recovery": "Read the current state, then send a command that fits it.",
    "request_id": "req_01K9D9S2R0RTNBY3FVERNQJ3B3"
  }
}

An unknown photo file

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "location_id": "loc_01JC000000000000000000000A",
  "product_id": "prd_01JC000000000000000000000A",
  "photo_file_id": "fil_01JC000000000000000000000Z"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    location_id: "loc_01JC000000000000000000000A",
    product_id: "prd_01JC000000000000000000000A",
    photo_file_id: "fil_01JC000000000000000000000Z",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.item.add HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "location_id": "loc_01JC000000000000000000000A",
  "product_id": "prd_01JC000000000000000000000A",
  "photo_file_id": "fil_01JC000000000000000000000Z"
}
Response, 404
HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R02A4SWV873DTT029Y

{
  "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_01K9D9S2R02A4SWV873DTT029Y"
  }
}

Put something away

A product that already exists, with its amount, size and best-by date from the label.

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01M6V9CSAJ5CG8JNZQWK1Y32ZS' \
  -d '{
  "product_id": "prd_01M6V9CSAG72MC7ERJ4GCZ0X7A",
  "location_id": "loc_01M6V9CSA910340EZNX67RFMV0",
  "quantity": 1,
  "quantity_unit": "bag",
  "size_value": 2,
  "size_unit": "kg",
  "brand": "Mill Road",
  "label_best_by": "2027-07-05",
  "acquired_on": "2026-10-29"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01M6V9CSAJ5CG8JNZQWK1Y32ZS",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    product_id: "prd_01M6V9CSAG72MC7ERJ4GCZ0X7A",
    location_id: "loc_01M6V9CSA910340EZNX67RFMV0",
    quantity: 1,
    quantity_unit: "bag",
    size_value: 2,
    size_unit: "kg",
    brand: "Mill Road",
    label_best_by: "2027-07-05",
    acquired_on: "2026-10-29",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CSAJ5CG8JNZQWK1Y32ZS

{
  "product_id": "prd_01M6V9CSAG72MC7ERJ4GCZ0X7A",
  "location_id": "loc_01M6V9CSA910340EZNX67RFMV0",
  "quantity": 1,
  "quantity_unit": "bag",
  "size_value": 2,
  "size_unit": "kg",
  "brand": "Mill Road",
  "label_best_by": "2027-07-05",
  "acquired_on": "2026-10-29"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CSAJ76J327C4WE8K64G4

{
  "result": {
    "item_id": "inv_01M6V9CSAJYYMNC0TXJX8NRN8T",
    "product_id": "prd_01M6V9CSAG72MC7ERJ4GCZ0X7A",
    "created_product": false
  },
  "version": 27
}

Put cans away

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01M6V9CSAP5MC2A1E9070YQEBG' \
  -d '{
  "product_id": "prd_01M6V9CSAMSN9ZJ52PTTKT8G6M",
  "location_id": "loc_01M6V9CSA910340EZNX67RFMV0",
  "quantity": 3,
  "quantity_unit": "can"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01M6V9CSAP5MC2A1E9070YQEBG",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    product_id: "prd_01M6V9CSAMSN9ZJ52PTTKT8G6M",
    location_id: "loc_01M6V9CSA910340EZNX67RFMV0",
    quantity: 3,
    quantity_unit: "can",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CSAP5MC2A1E9070YQEBG

{
  "product_id": "prd_01M6V9CSAMSN9ZJ52PTTKT8G6M",
  "location_id": "loc_01M6V9CSA910340EZNX67RFMV0",
  "quantity": 3,
  "quantity_unit": "can"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CSAPKCCFVM9N8JFPQ33Q

{
  "result": {
    "item_id": "inv_01M6V9CSAPM8JH7W1W1YEBHPRS",
    "product_id": "prd_01M6V9CSAMSN9ZJ52PTTKT8G6M",
    "created_product": false
  },
  "version": 29
}

Put something away by name

A name that matches no product makes one. created_product says whether it did.

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01M6V9CSAQMCFT7RPWGMHVZV73' \
  -d '{
  "product_name": "Orzo",
  "location_id": "loc_01M6V9CSA910340EZNX67RFMV0",
  "quantity": 1,
  "quantity_unit": "box"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01M6V9CSAQMCFT7RPWGMHVZV73",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    product_name: "Orzo",
    location_id: "loc_01M6V9CSA910340EZNX67RFMV0",
    quantity: 1,
    quantity_unit: "box",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CSAQMCFT7RPWGMHVZV73

{
  "product_name": "Orzo",
  "location_id": "loc_01M6V9CSA910340EZNX67RFMV0",
  "quantity": 1,
  "quantity_unit": "box"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CSAQYJ8CDG5C13W1TY3S

{
  "result": {
    "item_id": "inv_01M6V9CSAQY5ZPFNNXYTWXW5CF",
    "product_id": "prd_01M6V9CSAQDSZHDQNXHXRCDA8Z",
    "created_product": true
  },
  "version": 30
}

Put something away by how full it is

When there's no exact count, a level says how much is left: full, most, half or low.

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01M6V9CSATFVE7MX0HZ3VTSBSD' \
  -d '{
  "product_name": "Olive oil",
  "location_id": "loc_01M6V9CSA910340EZNX67RFMV0",
  "level": "most"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01M6V9CSATFVE7MX0HZ3VTSBSD",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    product_name: "Olive oil",
    location_id: "loc_01M6V9CSA910340EZNX67RFMV0",
    level: "most",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CSATFVE7MX0HZ3VTSBSD

{
  "product_name": "Olive oil",
  "location_id": "loc_01M6V9CSA910340EZNX67RFMV0",
  "level": "most"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CSATV9FH5FNZ48PY7Y68

{
  "result": {
    "item_id": "inv_01M6V9CSATNBB6KZZ14ZN1FE15",
    "product_id": "prd_01M6V9CSAT6M58YWZ1H4DFY9K2",
    "created_product": true
  },
  "version": 31
}

Put away something that expires

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01M6V9CSAW13GWXH3SR197EKKZ' \
  -d '{
  "product_name": "Milk",
  "location_id": "loc_01M6V9CSAACDPHW4NW889QQ2VV",
  "quantity": 1,
  "quantity_unit": "gallon",
  "expires_on": "2026-11-10",
  "expires_source": "label"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01M6V9CSAW13GWXH3SR197EKKZ",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    product_name: "Milk",
    location_id: "loc_01M6V9CSAACDPHW4NW889QQ2VV",
    quantity: 1,
    quantity_unit: "gallon",
    expires_on: "2026-11-10",
    expires_source: "label",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CSAW13GWXH3SR197EKKZ

{
  "product_name": "Milk",
  "location_id": "loc_01M6V9CSAACDPHW4NW889QQ2VV",
  "quantity": 1,
  "quantity_unit": "gallon",
  "expires_on": "2026-11-10",
  "expires_source": "label"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CSAWDS14ZGGS86S5DNQ1

{
  "result": {
    "item_id": "inv_01M6V9CSAWTFE7ARBQF4CXQ31Q",
    "product_id": "prd_01M6V9CSAWSAMCWTBQ2M7F80H9",
    "created_product": true
  },
  "version": 32
}

Put something away for one person

for_person_id marks something as one person's, such as Nia's yogurt.

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01M6V9CSB0Y1YVYFN0ATXPK2M9' \
  -d '{
  "product_name": "Yogurt",
  "location_id": "loc_01M6V9CSAACDPHW4NW889QQ2VV",
  "level": "half",
  "expires_on": "2026-11-13",
  "expires_source": "label",
  "for_person_id": "per_01M6V9CS79TMYHDAM7FTA9ZK3Z"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01M6V9CSB0Y1YVYFN0ATXPK2M9",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    product_name: "Yogurt",
    location_id: "loc_01M6V9CSAACDPHW4NW889QQ2VV",
    level: "half",
    expires_on: "2026-11-13",
    expires_source: "label",
    for_person_id: "per_01M6V9CS79TMYHDAM7FTA9ZK3Z",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CSB0Y1YVYFN0ATXPK2M9

{
  "product_name": "Yogurt",
  "location_id": "loc_01M6V9CSAACDPHW4NW889QQ2VV",
  "level": "half",
  "expires_on": "2026-11-13",
  "expires_source": "label",
  "for_person_id": "per_01M6V9CS79TMYHDAM7FTA9ZK3Z"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CSB0A457327BM7GSSA2K

{
  "result": {
    "item_id": "inv_01M6V9CSB0YB2Y7WBZBMR3G5Z0",
    "product_id": "prd_01M6V9CSB0DQFW5YBZYYMJ0A77",
    "created_product": true
  },
  "version": 34
}

Put something away without a date

Rigel estimates how long it keeps from what it is and where it's stored, and marks the date as an estimate.

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01M6V9CSB24WSG99GK4J78PC5M' \
  -d '{
  "product_name": "Chicken thighs",
  "location_id": "loc_01M6V9CSABVCCJRZ4RWVFW77D6",
  "quantity": 2,
  "quantity_unit": "lb",
  "acquired_on": "2026-10-18"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01M6V9CSB24WSG99GK4J78PC5M",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    product_name: "Chicken thighs",
    location_id: "loc_01M6V9CSABVCCJRZ4RWVFW77D6",
    quantity: 2,
    quantity_unit: "lb",
    acquired_on: "2026-10-18",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CSB24WSG99GK4J78PC5M

{
  "product_name": "Chicken thighs",
  "location_id": "loc_01M6V9CSABVCCJRZ4RWVFW77D6",
  "quantity": 2,
  "quantity_unit": "lb",
  "acquired_on": "2026-10-18"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CSB2W3ZKEFSYWC645JJS

{
  "result": {
    "item_id": "inv_01M6V9CSB2QRQDPSG49EFX353W",
    "product_id": "prd_01M6V9CSB2GBRX2QG46DDBK4TW",
    "created_product": true
  },
  "version": 35
}

Track something that isn't food

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01M6V9CSB412GW26WB9AREVQ1Y' \
  -d '{
  "product_name": "Paper towels",
  "location_id": "loc_01M6V9CSADPBG11HW38FMRV1ZQ",
  "quantity": 6,
  "quantity_unit": "roll"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01M6V9CSB412GW26WB9AREVQ1Y",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    product_name: "Paper towels",
    location_id: "loc_01M6V9CSADPBG11HW38FMRV1ZQ",
    quantity: 6,
    quantity_unit: "roll",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CSB412GW26WB9AREVQ1Y

{
  "product_name": "Paper towels",
  "location_id": "loc_01M6V9CSADPBG11HW38FMRV1ZQ",
  "quantity": 6,
  "quantity_unit": "roll"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CSB4NKFVWW1FK384VZF3

{
  "result": {
    "item_id": "inv_01M6V9CSB441KYPTJPNZGNVY4A",
    "product_id": "prd_01M6V9CSB4BEJEAXJPR0K7CZD9",
    "created_product": true
  },
  "version": 36
}

Put away something already opened

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01M6V9CSB60MVYZHQCQPE9R0RX' \
  -d '{
  "product_name": "Salsa",
  "location_id": "loc_01M6V9CSAACDPHW4NW889QQ2VV",
  "quantity": 1,
  "quantity_unit": "jar",
  "opened_on": "2026-11-05"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01M6V9CSB60MVYZHQCQPE9R0RX",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    product_name: "Salsa",
    location_id: "loc_01M6V9CSAACDPHW4NW889QQ2VV",
    quantity: 1,
    quantity_unit: "jar",
    opened_on: "2026-11-05",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.item.add HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CSB60MVYZHQCQPE9R0RX

{
  "product_name": "Salsa",
  "location_id": "loc_01M6V9CSAACDPHW4NW889QQ2VV",
  "quantity": 1,
  "quantity_unit": "jar",
  "opened_on": "2026-11-05"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CSB6FT8A3R67EC28366D

{
  "result": {
    "item_id": "inv_01M6V9CSB6S923R566WD7EAGGG",
    "product_id": "prd_01M6V9CSB6TEWX53669YBWSK0Y",
    "created_product": true
  },
  "version": 37
}

For Rigel#

Rigel's tool for this command is inventory_item_add. 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