---
title: "Find work emails"
method: POST
path: "/emails/find"
tags: ["contacts"]
---

# Find work emails

`POST /emails/find`

## Request

- Base URL: `https://api.bereach.ai`
- URL: `https://api.bereach.ai/emails/find`
- Auth: HTTP bearer

Find the work email of up to 25 people, saved people by contact id or anyone by profile address, and keep each email found on the saved contact. Each email found uses one email credit; email credits are bought in packs of 1,000, apart from the plan's credits. A person with no email found costs nothing. Available through the Claude connector only.

## Request body

- object
  - `contactIds` string[]: Saved people, by the contact ids a contacts or search result returned.
  - `profileUrls` string[]: People by their profile address, saved or not. The email is kept on the contact when the person is saved.

## Response `200`

One row per person, with the email credits this call spent

- object
  - `success` true, required
  - `people` object[], required
    - `contactId` string, nullable, required
    - `profileUrl` string, nullable, required
    - `name` string, nullable, required
    - `email` string, nullable, required
    - `verified` boolean, nullable, required: True when the mailbox was checked; null when nothing was said about it.
    - `status` 'found' | 'already_saved' | 'already_found' | 'not_found' | 'not_looked_up' | 'unavailable' | 'unknown_contact', required: found: found now, one email credit. already_saved: the email was already on the contact, free. already_found: found earlier for this person, who is not saved, free. not_found: none found, free. not_looked_up: no email credit left, free. unavailable: could not be looked up now, free. unknown_contact: no saved person has this contact id, free.
    - `saved` boolean, required: The email is on the saved contact.
  - `found` integer, required
  - `emailCreditsUsed` integer, required: Email credits this call spent: one per email found now.
  - `buyCreditsUrl` string: Where to buy a pack of email credits, when they ran out.
  - `note` string

## Other responses

- `400`: The server cannot or will not process the request due to something that is perceived to be a client error. The body is the flat `{ error: "<text>" }` form, with `code` when the answer carries one; a few answers use the envelope.
- `401`: Although HTTP specifies "unauthorized", this response means "unauthenticated". Authenticate to continue. NOTE: 401 is also returned with code "linkedin_not_connected" on an endpoint that acts from your account (invitations, messages, your own network or inbox) when the caller IS authenticated but has no connected LinkedIn account: connect LinkedIn (not re-authenticate) to continue. Every other read never returns it. The body is the flat `{ error: "<text>" }` form, with `code` when the answer carries one; a few answers use the envelope.
- `403`: The caller is authenticated but not allowed. Read code: subscription_required (API key or connector whose plan is not active), free_draft_limit (a free-plan limit was reached), sales_nav_seat_inactive (no active Sales Navigator seat), or forbidden (not permitted). The body is the flat `{ error: "<text>" }` form, with `code` when the answer carries one; a few answers use the envelope.
- `404`: The server cannot find the requested resource. The body is the flat `{ error: "<text>" }` form, with `code` when the answer carries one; a few answers use the envelope.
- `409`: The request conflicts with the current state of the server. The body is the flat `{ error: "<text>" }` form, with `code` when the answer carries one; a few answers use the envelope.
- `410`: The requested content has been permanently deleted from the server. The body is the flat `{ error: "<text>" }` form, with `code` when the answer carries one; a few answers use the envelope.
- `422`: The request was well-formed but was unable to be followed due to semantic errors. The body is the flat `{ error: "<text>" }` form, with `code` when the answer carries one; a few answers use the envelope.
- `429`: Rate limit exceeded. Read retryAfter for the wait time in seconds. The body is the flat `{ error: "<text>" }` form, with `code` when the answer carries one; a few answers use the envelope.
- `500`: The server encountered a situation it does not know how to handle. The body is the flat `{ error: "<text>" }` form, with `code` when the answer carries one; a few answers use the envelope.
- `502`: An upstream service returned an error. Retry after a few seconds. The body is the flat `{ error: "<text>" }` form, with `code` when the answer carries one; a few answers use the envelope.
- `503`: Capacity is temporarily exceeded. Retry after a few seconds. The body is the flat `{ error: "<text>" }` form, with `code` when the answer carries one; a few answers use the envelope.

## Changes

> 39 revisions in range; 1 not diffed.

- **2026-10-22** `549f4adbbfcf`: 33 breaking, 11 info
  - the response's body type changed from `object` to no type for status `400`
  - the response's body type changed from `object` to no type for status `401`
  - the response's body type changed from `object` to no type for status `403`
  - the response's body type changed from `object` to no type for status `404`
  - …40 more
- **2026-10-22** `bdaed6984b20`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/berea/apis/bereach-api/changes/emails/find/post.md)

---

[API](https://skmtc.dev/berea/apis/bereach-api.md) · [All operations](https://skmtc.dev/berea/apis/bereach-api/llms.txt) · [OpenAPI document](https://skmtc.dev/berea/apis/bereach-api/revisions/b657f915ce03?raw)
