Skip to content
Rigel docs
Open Rigel

Put several things on the shopping list at once

shopping.item.add_many

POST/api/v1/households/{household_id}/commands/shopping.item.add_many

  • Command
  • Rigel runs it
  • Applies offline

Adds up to 200 items, each as shopping.item.add takes it, in order, recorded as one change. Later items merge into earlier ones from the same batch, so the same product twice becomes one item. If any item is refused, nothing is added; the error names which item (counting from 1) and carries its position, counting from 0, as details.index. Returns one result per item, in order.

Parameters#

Put several things on the shopping list at once: 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.

Put several things on the shopping list at once: request body fields
FieldDescription
itemsarray of objectsrequired

What to add, each as shopping.item.add takes it.

1 to 200 items
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 inventory.product.search first so you reuse the right one.

1 to 120 characters
items[].quantitynumber or nulloptional

How many, when said. Leave out when no amount was given.

greater than 0, at most 1,000,000
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[].notestring or nulloptional

A note for whoever shops: "plain", "the big bag". Name a meal or recipe with meal_id or recipe_id, not here, as written, 1–500 characters.

at most 500 characters
items[].for_person_idstring or nulloptional

Who it's for, when someone said it's for a person in the family.

items[].meal_idstring or nulloptional

The planned meal it's for, from the meal plan, so the list shows the meal and follows it if it moves. For something several meals need, add it once per meal.

items[].recipe_idstring or nulloptional

The recipe it's for, when it comes from a recipe's ingredients, so the list can say so. For something several recipes need, add it once per recipe.

Response#

200 The command was applied.

Put several things on the shopping list at once: response fields
FieldDescription
resultobjectrequired

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

result.itemsarray of objectsrequired

One result per input item, in the same order.

result.items[].item_idstringrequired

The list item: the new one, or the one already on the list that this was added to.

result.items[].product_idstringrequired

The product it's for.

result.items[].mergedbooleanrequired

True when the product was already on the list and this was added to that 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.

Put several things on the shopping list at once: 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_foundA refused item rejects the whole batch.
404person_not_foundAn unknown person in a later item rejects the whole batch.
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.

Several items are added in order

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

{
  "items": [
    {
      "product_id": "prd_01JC000000000000000000000A",
      "quantity": 1,
      "unit": "gallon"
    },
    {
      "product_name": "Rice"
    }
  ]
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R09J8VQASV32QPEH65

{
  "result": {
    "items": [
      {
        "item_id": "shi_01JC4N0000MBGE5RJ6Q7V6V6T8",
        "product_id": "prd_01JC000000000000000000000A",
        "merged": false
      },
      {
        "item_id": "shi_01JC4N0000JVP6PWJ6S8P7WZ6B",
        "product_id": "prd_01JC4N0000VGW1STJ6TGXRB7FY",
        "merged": false
      }
    ]
  },
  "version": 1
}

A later item merges into an earlier one from the same batch

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.item.add_many' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "items": [
    {
      "product_id": "prd_01JC000000000000000000000B",
      "quantity": 6
    },
    {
      "product_name": "eggs",
      "quantity": 6,
      "note": "for baking"
    }
  ]
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.item.add_many", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    items: [
      {
        product_id: "prd_01JC000000000000000000000B",
        quantity: 6,
      },
      {
        product_name: "eggs",
        quantity: 6,
        note: "for baking",
      },
    ],
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/shopping.item.add_many HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "items": [
    {
      "product_id": "prd_01JC000000000000000000000B",
      "quantity": 6
    },
    {
      "product_name": "eggs",
      "quantity": 6,
      "note": "for baking"
    }
  ]
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R049HPV8DYQJYD2Z7J

{
  "result": {
    "items": [
      {
        "item_id": "shi_01JC4N0000MBGE5RJ6Q7V6V6T8",
        "product_id": "prd_01JC000000000000000000000B",
        "merged": false
      },
      {
        "item_id": "shi_01JC4N0000MBGE5RJ6Q7V6V6T8",
        "product_id": "prd_01JC000000000000000000000B",
        "merged": true
      }
    ]
  },
  "version": 1
}

A later item merges into an item already on the list

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

