# Authentication

Bearer keys, required headers, and key verification.

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

Authenticate with a bearer API key, then verify the org, contract version, scopes, acting user, and effective capabilities before running a workflow.

The API key is a secret in the form `sk_...`. It is shown once when issued. Store it outside source control and read it from the environment.

## Base URL

Production:

```text
https://app.shelfcycle.com/api/v1
```

Local development:

```text
http://localhost:3000/api/v1
```

The route major remains `/api/v1`. The v1.44.1 contract is reported by `GET /me` and the OpenAPI document as `apiContractVersion` or `info.version`. `GET /me` also reports `minimumCompatibleContractVersion` so integrations can verify their supported compatibility floor.

## Check contract compatibility

Treat contract versions as numeric `major.minor.patch` values, not text and not an exact-equality check. Remove one leading `v`, accept two or three numeric segments, and treat a missing patch as zero. A client version is supported when it is at least `minimumCompatibleContractVersion` and no newer than `apiContractVersion`.

For example, `v1.44.1` becomes `[1, 44, 1]`, and a v1.42.2 client remains compatible with a server reporting v1.44.1 when the compatibility floor still includes it. After the version check, confirm the workflow's required scopes, effective capabilities, and OpenAPI operation ids. If a version is malformed, inspect the current contract before continuing.

## Required header

Every API request uses the bearer token header.

```text
Authorization: Bearer <SHELFCYCLE_API_KEY>
```

Recommended client metadata:

```text
X-ShelfCycle-Client: Email notes automation
X-ShelfCycle-Request-Source: local-agent
```

## Verify with /me

`GET /me` is the first request a workflow should make. It confirms the key, organization, contract, scopes, acting user, documentation links, and effective capabilities after current ShelfCycle access.

```bash
curl "$SHELFCYCLE_API_BASE_URL/me" \
  -H "Authorization: Bearer $SHELFCYCLE_API_KEY" \
  -H "X-ShelfCycle-Client: Email notes automation"
```

