# not_found

> The not_found status is a complete, unbilled result, not an error. What it contains, how it differs from a 404 or a 503, and what you can do with it.

`not_found` means: **the engine answered, and its answer is "nobody"**. No usable merchant identity was recognised in the descriptor. It is a normal, complete answer, returned as `200`.

## What it looks like

```json
{
  "enrichment_id": "enr_9a1d4c2e-7b3f-4e8a-a6d5-0c1b2e3f4a5b",
  "merchant": null,
  "enrichment": {
    "status": "not_found",
    "reason": "no_usable_merchant_identity",
    "environment": "production",
    "source": "noryo",
    "customized": false
  },
  "usage": { "billable": false, "units": 0, "deduplicated": false, "deduplicated_by": null }
}
```

This example illustrates the shape; its identifiers do not come from a real call.

| Item | Value |
|---|---|
| HTTP status | `200` |
| `merchant` | `null` |
| `enrichment.reason` | `no_usable_merchant_identity` |
| Billing | None: `billable: false`, `units: 0`. In Sandbox, nothing is taken from the allowance. |
| `enrichment_id` | Yes: the result is recorded and can be read back. Having no content to purge, it does not turn into a `410` after 90 days |

## Three responses not to confuse

| Response | What it means | What to do |
|---|---|---|
| `200` and `status: not_found` | The engine answered: nobody | Display the raw descriptor; do not retry |
| `404 enrichment_not_found` | The requested `enrichment_id` does not exist for you | Check the identifier, the key and the environment |
| `503 engine_error` | The engine did not answer; nothing is billed or memorised | Retry with the same `Idempotency-Key` |

Retrying a `not_found` unchanged changes nothing: the same transaction sent again returns the same result, through deduplication if it carries an `external_transaction_id`.

## A `not_found` is memorised

With an `external_transaction_id`, the `not_found` becomes the transaction's current result. Sending the same transaction again returns that same `not_found`, with `deduplicated: true`, unbilled. It is not a failure blocking the transaction: it is the result the transaction has.

## And later?

The catalogue's coverage evolves. To try a `not_found` transaction again, refresh it with the same economic input: see [Refresh](https://developer.noryo.app/en-GB/merchant/refresh).

- If the recomputation succeeds (`refresh_recalculated`), it becomes the current result and is billed.
- If it still returns `not_found` or `partial`, it is not billed and replaces nothing.

The refresh requires the original call to have carried an `external_transaction_id`.

## What to do with a `not_found`

- Display the raw descriptor as the bank wrote it, rather than an invented name.
- Count it separately in your metrics: it is a coverage limit, not an integration error.
- Do not treat it as an error in your alerts: keep those for `5xx` and unexpected `4xx`.

---

Canonical page: https://developer.noryo.app/en-GB/merchant/results/not-found
