Start a project
maintenance.project.start
POST/api/v1/households/{household_id}/commands/maintenance.project.start
- Command
- Rigel runs it
- Applies offline
Starts a repair, improvement or other multi-step job. kind defaults to repair and status to planning. asset_ids and issue_ids link the items it concerns and the problems it covers (a problem belongs to at most one project, so linking moves it here). All linked records must be at the project's property (different_property). A budget needs a currency (currency_required).
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 |
|---|---|
property_idstringoptional | Which property. Leave it out when the household has one property (it's made on first use); with several, give it, or the command is rejected with property_required. |
titlestringrequired | A short title, up to 200 characters. |
goalstringoptional | What the project is meant to achieve. |
kindone of: repair, improvement, maintenance, otheroptional | repair (the default), improvement, maintenance or other. |
statusone of: planning, active, on_hold, done, cancelledoptional | Defaults to planning. |
started_onstring (date)optional | A calendar date, YYYY-MM-DD. |
budgetintegeroptional | What the project is expected to cost, in minor units. Needs a currency. |
currencystringoptional | An ISO 4217 currency code, such as USD. |
asset_idsarray of stringsoptional | Items the project concerns. |
issue_idsarray of stringsoptional | Problems the project covers. |
notesstringoptional | Anything else worth keeping. |
Response#
200 The command was applied.
| Field | Description |
|---|---|
resultobjectrequired | What the command returned, such as the IDs it created. |
result.project_idstringrequired | The new project. |
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 | asset_not_found | An item that isn't there. |
404 | not_found | The household doesn't exist, or you aren't a member of it. |
409 | currency_required | A budget needs a currency. |
409 | different_property |
|
409 | property_required | Several properties need one named. |
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.
Defaults to a repair in planning
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/maintenance.project.start' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"property_id": "prp_01JC00000000000000000000P1",
"title": "Fix the fence"
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/maintenance.project.start", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
property_id: "prp_01JC00000000000000000000P1",
title: "Fix the fence",
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/maintenance.project.start HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"property_id": "prp_01JC00000000000000000000P1",
"title": "Fix the fence"
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0C5HJ0Y5C0AFNZFTC
{
"result": {
"project_id": "mpj_01JC4N0000MBGE5RJ6Q7V6V6T8"
},
"version": 1
}Links items and problems, and takes the property from them
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/maintenance.project.start' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"title": "Replace the furnace",
"goal": "Warm house",
"kind": "improvement",
"status": "active",
"started_on": "2025-11-01",
"budget": 850000,
"currency": "USD",
"asset_ids": [
"ast_01JC00000000000000000000A1",
"ast_01JC00000000000000000000A2"
],
"issue_ids": [
"iss_01JC00000000000000000000Q1",
"iss_01JC00000000000000000000Q2"
],
"notes": "Get three quotes"
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/maintenance.project.start", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
title: "Replace the furnace",
goal: "Warm house",
kind: "improvement",
status: "active",
started_on: "2025-11-01",
budget: 850000,
currency: "USD",
asset_ids: [
"ast_01JC00000000000000000000A1",
"ast_01JC00000000000000000000A2",
],
issue_ids: [
"iss_01JC00000000000000000000Q1",
"iss_01JC00000000000000000000Q2",
],
notes: "Get three quotes",
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/maintenance.project.start HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"title": "Replace the furnace",
"goal": "Warm house",
"kind": "improvement",
"status": "active",
"started_on": "2025-11-01",
"budget": 850000,
"currency": "USD",
"asset_ids": [
"ast_01JC00000000000000000000A1",
"ast_01JC00000000000000000000A2"
],
"issue_ids": [
"iss_01JC00000000000000000000Q1",
"iss_01JC00000000000000000000Q2"
],
"notes": "Get three quotes"
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0GSJA8PN10STSPW9A
{
"result": {
"project_id": "mpj_01JC4N0000MBGE5RJ6Q7V6V6T8"
},
"version": 1
}A budget needs a currency
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/maintenance.project.start' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"property_id": "prp_01JC00000000000000000000P1",
"title": "x",
"budget": 100
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/maintenance.project.start", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
property_id: "prp_01JC00000000000000000000P1",
title: "x",
budget: 100,
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/maintenance.project.start HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"property_id": "prp_01JC00000000000000000000P1",
"title": "x",
"budget": 100
}HTTP/1.1 409 Conflict
Content-Type: application/json
X-Request-Id: req_01K9D9S2R01ZZJHPF19TTRAM7R
{
"error": {
"code": "currency_required",
"message": "A budget needs a currency. No changes were applied.",
"details": {},
"recovery": "Read the current state, then send a command that fits it.",
"request_id": "req_01K9D9S2R01ZZJHPF19TTRAM7R"
}
}An item at another property
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/maintenance.project.start' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"property_id": "prp_01JC00000000000000000000P1",
"title": "x",
"asset_ids": [
"ast_01JC00000000000000000000A2"
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/maintenance.project.start", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
property_id: "prp_01JC00000000000000000000P1",
title: "x",
asset_ids: [
"ast_01JC00000000000000000000A2",
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/maintenance.project.start HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"property_id": "prp_01JC00000000000000000000P1",
"title": "x",
"asset_ids": [
"ast_01JC00000000000000000000A2"
]
}HTTP/1.1 409 Conflict
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0AT1RTDXJPAN5DSRR
{
"error": {
"code": "different_property",
"message": "That item is at a different property. No changes were applied.",
"details": {
"property_id": "prp_01JC00000000000000000000P2"
},
"recovery": "Read the current state, then send a command that fits it.",
"request_id": "req_01K9D9S2R0AT1RTDXJPAN5DSRR"
}
}A problem at another property
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/maintenance.project.start' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"property_id": "prp_01JC00000000000000000000P1",
"title": "x",
"issue_ids": [
"iss_01JC00000000000000000000Q2"
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/maintenance.project.start", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
property_id: "prp_01JC00000000000000000000P1",
title: "x",
issue_ids: [
"iss_01JC00000000000000000000Q2",
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/maintenance.project.start HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"property_id": "prp_01JC00000000000000000000P1",
"title": "x",
"issue_ids": [
"iss_01JC00000000000000000000Q2"
]
}HTTP/1.1 409 Conflict
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0MZ386668FA1JFX9S
{
"error": {
"code": "different_property",
"message": "That problem is at a different property. No changes were applied.",
"details": {
"property_id": "prp_01JC00000000000000000000P2"
},
"recovery": "Read the current state, then send a command that fits it.",
"request_id": "req_01K9D9S2R0MZ386668FA1JFX9S"
}
}An item that isn't there
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/maintenance.project.start' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"title": "x",
"asset_ids": [
"ast_01JC00000000000000000000AX"
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/maintenance.project.start", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
title: "x",
asset_ids: [
"ast_01JC00000000000000000000AX",
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/maintenance.project.start HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"title": "x",
"asset_ids": [
"ast_01JC00000000000000000000AX"
]
}HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0A6MCMCZY2YZ8PK3V
{
"error": {
"code": "asset_not_found",
"message": "That item isn't in the house records any more. No changes were applied.",
"details": {
"asset_id": "ast_01JC00000000000000000000AX"
},
"recovery": "Read the current state, then send a command that fits it.",
"request_id": "req_01K9D9S2R0A6MCMCZY2YZ8PK3V"
}
}Several properties need one named
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/maintenance.project.start' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
-d '{
"title": "x"
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/maintenance.project.start", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
title: "x",
}),
});
const data = await response.json();POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/maintenance.project.start HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA
{
"title": "x"
}HTTP/1.1 409 Conflict
Content-Type: application/json
X-Request-Id: req_01K9D9S2R049NTXVGC84FKFP7J
{
"error": {
"code": "property_required",
"message": "This household has more than one property. Say which one. No changes were applied.",
"details": {},
"recovery": "Read the current state, then send a command that fits it.",
"request_id": "req_01K9D9S2R049NTXVGC84FKFP7J"
}
}Start a project
issue_ids link the problems it covers. A problem belongs to one project.
curl -X POST 'https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/maintenance.project.start' \
-H "Cookie: rigel_session=$RIGEL_SESSION" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: cmd_01M6V9CSZCC6D72WAN8JECXWDG' \
-d '{
"title": "Stop the basement window leak",
"goal": "Dry basement walls before the spring rains.",
"kind": "repair",
"status": "active",
"started_on": "2026-10-19",
"budget": 150000,
"currency": "USD",
"issue_ids": [
"iss_01M6V9CSYFR1X4V2X9M3HXT85F"
]
}'const response = await fetch("https://rigel.house/api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/maintenance.project.start", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": "cmd_01M6V9CSZCC6D72WAN8JECXWDG",
Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
},
body: JSON.stringify({
title: "Stop the basement window leak",
goal: "Dry basement walls before the spring rains.",
kind: "repair",
status: "active",
started_on: "2026-10-19",
budget: 150000,
currency: "USD",
issue_ids: [
"iss_01M6V9CSYFR1X4V2X9M3HXT85F",
],
}),
});
const data = await response.json();POST /api/v1/households/hh_01M6V9CS6GGVFCY7NAS8ZTQV95/commands/maintenance.project.start HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01M6V9CSZCC6D72WAN8JECXWDG
{
"title": "Stop the basement window leak",
"goal": "Dry basement walls before the spring rains.",
"kind": "repair",
"status": "active",
"started_on": "2026-10-19",
"budget": 150000,
"currency": "USD",
"issue_ids": [
"iss_01M6V9CSYFR1X4V2X9M3HXT85F"
]
}HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01M6V9CSZCCP0N0FFNX6W6YAYA
{
"result": {
"project_id": "mpj_01M6V9CSZC4PE99PPRAQ7ASEZQ"
},
"version": 221
}For Rigel#
Rigel's tool for this command is maintenance_project_start. Rigel runs this on its own, then says what it did. The agent guide has the rest.