# Read a past enrichment

`GET /merchant/v1/enrichments/{enrichment_id}` — Merchant API · [API reference](https://developer.noryo.app/en-GB/merchant/reference)

Authentication: `bearerCredential` (http bearer).

Returns the stored result. Reading is free and never bills.

The `retrieval` object says what **this read** costs; the `original` object says
what the enrichment cost when it happened. Two different questions, two objects.

## Parameters

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| `enrichment_id` | path | yes | string | `enr_` followed by a version 4 UUID, as returned by Noryo. Any other shape returns `404`. Pattern: `^enr_[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$`. |

## Responses

| Status | Description |
| --- | --- |
| `200` | The stored result. |
| `400` | `invalid_request` (unknown host) or `invalid_idempotency_key`: a read needs no `Idempotency-Key`, but one that is sent is still validated. |
| `401` | `invalid_api_key`. Missing, malformed, unknown, revoked — **always the same code**. Any distinction would be an oracle. |
| `403` | `insufficient_scope`, `account_inactive`, `production_not_enabled`. |
| `404` | Unknown identifier — **or an identifier belonging to another tenant**. The two are deliberately indistinguishable. |
| `410` | `result_content_expired`. The content passed its 90-day retention. The identity, the ledger line and the accounting record survive; only the content is gone. |
| `429` | `rate_limited`. Nothing was computed and nothing was billed. |
| `500` | `internal_error`. The body carries no detail about the incident; quote the `request_id` to support. Retrying with the same `Idempotency-Key` is safe. |

### `200` — `StoredEnrichment`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `enrichment_id` | string | — | Example: `"enr_7f3c1e20-…"`. |
| `merchant` | Merchant \| null | — | — |
| `merchant.name` | string | — | Example: `"McDonald's"`. |
| `merchant.category` | string | — | Example: `"alimentation.restaurant"`. |
| `merchant.logo_url` | string · uri | — | — |
| `merchant.location` | object \| null | — | **Always present**, `null` when unknown. Absent and unknown look too alike for a client to have to tell them apart. |
| `merchant.location.city` | string | — | Example: `"PARIS"`. |
| `merchant.location.postal_code` | string | — | Example: `"75018"`. |
| `merchant.confidence` | number · 0–1 | — | A **model confidence score** from 0 to 1. It should **not** be interpreted as a calibrated probability of correctness — Noryo has measured that its ordering is not monotonic above 0.95. See the guide. |
| `enrichment` | object | — | — |
| `enrichment.status` | string | — | `resolved` — identity complete and above the policy threshold. `partial` — something is missing or below threshold. `not_found` — the engine answered, and its answer is "nobody". Values: `resolved`, `partial`, `not_found`, `refresh_recalculated`. |
| `enrichment.reason` | string | — | — |
| `enrichment.environment` | string | — | Values: `sandbox`, `production`. |
| `enrichment.source` | string | — | — |
| `enrichment.customized` | boolean | — | `true` when one of **your organization's rules** (Platform → Rules) changed this response — for example a display name or a category. The Noryo result itself is stored unchanged and rules never apply outside your organization and the key's environment. `false` otherwise. A `POST` is rendered with the rules published at that moment and an idempotent replay returns that same body; a `GET` applies the rules published **now**. |
| `enrichment.rules` | array<object> | — | **Optional** — present only when `customized` is `true`: the rules that changed this response, each with the version that applied. Which field each rule changed is shown in the Platform logs. |
| `enrichment.rules[].id` | string · uuid | — | — |
| `enrichment.rules[].version` | integer ≥ 1 | — | — |
| `retrieval` | object | — | What this read costs. Always free. |
| `retrieval.billable` | boolean = false | — | — |
| `retrieval.units` | integer = 0 | — | — |
| `original` | object | — | What the enrichment cost when it happened. |
| `original.billable` | boolean | — | — |
| `original.units` | integer | — | — |

## Errors named by the contract

- [`invalid_idempotency_key`](https://developer.noryo.app/en-GB/errors/invalid_idempotency_key)
- [`invalid_request`](https://developer.noryo.app/en-GB/errors/invalid_request)
- [`invalid_api_key`](https://developer.noryo.app/en-GB/errors/invalid_api_key)
- [`account_inactive`](https://developer.noryo.app/en-GB/errors/account_inactive)
- [`insufficient_scope`](https://developer.noryo.app/en-GB/errors/insufficient_scope)
- [`production_not_enabled`](https://developer.noryo.app/en-GB/errors/production_not_enabled)
- [`result_content_expired`](https://developer.noryo.app/en-GB/errors/result_content_expired)
- [`rate_limited`](https://developer.noryo.app/en-GB/errors/rate_limited)
- [`internal_error`](https://developer.noryo.app/en-GB/errors/internal_error)

## Request examples

cURL

```bash
curl -sS -g -X GET 'https://api.noryo.app/merchant/v1/enrichments/{enrichment_id}' \
  -H "Authorization: Bearer $NORYO_API_KEY"
```

JavaScript

```js
const response = await fetch("https://api.noryo.app/merchant/v1/enrichments/{enrichment_id}", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.NORYO_API_KEY}`,
  },
});
console.log(response.status, await response.text());
```

Python

```python
import os

import requests  # pip install requests

response = requests.get(
    "https://api.noryo.app/merchant/v1/enrichments/{enrichment_id}",
    headers={
        "Authorization": "Bearer " + os.environ["NORYO_API_KEY"],
    },
)
print(response.status_code, response.text)
```

Go

```go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.noryo.app/merchant/v1/enrichments/{enrichment_id}", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("NORYO_API_KEY"))

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	data, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(resp.StatusCode, string(data))
}
```

Java

```java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class Main {
    public static void main(String[] args) throws Exception {
        HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.noryo.app/merchant/v1/enrichments/{enrichment_id}"))
            .method("GET", HttpRequest.BodyPublishers.noBody())
            .header("Authorization", "Bearer " + System.getenv("NORYO_API_KEY"))
            .build();
        HttpResponse<String> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println(response.statusCode() + " " + response.body());
    }
}
```

C#

```csharp
using System;
using System.Net.Http;

using var client = new HttpClient();
using var request = new HttpRequestMessage(new HttpMethod("GET"), "https://api.noryo.app/merchant/v1/enrichments/{enrichment_id}");
request.Headers.TryAddWithoutValidation("Authorization", "Bearer " + Environment.GetEnvironmentVariable("NORYO_API_KEY"));

using var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
```

---

Canonical page: https://developer.noryo.app/en-GB/merchant/reference/get-enrichment
