# Tuski email validation result codes: verdicts and quality score

Each address in a finished Tuski email validation job carries a `verdict`, such as `deliverable`, `typo` or `catch_all`, and a `quality_score` from 0 to 100. The score comes beside the verdict on every row. Reading results is free, and validation costs $0.01 per address per address pay as you go.

## At a glance

- **Status:** `GET https://agents.tuski.ai/zcj/sycufywbb32c/api/v1/email-validation/jobs/{job_id}` returns the job's `status` and per-outcome counters.
- **Results:** `GET https://agents.tuski.ai/zcj/sycufywbb32c/api/v1/email-validation/jobs/{job_id}/results?format=json&limit=500&offset=0` returns one row per address, with `verdict`, `quality_score` and `charged`.
- **Reading status and results:** costs nothing, listed at $0.
- **Validation price:** $0.01 per address pay as you go, or from $0.0036 per address on prepaid credits. Credit plans start at $3.
- **Payment:** creating a job returns a 402, the price quote, which you pay over x402 or MPP and retry. A card works for calls of $0.50 or more.
- **Full purchase flow:** [the buyer skill](https://agents.tuski.ai/zcj/sycufywbb32c/SKILL.md)

## Verdicts and the action for each address

The `verdict` field on each row is derived from the row's `status`, `preflight` and `reason`. The table gives the action for the verdicts that have one.

| Verdict | `verdict` value | Action |
| --- | --- | --- |
| Deliverable | `deliverable` | Keep it |
| Invalid | `invalid` | Drop it |
| No MX | `no_mx` | Drop it |
| Burner | `burner` | Drop it |
| Typo | `typo` | Your decision |
| Catch-all | `catch_all` | Your decision |
| Full box | `full_box` | Your decision |
| Role | `role` | Your decision |

Two verdicts have a documented cause: `no_mx` marks a domain with no mail server, and `typo` marks a domain that misspells the domain of a well-known mail provider. Besides the eight, the `verdict` field can also hold `no_reply`, `blocked`, `unknown`, `soft_temp`, `routing_error`, `other_bounce` or `not_judged`.

To recheck an address, create a new job with `"fresh_probe": true`. Without it, Tuski can reuse a result it remembers from a recent check. A new job is billed like any other job.

## Quality score beside the verdict

`quality_score` is a number from 0 to 100 on every row, returned beside `verdict`. Both come in the JSON results and in the CSV export, so you can sort or filter by either.

## What reading and cancelling cost

Reading a job's status and results costs nothing, however often you poll.

If you cancel a job, each charged address that was not yet sent is refunded. Addresses already sent still receive a verdict. The no-MX and send-failure refunds follow once their bounce check finishes.

## Job status fields and counters

A finished job's status response is a JSON object with `job_id`, `status`, `total`, `queued`, `sent`, nine per-outcome counters, an `eta` object, `error` and `paused_reason`.

| Field | Holds |
| --- | --- |
| `status` | The job's state. `done` means finished, and `cancelled` means the job was cancelled. |
| `total`, `queued`, `sent` | Addresses in the job, still queued, and sent a probe |
| `valid`, `invalid`, `unknown`, `unreachable`, `mailbox_full`, `blocked`, `soft_temp`, `routing_error`, `other_bounce` | Per-outcome counters, each named after the row `status` value of the same name |
| `eta` | Progress: `total`, `sent`, `resolved`, `queued_remaining`, `sends_per_hour`, `eta_send_hours`, `finalize_after_sec` |
| `error`, `paused_reason` | Why a job failed or paused, when it did |

The counters count outcomes by `status`, not by verdict. To list the rows behind a counter, pass that value as `status` on the results call. Through the storefront, the status call always returns immediately and ignores `wait`.

## Result row fields

A JSON results page holds `job_id`, `rows`, `count`, `limit`, `offset` and `has_more`. Each row holds `email`, `status`, `smtp_code`, `dsn_status`, `reason`, `sent_at`, `bounce_at`, `preflight`, `mx_provider`, `mx_gateway`, `mx_records`, `quality_score`, `verdict` and `charged`.

| Field | Holds |
| --- | --- |
| `verdict` | The verdict you act on |
| `quality_score` | The 0 to 100 score |
| `status` | The pipeline outcome that the counters use |

## Results request parameters

| Parameter | Values |
| --- | --- |
| `format` | `json` (the default) or `csv` |
| `limit` | 1 to 5000 rows per page |
| `offset` | 0 or more. Request the next page while `has_more` is true. |
| `status` | One row status value. Leave it out to get every row. |

The accepted `status` values are the terminal outcomes `valid`, `invalid`, `unknown`, `unreachable`, `mailbox_full`, `blocked`, `soft_temp`, `routing_error` and `other_bounce`, and the in-flight states `pending`, `queued`, `sending`, `sent` and `cancelled`. In-flight states are not a deliverability judgement. A CSV page has no `has_more`. It carries an `X-Total-Count` header, plus a `Link` header with `rel="next"` when more rows remain.

## Errors on status and results reads

| Status and code | Meaning | Action |
| --- | --- | --- |
| 404 `job_not_found` | The job does not exist or belongs to another organization | Check `job_id` against the create response |
| 422 `unknown_status_filter` | The `status` value is not in the list above | Send an accepted value, or leave `status` out |
| 422 `invalid_request` | A query parameter is out of range | Keep `limit` within 1 to 5000 and `offset` at 0 or more |
| 413 | The CSV export is too large | Page it with `limit` and `offset` |
| 429 | Rate limited | Wait for `Retry-After`, then retry |

A storefront guard failure, such as a missing payment, comes back as `{"error": ...}`. Every other error comes back as `{"detail": ...}`. Payment and identity codes are in the [error reference](https://agents.tuski.ai/zcj/sycufywbb32c/errors.md).

## Frequently asked questions

### What does catch-all mean in a Tuski result?

Catch-all is one of the eight verdicts, written `catch_all` in the row's `verdict` field. The same row also carries its `quality_score` from 0 to 100, so you can weigh a catch-all address by its score as well as its verdict.

### What does a role email address verdict mean?

Role is one of the eight verdicts, written `role` in the row. Like every row, it also carries a `quality_score` from 0 to 100 that you can read beside the verdict.

### What does deliverable mean in Tuski email verification?

`deliverable` is one of the eight verdicts. Before any address gets a verdict, Tuski checks its syntax, domain and MX records, screens for disposable and typo domains, and sends controlled probes that gather bounce signals. Keep a deliverable address.

### Does reading the results cost anything?

No. Reading a job's status and results is free, listed at $0, however often you poll.

### Do I need the status counters if I read every row?

No. The counters give a summary by row `status` without reading the results. To act on individual addresses, read the rows and use `verdict` and `quality_score`.

## Keep reading

- [Buyer skill](https://agents.tuski.ai/zcj/sycufywbb32c/SKILL.md): the full purchase flow
- [Email Validation API reference](https://agents.tuski.ai/zcj/sycufywbb32c/services/email-validation/openapi.json): jobs, status, results and cancel
- [How to pay](https://agents.tuski.ai/zcj/sycufywbb32c/payment.md): rails, credit plans and top-ups
- [Machine catalog](https://agents.tuski.ai/zcj/sycufywbb32c/manifest.json): live prices and plans

---

Updated 2026-10-22. All Tuski guides: https://agents.tuski.ai/guides.md. Storefront: https://agents.tuski.ai/zcj/sycufywbb32c/llms.txt.
