# /systems/{id}/entitlements - Manually grant an add-on to a system **POST /systems/{id}/entitlements** Manually grant an add-on to a system. Only the owner organization or a Super Admin can manage grants directly (403 otherwise); the shop goes through `POST /entitlements/activate` instead. The entitlement must exist in the catalog; `scope` is only accepted for scoped catalog items, and a catalog item restricted to a `system_type` cannot be granted to a system of a different known type. ## Servers - Backend API server (port 8080): https://api.your-domain.com/api (Backend API server (port 8080)) - Collect API server (port 8081): https://collect.your-domain.com/api (Collect API server (port 8081)) ## Authentication methods - Bearer auth ## Parameters ### Path parameters - **id** (string) System ID ### Body: application/json (object) - **entitlement** (string) Catalog id of the add-on to grant - **scope** (string) Application instance to narrow the grant to (only for scoped catalog items) - **valid_from** (string(date-time)) Override the start date. Omitted = now. Used by the legacy import to preserve the original order date. - **valid_until** (string(date-time) | null) Expiry of the grant. Null/omitted = perpetual. - **source** (string) How the grant was created - **source_ref** (string) Free-form reference to the originating record - **buyer_email** (string) Customer email of the originating shop order (legacy-import backfill): resolved to a my user for the `purchased_by` snapshot, kept raw when no user matches. - **variant** (object) Shop variation (tier) of the purchased product line. Display metadata only: the add-on↔product mapping stays on the parent product and /auth enforcement ignores it. Refreshed by activate, so tier upgrades/downgrades follow the renewals. Omitted for manual grants and simple (non-variable) products. ## Responses ### 201 Entitlement created successfully #### Body: application/json (object) - **code** (integer) - **message** (string) - **data** (object) One add-on grant for one system, optionally narrowed to a single application instance via `scope` (omitted = whole system). `active` is derived: not revoked and not expired (`valid_until` null = perpetual). Revocation is soft (sets `revoked_at`, the row is kept for audit). ### 400 Unknown entitlement, scope not supported by the catalog item, invalid source, or system-type mismatch ("this entitlement applies to nsec systems only") #### Body: application/json (object) - **code** (integer) HTTP error code - **message** (string) Error message - **data** (object) ### 401 Unauthorized - invalid or missing token #### Body: application/json (object) - **code** (integer) - **message** (string) - **data** (object | null) ### 403 Forbidden - insufficient permissions #### Body: application/json (object) - **code** (integer) - **message** (string) - **data** (object | null) ### 404 Resource not found #### Body: application/json (object) - **code** (integer) HTTP error code - **message** (string) Error message - **data** (object) ### 409 Grant already exists for this (system, entitlement, scope) #### Body: application/json (object) - **code** (integer) - **message** (string) - **data** (object | null) ### 500 Internal server error #### Body: application/json (object) - **code** (integer) - **message** (string) - **data** (object | null) [Powered by Bump.sh](https://bump.sh)