---
title: Outcomes
description: The difference between status, outcome and outcomeReason on a run, what weak and guessed mean, and how whoseError and retryable steer a retry.
---

A run carries three separate reads on what happened: `status` (looot's own lifecycle state),
`outcome` (whether the answer was any good), and `outcomeReason` (why). A completed, charged run
can still be a `miss`.

## `status`

`status` is `queued`, `running`, `pending_provider`, `completed`, `failed`, `blocked`, `stopped`
or `reconciliation_pending`. It tells you where the run is in its lifecycle, not whether the
answer was useful. A run that finished normally is `completed` even when the provider found
nothing.

## `outcome`

`outcome` is `hit`, `weak`, `miss`, `error`, `rejected`, `skipped` or `pending`, and
`outcomeReason` says why. It judges the answer, not the lifecycle:

| `outcome` | Meaning |
| --- | --- |
| `hit` | A usable answer. |
| `weak` | A flagged answer: the provider marked it uncertain, or it is a pattern guess (`verdict: "guessed"`). Worth a second check before you use it. |
| `miss` | The provider answered and found nothing (`tomba`'s `email: null` is still a completed, `outcome: "miss"` run). |
| `error` | The provider or gateway failed to produce an answer at all. |
| `rejected` | Your input, or your own credential, was refused. |
| `skipped` | The candidate was not dispatched (a fallback step that never ran). |
| `pending` | Still waiting, usually an async provider. |

## `weak` and `guessed`

`weak` covers two different things: an answer the provider itself flagged (a catch-all email
domain, for example), and a pattern guess from a provider that builds an address from a known
format without looking it up. Read `route.attempts[].verdict` to tell them apart; a
guess carries `verdict: "guessed"`. See [Free first](/concepts/free-first) for what a guess does
to a fallback walk and its price.

## `whoseError`, `retryable` and `retryHint`

On a failed run, `error` carries:

```json
{
  "code": "provider_error",
  "providerStatus": 502,
  "message": "The provider returned an error response.",
  "requestId": "req_...",
  "whoseError": "provider",
  "retryable": true,
  "retryHint": "Retry the run; if it keeps failing, the provider itself is rejecting or down."
}
```

`whoseError` is `provider`, `gateway` or `customer` (you), telling you whose side the problem sits
on. `retryable` is `true` only when the exact same request may succeed on a retry (a timeout, a
429, a 5xx); it is `false` when the request itself has to change first, for example a 4xx on your
own input. `retryHint` is the one sentence on what to do next.

A failed run is charged $0 and its hold is released. See [Access](/concepts/access) for what
`credential` and `access` mean when the problem is on your own account, not in the run.

<Related />
