Skip to content
Coritan Docs

Create organization API keys

Create a key for your own systems to call the Commerce API, the email marketing API or the game network feed, choose its scopes and revoke it.

View as Markdown

An organization API key lets your own systems call the Commerce API, the email marketing API and the game network feed 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, at https://api.coritan.com/api/v1/orgs/{org_slug}/commerce/..., on the email marketing API, at https://api.coritan.com/api/v1/orgs/{org_slug}/marketing/..., and on the game network feed, at https://api.coritan.com/api/v1/orgs/{org_slug}/network/..., sent in the X-API-Key header. A key with the commerce.storefront:forward scope also works on the Store API routes where a storefront's server passes on its visitors' addresses. Every other organization route takes a member's access token instead.

  • You need the owner or admin role in the organization. The API keys page is not in the menu for other roles.
  • For the Commerce API, Commerce must be turned on for the organization. Coritan turns it on, so ask support if it is not. Until then, the API keys page says Commerce is not on for this organization, and every Commerce API route answers 404 with the message Commerce is not enabled for this organization. The game network feed works without Commerce.
  • Work out which scopes the key needs from the table below. Give it the fewest that do the job.

A key reaches nothing 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, the store's media, 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.media:write Uploading the store's images and PDFs, changing their alt text, deleting them and importing a WordPress media library. Listing them takes commerce.catalog:read.
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.orders:edit Changing the items of a placed order: adding a variant, removing a line, changing a quantity or a unit price. Not part of commerce.orders:write.
commerce.orders:delete Deleting an order from the platform entirely. Not part of commerce.orders:write.
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, tax reports and the payment routing stats.
commerce.payments:read The store's payment pages with what they reported, and the payment routing stats.
commerce.payments:write Adding, changing, testing and deleting payment pages.
commerce.checkout:read The store's hosted checkout pages with what their payment site sent back, the domains that serve them, and a preview of a style.
commerce.checkout:write Creating and cancelling hosted checkout pages, and adding, verifying and removing their domains.
commerce.disputes:write Saving a dispute's evidence, sending it to the bank and accepting a dispute.
commerce.storefront:forward Passing your visitors' addresses and browsers on the Store API, sign-in, chat and contact routes, from your storefront's server. A key with only this scope reaches nothing else. Server-side storefronts: pass the visitor's address shows how to use it.
marketing.contacts:read Contacts, lists, custom fields, tags and segments, and exporting contacts.
marketing.contacts:write Adding, changing, deleting and bulk changing contacts; managing lists, fields, tags and segments; importing contacts. Reading imports takes this scope too.
marketing.campaigns:read Campaigns and their reports, saved and starter designs, signup forms, and checking a campaign.
marketing.campaigns:write Writing campaigns, designs and signup forms, and sending test emails.
marketing.campaigns:send Scheduling and sending a campaign, pausing, resuming and cancelling it, and resending it to non-openers. Not part of marketing.campaigns:write.
marketing.automations:read Automations, their runs and stats.
marketing.automations:write Changing automations, sending a test of one, and reading the secret that signs its webhook steps.
marketing.settings:read The sending setup: the domain, its DNS records, the limits and any pause.
marketing.settings:write Setting up the sending domain, checking its records, changing the sender, the postal address and the limits, and pausing and resuming sending.
network:read The purchases your game network delivers, from the game network feed.
network:write Sending the game network's status, market, leaderboards and players, and recording deliveries.

Two wider forms exist. commerce:* grants every scope, the email marketing and game network scopes included, and an area with :*, such as commerce.orders:* or network:*, grants every scope in that area. marketing:* grants every email marketing scope. The marketing.campaigns:send scope is not part of marketing.campaigns:write: a key needs it by name. 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, then choose Settings, then API keys. In the sidebar, you find them in your organization's block, under Settings.
  2. 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. Under Scopes, tick the scopes the key needs, such as Read orders, or Update the game network for the program that runs your game network. Each one shows its scope name, such as commerce.orders:read, from the table above. Tick Every scope instead to grant commerce:*, which includes the scopes added later. You cannot change the scopes once the key exists. The email marketing scopes, such as Read contacts and Send campaigns, are in the same list, and Every scope grants them too.
  5. Choose a Rate limit. The default is 4,000 requests an hour.
  6. 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.
  7. Choose Create key. The dialog API key created shows the key, which starts with ct_, with its scopes and limits. Copy the key, then choose I have saved them. We show it once and cannot show it again.

Send the key in the X-API-Key header, as Call the Commerce API with the key shows.

  1. On the API keys page, 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, its Scopes (Every scope, or how many it has), its Rate limit and the addresses it is Allowed from, or Anywhere when it has no allow-list. A key with none, such as one created through the API without permissions, shows No scopes: it reaches nothing, so replace it. 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.

For the email marketing API, send the marketing.* scopes the same way. A key that reads contacts and sends campaigns holds ["marketing.contacts:read", "marketing.campaigns:write", "marketing.campaigns:send"].

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"

The game network feed takes the key the same way. Connect your game network to your storefront shows its requests.

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