Generating an API key

To call the API you need an API key. You create keys in the Epoch app; each key is tied to your user and organization. This guide explains how to generate a key and use it in requests.

Where to create a key

  1. Sign in to the Epoch app.
  2. Open Settings (from the app navigation).
  3. Go to API Keys (or Keys).
  4. Click New API Key.
  5. Enter a name for the key (e.g. "CI pipeline" or "Dashboard integration") and confirm.
  6. The app shows the new key once. Copy it and store it somewhere safe (e.g. a secrets manager or environment variable). You will not be able to see the full key again; only the last four characters are shown in the key list.

Keys start with sk-epoch- and identify you and your organization.

Using the key in requests

Send the key in the x-api-key header on every request to the API (except health checks, which do not require auth).

Example with cURL

curl -X GET "https://api.example.com/auth/me" \
  -H "Accept: application/json" \
  -H "x-api-key: sk-epoch-your-key-here"

Example in code

const response = await fetch("https://api.example.com/auth/me", {
  headers: {
    "Accept": "application/json",
    "x-api-key": process.env.EPOCH_API_KEY,
  },
});
import os
import requests

response = requests.get(
    "https://api.example.com/auth/me",
    headers={
        "Accept": "application/json",
        "x-api-key": os.environ["EPOCH_API_KEY"],
    },
)

Scopes

When creating a key you can optionally assign scopes to restrict which endpoints the key can access.

ScopeEndpoints
locations:readGET /locations/facilities, GET /locations/plots, GET /locations/sheds, etc.
metrics:readGET /metrics/plots/*, GET /metrics/sheds/*
ingestions:readGET /ingestions, GET /ingestions/assets, etc.
ingestions:writePOST /ingestions/assets, PUT /ingestions/assets
tags:readGET /tags
tags:writePATCH /tags/:name, DELETE /tags/:name
webhooks:readGET /webhooks, GET /webhooks/:id, deliveries
webhooks:writePOST /webhooks, PATCH /webhooks/:id, DELETE /webhooks/:id, verify, rotate
notifications:readGET /notifications, GET /notifications/:id
notifications:writePATCH /notifications/:id, POST /notifications/mark-read, DELETE /notifications/:id
auth:readGET /auth/me
eudr:referenceOnly GET /regulations/eudr/scope, GET /regulations/eudr/scope/entries and GET /regulations/eudr/species
  • A key with no scopes has access to all endpoints (default).
  • A key with scopes set can only call endpoints matching those scopes; other endpoints return 403 Insufficient scope.
  • Scopes can be edited after creation from the API Keys settings page.
  • Scope restrictions apply to both member keys (sk-epoch-) and organisation keys (ok-epoch-).

For a reference-only EUDR integration, select only EUDR reference data (eudr:reference). This permits HS-code classification, Annex I entries and species lookups. Other scope-protected endpoints, including /auth/me, return 403 Insufficient scope. Existing eudr:read keys can still call all three reference endpoints.

See Scopes for a reference-only key creation example and the full scope reference.

Resource Tags

Keys can be configured with resource tags in key:value format to restrict which resources are returned within allowed endpoints.

  • Tags use AND logic — only resources matching all tags on the key are returned.
  • A key with no resource tags sees all resources (default).
  • Single-resource endpoints (e.g. GET /locations/facilities/:id) return 404 if the resource does not match the key's tags.
  • Resource tags can be edited after creation from the API Keys settings page.
  • Org keys are not affected by resource tags.

Security

  • Never commit keys to version control. Use environment variables or a secrets manager.
  • Rotate keys if they may have been exposed, or periodically. Create a new key in the app, update your integration, then delete the old key from the API Keys list.
  • Keys are hashed on the server; the plain value is only shown once when you create the key.