---
title: Job inputs
description: The shared input names a job run accepts, how looot maps them to each provider's own fields, and the jobInputs coverage a search row shows.
sidebar:
  icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" class="looot-icon"><circle class="li-a" cx="5" cy="12" r="2.5"/><path class="li-i" d="M7.5 12c4.5 0 4.5-6 9-6M7.5 12h9M7.5 12c4.5 0 4.5 6 9 6"/><circle class="li-i" cx="19" cy="6" r="2"/><circle class="li-i" cx="19" cy="12" r="2"/><circle class="li-i" cx="19" cy="18" r="2"/></svg>'
---

A `job:<id>` run takes shared field names, not one provider's own parameter names. looot maps
what you send to each provider's own schema before it runs, or before it tries the next provider
in a fallback walk.

<InputFanout />

## The canonical names

```
email, url, domain, name, first_name, last_name, company, linkedin_url, phone
```

looot reads your top-level keys ignoring case, `_`, `-` and spaces, plus these synonyms:

| You send | looot reads |
| --- | --- |
| `firstName`, `firstname` | `first_name` |
| `lastName` | `last_name` |
| `fullName`, `full_name` | `name` |
| `website`, `site`, `companyDomain` | `domain` |
| `companyName`, `organization` | `company` |
| `linkedin`, `linkedinUrl`, `linkedInUrl`, `profile_url` | `linkedin_url` |
| `phoneNumber`, `mobile` | `phone` |
| `emailAddress` | `email` |
| `URL`, `link` | `url` |

A domain sent as a URL (`https://example.com/about`) is reduced to its host (`example.com`). A
blank string counts as not given, so `{name: "", first_name: "Jane", last_name: "Doe"}` reads as
the two name parts. Any other key you send is kept as is and passed through unchanged.

Each provider then gets its own input, built from its own schema. A schema that only takes a full
name gets `first_name + " " + last_name`; one that only takes name parts gets `name` split at the
first space. On a `company.*` job the key `name` is read as the company's name.

## Coverage: `jobInputs`

Search and discover rows carry a top-level `jobInputs` object when it is non-empty, one entry per
job id among the page's rows:

```json
{
  "jobInputs": {
    "people.email.find": {
      "first_name": { "endpoints": 6, "of": 7 },
      "last_name": { "endpoints": 6, "of": 7 },
      "domain": { "endpoints": 5, "of": 7 },
      "linkedin_url": { "endpoints": 2, "of": 7 }
    }
  }
}
```

`endpoints` is how many of the job's live providers take that field; `of` is how many live
providers the job has in total. An input more endpoints take gives a fallback walk more providers
to try. Names are ordered by `endpoints`, most first.

`looot search` and `looot discover` print this as a line under the search table or discover
answer:

```
Inputs for job:people.email.find: first_name (6 of 7), last_name (6 of 7), domain (5 of 7), linkedin_url (2 of 7)
```

## Checks before a provider is called

Before the pick happens, a job run's `email`, `url`, `domain` and `phone` values are checked
against one fixed rule, the same for every job and provider. A value that fails is refused as
[`invalid_input`](/errors/job-refusals#invalid_input) at $0, before any hold:

- **`email`** needs one `@`, a non-empty local part, and a domain with at least one dot and no
  whitespace. `jane.doe@example.com` passes; `jane.doe@example` and `"jane.doe@example.com "`
  (trailing space) do not.
- **`url`** must parse as `http` or `https` with a host. `https://example.com` passes;
  `www.example.com` (no scheme) does not.
- **`domain`** is refused only when it cannot be a host: no dot, or a space or `@` in it.
  `example.com` passes; `"not a domain"` does not. A URL is reduced to its host first, so
  `https://example.com/about` is never refused for being a URL.
- **`phone`** is refused only when it has fewer than 7 digits, in any format. There is no upper
  bound.

The message names the field you sent, for example `email: "not-an-email" is not an email address`
or `domain: "not a domain" is not a domain name like example.com`. The value is checked exactly as
sent, with no trimming.

This is a run-time refusal on `job:<id>` runs only. A direct run on an endpoint id is unchanged,
and every other field in a job's input is not checked here; it routes as sent.

<Related />
