# Find businesses in an area, with emails

`POST /api/v1/search`

Finds businesses of one kind in a place (for example dentists in Austin, TX) and the best email for each: the business email or the owner's, checked. It runs in rounds until it has `target` emails that work (or searched the whole area). Poll `GET /api/v1/lists/{listId}` or set `webhookUrl` (event `search.completed`).

Owner emails: only owners the business names on its own website. For businesses in Vermont, Oregon and Connecticut we deliver owner emails only when the website prints them.

**Credits:** 1 credit per delivered email that Works. Businesses without a website, and emails we could not confirm, are free. With `brief: true`, plus 0.5 credits per summary.

## Body (JSON)

| Name | Type | Required | What it is |
| --- | --- | --- | --- |
| `category` | string | yes | What kind of business, e.g. "dentist", "roofing contractor", "yoga studio". |
| `location` | string | yes | City, county, state or ZIP / post code. |
| `country` | `"US"` · `"CA"` · `"GB"` · `"AU"` · `"NZ"` · `"IE"` · `"DE"` · `"AT"` · `"CH"` · `"FR"` · `"ES"` · `"IT"` · `"NL"` · `"BE"` · `"LU"` · `"PT"` · `"DK"` · `"SE"` · `"FI"` · `"PL"` · `"CZ"` · `"MX"` | yes | Country of the location. |
| `mode` | `"target"` · `"all"` |  | target: stop at `target` emails that work. all: search the whole area (up to creditLimit). default `"target"` |
| `target` | integer |  | How many emails that work you want (mode "target"). default `25` |
| `creditLimit` | number |  | mode "all": stop when this many credits are used (default: until your credits run out). |
| `role` | `"any"` · `"best"` · `"owner"` · `"marketing"` · `"sales"` |  | any: the business email (info@, office@ …). best: the owner when the business names one on its own website, else the business email. owner: only owners named on the business's own website. default `"any"` |
| `brief` | boolean |  | Also write a short company summary and a first line for each business. default `false` |
| `webhookUrl` | string |  | Public https URL we POST the result to when the job is done (see the webhooks guide). |
| `webhookSecret` | string |  | Optional: sign this webhook with your own secret instead of the account signing secret. |

## Example request

```bash
curl -X POST "https://moleman.io/api/v1/search" \
  -H "Authorization: Bearer $MOLEMAN_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"category":"dentist","location":"Austin, TX","country":"US","target":25}'
```

## Example answer

```json
{
  "runId": 55,
  "listId": 380,
  "jobId": 984,
  "livemode": true,
  "run": {
    "status": "running",
    "delivered": 0,
    "creditsUsed": 0
  },
  "pollUrl": "/api/v1/lists/380"
}
```

## Errors

| Status | Code | When |
| --- | --- | --- |
| 401 | [`missing_api_key`](/docs/errors#missing_api_key) | The request has no API key. |
| 401 | [`invalid_api_key`](/docs/errors#invalid_api_key) | The API key is not one of ours (a typo, a cut-off copy, or a key from another account that was deleted). |
| 401 | [`revoked_api_key`](/docs/errors#revoked_api_key) | The API key was revoked on the API page. Revoking takes effect at once. |
| 429 | [`rate_limited`](/docs/errors#rate_limited) | More than 120 requests in one minute with this key. |
| 500 | [`server_error`](/docs/errors#server_error) | Something broke on our side. Nothing was charged for it. |
| 400 | [`invalid_request`](/docs/errors#invalid_request) | A parameter is missing, has the wrong type or is out of range. `details` lists every problem with its path. |
| 400 | [`invalid_json`](/docs/errors#invalid_json) | The body is not valid JSON. |
| 409 | [`idempotency_in_progress`](/docs/errors#idempotency_in_progress) | A request with the same Idempotency-Key is still running. |
| 422 | [`idempotency_key_reused`](/docs/errors#idempotency_key_reused) | The Idempotency-Key was already used in the last 24 hours with a different request. |
| 402 | [`insufficient_credits`](/docs/errors#insufficient_credits) | The account has fewer credits than this request could use at most. We hold the maximum while the job runs and give back what it does not use. |
| 404 | [`place_not_found`](/docs/errors#place_not_found) | We could not find the place you searched in. |
| 503 | [`search_unavailable`](/docs/errors#search_unavailable) | Business search is not available right now. |
| 400 | [`invalid_webhook_url`](/docs/errors#invalid_webhook_url) | The webhook URL is not a public https address (private networks and other schemes are refused). |
