# Scopes

Capability ceilings, effective access, and live permission checks.

Canonical HTML: https://developer.shelfcycle.com/guides/scopes

Scopes define the maximum a key can do. The acting user's current ShelfCycle permissions can only narrow that access.

Keys are issued to a ShelfCycle user for attribution and current permission checks. A key must have the endpoint scope, and the acting user must still have the required ShelfCycle permission. `GET /me` returns both the raw scopes and effective capabilities after current access is applied.

## Scope list

| Scope | Endpoints |
| --- | --- |
| `documents:upload` | `POST /document-uploads` for one private Product, Customer, Supplier, or Purchase Order file upload. |
| `search:read` | `GET /search`, `GET /entity-resolution`, detail readback for customers, suppliers, contacts, and products, and exact parent-scoped child or document reads after selecting a visible parent. |
| `tags:read` | `GET /tags`, `GET /tagged-records`, `GET /tag-assignments`, and related tags on Entity Resolution when the acting user has matching Tags and record access. |
| `tags:write` | `POST /tags`, `PATCH /tags/{id}`, and `POST` or `DELETE /tag-assignments`. |
| `notes:read` | `GET /notes`, `GET /notes/{id}`, and organization-wide counts or excerpt lists from `GET /note-activity`. |
| `notes:write` | `POST /notes`, `PATCH /notes/{id}`, and API-created note readback. |
| `opportunities:read` | `GET /opportunities` and `GET /opportunities/{id}` for visible customer- and supplier-side opportunities. |
| `opportunities:write` | `POST /opportunities`, `PATCH /opportunities/{id}`, `POST /opportunities/{id}/close`, `PUT /opportunities/{id}/meta`, and write-compatible detail readback. |
| `contacts:read` | `GET /contacts`, `GET /contacts/{id}` |
| `contacts:create` | `POST /contacts` |
| `contacts:update` | `GET /contacts/{id}`, `PATCH /contacts/{id}`, and guarded `POST /contacts/{id}/archive` or `/unarchive`. |
| `customers:read` | `GET /customers`, `GET /customers/{id}`, and `GET /customers/{id}/documents` |
| `customers:write` | `POST /customers`, `PATCH /customers/{id}`, guarded customer and customer-address archive or restore actions, parent-scoped customer location/address writes, and `POST /customers/{id}/documents`. |
| `suppliers:read` | `GET /suppliers`, `GET /suppliers/{id}`, and `GET /suppliers/{id}/documents` |
| `suppliers:write` | `POST /suppliers`, `PATCH /suppliers/{id}`, guarded supplier and ship-from archive or restore actions, parent-scoped supplier ship-from writes, and `POST /suppliers/{id}/documents`. |
| `products:read` | Product finder, detail, directory, documents, packaging and code-attribute references, assignments, aliases, and available catalog relationships. |
| `products:write` | Product and product-family create or update, packaging create, typed product assignments, supplier links, product and family aliases, customer part numbers, product archive or restore, documents, and current SDS assignment. |
| `orders:read` | `GET /orders`, `GET /orders/{id}` |
| `purchase-orders:read` | `GET /purchase-orders`, `GET /purchase-orders/{id}` |
| `invoices:read` | `GET /invoices` and `GET /invoices/{id}` for invoices and customer credits. |
| `bills:read` | `GET /bills` and `GET /bills/{id}` for bills and supplier credits. |
| `customer-payments:read` | `GET /customer-payments` and `GET /customer-payments/{id}` for customer payments and deposit context. |
| `supplier-payments:read` | `GET /supplier-payments` and `GET /supplier-payments/{id}` for supplier payments and payment-batch context. |
| `purchase-order-execution:read` | `GET /purchase-order-execution`, including destination-warehouse filtering, `GET /purchase-order-lines/{id}/receipt-events`, and `GET /purchase-orders/{id}/documents` |
| `inventory:read` | `GET /inventory-balances` for current physical product-by-warehouse balances, availability states, and stock-out counts. |
| `lots:read` | `GET /lots` and `GET /lots/{id}` for named lots, exact quantities, and remaining-stock age. |
| `warehouses:read` | `GET /warehouses` and `GET /warehouses/{id}` for warehouse identity, address, contact, source ID, archive state, and update time. |
| `warehouses:write` | `POST /warehouses`, `PATCH /warehouses/{id}`, and warehouse archive or restore actions. |
| `reorder:read` | `GET /reorder-status` for configured reorder points, allocated and committed demand, projected availability, projected deficit, and status counts. |
| `reorder:write` | `POST /reorder-points` to set or clear 1 to 50 product-and-warehouse thresholds together. |
| `certifications:read` | `GET /certification-types`, `GET /certification-records`, exact certification record detail, and `GET /certification-subjects`. Warehouse results also require `warehouses:read`. |
| `purchase-order-documents:write` | `POST /purchase-orders/{id}/documents` for readiness checks and verified document association. |
| `company-reference:read` | `GET /reference/customers`, `GET /reference/suppliers`, `GET /representatives`, `GET /payment-terms`, and `GET /reference/ledger-accounts`. |
| `company-reference:write` | Create and maintain representatives, payment terms, and supported Chart of Accounts fields through their documented endpoints. |
| `shipping-options:read` | `GET /shipping-options` and `GET /shipping-options/{id}` for freight terms, carriers, FOB terms, freight methods, and border crossing points. |
| `shipping-options:write` | `POST /shipping-options`, `PATCH /shipping-options/{id}`, and Shipping Options archive or restore actions. |
| `reports:read` | `GET /reports` and `GET /reports/{reportKey}` for sales, purchasing, open-order, pipeline, receivables, payables, and payment reports. Accounts Payable aging and payment reports also require their matching resource-family scope. |
| `cost-book-entries:read` | `GET /cost-book-entries` by supplier and optional ship-from origin, `GET /products/{id}/cost-context`, and supplier history when combined with `suppliers:read`. |
| `cost-book-entries:write` | `POST /cost-book-entries`, `PATCH` or `DELETE /cost-book-entries/{id}`, and `POST /cost-book-entries/batch` for previews, verified updates, preserved corrections, mistaken-entry removal, and approved batches. |
| `current-cost-sources:read` | `GET /products/{id}/current-cost-source` for a product's supplier-and-origin source state, eligible choices, and selection details. |
| `current-cost-sources:write` | `PUT /products/{id}/current-cost-source` to preview, set, replace, or clear an exact supplier-location Current Source. |
| `price-book-entries:read` | `GET /price-book-entries` for active, scheduled, expired, all, and historical configured sale prices. |
| `price-book-entries:write` | `POST /price-book-entries` for reviewed single-price updates in the organization's base currency. |

