Developer Docs

← Back to Console

API Keys

Manage your API keys and authentication credentials

Overview

API keys are managed through the EQUOS subscriber console under Integrations → API Keys. Each key is an OAuth 2.0 machine-to-machine credential for server-to-server calls to /e9v3.

Authentication: These management endpoints require a signed-in account admin (Firebase ID token). They are separate from the M2M JWT you use on /e9v3.

Business tenancy

One API key binds to one business by default. When you exchange a classic key for a token and call /e9v3, EQUOS resolves the tenant from the key itself. Do not send X-Business-ID (or a businessId query) on public API requests for those keys — the header is ignored for tenancy.

  • In the console, use the business picker at the top of Integrations to choose which business you are managing, then generate or revoke keys for that business.
  • Multi-business account admins can still mint one key per business (you do not need to change your default claim first — pass businessId on the admin API, or pick the business in the UI). Existing keys keep working this way.
  • Optionally, select additional owned businesses when minting to create a multi-business key. Those keys require X-Business-ID on every /e9v3 call; the value must be one of the businesses bound at create time. Missing header → 400 businessId required; unbound id → 403 key not bound to business. Revoking that key from any one bound business stops it working for all of them.

GET/api/keysList API keys
🔒 Bearer (admin token)

List API keys for a business (home tenant or extra tenant). Omit businessId to use your Firebase claim default; pass ?businessId= for a business you own (or super admin).

Query Parameters
FieldTypeRequiredDescription
businessIdstringOptionalTarget business. Defaults to the businessId claim on your admin token. Override requires a business you own (or super admin).
[
  {
    "id": "key-uuid-1",
    "businessId": "biz_equos_demo",
    "name": "Production Integration",
    "prefix": "abc12345",
    "scopes": ["orders:write"],
    "createdAt": "2024-01-15T10:00:00Z",
    "expiresAt": null,
    "isActive": true
  },
  {
    "id": "key-uuid-2",
    "businessId": "biz_equos_demo",
    "name": "Staging Integration",
    "prefix": "def67890",
    "scopes": ["orders:read", "orders:write"],
    "createdAt": "2024-01-10T15:30:00Z",
    "expiresAt": "2025-01-10T00:00:00Z",
    "isActive": true
  }
]
{"error": "no businessId in user claims"}
{"error": "not authorized for business"}
Response Fields
  • id: Unique identifier for the key
  • businessId: On a list response, the business you requested, not the key's home business
  • businessIds: Missing means a single-business key. Present means the key is shared. On a list response the array is only the business you requested.
  • name: Human-readable label
  • prefix: First 8 characters of the client_id (for identification)
  • scopes: Array of granted scopes
  • createdAt: Creation timestamp
  • expiresAt: Expiration timestamp (null = never expires)
  • isActive: Whether the key is active

A missing businessIds means a single-business key. A present businessIds means the key is shared. On a list response, businessId is the business you requested, not the key's home business, and a present businessIds array names only that business.

POST/api/keysCreate API key
🔒 Bearer (admin token)

Create a new API key bound to one business, or to several when businessIds has two or more ids and each is a business you own (or super admin). The clientSecret is only returned once at creation time.

Request Body
FieldTypeRequiredDescription
namestringRequiredDisplay name for the key
scopesarrayRequiredAt least one scope (see Available Scopes below)
expiresAtstring (RFC3339)OptionalExpiration date (null = never expires)
businessIdstringOptionalHome business to bind the key to. Defaults to your claim businessId. Must be a business you own (or super admin).
businessIdsstring[]OptionalTwo or more ids, each a business you own (or super admin). Omit, or send a single id, for a classic one-business key. Home is businessId (or the claim default); extras are the remaining ids.
{
  "id": "key-uuid-3",
  "businessId": "biz_equos_demo",
  "name": "New Integration",
  "prefix": "ghi11111",
  "scopes": ["orders:write"],
  "createdAt": "2024-01-20T12:00:00Z",
  "expiresAt": null,
  "isActive": true,
  "clientId": "your_client_id",
  "clientSecret": "secret_abc123def456..."
}
{"error": "at least one scope is required"}
{"error": "no businessId in user claims"}
{"error": "not authorized for business"}
Important Notes
  • Save the clientSecret immediately: It is only shown once at creation time
  • Use clientId and clientSecret for token exchange: See Authentication for details
  • Expiration is optional: Leave expiresAt null for keys that never expire
  • Binding is permanent: A classic key always resolves to the businessId stamped at create time. A multi-business key is permanently bound to that set; callers must send X-Business-ID.
DELETE/api/keys/:idRevoke API key
🔒 Bearer (admin token)

Revoke an API key. This immediately invalidates the key for every business it is bound to. Pass ?businessId= when revoking a key for a non-default business.

Query Parameters
FieldTypeRequiredDescription
businessIdstringOptionalBusiness that owns the key. Defaults to your claim businessId.
{
  "ok": true
}
{"error": "api key not found"}
{"error": "no businessId in user claims"}
{"error": "not authorized for business"}
Important Notes
  • One revoke covers every binding: A key can be bound to several businesses. Revoking it from any one of them stops it working for all of them. On a list, a present businessIds means the key is shared, even when the array only names the business you requested.

Available Scopes

ScopeDescriptionCommon Use
orders:readRead order data and statusMonitoring, analytics
orders:writeCreate and manage ordersOrder creation, integrations
orders:fulfilFinalize, fulfil (create warehouse tasks) and commit orders. Higher risk. Requires orders:write.Ingest and other integrations that finalize, fulfil, and commit — on create via advance, or POST /e9v3/orders/{type}/{orderId}/finalize|fulfil|commit
inventory:readRead inventory dataStock levels, forecasting
inventory:writeDeclare on-hand quantities and upsert/archive catalogue itemsStock adjustments, product catalogue sync
contacts:readRead contacts and search addresses; export a shopper's personal data (POST /e9v3/contacts/export)Customer/supplier lookups, GDPR data requests
contacts:writeErase a shopper's personal data (POST /e9v3/contacts/erase and /erase/shop)Shopify customers/redact and shop/redact
warehouse:readReserved — not yet enforced by any endpoint—
warehouse:writeReserved — not yet enforced by any endpoint—
webhooks:manageManage webhook subscriptions (order, shipment and inventory events)Shopify app, event-driven integrations

Best Practices

Key Security

  • Store safely: Use environment variables or secrets management systems (AWS Secrets Manager, HashiCorp Vault, etc.)
  • Never commit to version control: Add .env and similar files to .gitignore
  • Rotate regularly: Create new keys and revoke old ones on a scheduled basis
  • Prefer one key per business unless you need a multi-business key: Classic keys need no tenant header. Multi-business keys must send X-Business-ID on every /e9v3 call.
  • Use separate keys per environment: Maintain distinct keys for development, staging, and production
  • Revoke immediately if compromised: If a key is exposed, revoke it using the DELETE endpoint

Scope Management

  • Principle of least privilege: Grant only the scopes your integration actually needs
  • Review regularly: Audit your active keys and remove any that are no longer in use
  • Set expiration dates: Consider setting expiration dates for time-limited integrations

Monitoring

  • Monitor for errors: Alert on repeated 401/403 errors which may indicate compromised credentials
  • Track usage: Monitor which keys are being used and from which IP addresses (if applicable)
  • Audit logs: Keep records of when keys are created, rotated, and revoked