Scopes & permissions
Integration JWTs carry a scopes array. Each v2 route requires a specific scope; missing scope returns 403 insufficient_scope.
Default scopes
All tokens issued via API key exchange include:
| Scope |
Access |
orders.read |
List and get orders |
orders.write |
Create, update, patch order status |
order_requests.write |
Submit order requests (v2) |
prescriptions.read |
List and get prescriptions |
prescriptions.write |
Ingest prescriptions |
products.read |
List shops, shop products |
products.write |
Add to inventory, update product, attach/detach shop products, overrides |
inventory.read |
List inventory, log, history |
inventory.write |
Adjust stock |
reports.read |
Stats, product performance, sales, PharmaOne fee reports |
Example decoded JWT:
{
"org_id": "org1",
"scopes": [
"orders.read",
"orders.write",
"order_requests.write",
"prescriptions.read",
"prescriptions.write",
"products.read",
"products.write",
"inventory.read",
"inventory.write",
"reports.read"
],
"iss": "pharmaone-integration",
"sub": "integration"
}
Scope-to-route matrix
Orders
| Route |
Scope |
GET /orders, GET /orders/{id} |
orders.read |
POST /orders, PUT /orders/{id}, PATCH /orders/{id}/status |
orders.write |
Order requests
| Route |
Scope |
POST /order-requests |
order_requests.write |
Prescriptions
| Route |
Scope |
GET /prescriptions, GET /prescriptions/{id} |
prescriptions.read |
POST /prescriptions |
prescriptions.write |
Products & shops
| Route |
Scope |
GET /shops, GET /products |
products.read |
POST /products/add-to-inventory, PUT /products/{id} |
products.write |
POST /shops/attach-product, detach-product, product-overrides |
products.write |
Inventory
| Route |
Scope |
GET /inventory, GET /inventory/{id}/log, GET /inventory/{id}/history |
inventory.read |
POST /inventory/adjust |
inventory.write |
Reports
| Route |
Scope |
All GET /reports/* |
reports.read |
Insufficient scope response
{
"error": "insufficient_scope",
"message": "Missing scope: inventory.write"
}
Future: granular keys
Today all integration keys receive the full default scope set. Per-key scope reduction may be added in a future release; design integrations to request only the scopes you need conceptually.