# Getting started

> Set up your first Reverse Contact request in less than 5 minutes.

> [!WARNING]
> **Endpoint transition on October 13, 2026.** `/v2/search/persons` is replaced by `/v2/search/people`, and `/v2/resolve` by `/v2/enrich`. The old endpoints stay live until October 13, 2026. See the [endpoint transition guide](https://docs.reversecontact.com/guides/endpoint-transition-october-2026) to prepare your integration.

## Before you begin

1. **Create an account.** [Sign up](https://app.reversecontact.com/auth/signup) if you don't have one yet
2. **Generate an API key.** Open Workspace > [API Keys](https://app.reversecontact.com/api-keys), create a new key, copy and keep it secure.
3. **Have a LinkedIn URL ready,** e.g. `https://www.social.com/in/janedoe`, or a person's full name and company domain.

See [Authentication](https://docs.reversecontact.com/authentication) for more details on API keys and permissions.

## 1. Make your first request

All endpoints are served from `https://api.reversecontact.com/v2/`. Here is a quick example:

**POST /v2/fetch/persons**

```javascript [JavaScript]
const response = await fetch("https://api.reversecontact.com/v2/fetch/persons", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.RC_API_KEY}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    url: "https://www.social.com/in/janedoe"
  })
});

const result = await response.json();
console.log(result.data.firstName, result.data.lastName);
```
```bash [cURL]
curl -X POST https://api.reversecontact.com/v2/fetch/persons \
  -H "Authorization: Bearer ${RC_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://www.social.com/in/janedoe"}'
```
```python [Python]
import os
import requests

response = requests.post(
    "https://api.reversecontact.com/v2/fetch/persons",
    headers={
        "Authorization": f"Bearer {os.environ['RC_API_KEY']}",
        "Content-Type": "application/json"
    },
    json={"url": "https://www.social.com/in/janedoe"}
)

result = response.json()
print(result["data"]["firstName"], result["data"]["lastName"])
```

> [!TIP]
> Want to test without writing code? Every endpoint page has a **Try it** button that runs the request from your browser with your API key.

## 2. Read the response

Every API response follows the same structure. Here is what you get back:

| Field | Description |
| ----- | ----------- |
| `success` | `true` if the request succeeded |
| `data` | The returned object for this endpoint |
| `error` | Error details if something went wrong, `null` on success |
| `metadata` | Request ID and execution time, useful for debugging |
| `quotas` | Your remaining credits and rate limit status |

See [API reference](https://docs.reversecontact.com/api-reference) for the full response format, metadata, quotas, and shared types.

## 3. Need real-time data? Use the live endpoints

The `live` and Contact Email Finder endpoints fetch fresh data asynchronously. They reply immediately with a `webhookId`, then deliver the actual result once it's ready, usually within seconds.

> [!IMPORTANT]
> **Async, not synchronous.** We aim to deliver each result in under 15 seconds, but it can take tens of minutes depending on conditions. Live endpoints are built to update databases and feed async pipelines, not to block a synchronous, real-time request a user is waiting on.

For live profile endpoints, the simplest way to retrieve that result is **polling**: trigger the job, then call `GET /v2/webhooks/:webhookId` until the status is `succeeded`. For Contact Email Finder, provide a `webhookUrl` and handle the callback described in the [Find Email endpoint guide](https://docs.reversecontact.com/endpoints/contact-email).

**Trigger + poll**

```javascript [JavaScript]
const KEY = "YOUR_API_KEY";
const BASE = "https://api.reversecontact.com";

const trigger = await fetch(`${BASE}/v2/fetch/persons/live`, {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${KEY}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({ url: "https://social.com/in/janedoe" })
});
const { data: { webhookId } } = await trigger.json();

while (true) {
  const res = await fetch(`${BASE}/v2/webhooks/${webhookId}`, {
    headers: { "Authorization": `Bearer ${KEY}` }
  });
  const { data } = await res.json();
  if (data.status === "succeeded") { console.log(data.result); break; }
  if (data.status === "errored")   throw new Error(data.errorCode ?? "Job failed");
  await new Promise(r => setTimeout(r, 2000));
}
```
```bash [cURL]
KEY="YOUR_API_KEY"
ID=$(curl -sX POST https://api.reversecontact.com/v2/fetch/persons/live \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"url":"https://social.com/in/janedoe"}' | jq -r .data.webhookId)

while :; do
  S=$(curl -s https://api.reversecontact.com/v2/webhooks/$ID \
    -H "Authorization: Bearer $KEY" | jq -r .data.status)
  [ "$S" = "succeeded" ] && break
  [ "$S" = "errored" ] && echo "job failed" && exit 1
  sleep 2
done

curl -s https://api.reversecontact.com/v2/webhooks/$ID \
  -H "Authorization: Bearer $KEY" | jq .data.result
```

> [!TIP]
> Polling is the simplest way to use live endpoints. No webhook receiver required, free to call, off the rate-limit clock.

See the [Polling guide](https://docs.reversecontact.com/guides/polling) for the full integration walkthrough, comparison with webhooks, status codes, polling frequency, and retention details.
