Skip to content
Rigel docs
Open Rigel

Add a product, or use the one with that name

inventory.product.create

POST/api/v1/households/{household_id}/commands/inventory.product.create

  • Command
  • Rigel runs it
  • Applies offline

Finds the product with this name, ignoring case, or adds it. For a product that already exists, an empty category or usual location is filled from the input; nothing it already has is changed. Search with inventory.product.search first to reuse a product under a slightly different name.

Parameters#

Add a product, or use the one with that name: 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 a product, or use the one with that name: request body fields
FieldDescription
namestringrequired

What the thing is, in the household's words, generic rather than a brand: "milk", "black beans", "paper towels". 1–120 characters. Unique ignoring case.

1 to 120 characters
categorystring or nulloptional

Its grouping, by name, such as "Produce", "Dairy" or "Canned". A new name adds the category; keep to the ones already in use (inventory.category.list). Null clears it.

1 to 60 characters
is_staplebooleanoptional

Something we normally have, like salt, oil or rice.

is_trackedbooleanoptional

Whether the household keeps inventory of it. Untracked products can still be in recipes and on lists. Defaults to true.

default_location_idstring or nulloptional

Where it usually goes, for putting away purchases.

Response#

200 The command was applied.

Add a product, or use the one with that name: response fields
FieldDescription
resultobjectrequired

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

result.product_idstringrequired

The product, new or existing.

result.createdbooleanrequired

Whether it was added just now.

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 a product, or use the one with that name: errors
StatusCodeWhen
400validation_failedA field is missing, misspelled or out of range. details.fields lists each problem.
401unauthenticatedThe request has no valid session.
404location_not_found
  • A usual place that isn't there.
  • A usual place that isn't there, for an existing product.
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.

A new product with a new category

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

