Skip to content
Coritan Docs

Create organization API keys

Create a key for your own systems to call the Commerce API, choose its scopes, and revoke it when it is no longer needed.

View as Markdown

An organization API key lets your own systems call the Commerce API without a person signing in. The key belongs to one organization. Its scopes say what it may do, and you can cap how many requests it makes and where they come from.

A key works on the Commerce API only, at https://api.coritan.com/api/v1/orgs/{org_slug}/commerce/..., sent in the X-API-Key header. Every other organization route takes a member's access token instead.

  • You need the owner or admin role in the organization.
  • Commerce must be turned on for the organization. Coritan turns it on, so ask support if it is not. Until then, every Commerce API route answers 404 with the message Commerce is not enabled for this organization.
  • Work out which scopes the key needs from the table below. Give it the fewest that do the job.

A key reaches nothing in the Commerce API until you give it scopes. A :write scope includes the :read scope of the same area.

Scope What it opens
commerce.store:read The store's settings, its publishable keys and its events.
commerce.store:write Changing the store's settings, publishable keys, sales channels, regions, shipping profiles, zones and options, and fulfilment providers.
commerce.catalog:read Products, tags, collections, categories, price lists, regions, shipping, stock locations, inventory items and sales channels, and your imports and their reports.
commerce.catalog:write Changing products with their options, variants, prices and images; collections, categories and price lists; stock locations and inventory items; importing products from Shopify.
commerce.inventory:write Setting stock levels, for one item or in a batch by SKU.
commerce.customers:read Customers, customer groups and gift cards.
commerce.customers:write Changing customers and customer groups.
commerce.orders:read Orders with their documents and fulfilments, fulfilment providers with their deliveries and events, and returns with their reasons.
commerce.orders:write Editing orders and adding notes.
commerce.returns:write Creating, approving, rejecting, receiving and cancelling returns, and changing return reasons.
commerce.refunds:write Refunding and cancelling orders, and refunding returns.
commerce.promotions:write Promotions, reading them included, and issuing, changing and adjusting gift cards.
commerce.fulfillment:write Creating fulfilments and marking them dispatched, shipped, delivered or cancelled.
commerce.finance:read The balance and the ledger, disputes, payouts and tax reports.
commerce.disputes:write Saving a dispute's evidence, sending it to the bank and accepting a dispute.

Two wider forms exist. commerce:* grants every scope, and an area with :*, such as commerce.orders:*, grants every scope in that area. No key can manage the merchant profile, because it holds the owners' identities: an admin does that signed in. No key can ask for a payout either: an admin asks for one signed in.

  1. Go to Organizations, open your organization and choose Settings.
  2. In the API keys card, choose New key….
  3. Enter a Label of at least two characters that says what the key is for. The label is the only way to tell keys apart later.
  4. Choose a Rate limit. The default is 4,000 requests an hour.
  5. Optionally, fill in the IP allow-list with the addresses or CIDR ranges the key may be used from, such as 203.0.113.0/24. Separate them with commas or new lines. We refuse requests from anywhere else.
  6. Choose Create key, then copy the key from the dialog. It starts with ct_. We show it once and cannot show it again.

Warning

The form cannot set scopes yet, so a key made in the dashboard is refused by every Commerce API route. Create keys that need to work through the API, as With the API shows. The dialog also tells you to send the key as a Bearer token; send it in the X-API-Key header instead.

  1. In the API keys card, choose Revoke… on the key's row.
  2. Type revoke and choose Revoke key.

The key stays in the table marked Revoked. You cannot turn it back on, so create a new key to replace it. Requests with the key can succeed for up to 10 seconds after you revoke it.

The table lists every key with its Status, Rate limit and the addresses it is Allowed from, or Anywhere when it has no allow-list. The Last used column shows Never for every key, because we do not record when a key is used yet. A key never appears in full again after the creation dialog closes.

401 Missing API key or 401 Invalid API key
The request had no X-API-Key header, or the key is wrong or revoked. A key sent as Authorization: Bearer is not read at all.
403 API key is not allowed from this address
The request came from an address outside the key's allow-list.
403 with scope_required
The key lacks the scope the route needs. The message names it, for example This API key needs the commerce.orders:read scope. Scopes cannot be changed on an existing key, so create a new key with the scopes it needs and revoke the old one.
403 with people_only
The route manages the merchant profile, which no key can reach. An admin has to do it signed in.
403 Organization inactive
The organization is not active: it is pending, suspended, closed or deleted. Its keys work again only if it becomes active.
404 Organization not found
The organization slug in the path is not the one the key belongs to.
429 API key rate limit exceeded
The key made more requests in the last 60 minutes than its rate limit allows. Wait, or create a key with a higher limit.

Managing keys takes an owner's or admin's access token, sent as Authorization: Bearer $CORITAN_TOKEN.

Send the scopes as a list under permissions.scopes:

Shell
curl -X POST "https://api.coritan.com/api/v1/orgs/acme/api-keys" \
  -H "Authorization: Bearer $CORITAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"label": "Order sync", "permissions": {"scopes": ["commerce.orders:read", "commerce.fulfillment:write"]}, "rate_limit_per_hour": 4000, "ip_whitelist": ["203.0.113.0/24"]}'
Field Required What it holds
label Yes Up to 100 characters.
permissions No An object whose scopes list holds the key's scopes. Without it, the key has none.
rate_limit_per_hour No Requests allowed in any 60 minutes. Defaults to 4000.
ip_whitelist No Addresses or CIDR ranges the key may be used from. Leave it out to allow any address.

The answer is 201 with the key's id, label, permissions, rate_limit_per_hour, ip_whitelist, is_active and created_at, and the key itself in raw_key. Store raw_key now: no later answer contains it.

Call the Commerce API with the key

Section titled Call the Commerce API with the key
Shell
curl "https://api.coritan.com/api/v1/orgs/acme/commerce/orders?limit=20" \
  -H "X-API-Key: $ORG_API_KEY"
Route What it does
GET /api/v1/orgs/{org_slug}/api-keys Lists every key, newest first, revoked ones included.
POST /api/v1/orgs/{org_slug}/api-keys Creates a key and answers 201 with raw_key.
DELETE /api/v1/orgs/{org_slug}/api-keys/{key_id} Revokes the key. Answers 404 API key not found for a key another organization owns.

No route changes a key once it exists.

API operations on this page

MethodPathWhat it does
GET/api/v1/orgs/{org_slug}/api-keysList API keys
POST/api/v1/orgs/{org_slug}/api-keysCreate API key
DELETE/api/v1/orgs/{org_slug}/api-keys/{key_id}Revoke API key