# Email search: find a professional email

> POST /email-search: find the professional email address of a person from their first name, last name and company name or domain. 1 credit per email found.

Source: https://api-doc.icypeas.com/reference/email-search


Find the professional email of one person from their name and their company. Costs **1 credit** only if an email is found.

**How to use it:**

1. Send the person's `firstname`, `lastname` and `domainOrCompany`. You get back a search `_id`.
2. A few seconds later, read the result with [`/bulk-single-searchs/read`](https://api-doc.icypeas.com/reference/get-results), or receive it on a [webhook](https://api-doc.icypeas.com/reference/webhook-search-item).

> **Tips for better results**
>
> - Use the company **website** (`icypeas.com`) rather than its name (`Icypeas`) when you have it.
> - You can leave `firstname` **or** `lastname` empty, but not both.
> - For more than a few people, use the [bulk search](https://api-doc.icypeas.com/reference/bulk-search): it handles thousands of rows in parallel.

**Endpoint:** `POST https://app.icypeas.com/api/email-search`

**Headers:** `Authorization: YOUR_API_KEY` (the key alone, no `Bearer` prefix) and `Content-Type: application/json`.

#### Body parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `firstname` | string | yes | The firstname of the person you want to find. Rule: can be empty if a lastname is set. |
| `lastname` | string | yes | The lastname of the person you want to find. Rule: can be empty if a firstname is set. |
| `domainOrCompany` | string | yes | The domain or the company name of the person you want to find. |
| `custom` | object | no | Optional settings for this search: a webhook URL and/or your own id. |
| `custom.webhookUrl` | url | no | A URL Icypeas calls with the result as soon as this search is done. See the 'Search item processed' webhook. |
| `custom.externalId` | string | no | Your own id for this search (for example a CRM id). It comes back with the result and in webhooks. Icypeas doesn't check that it's unique. |

#### Request example

```bash
curl -X POST "https://app.icypeas.com/api/email-search" \
  -H "Content-Type: application/json" \
  -H "Authorization: YOUR_API_KEY" \
  -d '{
  "firstname": "John",
  "lastname": "Doe",
  "domainOrCompany": "icypeas.com"
}'
```

#### Responses

##### 200: Response when your input is good.

```json
{
  "success": true,
  "item": {
    "_id": "#YOUR_SEARCH_ID#",
    "status": "NONE"
  }
}
```

| Name | Type | Description |
| --- | --- | --- |
| `success` | boolean | true means that your search has been taken into account |
| `item` | object | Information about your search |
| `item._id` | string | Search id to follow its progression |
| `item.status` | string | Status of this search (NONE right after creation). See the Result statuses page. |

##### 200 (validation error): Response when there are validation errors.

```json
{
  "validationErrors": [
    {
      "expected": "string",
      "type": "required",
      "field": "firstname",
      "message": "validation_required"
    },
    {
      "expected": "string",
      "type": "required",
      "field": "lastname",
      "message": "validation_required"
    },
    {
      "expected": "string",
      "type": "required",
      "field": "domainOrCompany",
      "message": "validation_required"
    }
  ],
  "success": false
}
```

| Type | Message | Fields | When it happens |
| --- | --- | --- | --- |
| `required` | `validation_required` | `firstname`, `lastname`, `domainOrCompany` | Error sent when the field is missing |
| `string` | `validation_string` | `firstname`, `lastname`, `domainOrCompany`, `custom.externalId` | Error sent when the field is not a string |
| `url` | `validation_url` | `custom.webhookUrl` | Error sent when the field is not a valid URL |
| `stringEmpty` | `validation_string_empty` | `firstname`, `lastname`, `domainOrCompany` | Error sent when the field is empty |
| `FirstLastMandatoryDiscoveryError` | `first_last_mandatory_discovery_error` | `firstname`, `lastname` | Error sent when you need to at least specify a firstname or a lastname and you left both empty |
| `UnpaidSubscriptionError` | `unpaid_subscription_error` | `user` | Error sent when you have a pending payment and your subscription is therefore not paid |

##### 401: Response when we could not authenticate you.

```json
{
  "message": "Unauthorized access.",
  "error": "UnauthorizedAccessError",
  "status": 401,
  "code": "unauthorized_access_error"
}
```

| Name | Type | Description |
| --- | --- | --- |
| `message` | string | Human-readable message. |
| `error` | string | Error name |
| `status` | number | HTTP error code |
| `code` | string | Error code |

##### 429: Error received when rate limit is exceeded

```json
{
  "message": "You have exceeded the max number of requests per minute.",
  "error": "RateLimitExceededError",
  "status": 429,
  "code": "rate_limit_exceeded_error"
}
```

| Name | Type | Description |
| --- | --- | --- |
| `message` | string | Human-readable message. |
| `error` | string | Error name |
| `status` | number | HTTP error code |
| `code` | string | Error code |

## Then: read the result

```bash
curl -X POST "https://app.icypeas.com/api/bulk-single-searchs/read" \
  -H "Content-Type: application/json" \
  -H "Authorization: YOUR_API_KEY" \
  -d '{ "id": "THE_ID_YOU_RECEIVED" }'
```

The email is in `items[0].results.emails[0].email`, its reliability in `certainty`. See [Read results](https://api-doc.icypeas.com/reference/get-results) and the [step-by-step quickstart](https://api-doc.icypeas.com/getting-started).