## Scope ceiling

A key with only `search:read` cannot write anything. A key with `tags:read` can browse the organization tag vocabulary, find authorized records carrying one exact tag, and receive related tags on Entity Resolution when live access allows it. A key with `documents:upload` can prepare a private file upload, while the matching record write scope controls whether that file can be attached. A key with `notes:read` can read notes for a selected visible customer, supplier, or product and can count or review organization-wide note activity when the acting user has current Note viewing access. A key with `opportunities:read` can find and read visible customer- and supplier-side opportunities. A key with `opportunities:write` can create, update, close, and maintain details for visible opportunities. A key with `company-reference:read` can page active customer and supplier matching hints. A key with `products:read` can find products and product families, resolve packaging and code attributes, and reconcile available product relationships. A key with `products:write` can build and rename products, maintain product families, create packaging, save typed product assignments, maintain aliases, connect suppliers and customer part numbers, manage product lifecycle, attach documents, and assign the current SDS. Supplier- or customer-specific product relationships also require the matching read scope. A key with `orders:read` can find sales orders and read their lines, fulfillment context, and totals. A key with `purchase-orders:read` can find purchase orders and read their lines, receipt summaries, supplier document costs, and totals. Invoices, bills, customer payments, and supplier payments each use their own read scope, and connected financial details appear only when the key can read both families. A key with `purchase-order-execution:read` can review current open purchase lines by destination warehouse, exact receipt events, and attached purchase-order documents. A key with `inventory:read` can review current balances and complete stock-out counts by product and warehouse. A key with `lots:read` can find named lots and read their exact quantities, COA readiness, and remaining-stock age. A key with `warehouses:read` can find and read warehouse records; `warehouses:write` can create, maintain, archive, and restore physical warehouses. A key with `reorder:read` can review configured reorder points, current stock, committed demand, projected availability, and status counts; `reorder:write` can set or clear grouped thresholds. A key with `certifications:read` can browse authorized certification types, records, renewal states, subjects, dates, and evidence filenames; warehouse results also require `warehouses:read`. A key with `purchase-order-documents:write` can preview and attach one document to a visible purchase order. A key with `reports:read` can discover and run available sales, purchasing, open-order, pipeline, receivables, payables, and payment reports; Accounts Payable aging and payment reports also require their matching family scopes. A key with `cost-book-entries:read` can read current Cost Book entries, product cost context, and supplier history when combined with `suppliers:read`. A key with `cost-book-entries:write` can create or supersede a verified Cost Book entry, correct an existing event while preserving its history, remove one mistaken entry when ready, or apply an approved batch after the acting user's current access is checked. A key with `current-cost-sources:read` can read a product's fixed, selected, unconfigured, or unavailable supplier-and-origin source state. A key with `current-cost-sources:write` can preview, set, replace, or clear an eligible supplier-location Current Source after current access is checked. A key with `price-book-entries:read` can review active, scheduled, expired, and historical configured sale prices with exact package and base-unit context. A key with `price-book-entries:write` can preview and apply one exact price update after the acting user's current Pricing Engine access and customer visibility are checked. A key with `customers:write` can create or patch customer profile, location, address, and attached document fields, and archive or restore customers and customer addresses. A key with `suppliers:write` can maintain supplier profiles and ship-from locations and archive or restore either record type. A key with `contacts:update` can update, archive, or restore a selected customer or supplier contact.

