Skip to content
Rigel docs
Open Rigel

Change an ongoing service's terms

maintenance.service.update

POST/api/v1/households/{household_id}/commands/maintenance.service.update

  • Command
  • Rigel runs it
  • Applies offline

Sets only the fields given; null clears an optional one. A price needs a currency (currency_required); ends_on before starts_on fails with invalid_range. To stop a service use maintenance.service.end.

Parameters#

Change an ongoing service's terms: 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.

Change an ongoing service's terms: request body fields
FieldDescription
service_idstringrequired

A ongoing service ID, such as osv_01JC0000000000000000000000.

contractor_idstring or nulloptional

Who provides it; null clears it.

namestringoptional

A name as the household says it, 1–120 characters.

at most 120 characters
scopestring or nulloptional

What they do each time.

at most 20,000 characters
cadencestring or nulloptional

How often, in words: every other week, April to October.

at most 500 characters
priceinteger or nulloptional

What it costs per period, in minor units. Needs a currency.

-1,000,000,000 to 1,000,000,000
currencystring or nulloptional

An ISO 4217 currency code, such as USD.

pattern ^[A-Z]{3}$
price_perstring or nulloptional

What the price is for: visit, month, season.

at most 500 characters
starts_onstring (date) or nulloptional

A calendar date, YYYY-MM-DD.

ends_onstring (date) or nulloptional

A calendar date, YYYY-MM-DD.

renews_onstring (date) or nulloptional

When the agreement renews, YYYY-MM-DD.

notesstring or nulloptional

Anything else worth keeping, such as the contract terms.

at most 20,000 characters

Response#

200 The command was applied.

Change an ongoing service's terms: response fields
FieldDescription
resultobjectrequired

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

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.

Change an ongoing service's terms: errors
StatusCodeWhen
400validation_failedA field is missing, misspelled or out of range. details.fields lists each problem.
401unauthenticatedThe request has no valid session.
404contractor_not_foundA contractor that isn't there.
404service_not_foundA service that isn't there.
404not_foundThe household doesn't exist, or you aren't a member of it.
409currency_requiredA price needs a currency.
409invalid_rangeEnding before it starts.
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.

Changes only what's given

Request, curl
curl -X POST 'https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/maintenance.service.update' \
  -H "Cookie: rigel_session=$RIGEL_SESSION" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA' \
  -d '{
  "service_id": "osv_01JC00000000000000000000S1",
  "cadence": "every other week",
  "notes": null,
  "price": 7000,
  "currency": "USD"
}'
Request, TypeScript
const response = await fetch("https://rigel.house/api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/maintenance.service.update", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": "cmd_01JC4N0000AAAAAAAAAAAAAAAA",
    Cookie: `rigel_session=${process.env.RIGEL_SESSION}`,
  },
  body: JSON.stringify({
    service_id: "osv_01JC00000000000000000000S1",
    cadence: "every other week",
    notes: null,
    price: 7000,
    currency: "USD",
  }),
});
const data = await response.json();
Request, HTTP
POST /api/v1/households/hh_01K9BKKP003AHRZ6DMV29GQY5C/commands/maintenance.service.update HTTP/1.1
Host: rigel.house
Cookie: rigel_session=<your session>
Content-Type: application/json
Idempotency-Key: cmd_01JC4N0000AAAAAAAAAAAAAAAA

{
  "service_id": "osv_01JC00000000000000000000S1",
  "cadence": "every other week",
  "notes": null,
  "price": 7000,
  "currency": "USD"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R01GTJNK9S91ESTTHP

{
  "result": {},
  "version": 1
}

A price keeps the currency already there

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

{
  "service_id": "osv_01JC00000000000000000000S1",
  "price": 200
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0KX9G2AX5KQ5HT55F

{
  "result": {},
  "version": 1
}

The contractor can be changed

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

{
  "service_id": "osv_01JC00000000000000000000S1",
  "contractor_id": "ctr_01JC00000000000000000000K1"
}
Response, 200
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01K9D9S2R00XS04T3CHMTDTQQF

{
  "result": {},
  "version": 1
}

A price needs a currency

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

{
  "service_id": "osv_01JC00000000000000000000S1",
  "price": 200
}
Response, 409
HTTP/1.1 409 Conflict
Content-Type: application/json
X-Request-Id: req_01K9D9S2R08TKXASPB61QN79C9

{
  "error": {
    "code": "currency_required",
    "message": "A price needs a currency. No changes were applied.",
    "details": {},
    "recovery": "Read the current state, then send a command that fits it.",
    "request_id": "req_01K9D9S2R08TKXASPB61QN79C9"
  }
}

Ending before it starts

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

{
  "service_id": "osv_01JC00000000000000000000S1",
  "ends_on": "2025-04-01"
}
Response, 409
HTTP/1.1 409 Conflict
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0B0RK1S5KPWCXK0XM

{
  "error": {
    "code": "invalid_range",
    "message": "The service can't end before it starts. No changes were applied.",
    "details": {},
    "recovery": "Read the current state, then send a command that fits it.",
    "request_id": "req_01K9D9S2R0B0RK1S5KPWCXK0XM"
  }
}

A contractor that isn't there

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

{
  "service_id": "osv_01JC00000000000000000000S1",
  "contractor_id": "ctr_01JC00000000000000000000K1"
}
Response, 404
HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0KGAAXE0BV2XGSRWE

{
  "error": {
    "code": "contractor_not_found",
    "message": "That contractor isn't there any more. No changes were applied.",
    "details": {
      "contractor_id": "ctr_01JC00000000000000000000K1"
    },
    "recovery": "Read the current state, then send a command that fits it.",
    "request_id": "req_01K9D9S2R0KGAAXE0BV2XGSRWE"
  }
}

A service that isn't there

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

{
  "service_id": "osv_01JC00000000000000000000S1",
  "name": "x"
}
Response, 404
HTTP/1.1 404 Not Found
Content-Type: application/json
X-Request-Id: req_01K9D9S2R0JXM7QPK6HPZ58DBK

{
  "error": {
    "code": "service_not_found",
    "message": "That service isn't there any more. No changes were applied.",
    "details": {
      "service_id": "osv_01JC00000000000000000000S1"
    },
    "recovery": "Read the current state, then send a command that fits it.",
    "request_id": "req_01K9D9S2R0JXM7QPK6HPZ58DBK"
  }
}

For Rigel#

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