```json
{
  "data": {
    "apiVersion": "v1",
    "apiContractVersion": "v1.44.1",
    "minimumCompatibleContractVersion": "v1.21",
    "org": { "id": "org-id", "name": "Northstar Chemical", "baseCurrencyCode": "USD" },
    "key": {
      "id": "api-key-id",
      "name": "Email notes automation",
      "purpose": "Workflow for creating notes from source emails",
      "preview": "sk_...abcd",
      "scopes": ["company-reference:read", "company-reference:write", "shipping-options:read", "shipping-options:write", "search:read", "tags:read", "tags:write", "warehouses:read", "warehouses:write", "lots:read", "reorder:read", "reorder:write", "notes:read", "notes:write", "customers:read", "products:read"],
      "accessMode": "restricted",
      "storedGrants": ["company-reference:read", "company-reference:write", "shipping-options:read", "shipping-options:write", "search:read", "tags:read", "tags:write", "warehouses:read", "warehouses:write", "lots:read", "reorder:read", "reorder:write", "notes:read", "notes:write", "customers:read", "products:read"],
      "effectiveScopes": ["company-reference:read", "company-reference:write", "shipping-options:read", "shipping-options:write", "search:read", "tags:read", "tags:write", "warehouses:read", "warehouses:write", "lots:read", "reorder:read", "reorder:write", "notes:read", "notes:write", "customers:read", "products:read"],
      "retiredScopes": [],
      "expiresAt": null
    },
    "actor": { "type": "user", "id": "user-id", "displayName": "Jordan Buyer" },
    "documentation": {
      "openapiJsonUrl": "https://app.shelfcycle.com/api/v1/openapi.json",
      "llmsTxtUrl": "https://app.shelfcycle.com/llms.txt"
    },
    "effectiveCapabilities": {
      "documentUploads": { "create": false },
      "search": { "viewableTypes": ["customer", "contact", "product", "order", "purchase_order", "location"] },
      "entityResolution": { "viewableClasses": ["customer", "product", "product_family", "warehouse"] },
      "tags": { "vocabulary": true, "viewableEntityTypes": ["customer", "product", "product_family"] },
      "productDirectory": { "view": true, "createdRecordDiscovery": true },
      "notes": {
        "create": true,
        "view": true,
        "update": true,
        "activityReport": true,
        "viewableSubjectTypes": ["customer", "product"]
      },
      "opportunities": { "view": false, "createdRecordDiscovery": false, "create": false, "update": false, "close": false, "metaUpsert": false },
      "contacts": {
        "create": false,
        "view": false,
        "update": false,
        "archive": false,
        "unarchive": false,
        "customer": { "create": false, "view": false, "update": false, "archive": false, "unarchive": false },
        "supplier": { "create": false, "view": false, "update": false, "archive": false, "unarchive": false }
      },
      "customers": {
        "create": false,
        "view": true,
        "update": false,
        "archive": false,
        "unarchive": false,
        "activityFilter": false,
        "createdRecordDiscovery": true,
        "locations": { "view": true, "create": false, "update": false },
        "addresses": { "view": true, "create": false, "update": false, "archive": false, "unarchive": false },
        "documents": { "view": true, "create": false }
      },
      "suppliers": {
        "create": false,
        "view": false,
        "createdRecordDiscovery": false,
        "update": false,
        "archive": false,
        "unarchive": false,
        "shipFromLocations": { "view": false, "create": false, "update": false, "archive": false, "unarchive": false },
        "documents": { "view": false, "create": false }
      },
      "companyReference": {
        "activeDirectory": true,
        "customers": true,
        "suppliers": false,
        "representatives": true,
        "paymentTerms": true,
        "ledgerAccounts": true,
        "write": {
          "salesRepresentatives": false,
          "customerServiceRepresentatives": false,
          "supplierRepresentatives": false,
          "paymentTermsCreate": false,
          "paymentTermsMetadataUpdate": false,
          "ledgerAccountsCreate": true,
          "ledgerAccountsUpdate": true
        }
      },
      "shippingOptions": { "view": true, "create": true, "update": true, "archive": true, "unarchive": true },
      "products": {
        "view": true,
        "create": false,
        "update": false,
        "archive": false,
        "unarchive": false,
        "packaging": { "view": true, "create": false },
        "codeAttributes": { "view": true },
        "attributeAssignments": { "view": true, "update": false },
        "suppliers": { "view": false, "create": false, "remove": false },
        "aliases": { "view": true, "create": false, "update": false, "remove": false },
        "customerPartNumbers": { "view": true, "create": false, "update": false, "remove": false },
        "documents": { "view": true, "create": false },
        "sds": { "view": true, "update": false }
      },
      "productFamilies": {
        "view": true,
        "create": false,
        "update": false,
        "aliases": { "view": true, "create": false, "update": false, "remove": false }
      },
      "costBookEntries": { "view": false, "createdRecordDiscovery": false, "create": false, "delete": false },
      "currentCostSources": { "read": false, "write": false },
      "priceBookEntries": { "read": false, "createdRecordDiscovery": false, "write": false, "writeCurrencyMode": "org_base_only" },
      "orders": { "view": false, "createdRecordDiscovery": false, "changedRecordDiscovery": false },
      "purchaseOrders": {
        "view": false,
        "createdRecordDiscovery": false,
        "changedRecordDiscovery": false,
        "execution": { "view": false, "currentStateRefresh": false },
        "documents": { "view": false, "create": false }
      },
      "inventory": {
        "balances": { "view": false, "currentStateRefresh": false },
        "lots": { "view": true, "createdRecordDiscovery": true, "currentStateRefresh": true }
      },
      "reorder": { "status": { "view": false, "currentStateRefresh": false } },
      "warehouses": { "view": true, "create": true, "update": true, "archive": true, "unarchive": true },
      "reorderPoints": { "write": true },
      "certifications": { "view": true, "createdRecordDiscovery": true, "viewableSubjectTypes": ["customer", "product"] },
      "reports": { "available": [] },
      "writeReadiness": {
        "shippingOptions": { "create": true, "update": true, "archive": true, "unarchive": true },
        "warehouses": { "create": true, "update": true, "archive": true, "unarchive": true },
        "reorderPoints": { "write": true },
        "tags": { "create": true, "update": true, "assignableEntityTypes": ["customer", "product", "product_family"] },
        "notes": { "create": true, "update": true },
        "opportunities": { "create": false, "update": false, "close": false, "metaUpsert": false },
        "contacts": {
          "create": false,
          "update": false,
          "archive": false,
          "unarchive": false,
          "customer": { "create": false, "update": false, "archive": false, "unarchive": false },
          "supplier": { "create": false, "update": false, "archive": false, "unarchive": false }
        },
        "customers": {
          "create": false,
          "update": false,
          "archive": false,
          "unarchive": false,
          "locations": { "create": false, "update": false },
          "addresses": { "create": false, "update": false, "archive": false, "unarchive": false },
          "documents": { "create": false }
        },
        "suppliers": {
          "create": false,
          "update": false,
          "archive": false,
          "unarchive": false,
          "shipFromLocations": { "create": false, "update": false, "archive": false, "unarchive": false },
          "documents": { "create": false }
        },
        "products": {
          "create": false,
          "update": false,
          "archive": false,
          "unarchive": false,
          "packaging": { "create": false },
          "suppliers": { "create": false, "remove": false },
          "aliases": { "create": false, "update": false, "remove": false },
          "customerPartNumbers": { "create": false, "update": false, "remove": false },
          "documents": { "create": false },
          "sds": { "update": false }
        },
        "productFamilies": {
          "create": false,
          "update": false,
          "aliases": { "create": false, "update": false, "remove": false }
        },
        "costBookEntries": { "create": false, "delete": false },
        "currentCostSources": { "write": false },
        "priceBookEntries": { "create": false },
        "purchaseOrders": { "documents": { "create": false } }
      }
    }
  }
}
```

> **Guardrail**: If the org, actor, contract version, scopes, or effective capabilities are not what the workflow expects, stop before any search or write.

## Key lifecycle errors

Authentication fails closed. These errors mean the caller should stop and request a new key or a permission change.

| Code | Meaning |
| --- | --- |
| `invalid_api_key` | Missing, malformed, unknown, or ambiguous bearer token. |
| `api_key_revoked` | The key was revoked. |
| `api_key_expired` | The key is past its expiry. |
| `api_actor_inactive` | The issued-to user no longer belongs to the org. |

## Handling secrets

Never paste the key into a coding agent prompt, Slack, email, logs, or source control. A local agent should read `SHELFCYCLE_API_KEY` from `.env` and redact the key from all output.