`tags:write` maintains the shared tag vocabulary and adds or removes assignments for record types the acting person can update. `tags:read` remains the readback scope for vocabulary, tagged-record directories, and a selected record's current tags.

Company Reference access also covers representative, payment-term, and ledger-account directories. `company-reference:write` adds representative create, metadata update, archive, and restore actions; payment-term creation and metadata updates; and Chart of Accounts create and update. The acting person's matching access still applies.

Shipping Options access is separate from Company Reference. `shipping-options:read` lists and reads the six supported freight and shipping vocabularies; `shipping-options:write` creates, updates, archives, and restores those options. Payment terms remain under Company Reference.

## Restricted and full access keys

Most keys are restricted to named scopes. Full access keys can carry the current public API scope set, but they are still tenant-bound, user-attributed, revocable, and narrowed by live ShelfCycle permissions.

Full access keys include the current public scope set, including `invoices:read`, `bills:read`, `customer-payments:read`, `supplier-payments:read`, `company-reference:write`, `shipping-options:read`, `shipping-options:write`, `tags:read`, `tags:write`, `inventory:read`, `lots:read`, `warehouses:read`, `warehouses:write`, `reorder:read`, `reorder:write`, `certifications:read`, `current-cost-sources:read`, and `current-cost-sources:write`, automatically. Restricted keys receive only the scopes selected for their workflow.

`GET /me` reports:

| Field | Use it for |
| --- | --- |
| `key.accessMode` | Whether the key is `restricted` or `full`. |
| `key.storedGrants` | The grants stored on the key, which may be named scopes or a broad public API grant. |
| `key.effectiveScopes` | The current scope list a caller should reason over after expanding broad grants and removing retired scopes. |
| `key.retiredScopes` | Any stored grants that no longer map to current public API scopes. |

Use `effectiveScopes`, not `storedGrants`, when deciding which endpoint families a workflow may call.

## Live user permission floor

Scopes are not the only authorization check. The API also checks the acting user's current ShelfCycle permissions. If that user is removed, inactive, or loses the required role, the key loses that ability without changing the key.

> **Guardrail**: Do not treat scopes as a substitute for user permissions. The API requires both.

## Effective capabilities

Use `GET /me` to inspect what the key can actually do now. Tag capabilities report vocabulary access and viewable record types, while tag write readiness reports create, update, and assignable record types. Product capabilities report packaging, code attributes, assignments, suppliers, aliases, customer part numbers, archive, restore, documents, and SDS actions individually. Warehouse and Shipping Options capabilities report view, create, update, archive, and restore, while reorder-point write readiness reports whether threshold changes are available. Product-family capabilities report alias actions alongside family create and update. The response also covers document uploads, search, Entity Resolution, Product Directory, Certification Intelligence, notes, opportunities, contacts, customers, suppliers, company reference, Cost Book entries, Current Source, Price Book entries, orders, purchase orders, inventory balances, lots, reorder status, reports, and write readiness.

