Skip to content
Sandbox

Authentication

How to present a Transaction Intelligence API key, where to keep its secret, and what a 401 or a 403 response means.

View as Markdown

Every request to the Transaction Intelligence API, apart from the public contract at GET /openapi.json, is authenticated with an API key carried in the Authorization header. This page covers the key format, how to present it, where to keep its secret and how to read 401 and 403 refusals. Creating a key step by step is covered in the Quickstart; reading usage per key is covered in Usage and API keys.

The credential format

A Transaction Intelligence key belongs to the txn family. In the sandbox it reads:

nry_txn_sbx_<key_id>.<secret>
  • nry_txn_sbx_: the prefix. It states the family (txn) and the environment (sbx, the sandbox).
  • <key_id>: the key's public identifier, 10 characters long. It is what Platform shows in the key list and on the Usage page; it is not secret.
  • <secret>: the secret part, after the dot. It is shown once only.

The contract also describes a nry_txn_live_ prefix for production. No such key can be created today: production is not open (see Sandbox limitations). It is not obtained through any sequence of actions: it is requested, Noryo reviews it, and an approval issues no key of that form (see Production access).

The prefix is part of what the server checks: a key presented under a prefix that does not match the one recorded when it was created is refused with 401, even if the secret is correct.

Presenting the key

Send the whole key, prefix included, in the Authorization header with the Bearer scheme. It is the only authentication scheme in the contract.

curl -X POST https://api.noryo.app/transactions/v1/enrichments \
  -H "Authorization: Bearer $NORYO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "descriptor": "PRLV SEPA NETFLIX INTERNATIONAL",
    "direction": "outgoing",
    "occurred_at": "2026-09-05T03:10:00+02:00",
    "amount": { "value": "13.49", "currency": "EUR" }
  }'
Shell
const response = await fetch("https://api.noryo.app/transactions/v1/enrichments", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.NORYO_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    descriptor: "PRLV SEPA NETFLIX INTERNATIONAL",
    direction: "outgoing",
    occurred_at: "2026-09-05T03:10:00+02:00",
    amount: { value: "13.49", currency: "EUR" },
  }),
});
TypeScript

The contract itself, GET https://api.noryo.app/openapi.json, is the only resource served without a key: a machine can read it with no workspace context and without consuming any rate-limit token.

Getting a key on Platform

Keys are created on Platform, on the API keys page. You sign in with your Noryo identity; keys belong to the workspace you are a member of, not to you personally.

  1. Enable the Transaction Intelligence sandbox. A workspace owner or admin enables it once; the action is logged. It is specific to Transaction Intelligence, and it requires a complete developer profile for the workspace: identity, professional phone number, organisation, and what you are building. Without it, enabling is refused and no key is issued.
  2. Create a key. You give it a name and a purpose. Platform then shows the full credential.
  3. Copy the secret straight away. It is shown at that moment only. Noryo does not keep the secret: only a verifier is stored, enough to recognise the key but not to reconstruct it. A lost secret cannot be recovered; you revoke the key and create another.

The number of active keys per workspace is capped. Platform reads the cap from the server; revoked keys do not count towards it.

Note

There is no documented rotation procedure. To replace a key: revoke it, then create a new one. If you suspect a secret has leaked, revoke first.

Where to keep the secret

The secret is a server credential. It lives in an environment variable on your server (NORYO_API_KEY in the examples throughout this documentation), read by the process that calls the API.

LocationVerdict
Server environment variable, or a secrets managerRecommended
JavaScript bundle served to a browserNever
Public code repository, or any committed fileNever
Mobile application binaryNever
Client-side JavaScript, browser extension, web pageNever

A secret embedded in a client can be read by anyone who holds that client. If your mobile apps or web pages need enrichments, route them through your own server, which alone holds the key.

Revocation

A key is revoked from Platform, immediately and with no grace period. From the very next request it receives 401; that request is not counted as usage and does not touch the rate limit. A revoked key keeps its history on the Usage page: what it did before revocation remains readable.

Isolated families

Noryo exposes several APIs, each with its own key family. A Merchant API key, prefixed nry_mer_, is refused with 401 on Transaction Intelligence, and a nry_txn_ key is refused on the Merchant API. The isolation is enforced by the verifier itself, not by a mere filter on the prefix: to this server, a key from another family is an unknown credential.

401 or 403

The two identity-related refusals read differently.

StatusProblem typeWhat it meansWhat to do
401invalid_api_keyThe credential is not usable: missing, malformed, from another family, unknown, revoked, or presented under a prefix that does not match.Check the Authorization header, then the key's state on Platform.
403account_inactiveThe key is recognised, but the workspace or organisation is not active.Contact support with the request_id.

The 401 is deliberately a single code: the server does not say whether the key exists, whether it once existed, or whether only the secret is wrong. Telling those cases apart would be an enumeration oracle.

Neither a 401 nor a 403 consumes a rate-limit token, and neither appears in usage on Platform: the credential check comes before the rate limit. Three refusals come even earlier: 400 for an undeclared host, 415 for a body that is not application/json, 413 for a body that is too large. Past the credential, a 400 on the JSON or on the Idempotency-Key, a 422, a 404 or a 409 does consume a token, because the key was valid.

A refusal is an RFC 9457 problem, served as application/problem+json:

{
  "type": "https://noryo.app/problems/transactions/invalid_api_key",
  "title": "La credential presentee n'est pas utilisable.",
  "status": 401,
  "request_id": "req_01J9…"
}
JSON

Compare the type, never the title: the URI is stable, the sentence may be reworded. The full catalogue is in Errors and at /errors/invalid_api_key.

The request identifier

Every response rendered after authentication carries the noryo-request-id header; every error, even one prior to the credential, carries the same identifier in the request_id field of its body. It is the identifier to quote to support.

Two responses come from the hosting layer, before the API, and carry none: a 405 (undeclared verb on a known path, empty body, no Allow header) and a 404 on an unknown path. If your call gets either of those without a noryo-request-id, check the verb and the path first.

Warning

Never paste the key into a support ticket, an application log or a screenshot. The noryo-request-id is enough.

Further reading

Published on 2026-10-09 10:17 UTC (version 3).

Was this page helpful?