Skip to content
Sandbox

Quickstart

One enrichment end to end in Sandbox: create, replay, read back, refresh, then trigger an error, with the API's real responses.

View as Markdown

This walkthrough makes a first complete call in Sandbox. The responses shown come from real calls to the API; only the identifiers will differ for you. Copy the shape, not the identifiers.

Before you start

You need a Sandbox key, shaped nry_mer_sbx_<key_id>.<secret>. It is created on the API keys page of Platform, and its secret is shown only once. See API keys.

export NORYO_API_KEY='nry_mer_sbx_<key_id>.<secret>'   # the secret shown at creation
export NORYO_API='https://api.noryo.app'               # base URL: configure it, the host is not in the contract
Shell

1. Enrich a descriptor

curl -sS -i -X POST "$NORYO_API/merchant/v1/enrichments" \
  -H "Authorization: Bearer $NORYO_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: demo-001" \
  -d '{
    "descriptor": "CB MCDONALDS PARIS 4519",
    "amount": 12.40,
    "currency": "EUR",
    "occurred_at": "2026-09-06T11:42:00Z",
    "country": "FR",
    "mcc": "5814",
    "external_transaction_id": "tx_demo_001"
  }'
Shell
HTTP/1.1 200 OK
content-type: application/json
noryo-request-id: req_01a07868-6443-79fa-a4c8-221f1745244f
noryo-idempotency-replayed: false
noryo-ratelimit-limit: 60
noryo-ratelimit-remaining: 59
HTTP
{
  "enrichment_id": "enr_ffe80956-cc3e-4e1f-b4b6-724ad231fbb7",
  "merchant": {
    "name": "McDonald's",
    "category": "alimentation.restaurant",
    "location": { "city": "PARIS", "postal_code": "75018" },
    "logo_url": "https://www.mcdonalds.fr/apple-touch-icon.png",
    "confidence": 0.96
  },
  "enrichment": {
    "status": "resolved",
    "reason": null,
    "environment": "sandbox",
    "source": "noryo",
    "customized": false
  },
  "usage": { "billable": false, "units": 1, "deduplicated": false, "deduplicated_by": null }
}
JSON

Read enrichment.status first: here, resolved. In Sandbox, billable is always false; units: 1 is taken from the Sandbox allowance. confidence: 0.96 is a score, not a probability: see Confidence.

2. Replay the same request

Run exactly the same command again, with the same Idempotency-Key and the same body.

HTTP/1.1 200 OK
noryo-idempotency-replayed: true
HTTP

The body is the first response's, served from the idempotency memory. Nothing was recomputed and nothing new was billed. The noryo-request-id is new: every attempt has its own. This is what makes a network retry safe. See Idempotency.

3. Read the result back

curl -sS "$NORYO_API/merchant/v1/enrichments/enr_ffe80956-cc3e-4e1f-b4b6-724ad231fbb7" \
  -H "Authorization: Bearer $NORYO_API_KEY"
Shell
{
  "enrichment_id": "enr_ffe80956-cc3e-4e1f-b4b6-724ad231fbb7",
  "merchant": { "name": "McDonald's", "confidence": 0.96, "…": "…" },
  "enrichment": { "status": "resolved", "environment": "sandbox", "…": "…" },
  "retrieval": { "billable": false, "units": 0 },
  "original": { "billable": false, "units": 1 }
}
JSON

retrieval says what this read costs: always nothing. original says what the enrichment cost when it happened. See Read an enrichment.

4. Refresh

A refresh recomputes the same transaction. It requires an Idempotency-Key and the same economic input as the original call, without external_transaction_id in the body.

curl -sS -i -X POST "$NORYO_API/merchant/v1/enrichments/enr_ffe80956-cc3e-4e1f-b4b6-724ad231fbb7/refresh" \
  -H "Authorization: Bearer $NORYO_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: demo-refresh-001" \
  -d '{"descriptor":"CB MCDONALDS PARIS 4519","amount":12.40,"currency":"EUR","occurred_at":"2026-09-06T11:42:00Z","country":"FR","mcc":"5814"}'
Shell
HTTP/1.1 200 OK
location: /merchant/v1/enrichments/enr_dd424f15-6371-4565-a4dc-8770815d48c4
noryo-idempotency-replayed: false
HTTP

A new enrichment_id, announced in a relative Location header. enrichment.status is refresh_recalculated, and the old identifier still points at the old result. See Refresh.

5. Trigger an error

Reuse the key demo-001 with a different body:

curl -sS -X POST "$NORYO_API/merchant/v1/enrichments" \
  -H "Authorization: Bearer $NORYO_API_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: demo-001" \
  -d '{"descriptor":"AUTRE CHARGE","external_transaction_id":"tx_autre"}'
Shell
{
  "type": "https://developer.noryo.app/errors/idempotency_key_reuse",
  "title": "Idempotency key reused",
  "status": 409,
  "code": "idempotency_key_reuse",
  "detail": "this Idempotency-Key is bound to a different request for the remainder of its TTL",
  "request_id": "req_01a07784-d343-75f8-b0ae-b0629b305cd4"
}
JSON

A key stays bound to its first request for 24 hours. Every error has this shape; build your logic on code. See Errors.

Next steps

  • Send both identifiers in production: the key protects the retry, the transaction identifier protects the invoice. See The two identifiers.
  • Implement retries that honour Retry-After and keep the same Idempotency-Key. See Retries.
  • Store what you need on your side: the content of a result is only kept for 90 days. See Retention and 410.
  • Prepare for Production: see Going live.

Published on 2026-10-09 10:18 UTC (version 2).

Was this page helpful?