# Search companies

> Parameters that fail validation return 400 badrequest with the message invalidfilters.

Source: https://warmerly.com/docs/leads/search-companies

```text
GET /leads/search
```

| Query param | Type | Required | Description |
| --- | --- | --- | --- |
| `q` | string (max 200) | No | Full-text search across company name, description, and other indexed fields. |
| `country` | string (exactly 2 letters) | No | ISO country code, e.g. `GB`. |
| `category` | string (max 400) | No | One or more categories, comma-separated (e.g. `Restaurant,CafeOrCoffeeShop`). Matches a company's declared business type or industry exactly. |
| `provider` | string (max 100) | No | Email provider segment, e.g. `google`, `microsoft`. |
| `tech` | string (max 300) | No | One or more technologies, comma-separated (e.g. `shopify,klaviyo`), matches companies using **any** of them. |
| `channel` | `"email"` \\| `"form"` \\| `"linkedin"` | No | Which contact channel a company must have. **Defaults to `email`**: a company with no published contact address is never returned unless you ask for a different channel. `form` returns companies publishing a contact form, `linkedin` those with a company page. There is no value that removes the requirement. |
| `hasPhone` | `"true"` | No | Only companies publishing a telephone number. The flag filters (this one and the next four) accept `"true"` or `"false"`; `"false"` narrows nothing, and any other value returns `400 invalid_filters`. |
| `hasCompanyNumber` | `"true"` | No | Only companies publishing a Companies House registration number, in practice, UK-registered. |
| `hasVatNumber` | `"true"` | No | Only companies publishing a VAT number. |
| `hiring` | `"true"` | No | Only companies linking a careers page or stating they are hiring. |
| `hasContactForm` | `"true"` | No | Only companies publishing a contact form URL. |
| `city` | string (max 120) | No | Town or city, matched through the same text index as `q`. |
| `employeeBand` | string (max 20) | No | One coarse size band, e.g. `11-50`. Exact match, not a range. |
| `foundedFrom` / `foundedTo` | integer (1200-2100) | No | Inclusive founded-year range. |
| `cursor` | string (UUID) | No | Pass the previous response's `nextCursor` to fetch the next page. |
| `limit` | integer (1-100) | No | Page size. Default `50`. |

Parameters that fail validation return `400 bad_request` with the message `invalid_filters`.

```bash
curl "https://app.warmerly.com/api/v1/leads/search?country=GB&category=Restaurant&tech=shopify&limit=25" \
  -H "X-Api-Key: wmv_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

```json
{
  "rows": [
    { "id": "b1e6a2c4-9f3d-4a7e-8c1b-2d5f9a3e7c6b", "domain": "northwindtraders.com", "...": "every other field of the company object" }
  ],
  "nextCursor": "b1e6a2c4-9f3d-4a7e-8c1b-2d5f9a3e7c6b"
}
```

Each row is the full [company object](https://warmerly.com/docs/leads/search-companies#the-company-object). The response holds rows only: the number of matches and how complete the records are come from [`GET /leads/count`](https://warmerly.com/docs/leads/search-companies#match-count). `nextCursor` is `null` on the last page; keep paging with it until it is `null`. With `channel=form` or `channel=linkedin` a row's `contactEmail` can be `null`.

This endpoint has its own per-user throttle, separate from your API key's per-minute rate limit, see [Rate limits](https://warmerly.com/docs/leads/search-companies#rate-limits--errors) below.

## More from Leads

- [The company object](https://warmerly.com/docs/leads/the-company-object): Most fields can be null when the company does not publish them. inferredCategoryId is a display-only guess…
- [Match count](https://warmerly.com/docs/leads/match-count): A search response does not include a match count, because counting inside a search request would make the…
- [Database size](https://warmerly.com/docs/leads/database-size): How many companies the lead database currently holds. The crawl adds rows continuously, so these figures move.