{
  "name": "Milk",
  "category": "Dairy",
  "is_staple": true
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R02WP7ZZHYTMT1JK2Q

{
  "result": {
    "product_id": "prd_01JC4N0000VGW1STJ6TGXRB7FY",
    "created": true
  },
  "version": 1
}

A category matching an existing one ignoring case is reused

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

{
  "name": "Cheese",
  "category": "dAIRY"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0GT8ZN1FSYBNWX9TD

{
  "result": {
    "product_id": "prd_01JC4N0000MBGE5RJ6Q7V6V6T8",
    "created": true
  },
  "version": 1
}

A second new category goes last in order

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

{
  "name": "Rice",
  "category": "Pantry"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R02ZPZDWBJP5JX191G

{
  "result": {
    "product_id": "prd_01JC4N0000VGW1STJ6TGXRB7FY",
    "created": true
  },
  "version": 1
}

An existing product with no category takes an existing category

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

{
  "name": "milk",
  "category": "dairy"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R00KG20ZH7ZT1CKZAF

{
  "result": {
    "product_id": "prd_01JC000000000000000000000A",
    "created": false
  },
  "version": 1
}

Only a name takes the defaults

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

{
  "name": "Rice"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0MF654XF9VDAAWR3Z

{
  "result": {
    "product_id": "prd_01JC4N0000MBGE5RJ6Q7V6V6T8",
    "created": true
  },
  "version": 1
}

Untracked staple with a usual place

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

{
  "name": "Salt",
  "is_staple": true,
  "is_tracked": false,
  "default_location_id": "loc_01JC000000000000000000000A"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0GJDKAMYV8DVRRJ12

{
  "result": {
    "product_id": "prd_01JC4N0000MBGE5RJ6Q7V6V6T8",
    "created": true
  },
  "version": 1
}

Explicit false staple and null category

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.product.create' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "name": "Eggs",
  "is_staple": false,
  "category": null,
  "default_location_id": null,
  "is_tracked": true
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.product.create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    name: "Eggs",
    is_staple: false,
    category: null,
    default_location_id: null,
    is_tracked: true,
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/inventory.product.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "name": "Eggs",
  "is_staple": false,
  "category": null,
  "default_location_id": null,
  "is_tracked": true
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0KFQ533CNM8ENYZ7A

{
  "result": {
    "product_id": "prd_01JC4N0000MBGE5RJ6Q7V6V6T8",
    "created": true
  },
  "version": 1
}

A name of 120 characters

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

{
  "name": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0PJJHQB0W1Z1K13Y9

{
  "result": {
    "product_id": "prd_01JC4N0000MBGE5RJ6Q7V6V6T8",
    "created": true
  },
  "version": 1
}

The same product by a different case

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

{
  "name": "milk"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R05D9QHYHV871SH317

{
  "result": {
    "product_id": "prd_01JC000000000000000000000A",
    "created": false
  },
  "version": 1
}

An existing product with no category gets the category

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

{
  "name": "MILK",
  "category": "Dairy"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0JHR5GBM6CJ4BR33T

{
  "result": {
    "product_id": "prd_01JC000000000000000000000A",
    "created": false
  },
  "version": 1
}

An existing category is not overwritten

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

{
  "name": "milk",
  "category": "Drinks"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0CNMA4P58PE66TNCY

{
  "result": {
    "product_id": "prd_01JC000000000000000000000A",
    "created": false
  },
  "version": 1
}

An existing product with no usual place gets one

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

{
  "name": "milk",
  "default_location_id": "loc_01JC000000000000000000000A"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0PCWYKG7F5V05RP2C

{
  "result": {
    "product_id": "prd_01JC000000000000000000000A",
    "created": false
  },
  "version": 1
}

An existing usual place is not overwritten

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

{
  "name": "milk",
  "default_location_id": "loc_01JC000000000000000000000B"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0PY1SF90WVH2QRB8C

{
  "result": {
    "product_id": "prd_01JC000000000000000000000A",
    "created": false
  },
  "version": 1
}

Other fields of an existing product are not changed

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

{
  "name": "milk",
  "is_staple": true,
  "is_tracked": false
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0DZ388M24E8K7FP2G

{
  "result": {
    "product_id": "prd_01JC000000000000000000000A",
    "created": false
  },
  "version": 1
}

A usual place that isn't there

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

{
  "name": "Milk",
  "default_location_id": "loc_01JC000000000000000000000A"
}
Response, 404
HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0TS8XBQ35C5CRN509

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

A usual place that isn't there, for an existing product

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

{
  "name": "Milk",
  "default_location_id": "loc_01JC000000000000000000000A"
}
Response, 404
HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0583TQNZ6EG9CSDVJ

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

Add a product

Products are what a thing is, in the household's words. Brand and size belong to the item.

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.product.create' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01M6V9CSAGDK2E4YQ3BFYWB677' \
  -d '{
  "name": "Flour",
  "category": "Baking",
  "is_staple": true
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.product.create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01M6V9CSAGDK2E4YQ3BFYWB677",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    name: "Flour",
    category: "Baking",
    is_staple: true,
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.product.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CSAGDK2E4YQ3BFYWB677

{
  "name": "Flour",
  "category": "Baking",
  "is_staple": true
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CSAG71HKSS39D3G0Y2SB

{
  "result": {
    "product_id": "prd_01M6V9CSAG72MC7ERJ4GCZ0X7A",
    "created": true
  },
  "version": 26
}

Add a product in a category

The category is given by name. An existing one is reused, ignoring case.

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.product.create' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01M6V9CSAMXTNB6TKKRHP2DEPB' \
  -d '{
  "name": "Black beans",
  "category": "Canned goods"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.product.create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01M6V9CSAMXTNB6TKKRHP2DEPB",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    name: "Black beans",
    category: "Canned goods",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.product.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CSAMXTNB6TKKRHP2DEPB

{
  "name": "Black beans",
  "category": "Canned goods"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CSAMHB1RPT5KM7P82T18

{
  "result": {
    "product_id": "prd_01M6V9CSAMSN9ZJ52PTTKT8G6M",
    "created": true
  },
  "version": 28
}

Add a product that's a duplicate

The household ends up with Black bean and Black beans.

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.product.create' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01M6V9CSCWTN2XWXN2ZGES2NAX' \
  -d '{
  "name": "Black bean"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.product.create", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01M6V9CSCWTN2XWXN2ZGES2NAX",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    name: "Black bean",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/inventory.product.create HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CSCWTN2XWXN2ZGES2NAX

{
  "name": "Black bean"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CSCW5Z27A36C6PXVP8DE

{
  "result": {
    "product_id": "prd_01M6V9CSCW6MS7PRXS1HETX9KW",
    "created": true
  },
  "version": 48
}

For Rigel#

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

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