{
  "items": [
    {
      "product_id": "prd_01JC000000000000000000000C"
    },
    {
      "product_id": "prd_01JC000000000000000000000A",
      "quantity": 1,
      "unit": "gallon"
    }
  ]
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R00TNHVSH2QV1X6GXB

{
  "result": {
    "items": [
      {
        "item_id": "shi_01JC4N0000MBGE5RJ6Q7V6V6T8",
        "product_id": "prd_01JC000000000000000000000C",
        "merged": false
      },
      {
        "item_id": "shi_01JC0000000000000000000001",
        "product_id": "prd_01JC000000000000000000000A",
        "merged": true
      }
    ]
  },
  "version": 1
}

A refused item rejects the whole batch

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

{
  "items": [
    {
      "product_id": "prd_01JC000000000000000000000A"
    },
    {
      "product_id": "prd_01JC000000000000000000000Z"
    }
  ]
}
Response, 404
HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R07AEYKZ1VNMEKQJCV

{
  "error": {
    "code": "product_not_found",
    "message": "Item 2: That product isn't there any more. No changes were applied.",
    "details": {
      "product_id": "prd_01JC000000000000000000000Z",
      "index": 1
    },
    "recovery": "Read the current state, then send a command that fits it.",
    "request_id": "req_01K9D9S2R07AEYKZ1VNMEKQJCV"
  }
}

An unknown person in a later item rejects the whole batch

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

{
  "items": [
    {
      "product_id": "prd_01JC000000000000000000000A"
    },
    {
      "product_id": "prd_01JC000000000000000000000B"
    },
    {
      "product_id": "prd_01JC000000000000000000000C",
      "for_person_id": "per_01JC000000000000000000000Z"
    }
  ]
}
Response, 404
HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R05C4ZFF27BGXXNAM7

{
  "error": {
    "code": "person_not_found",
    "message": "Item 3: That person isn't in the household any more. No changes were applied.",
    "details": {
      "person_id": "per_01JC000000000000000000000Z",
      "index": 2
    },
    "recovery": "Read the current state, then send a command that fits it.",
    "request_id": "req_01K9D9S2R05C4ZFF27BGXXNAM7"
  }
}

Put several things on the list at once

Added in order as one change. If one is refused, none are.

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/shopping.item.add_many' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01M6V9CT7N2YY2GJBBPVD2ZD2H' \
  -d '{
  "items": [
    {
      "product_name": "Baby spinach",
      "quantity": 1,
      "unit": "bag",
      "recipe_id": "rcp_01M6V9CSD8VZYF11AC568Y7QPZ"
    },
    {
      "product_name": "White beans",
      "quantity": 2,
      "unit": "can",
      "recipe_id": "rcp_01M6V9CSD8VZYF11AC568Y7QPZ"
    },
    {
      "product_name": "Vegetable broth",
      "quantity": 1,
      "unit": "carton",
      "recipe_id": "rcp_01M6V9CSD8VZYF11AC568Y7QPZ"
    },
    {
      "product_id": "prd_01M6V9CSWCK03ABGA7BSJA03Q1",
      "quantity": 1,
      "unit": "package",
      "note": "A 4-pack. The filter is due soon."
    },
    {
      "product_name": "Birthday candles"
    }
  ]
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/shopping.item.add_many", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01M6V9CT7N2YY2GJBBPVD2ZD2H",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    items: [
      {
        product_name: "Baby spinach",
        quantity: 1,
        unit: "bag",
        recipe_id: "rcp_01M6V9CSD8VZYF11AC568Y7QPZ",
      },
      {
        product_name: "White beans",
        quantity: 2,
        unit: "can",
        recipe_id: "rcp_01M6V9CSD8VZYF11AC568Y7QPZ",
      },
      {
        product_name: "Vegetable broth",
        quantity: 1,
        unit: "carton",
        recipe_id: "rcp_01M6V9CSD8VZYF11AC568Y7QPZ",
      },
      {
        product_id: "prd_01M6V9CSWCK03ABGA7BSJA03Q1",
        quantity: 1,
        unit: "package",
        note: "A 4-pack. The filter is due soon.",
      },
      {
        product_name: "Birthday candles",
      },
    ],
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/shopping.item.add_many HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CT7N2YY2GJBBPVD2ZD2H

{
  "items": [
    {
      "product_name": "Baby spinach",
      "quantity": 1,
      "unit": "bag",
      "recipe_id": "rcp_01M6V9CSD8VZYF11AC568Y7QPZ"
    },
    {
      "product_name": "White beans",
      "quantity": 2,
      "unit": "can",
      "recipe_id": "rcp_01M6V9CSD8VZYF11AC568Y7QPZ"
    },
    {
      "product_name": "Vegetable broth",
      "quantity": 1,
      "unit": "carton",
      "recipe_id": "rcp_01M6V9CSD8VZYF11AC568Y7QPZ"
    },
    {
      "product_id": "prd_01M6V9CSWCK03ABGA7BSJA03Q1",
      "quantity": 1,
      "unit": "package",
      "note": "A 4-pack. The filter is due soon."
    },
    {
      "product_name": "Birthday candles"
    }
  ]
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CT7N12CRDXA3RGFEZE6Z

{
  "result": {
    "items": [
      {
        "item_id": "shi_01M6V9CT7NDTGH8Q6235X75TRQ",
        "product_id": "prd_01M6V9CT7NYAYFKM62G2MNMNYY",
        "merged": false
      },
      {
        "item_id": "shi_01M6V9CT7NJAFAZA624X5HJFE7",
        "product_id": "prd_01M6V9CT7NQ4N22J62H1W345SA",
        "merged": false
      },
      {
        "item_id": "shi_01M6V9CT7NV33ZA862550Z1QRH",
        "product_id": "prd_01M6V9CT7NMP3FQ56224YCHPFJ",
        "merged": false
      },
      {
        "item_id": "shi_01M6V9CT7NNVHTKA72V67H9E98",
        "product_id": "prd_01M6V9CSWCK03ABGA7BSJA03Q1",
        "merged": false
      },
      {
        "item_id": "shi_01M6V9CT7N0J83HDD19351XCXM",
        "product_id": "prd_01M6V9CT7N753M4GD1C67KDDS1",
        "merged": false
      }
    ]
  },
  "version": 278
}

For Rigel#

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