Add several tasks at once
tasks.task.create_many
POST/api/v1/households/{household_id}/commands/tasks.task.create_many
- Command
- Rigel runs it
- Applies offline
Adds up to 100 tasks in one change, such as a project and its subtasks. Later items can point at earlier ones by position, with parent_index and depends_on_indexes. Fails as tasks.task.create does, with the item's index in the error's details.
Parameters#
| Field | Description |
|---|---|
household_idpathstringrequired | The household's ID. |
Idempotency-Keyheaderstringoptional | The command's ID. Reuse it when retrying the same command. |
Request body#
JSON, as application/json.
| Field | Description |
|---|---|
tasksarray of objectsrequired | The tasks, in order. A project comes first, then its subtasks with parent_index 0. |
tasks[].titlestringrequired | What needs doing, as written, 1–500 characters: "Call the pediatrician about Theo's rash". |
tasks[].descriptionstringoptional | More about the task, in Markdown, as written. Up to 20,000 characters. |
tasks[].priorityintegeroptional | 0 Urgent, 1 High, 2 Medium, 3 Low, 4 Someday. Leave out unless someone said how important it is. |
tasks[].assignee_person_idstringoptional | Who's doing it: the person speaking unless someone else was named. Leave out when it's unclear. |
tasks[].due_datestring (date)optional | When it's due, YYYY-MM-DD. Leave out when no date was given. |
tasks[].scheduled_startstring (date-time)optional | When it's planned to be worked on. Give scheduled_end with it. |
tasks[].scheduled_endstring (date-time)optional | When the planned time ends, after scheduled_start. |
tasks[].tagsarray of stringsoptional | Tag names. Existing tags are matched ignoring case; others are created. Reuse existing tags. |
tasks[].linksarray of stringsoptional | Records in other apps this task is about, such as a maintenance task or a document. |
tasks[].parent_task_idstringoptional | An existing task this is a subtask of. |
tasks[].parent_indexintegeroptional | The position (from 0) of an earlier item in this list that this is a subtask of. |
tasks[].depends_on_task_idsarray of stringsoptional | Existing tasks that must be done first. |
tasks[].depends_on_indexesarray of integersoptional | Positions (from 0) of earlier items in this list that must be done first. |
Response#
200 The command was applied.
| Field | Description |
|---|---|
resultobjectrequired | What the command returned, such as the IDs it created. |
result.task_idsarray of stringsrequired | The new tasks, in the order given. |
versionintegerrequired | The household version after the command. |
Errors#
Every error has the same envelope: error.code, error.message, error.details, error.recovery and error.request_id.
| Status | Code | When |
|---|---|---|
400 | validation_failed | A field is missing, misspelled or out of range. details.fields lists each problem. |
401 | unauthenticated | The request has no valid session. |
404 | person_not_found | An error names the item that caused it. |
404 | task_not_found |
|
404 | not_found | The household doesn't exist, or you aren't a member of it. |
409 | idempotency_key_reused | The Idempotency-Key was already used for a different command. |
Examples#
These are real. Each scenario is one of the command's test cases, run on a household when this site was built, and the response is what the API returned.
A project with subtasks and ordered dependencies
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/tasks.task.create_many' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"tasks": [
{
"title": "Redo the playroom",
"tags": [
"home"
],
"assignee_person_id": "per_01JC000000000000000000000B",
"due_date": "2025-12-01"
},
{
"title": "Pick a color",
"parent_index": 0
},
{
"title": "Buy paint",
"parent_index": 0,
"depends_on_indexes": [
1
]
},
{
"title": "Paint the walls",
"parent_index": 0,
"depends_on_indexes": [
1,
2
],
"tags": [
"Home"
]
}
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/tasks.task.create_many", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
tasks: [
{
title: "Redo the playroom",
tags: [
"home",
],
assignee_person_id: "per_01JC000000000000000000000B",
due_date: "2025-12-01",
},
{
title: "Pick a color",
parent_index: 0,
},
{
title: "Buy paint",
parent_index: 0,
depends_on_indexes: [
1,
],
},
{
title: "Paint the walls",
parent_index: 0,
depends_on_indexes: [
1,
2,
],
tags: [
"Home",
],
},
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/tasks.task.create_many HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"tasks": [
{
"title": "Redo the playroom",
"tags": [
"home"
],
"assignee_person_id": "per_01JC000000000000000000000B",
"due_date": "2025-12-01"
},
{
"title": "Pick a color",
"parent_index": 0
},
{
"title": "Buy paint",
"parent_index": 0,
"depends_on_indexes": [
1
]
},
{
"title": "Paint the walls",
"parent_index": 0,
"depends_on_indexes": [
1,
2
],
"tags": [
"Home"
]
}
]
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0Y1GWF2XAM8QE4HZV
{
"result": {
"task_ids": [
"tsk_01JC4N0000MBGE5RJ6Q7V6V6T8",
"tsk_01JC4N0000DBRDZ8K6RGDYEAHV",
"tsk_01JC4N00003JXA4EK6JJ720VZE",
"tsk_01JC4N0000VJDFSE1JR5KF870Q"
]
},
"version": 1
}An item can sit under an existing task and wait on existing tasks
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/tasks.task.create_many' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"tasks": [
{
"title": "Call the electrician",
"parent_task_id": "tsk_01JC000000000000000000000P",
"depends_on_task_ids": [
"tsk_01JC000000000000000000000X"
]
},
{
"title": "Confirm the date",
"parent_index": 0
}
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/tasks.task.create_many", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
tasks: [
{
title: "Call the electrician",
parent_task_id: "tsk_01JC000000000000000000000P",
depends_on_task_ids: [
"tsk_01JC000000000000000000000X",
],
},
{
title: "Confirm the date",
parent_index: 0,
},
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/tasks.task.create_many HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"tasks": [
{
"title": "Call the electrician",
"parent_task_id": "tsk_01JC000000000000000000000P",
"depends_on_task_ids": [
"tsk_01JC000000000000000000000X"
]
},
{
"title": "Confirm the date",
"parent_index": 0
}
]
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0S6YG8GQ9NQX5F5EK
{
"result": {
"task_ids": [
"tsk_01JC4N0000MBGE5RJ6Q7V6V6T8",
"tsk_01JC4N0000H4B98ZJ6CJHSCWXM"
]
},
"version": 1
}One item is just a create
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/tasks.task.create_many' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"tasks": [
{
"title": "Only one"
}
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/tasks.task.create_many", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
tasks: [
{
title: "Only one",
},
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/tasks.task.create_many HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"tasks": [
{
"title": "Only one"
}
]
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0KETJGKZS9M4E5XR5
{
"result": {
"task_ids": [
"tsk_01JC4N0000MBGE5RJ6Q7V6V6T8"
]
},
"version": 1
}An error names the item that caused it
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/tasks.task.create_many' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"tasks": [
{
"title": "Fine"
},
{
"title": "Fine too"
},
{
"title": "Bad",
"assignee_person_id": "per_01JC000000000000000000000Z"
}
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/tasks.task.create_many", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
tasks: [
{
title: "Fine",
},
{
title: "Fine too",
},
{
title: "Bad",
assignee_person_id: "per_01JC000000000000000000000Z",
},
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/tasks.task.create_many HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"tasks": [
{
"title": "Fine"
},
{
"title": "Fine too"
},
{
"title": "Bad",
"assignee_person_id": "per_01JC000000000000000000000Z"
}
]
}HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0VMXEKMXQEJG5A8QV
{
"error": {
"code": "person_not_found",
"message": "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_01K9D9S2R0VMXEKMXQEJG5A8QV"
}
}A missing parent on a later item
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/tasks.task.create_many' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"tasks": [
{
"title": "Fine"
},
{
"title": "Bad",
"parent_task_id": "tsk_01JC000000000000000000000Z"
}
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/tasks.task.create_many", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
tasks: [
{
title: "Fine",
},
{
title: "Bad",
parent_task_id: "tsk_01JC000000000000000000000Z",
},
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/tasks.task.create_many HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"tasks": [
{
"title": "Fine"
},
{
"title": "Bad",
"parent_task_id": "tsk_01JC000000000000000000000Z"
}
]
}HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R039TFA803Q1P9H4VV
{
"error": {
"code": "task_not_found",
"message": "That task isn't there any more. No changes were applied.",
"details": {
"task_id": "tsk_01JC000000000000000000000Z",
"field": "parent_task_id",
"index": 1
},
"recovery": "Read the current state, then send a command that fits it.",
"request_id": "req_01K9D9S2R039TFA803Q1P9H4VV"
}
}A missing dependency
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/tasks.task.create_many' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"tasks": [
{
"title": "Bad",
"depends_on_task_ids": [
"tsk_01JC000000000000000000000Z"
]
}
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/tasks.task.create_many", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
tasks: [
{
title: "Bad",
depends_on_task_ids: [
"tsk_01JC000000000000000000000Z",
],
},
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/tasks.task.create_many HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"tasks": [
{
"title": "Bad",
"depends_on_task_ids": [
"tsk_01JC000000000000000000000Z"
]
}
]
}HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0SX5H0AB18JMY1DEE
{
"error": {
"code": "task_not_found",
"message": "That task isn't there any more. No changes were applied.",
"details": {
"task_id": "tsk_01JC000000000000000000000Z",
"field": "depends_on_task_ids",
"index": 0
},
"recovery": "Read the current state, then send a command that fits it.",
"request_id": "req_01K9D9S2R0SX5H0AB18JMY1DEE"
}
}Add a project and its subtasks
A project is a task with subtasks. Later items point at earlier ones by position: parent_index for the project, depends_on_indexes for what must be done first.
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/tasks.task.create_many' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01M6V9CT2ZWN4SYJ04X0RVFCJB' \
-d '{
"tasks": [
{
"title": "Redo the playroom",
"description": "New paint and shelves before the holidays, so the toys have a home.",
"priority": 2,
"due_date": "2026-12-12",
"tags": [
"house"
]
},
{
"title": "Measure the walls",
"parent_index": 0,
"assignee_person_id": "per_01M6V9CS744BQQH188FS6CXY9W",
"priority": 1,
"due_date": "2026-11-11"
},
{
"title": "Pick a paint color",
"parent_index": 0,
"assignee_person_id": "per_01M6V9CS79TMYHDAM7FTA9ZK3Z"
},
{
"title": "Get a carpenter'\''s quote for built-in shelves",
"parent_index": 0,
"assignee_person_id": "per_01M6V9CS6RX26JK5KVYGRN22D2"
},
{
"title": "Order the shelves",
"parent_index": 0,
"assignee_person_id": "per_01M6V9CS6RX26JK5KVYGRN22D2",
"due_date": "2026-11-21",
"depends_on_indexes": [
1,
3
]
},
{
"title": "Paint the walls",
"parent_index": 0,
"assignee_person_id": "per_01M6V9CS744BQQH188FS6CXY9W",
"depends_on_indexes": [
2
]
},
{
"title": "Assemble the shelves",
"parent_index": 0,
"assignee_person_id": "per_01M6V9CS744BQQH188FS6CXY9W",
"depends_on_indexes": [
4
],
"scheduled_start": "2026-11-14T10:00:00-06:00",
"scheduled_end": "2026-11-14T12:00:00-06:00"
}
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/tasks.task.create_many", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01M6V9CT2ZWN4SYJ04X0RVFCJB",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
tasks: [
{
title: "Redo the playroom",
description: "New paint and shelves before the holidays, so the toys have a home.",
priority: 2,
due_date: "2026-12-12",
tags: [
"house",
],
},
{
title: "Measure the walls",
parent_index: 0,
assignee_person_id: "per_01M6V9CS744BQQH188FS6CXY9W",
priority: 1,
due_date: "2026-11-11",
},
{
title: "Pick a paint color",
parent_index: 0,
assignee_person_id: "per_01M6V9CS79TMYHDAM7FTA9ZK3Z",
},
{
title: "Get a carpenter's quote for built-in shelves",
parent_index: 0,
assignee_person_id: "per_01M6V9CS6RX26JK5KVYGRN22D2",
},
{
title: "Order the shelves",
parent_index: 0,
assignee_person_id: "per_01M6V9CS6RX26JK5KVYGRN22D2",
due_date: "2026-11-21",
depends_on_indexes: [
1,
3,
],
},
{
title: "Paint the walls",
parent_index: 0,
assignee_person_id: "per_01M6V9CS744BQQH188FS6CXY9W",
depends_on_indexes: [
2,
],
},
{
title: "Assemble the shelves",
parent_index: 0,
assignee_person_id: "per_01M6V9CS744BQQH188FS6CXY9W",
depends_on_indexes: [
4,
],
scheduled_start: "2026-11-14T10:00:00-06:00",
scheduled_end: "2026-11-14T12:00:00-06:00",
},
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/tasks.task.create_many HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CT2ZWN4SYJ04X0RVFCJB
{
"tasks": [
{
"title": "Redo the playroom",
"description": "New paint and shelves before the holidays, so the toys have a home.",
"priority": 2,
"due_date": "2026-12-12",
"tags": [
"house"
]
},
{
"title": "Measure the walls",
"parent_index": 0,
"assignee_person_id": "per_01M6V9CS744BQQH188FS6CXY9W",
"priority": 1,
"due_date": "2026-11-11"
},
{
"title": "Pick a paint color",
"parent_index": 0,
"assignee_person_id": "per_01M6V9CS79TMYHDAM7FTA9ZK3Z"
},
{
"title": "Get a carpenter's quote for built-in shelves",
"parent_index": 0,
"assignee_person_id": "per_01M6V9CS6RX26JK5KVYGRN22D2"
},
{
"title": "Order the shelves",
"parent_index": 0,
"assignee_person_id": "per_01M6V9CS6RX26JK5KVYGRN22D2",
"due_date": "2026-11-21",
"depends_on_indexes": [
1,
3
]
},
{
"title": "Paint the walls",
"parent_index": 0,
"assignee_person_id": "per_01M6V9CS744BQQH188FS6CXY9W",
"depends_on_indexes": [
2
]
},
{
"title": "Assemble the shelves",
"parent_index": 0,
"assignee_person_id": "per_01M6V9CS744BQQH188FS6CXY9W",
"depends_on_indexes": [
4
],
"scheduled_start": "2026-11-14T10:00:00-06:00",
"scheduled_end": "2026-11-14T12:00:00-06:00"
}
]
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CT2Z0T3D61E4NA68G8C3
{
"result": {
"task_ids": [
"tsk_01M6V9CT2Z01QVT17DRMSXTW4W",
"tsk_01M6V9CT2ZX70MX87DDSFGCJFZ",
"tsk_01M6V9CT2Z2YSDMW6DEKRSS7RW",
"tsk_01M6V9CT2ZFNJNSQ7DKS5SFHHS",
"tsk_01M6V9CT2ZPDDMRBRQ0SBNP1G6",
"tsk_01M6V9CT2ZK0Q2GZQQNSQY33QB",
"tsk_01M6V9CT2Z2YZR1SSR7XB5H7RF"
]
},
"version": 235
}For Rigel#
Rigel's tool for this command is tasks_task_create_many. Rigel runs this on its own, then says what it did. The agent guide has the rest.