> ## Documentation Index
> Fetch the complete documentation index at: https://docs.freshtalent.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Add target people

> Add people to a manual Target by LinkedIn profile URL. They start as watching.

Adds people to a Target created with `kind: "manual"`. URLs are normalized and de-duplicated the same way as on [Create target](https://docs.freshtalent.ai/api-reference/targets/create.md). New people start as `watching`; a person who was `excluded` comes back as `watching`; people already `watching` are left alone.

## Request

**id** `string` *required*

Manual Target UUID.

**urls** `string[]` *required*

1–2000 strings, each at most 500 characters. Values that are not LinkedIn profile URLs are ignored; at least one must be valid.

## Response

`202 Accepted` returns `{ "data": { "added": integer, "already_added": integer, "target": Target } }`. `added` counts people who became `watching` (new or restored); `already_added` counts people who were already `watching`. `target` uses the schema from [List targets](https://docs.freshtalent.ai/api-reference/targets/list.md).

People already in the graph are ready at once. Everyone else is loaded in the background. If a load job is already queued or running for this Target, the new people join it or get a follow-up load when it finishes; no second job is queued.

```json 202 theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "data": {
    "added": 2,
    "already_added": 1,
    "target": {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "kind": "manual",
      "name": "Q4 backend pipeline",
      "linkedin_url": null,
      "auto_admit": false,
      "watching_count": 216,
      "proposed_count": 0,
      "excluded_count": 0,
      "current_count": 0,
      "alum_count": 0,
      "enriched_count": 191,
      "member_count": 216,
      "allocation_used": 155,
      "in_graph_count": 61,
      "result_limit": null,
      "created_at": "2026-10-26T11:43:00.000Z",
      "query": { "input": "Q4 backend pipeline" },
      "job": {
        "id": "7b1d9b3c-0b8f-4d4d-a8b4-72ef8fbb4c81",
        "status": "pending",
        "phase": "queued",
        "total": 0,
        "completed": 0,
        "failed": 0,
        "error": null
      }
    }
  }
}
```

## Examples

```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --fail-with-body --max-time 30 -X POST "https://api.freshtalent.ai/v1/targets/550e8400-e29b-41d4-a716-446655440000/people" \
  -H "Authorization: Bearer $FRESHTALENT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"urls":["https://www.linkedin.com/in/derek-morrow"]}'
```

```js JavaScript fetch theme={"theme":{"light":"github-light","dark":"github-dark"}}
const id = "550e8400-e29b-41d4-a716-446655440000";
const response = await fetch(`https://api.freshtalent.ai/v1/targets/${id}/people`, {
  method: "POST",
  signal: AbortSignal.timeout(30_000),
  headers: {
    Authorization: `Bearer ${process.env.FRESHTALENT_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ urls: ["https://www.linkedin.com/in/derek-morrow"] }),
});
const body = await response.json();
if (!response.ok) throw new Error(`${response.status}: ${JSON.stringify(body)}`);
console.log(body.data.added, body.data.target.watching_count);
```

```python Python stdlib theme={"theme":{"light":"github-light","dark":"github-dark"}}
import json
import os
import urllib.request

payload = json.dumps({"urls": ["https://www.linkedin.com/in/derek-morrow"]}).encode()
request = urllib.request.Request(
    "https://api.freshtalent.ai/v1/targets/550e8400-e29b-41d4-a716-446655440000/people",
    data=payload,
    method="POST",
    headers={
        "Authorization": f"Bearer {os.environ['FRESHTALENT_API_KEY']}",
        "Content-Type": "application/json",
    },
)
with urllib.request.urlopen(request, timeout=30) as response:
    body = json.load(response)
print(body["data"]["added"], body["data"]["target"]["watching_count"])
```

## Lifecycle and retry safety

Adding is idempotent for the same URLs: a replay reports them as `already_added` and changes nothing. To take someone off the Target, set them to `excluded` with [Accept target members](https://docs.freshtalent.ai/api-reference/targets/admit.md).

## Errors and recovery

* `400 invalid_request`: missing `urls`, more than 2000 entries, no valid profile URL, or the Target is not `kind: "manual"`. Fix the request.
* `401 unauthorized`, `402 payment_required`, `403 upgrade_required`: fix the API key or organization access.
* `404 not_found`: the Target is not in the authenticated organization.
* `409 conflict`: a message starting `slot_limit:` means the new people need more monitoring slots than remain. Nothing was added. Check with [Preview target people](https://docs.freshtalent.ai/api-reference/targets/preview.md), remove some URLs, or add capacity.
* `429`/`5xx`: back off. Replaying is safe.

## Next

* [List target members](https://docs.freshtalent.ai/api-reference/targets/members.md) with `depth=stub` to see who is still loading.
* [Get target](https://docs.freshtalent.ai/api-reference/targets/get.md) to follow `enriched_count` and the job.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.