---
title: Normalized output
description: The normalized block next to result, which jobs carry fixed field names, the email status vocabulary, and how verdict differs from outcome.
---

Every provider answers in its own shape. On a handful of jobs, a completed run can also carry
`normalized`, a fixed-field reading of that same answer, next to `result`.

## Shape

```json
{
  "job": "people.email.verify",
  "endpointId": "icypeas-email-verify",
  "fields": { "email": "jane.doe@example.com", "status": "valid", "deliverable": true },
  "missing": [],
  "ambiguous": [],
  "unmapped": [],
  "providerValues": { "status": "VALID" },
  "verdict": "hit",
  "verdictReason": null,
  "mapVerified": true
}
```

- `fields` always holds every field of the job, `null` for one that was not found.
- `missing` lists fields whose path found nothing in the answer; `unmapped` is the subset of those
  with no path defined at all.
- `ambiguous` lists fields the provider did answer, whose value did not translate to a known one.
- `providerValues` keeps the provider's own word for each translated field.
- `verdict` is the extractor's own read of the answer: `hit`, `weak`, `miss`, `rejected` or
  `skipped`. It can differ from the run's own [`outcome`](/concepts/outcomes) (see below).
- `mapVerified` is `true` only when the field map has been checked against saved provider answers and
  every checked path matched.

## Jobs and fields

| Job | Fields |
| --- | --- |
| `people.email.verify` | `email`, `status`, `deliverable` |
| `people.email.find` | `email`, `check` |
| `people.phone.find` | `phone`, `lineType`, `country` |
| `company.enrich` | `name`, `domain`, `industry`, `size` |
| `web.scrape.markdown` | `markdown`, `title` |
| `backlinks.domain.summary` | `backlinks`, `referringDomains`, `rank` |

`endpointId` inside the block is the endpoint whose answer is in `result`: the route's hit, else
the last attempt that missed, else the endpoint you asked for.

## Email status vocabulary

`status` (verify) and `check` (find) use: `valid`, `invalid`, `catch_all`, `risky`, `unknown`. A
provider word the table does not recognize lands as `unknown` and appears in `ambiguous`.
`deliverable` is set only when the provider has a field that reports deliverability itself. looot
never derives it from `status`.

Worked example, `job:people.email.find` on `jane.doe@example.com` at `example.com`:

```json
{ "job": "people.email.find", "fields": { "email": "jane.doe@example.com", "check": "valid" } }
```

## When it is absent

`normalized` is absent, never `null`, when:

- the run did not complete,
- the endpoint that answered has no stored field map for its job,
- the run asked for a non-raw `output` mode, or
- there is no saved answer to read.

It only appears on a run whose gateway has this turned on; treat it as optional on every job, not
only the ones without a map yet.

## `verdict` vs `outcome`

`verdict` is a second, independent read of the same answer, and the two can disagree by design.
Known cases: a catch-all verify answer reads `verdict: "hit"` while `outcome` reads `weak`; an
Icypeas `not_sure` reads `verdict: "unknown"` (a miss) while `outcome` reads `hit`. Neither field
ever rewrites the other, and neither changes which provider fallback tries next or what you were
charged. Use `outcome` for money and routing questions, `verdict` for a second opinion on the
answer's field-level content.

<Related />