`entityResolution.viewableClasses` lists the customer, supplier, product, product-family, sales-order, purchase-order, salesperson, and warehouse classes currently available. Company-reference capabilities show directory access for customers, suppliers, representatives, payment terms, and ledger accounts. Its `write` group reports representative actions, payment-term creation and metadata updates, and `ledgerAccountsCreate` or `ledgerAccountsUpdate`. Customer capabilities report `activityFilter` separately for qualifying shipped-sales discovery.

`createdRecordDiscovery` reports whether creator and created-time discovery is currently available for Product Directory, opportunities, customers, suppliers, Cost Book, Price Book, sales orders, purchase orders, lots, and certifications. It appears inside the matching capability group, for example `effectiveCapabilities.orders.createdRecordDiscovery` and `effectiveCapabilities.inventory.lots.createdRecordDiscovery`. Reports continue to list available report keys under `effectiveCapabilities.reports.available`. These flags use each family's existing read scope; v1.42.1 adds no new scope.

The remaining groups report the matching view, create, update, archive, restore, document, report, or readiness actions for their resources. A scope can be present while the corresponding effective capability is false because the acting person does not currently have that access.

Repair metadata does not introduce a new scope. Responses may add `repairCategory`, `suggestedAction`, `validValues`, `repairContext`, accepted filters, examples, and retry guidance to errors for the scopes a key already uses.

## Write readiness and scopes

`dryRun=true` does not introduce a separate scope. It uses the same write scope, live user permission, and rate-limit family as execution:

| Write family | Readiness scope |
| --- | --- |
| `POST /reference/ledger-accounts` and `PATCH /reference/ledger-accounts/{id}` | `company-reference:write` |
| `POST /shipping-options`, `PATCH /shipping-options/{id}`, and Shipping Options `archive` or `unarchive` actions | `shipping-options:write` |
| `POST /representatives`, representative `PATCH`, `archive`, and `unarchive` actions, plus `POST /payment-terms` and `PATCH /payment-terms/{id}` | `company-reference:write` |
| `POST /notes`, `PATCH /notes/{id}` | `notes:write` |
| `POST /opportunities`, `PATCH /opportunities/{id}`, `POST /opportunities/{id}/close`, `PUT /opportunities/{id}/meta` | `opportunities:write` |
| `POST /contacts` | `contacts:create` |
| `PATCH /contacts/{id}`, `POST /contacts/{id}/archive`, `POST /contacts/{id}/unarchive` | `contacts:update` |
| `POST /customers`, `PATCH /customers/{id}`, `POST /customers/{id}/archive`, `POST /customers/{id}/unarchive` | `customers:write` |
| `POST /suppliers`, `PATCH /suppliers/{id}`, `POST /suppliers/{id}/archive`, `POST /suppliers/{id}/unarchive` | `suppliers:write` |
| `POST /customers/{id}/locations`, `PATCH /customers/{id}/locations/{locationId}`, and customer address writes | `customers:write` |
| Customer-address `archive` and `unarchive` actions | `customers:write` |
| `POST /customers/{id}/documents` | `customers:write` |
| `POST /suppliers/{id}/ship-from-locations`, `PATCH /suppliers/{id}/ship-from-locations/{locationId}` | `suppliers:write` |
| Supplier ship-from `archive` and `unarchive` actions | `suppliers:write` |
| `POST /suppliers/{id}/documents` | `suppliers:write` |
| Product and product-family create or update, packaging create, supplier, alias, and customer-part-number relationship changes, plus product archive and restore | `products:write` |
| `POST /products/{id}/documents` | `products:write` |
| `POST /purchase-orders/{id}/documents` | `purchase-order-documents:write` |
| `PUT /products/{id}/sds` | `products:write` |
| `POST /cost-book-entries`, `PATCH` or `DELETE /cost-book-entries/{id}`, `POST /cost-book-entries/batch` | `cost-book-entries:write` |
| `PUT /products/{id}/current-cost-source` | `current-cost-sources:write` |
| `POST /price-book-entries` | `price-book-entries:write` |

Authorized callers may execute without dryRun when their integration policy allows it. ShelfCycle does not require human approval before these supported public API writes.

## Missing access

The two access errors are distinct.

```json
{
  "error": {
    "type": "permission_error",
    "code": "missing_scope",
    "message": "The API key does not include the required scope.",
    "requestId": "request-id"
  }
}
```

```json
{
  "error": {
    "type": "permission_error",
    "code": "missing_permission",
    "message": "The acting user does not have permission for this operation.",
    "requestId": "request-id"
  }
}
```
