> For the complete documentation index, see [llms.txt](https://developers.share.inc/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.share.inc/api-reference/installations.md).

# Installations

Installation lifecycle (per subscription): create, list, get, update notes, cancel. Status transitions are event-driven — only `notes` is mutable through `PATCH`. The Subscriber Lifecycle guide and `installations-architecture.md` cover gate semantics (D2/D19/D30) and the relationship to one-time charges.

## List installations

> Returns the paginated set of installations owned by the authenticated provider, with optional filtering by status, subscriber, subscription, and kind.

```json
{"openapi":"3.0.0","info":{"title":"Share API","version":"1.0"},"tags":[{"description":"Installation lifecycle (per subscription): create, list, get, update notes, cancel. Status transitions are event-driven — only `notes` is mutable through `PATCH`. The Subscriber Lifecycle guide and `installations-architecture.md` cover gate semantics (D2/D19/D30) and the relationship to one-time charges.","name":"Installations"}],"security":[{"X-Access-Secret":[]},{"X-Access-Id":[]}],"components":{"securitySchemes":{"X-Access-Secret":{"description":"Provider Access Secret Key (JWT)","in":"header","name":"X-Access-Secret","type":"apiKey"},"X-Access-Id":{"description":"Provider Access ID","in":"header","name":"X-Access-Id","type":"apiKey"}},"schemas":{"ApiResponseDto":{"properties":{},"type":"object"},"InstallationResponseDto":{"properties":{"activatedAt":{"format":"date-time","type":"object"},"cancellationReason":{"type":"object"},"cancelledAt":{"format":"date-time","type":"object"},"cpeId":{"format":"uuid","type":"object"},"createdAt":{"format":"date-time","type":"string"},"externalProjectId":{"type":"object"},"externalSystem":{"type":"object"},"externalTaskId":{"type":"object"},"firstBillingCycleId":{"format":"uuid","type":"object"},"firstCyclePaidAt":{"format":"date-time","type":"object"},"id":{"format":"uuid","type":"string"},"installedAt":{"format":"date-time","type":"object"},"isFree":{"type":"boolean"},"kind":{"enum":["INITIAL","REPLACEMENT","RELOCATION"],"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"notes":{"type":"object"},"oneTimeChargeId":{"description":"Identifier of the linked one-time installation charge. Null when the installation is free, and until the charge has been created on the paid path.","format":"uuid","type":"object"},"status":{"enum":["PENDING_PAYMENT","AWAITING_INSTALLATION","AWAITING_CYCLE_PAYMENT","ACTIVATED","CANCELLED","ABANDONED","ARCHIVED"],"type":"string"},"subscriberId":{"format":"uuid","type":"string"},"subscriptionId":{"format":"uuid","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","subscriberId","subscriptionId","kind","status","isFree","createdAt","updatedAt"],"type":"object"}}},"paths":{"/v1/installations":{"get":{"description":"Returns the paginated set of installations owned by the authenticated provider, with optional filtering by status, subscriber, subscription, and kind.","operationId":"InstallationsController_listInstallations_v1","parameters":[{"description":"1-based page number. Defaults to 1 when omitted.","in":"query","name":"page","required":false,"schema":{"default":1,"minimum":1,"type":"number"}},{"description":"Number of items per page. Capped at 100 server-side. Defaults to 20 when omitted.","in":"query","name":"limit","required":false,"schema":{"default":20,"maximum":100,"minimum":1,"type":"number"}},{"description":"Filter by `Installation.status`. Omit to include every status.","in":"query","name":"status","required":false,"schema":{"enum":["PENDING_PAYMENT","AWAITING_INSTALLATION","AWAITING_CYCLE_PAYMENT","ACTIVATED","CANCELLED","ABANDONED","ARCHIVED"],"type":"string"}},{"description":"Filter to installations whose subscription is owned by this subscriber.","in":"query","name":"subscriberId","required":false,"schema":{"format":"uuid","type":"string"}},{"description":"Filter to installations linked to this subscription.","in":"query","name":"subscriptionId","required":false,"schema":{"format":"uuid","type":"string"}},{"description":"Filter by `Installation.kind` (`INITIAL`, `REPLACEMENT`, `RELOCATION`).","in":"query","name":"kind","required":false,"schema":{"enum":["INITIAL","REPLACEMENT","RELOCATION"],"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiResponseDto"},{"properties":{"data":{"items":{"$ref":"#/components/schemas/InstallationResponseDto"},"type":"array"},"success":{"type":"boolean"}}}]}}},"description":"Paginated list of installations."},"400":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"rejectionReasons":{"items":{"properties":{"code":{"type":"string"},"field":{"type":"string"},"message":{"type":"string"}},"type":"object"},"type":"array"},"success":{"type":"boolean"}}}}},"description":"Validation failed"},"401":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Unauthorized — missing or invalid credentials"},"403":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Forbidden — insufficient permissions"},"404":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Resource not found"},"408":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Request timeout"},"500":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Internal server error"}},"summary":"List installations","tags":["Installations"]}}}}
```

## Create an installation

> Creates an installation record scoped to the supplied \`subscriptionId\`. When \`free=false\` (default) a linked one-time installation charge is created and must be settled before the installation can be dispatched. When \`free=true\` no charge is created and the installation moves straight to \`AWAITING\_INSTALLATION\`.\
> \
> Only one non-terminal installation may exist per subscription — a 409 is returned otherwise.\
> \
> Idempotency: supply an \`Idempotency-Key\` (UUID) header. Repeat requests with the same key for the same subscription return the original installation without re-emitting events.\
> \
> \*\*Error codes:\*\* \`installation\_already\_active\` (409), \`subscription\_missing\_demarcation\_point\` (400). See the \[Error codes]\(../errors/error-codes.md) reference.

```json
{"openapi":"3.0.0","info":{"title":"Share API","version":"1.0"},"tags":[{"description":"Installation lifecycle (per subscription): create, list, get, update notes, cancel. Status transitions are event-driven — only `notes` is mutable through `PATCH`. The Subscriber Lifecycle guide and `installations-architecture.md` cover gate semantics (D2/D19/D30) and the relationship to one-time charges.","name":"Installations"}],"security":[{"X-Access-Secret":[]},{"X-Access-Id":[]}],"components":{"securitySchemes":{"X-Access-Secret":{"description":"Provider Access Secret Key (JWT)","in":"header","name":"X-Access-Secret","type":"apiKey"},"X-Access-Id":{"description":"Provider Access ID","in":"header","name":"X-Access-Id","type":"apiKey"}},"schemas":{"CreateInstallationRequestDto":{"properties":{"fee":{"description":"Installation fee amount. Defaults to the plan-level installation fee when omitted. Ignored when `free=true`.","type":"number"},"free":{"default":false,"description":"When `true`, no one-time installation charge is created. The installation moves straight to `AWAITING_INSTALLATION` and the outbound provisioning jobs fire immediately.","type":"boolean"},"kind":{"default":"INITIAL","description":"Installation kind. Defaults to `INITIAL`. Use `REPLACEMENT` for a CPE swap, or `RELOCATION` for a subscriber move — for a relocation, update the parent subscription's `demarcationPointId` first via `PATCH /v1/subscriptions/:id`.","enum":["INITIAL","REPLACEMENT","RELOCATION"],"type":"string"},"notes":{"description":"Free-text operator notes (up to 1000 characters).","maxLength":1000,"type":"string"},"subscriptionId":{"description":"Subscription the installation belongs to (provider-scoped).","format":"uuid","type":"string"}},"required":["subscriptionId"],"type":"object"},"ApiResponseDto":{"properties":{},"type":"object"},"InstallationResponseDto":{"properties":{"activatedAt":{"format":"date-time","type":"object"},"cancellationReason":{"type":"object"},"cancelledAt":{"format":"date-time","type":"object"},"cpeId":{"format":"uuid","type":"object"},"createdAt":{"format":"date-time","type":"string"},"externalProjectId":{"type":"object"},"externalSystem":{"type":"object"},"externalTaskId":{"type":"object"},"firstBillingCycleId":{"format":"uuid","type":"object"},"firstCyclePaidAt":{"format":"date-time","type":"object"},"id":{"format":"uuid","type":"string"},"installedAt":{"format":"date-time","type":"object"},"isFree":{"type":"boolean"},"kind":{"enum":["INITIAL","REPLACEMENT","RELOCATION"],"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"notes":{"type":"object"},"oneTimeChargeId":{"description":"Identifier of the linked one-time installation charge. Null when the installation is free, and until the charge has been created on the paid path.","format":"uuid","type":"object"},"status":{"enum":["PENDING_PAYMENT","AWAITING_INSTALLATION","AWAITING_CYCLE_PAYMENT","ACTIVATED","CANCELLED","ABANDONED","ARCHIVED"],"type":"string"},"subscriberId":{"format":"uuid","type":"string"},"subscriptionId":{"format":"uuid","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","subscriberId","subscriptionId","kind","status","isFree","createdAt","updatedAt"],"type":"object"}}},"paths":{"/v1/installations":{"post":{"description":"Creates an installation record scoped to the supplied `subscriptionId`. When `free=false` (default) a linked one-time installation charge is created and must be settled before the installation can be dispatched. When `free=true` no charge is created and the installation moves straight to `AWAITING_INSTALLATION`.\n\nOnly one non-terminal installation may exist per subscription — a 409 is returned otherwise.\n\nIdempotency: supply an `Idempotency-Key` (UUID) header. Repeat requests with the same key for the same subscription return the original installation without re-emitting events.\n\n**Error codes:** `installation_already_active` (409), `subscription_missing_demarcation_point` (400). See the [Error codes](../errors/error-codes.md) reference.","operationId":"InstallationsController_createInstallation_v1","parameters":[{"description":"Client-generated UUID. Duplicate POSTs with the same key for the same target resource return the original response without re-emitting downstream events. Keep ≤ 255 chars.\n\nExample: `9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d`.","in":"header","name":"idempotency-key","required":false,"schema":{"format":"uuid","maxLength":255,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInstallationRequestDto"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiResponseDto"},{"properties":{"data":{"$ref":"#/components/schemas/InstallationResponseDto"},"success":{"type":"boolean"}}}]}}},"description":"The newly created installation."},"400":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"rejectionReasons":{"items":{"properties":{"code":{"type":"string"},"field":{"type":"string"},"message":{"type":"string"}},"type":"object"},"type":"array"},"success":{"type":"boolean"}}}}},"description":"Validation failed"},"401":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Unauthorized — missing or invalid credentials"},"403":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Forbidden — insufficient permissions"},"404":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Resource not found"},"408":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Request timeout"},"500":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Internal server error"}},"summary":"Create an installation","tags":["Installations"]}}}}
```

## Get an installation

> Returns a single installation owned by the authenticated provider.

```json
{"openapi":"3.0.0","info":{"title":"Share API","version":"1.0"},"tags":[{"description":"Installation lifecycle (per subscription): create, list, get, update notes, cancel. Status transitions are event-driven — only `notes` is mutable through `PATCH`. The Subscriber Lifecycle guide and `installations-architecture.md` cover gate semantics (D2/D19/D30) and the relationship to one-time charges.","name":"Installations"}],"security":[{"X-Access-Secret":[]},{"X-Access-Id":[]}],"components":{"securitySchemes":{"X-Access-Secret":{"description":"Provider Access Secret Key (JWT)","in":"header","name":"X-Access-Secret","type":"apiKey"},"X-Access-Id":{"description":"Provider Access ID","in":"header","name":"X-Access-Id","type":"apiKey"}},"schemas":{"ApiResponseDto":{"properties":{},"type":"object"},"InstallationResponseDto":{"properties":{"activatedAt":{"format":"date-time","type":"object"},"cancellationReason":{"type":"object"},"cancelledAt":{"format":"date-time","type":"object"},"cpeId":{"format":"uuid","type":"object"},"createdAt":{"format":"date-time","type":"string"},"externalProjectId":{"type":"object"},"externalSystem":{"type":"object"},"externalTaskId":{"type":"object"},"firstBillingCycleId":{"format":"uuid","type":"object"},"firstCyclePaidAt":{"format":"date-time","type":"object"},"id":{"format":"uuid","type":"string"},"installedAt":{"format":"date-time","type":"object"},"isFree":{"type":"boolean"},"kind":{"enum":["INITIAL","REPLACEMENT","RELOCATION"],"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"notes":{"type":"object"},"oneTimeChargeId":{"description":"Identifier of the linked one-time installation charge. Null when the installation is free, and until the charge has been created on the paid path.","format":"uuid","type":"object"},"status":{"enum":["PENDING_PAYMENT","AWAITING_INSTALLATION","AWAITING_CYCLE_PAYMENT","ACTIVATED","CANCELLED","ABANDONED","ARCHIVED"],"type":"string"},"subscriberId":{"format":"uuid","type":"string"},"subscriptionId":{"format":"uuid","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","subscriberId","subscriptionId","kind","status","isFree","createdAt","updatedAt"],"type":"object"}}},"paths":{"/v1/installations/{id}":{"get":{"description":"Returns a single installation owned by the authenticated provider.","operationId":"InstallationsController_getInstallation_v1","parameters":[{"description":"Installation identifier (UUID).","in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiResponseDto"},{"properties":{"data":{"$ref":"#/components/schemas/InstallationResponseDto"},"success":{"type":"boolean"}}}]}}},"description":"The requested installation."},"400":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"rejectionReasons":{"items":{"properties":{"code":{"type":"string"},"field":{"type":"string"},"message":{"type":"string"}},"type":"object"},"type":"array"},"success":{"type":"boolean"}}}}},"description":"Validation failed"},"401":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Unauthorized — missing or invalid credentials"},"403":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Forbidden — insufficient permissions"},"404":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Resource not found"},"408":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Request timeout"},"500":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Internal server error"}},"summary":"Get an installation","tags":["Installations"]}}}}
```

## Update an installation

> Updates the writable fields on an installation. Only \`notes\` is mutable here — status transitions are event-driven, and demarcation-point changes are performed via \`PATCH /v1/subscriptions/:id\`.

```json
{"openapi":"3.0.0","info":{"title":"Share API","version":"1.0"},"tags":[{"description":"Installation lifecycle (per subscription): create, list, get, update notes, cancel. Status transitions are event-driven — only `notes` is mutable through `PATCH`. The Subscriber Lifecycle guide and `installations-architecture.md` cover gate semantics (D2/D19/D30) and the relationship to one-time charges.","name":"Installations"}],"security":[{"X-Access-Secret":[]},{"X-Access-Id":[]}],"components":{"securitySchemes":{"X-Access-Secret":{"description":"Provider Access Secret Key (JWT)","in":"header","name":"X-Access-Secret","type":"apiKey"},"X-Access-Id":{"description":"Provider Access ID","in":"header","name":"X-Access-Id","type":"apiKey"}},"schemas":{"UpdateInstallationRequestDto":{"properties":{"notes":{"description":"Free-text operator notes (up to 1000 characters).","maxLength":1000,"type":"string"}},"type":"object"},"ApiResponseDto":{"properties":{},"type":"object"},"InstallationResponseDto":{"properties":{"activatedAt":{"format":"date-time","type":"object"},"cancellationReason":{"type":"object"},"cancelledAt":{"format":"date-time","type":"object"},"cpeId":{"format":"uuid","type":"object"},"createdAt":{"format":"date-time","type":"string"},"externalProjectId":{"type":"object"},"externalSystem":{"type":"object"},"externalTaskId":{"type":"object"},"firstBillingCycleId":{"format":"uuid","type":"object"},"firstCyclePaidAt":{"format":"date-time","type":"object"},"id":{"format":"uuid","type":"string"},"installedAt":{"format":"date-time","type":"object"},"isFree":{"type":"boolean"},"kind":{"enum":["INITIAL","REPLACEMENT","RELOCATION"],"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"notes":{"type":"object"},"oneTimeChargeId":{"description":"Identifier of the linked one-time installation charge. Null when the installation is free, and until the charge has been created on the paid path.","format":"uuid","type":"object"},"status":{"enum":["PENDING_PAYMENT","AWAITING_INSTALLATION","AWAITING_CYCLE_PAYMENT","ACTIVATED","CANCELLED","ABANDONED","ARCHIVED"],"type":"string"},"subscriberId":{"format":"uuid","type":"string"},"subscriptionId":{"format":"uuid","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","subscriberId","subscriptionId","kind","status","isFree","createdAt","updatedAt"],"type":"object"}}},"paths":{"/v1/installations/{id}":{"patch":{"description":"Updates the writable fields on an installation. Only `notes` is mutable here — status transitions are event-driven, and demarcation-point changes are performed via `PATCH /v1/subscriptions/:id`.","operationId":"InstallationsController_updateInstallation_v1","parameters":[{"description":"Installation identifier (UUID).","in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateInstallationRequestDto"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiResponseDto"},{"properties":{"data":{"$ref":"#/components/schemas/InstallationResponseDto"},"success":{"type":"boolean"}}}]}}},"description":"The updated installation."},"400":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"rejectionReasons":{"items":{"properties":{"code":{"type":"string"},"field":{"type":"string"},"message":{"type":"string"}},"type":"object"},"type":"array"},"success":{"type":"boolean"}}}}},"description":"Validation failed"},"401":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Unauthorized — missing or invalid credentials"},"403":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Forbidden — insufficient permissions"},"404":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Resource not found"},"408":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Request timeout"},"500":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Internal server error"}},"summary":"Update an installation","tags":["Installations"]}}}}
```

## Cancel an installation

> Transitions the installation to \`CANCELLED\` and cascades any linked PENDING installation charge to \`CANCELLED\`. Already paid, waived, or refunded charges are left untouched — refunds remain a manual operation. External-system cancellations (e.g. partner BSS task closure, RADIUS credential cleanup) are dispatched through the durable outbound queue.\
> \
> \*\*Error codes:\*\* \`installation\_terminal\` (400) — the installation is already in a terminal state (CANCELLED / COMPLETED). See the \[Error codes]\(../errors/error-codes.md) reference.

```json
{"openapi":"3.0.0","info":{"title":"Share API","version":"1.0"},"tags":[{"description":"Installation lifecycle (per subscription): create, list, get, update notes, cancel. Status transitions are event-driven — only `notes` is mutable through `PATCH`. The Subscriber Lifecycle guide and `installations-architecture.md` cover gate semantics (D2/D19/D30) and the relationship to one-time charges.","name":"Installations"}],"security":[{"X-Access-Secret":[]},{"X-Access-Id":[]}],"components":{"securitySchemes":{"X-Access-Secret":{"description":"Provider Access Secret Key (JWT)","in":"header","name":"X-Access-Secret","type":"apiKey"},"X-Access-Id":{"description":"Provider Access ID","in":"header","name":"X-Access-Id","type":"apiKey"}},"schemas":{"CancelInstallationRequestDto":{"properties":{"cancellationReason":{"description":"Free-text reason for the cancellation. Persisted on the installation record and surfaced in audit logs and partner webhooks.","maxLength":1000,"type":"string"}},"type":"object"},"ApiResponseDto":{"properties":{},"type":"object"},"InstallationResponseDto":{"properties":{"activatedAt":{"format":"date-time","type":"object"},"cancellationReason":{"type":"object"},"cancelledAt":{"format":"date-time","type":"object"},"cpeId":{"format":"uuid","type":"object"},"createdAt":{"format":"date-time","type":"string"},"externalProjectId":{"type":"object"},"externalSystem":{"type":"object"},"externalTaskId":{"type":"object"},"firstBillingCycleId":{"format":"uuid","type":"object"},"firstCyclePaidAt":{"format":"date-time","type":"object"},"id":{"format":"uuid","type":"string"},"installedAt":{"format":"date-time","type":"object"},"isFree":{"type":"boolean"},"kind":{"enum":["INITIAL","REPLACEMENT","RELOCATION"],"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"notes":{"type":"object"},"oneTimeChargeId":{"description":"Identifier of the linked one-time installation charge. Null when the installation is free, and until the charge has been created on the paid path.","format":"uuid","type":"object"},"status":{"enum":["PENDING_PAYMENT","AWAITING_INSTALLATION","AWAITING_CYCLE_PAYMENT","ACTIVATED","CANCELLED","ABANDONED","ARCHIVED"],"type":"string"},"subscriberId":{"format":"uuid","type":"string"},"subscriptionId":{"format":"uuid","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","subscriberId","subscriptionId","kind","status","isFree","createdAt","updatedAt"],"type":"object"}}},"paths":{"/v1/installations/{id}/cancel":{"post":{"description":"Transitions the installation to `CANCELLED` and cascades any linked PENDING installation charge to `CANCELLED`. Already paid, waived, or refunded charges are left untouched — refunds remain a manual operation. External-system cancellations (e.g. partner BSS task closure, RADIUS credential cleanup) are dispatched through the durable outbound queue.\n\n**Error codes:** `installation_terminal` (400) — the installation is already in a terminal state (CANCELLED / COMPLETED). See the [Error codes](../errors/error-codes.md) reference.","operationId":"InstallationsController_cancelInstallation_v1","parameters":[{"description":"Installation identifier (UUID).","in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelInstallationRequestDto"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiResponseDto"},{"properties":{"data":{"$ref":"#/components/schemas/InstallationResponseDto"},"success":{"type":"boolean"}}}]}}},"description":"The cancelled installation."},"400":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"rejectionReasons":{"items":{"properties":{"code":{"type":"string"},"field":{"type":"string"},"message":{"type":"string"}},"type":"object"},"type":"array"},"success":{"type":"boolean"}}}}},"description":"Validation failed"},"401":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Unauthorized — missing or invalid credentials"},"403":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Forbidden — insufficient permissions"},"404":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Resource not found"},"408":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Request timeout"},"500":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Internal server error"}},"summary":"Cancel an installation","tags":["Installations"]}}}}
```

## Mark an installation as done (Gate B)

> Partner-facing Gate B satisfaction — stamps \`installedAt\` and advances the installation state machine, mirroring the Splynx \`SchedulingTask\` Done webhook path. Idempotent: a second call returns the current state without re-firing side effects.\
> \
> When Gate C (\`firstCyclePaidAt\`) is already set the installation transitions to \`ACTIVATED\` and billing activation is triggered. When Gate C is not yet met and the installation is \`AWAITING\_INSTALLATION\`, it transitions to \`AWAITING\_CYCLE\_PAYMENT\`.\
> \
> \*\*Error codes:\*\* \`installation\_fee\_not\_paid\` (400) — the installation fee has not been settled yet (Gate A must be cleared first). \`installation\_terminal\` (400) — the installation is already in a terminal state (\`CANCELLED\` / \`ABANDONED\`). See the \[Error codes]\(../errors/error-codes.md) reference.

```json
{"openapi":"3.0.0","info":{"title":"Share API","version":"1.0"},"tags":[{"description":"Installation lifecycle (per subscription): create, list, get, update notes, cancel. Status transitions are event-driven — only `notes` is mutable through `PATCH`. The Subscriber Lifecycle guide and `installations-architecture.md` cover gate semantics (D2/D19/D30) and the relationship to one-time charges.","name":"Installations"}],"security":[{"X-Access-Secret":[]},{"X-Access-Id":[]}],"components":{"securitySchemes":{"X-Access-Secret":{"description":"Provider Access Secret Key (JWT)","in":"header","name":"X-Access-Secret","type":"apiKey"},"X-Access-Id":{"description":"Provider Access ID","in":"header","name":"X-Access-Id","type":"apiKey"}},"schemas":{"ApiResponseDto":{"properties":{},"type":"object"},"InstallationResponseDto":{"properties":{"activatedAt":{"format":"date-time","type":"object"},"cancellationReason":{"type":"object"},"cancelledAt":{"format":"date-time","type":"object"},"cpeId":{"format":"uuid","type":"object"},"createdAt":{"format":"date-time","type":"string"},"externalProjectId":{"type":"object"},"externalSystem":{"type":"object"},"externalTaskId":{"type":"object"},"firstBillingCycleId":{"format":"uuid","type":"object"},"firstCyclePaidAt":{"format":"date-time","type":"object"},"id":{"format":"uuid","type":"string"},"installedAt":{"format":"date-time","type":"object"},"isFree":{"type":"boolean"},"kind":{"enum":["INITIAL","REPLACEMENT","RELOCATION"],"type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"notes":{"type":"object"},"oneTimeChargeId":{"description":"Identifier of the linked one-time installation charge. Null when the installation is free, and until the charge has been created on the paid path.","format":"uuid","type":"object"},"status":{"enum":["PENDING_PAYMENT","AWAITING_INSTALLATION","AWAITING_CYCLE_PAYMENT","ACTIVATED","CANCELLED","ABANDONED","ARCHIVED"],"type":"string"},"subscriberId":{"format":"uuid","type":"string"},"subscriptionId":{"format":"uuid","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","subscriberId","subscriptionId","kind","status","isFree","createdAt","updatedAt"],"type":"object"}}},"paths":{"/v1/installations/{id}/mark-done":{"post":{"description":"Partner-facing Gate B satisfaction — stamps `installedAt` and advances the installation state machine, mirroring the Splynx `SchedulingTask` Done webhook path. Idempotent: a second call returns the current state without re-firing side effects.\n\nWhen Gate C (`firstCyclePaidAt`) is already set the installation transitions to `ACTIVATED` and billing activation is triggered. When Gate C is not yet met and the installation is `AWAITING_INSTALLATION`, it transitions to `AWAITING_CYCLE_PAYMENT`.\n\n**Error codes:** `installation_fee_not_paid` (400) — the installation fee has not been settled yet (Gate A must be cleared first). `installation_terminal` (400) — the installation is already in a terminal state (`CANCELLED` / `ABANDONED`). See the [Error codes](../errors/error-codes.md) reference.","operationId":"InstallationsController_markInstallationDone_v1","parameters":[{"description":"Installation identifier (UUID).","in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiResponseDto"},{"properties":{"data":{"$ref":"#/components/schemas/InstallationResponseDto"},"success":{"type":"boolean"}}}]}}},"description":"The updated installation."},"400":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"rejectionReasons":{"items":{"properties":{"code":{"type":"string"},"field":{"type":"string"},"message":{"type":"string"}},"type":"object"},"type":"array"},"success":{"type":"boolean"}}}}},"description":"Validation failed"},"401":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Unauthorized — missing or invalid credentials"},"403":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Forbidden — insufficient permissions"},"404":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Resource not found"},"408":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Request timeout"},"500":{"content":{"application/json":{"schema":{"properties":{"error":{"type":"string"},"success":{"type":"boolean"}}}}},"description":"Internal server error"}},"summary":"Mark an installation as done (Gate B)","tags":["Installations"]}}}}
```
