curl --fail-with-body --max-time 30 -X POST "https://api.freshtalent.ai/v1/targets/preview" \
-H "Authorization: Bearer $FRESHTALENT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"urls":[
"https://www.linkedin.com/in/derek-morrow",
"linkedin.com/in/jane-doe"
]
}'
const response = await fetch("https://api.freshtalent.ai/v1/targets/preview", {
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", "linkedin.com/in/jane-doe"],
}),
});
const body = await response.json();
if (!response.ok) throw new Error(`${response.status}: ${JSON.stringify(body)}`);
console.log(body.data.uses_slots, body.data.over_by);
import json
import os
import urllib.request
payload = json.dumps({
"urls": ["https://www.linkedin.com/in/derek-morrow", "linkedin.com/in/jane-doe"],
}).encode()
request = urllib.request.Request(
"https://api.freshtalent.ai/v1/targets/preview",
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"]["uses_slots"], body["data"]["over_by"])
{
"data": {
"profiles": 214,
"already_added": 0,
"free": 61,
"uses_slots": 153,
"over_by": 0,
"slots": { "included": 1000, "used": 214, "max": 1000, "remaining": 786 }
}
}
Preview target people
Check a list of LinkedIn profile URLs against your monitoring slots before you create or add to a manual Target.
POST
/
targets
/
preview
curl --fail-with-body --max-time 30 -X POST "https://api.freshtalent.ai/v1/targets/preview" \
-H "Authorization: Bearer $FRESHTALENT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"urls":[
"https://www.linkedin.com/in/derek-morrow",
"linkedin.com/in/jane-doe"
]
}'
const response = await fetch("https://api.freshtalent.ai/v1/targets/preview", {
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", "linkedin.com/in/jane-doe"],
}),
});
const body = await response.json();
if (!response.ok) throw new Error(`${response.status}: ${JSON.stringify(body)}`);
console.log(body.data.uses_slots, body.data.over_by);
import json
import os
import urllib.request
payload = json.dumps({
"urls": ["https://www.linkedin.com/in/derek-morrow", "linkedin.com/in/jane-doe"],
}).encode()
request = urllib.request.Request(
"https://api.freshtalent.ai/v1/targets/preview",
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"]["uses_slots"], body["data"]["over_by"])
{
"data": {
"profiles": 214,
"already_added": 0,
"free": 61,
"uses_slots": 153,
"over_by": 0,
"slots": { "included": 1000, "used": 214, "max": 1000, "remaining": 786 }
}
}
Read-only. Normalizes the URLs the same way Create target does for
kind: "manual", then reports how many are valid, how many are free, and how many would each need a monitoring slot. Nothing is created or queued.
Request body
string[]
required
1–2000 strings, each at most 500 characters. Values that are not LinkedIn profile URLs (
linkedin.com/in/…) are ignored; at least one must be valid.string
Optional manual Target UUID. When set, people already
watching on that Target are counted in already_added instead of free or uses_slots.Response
200 OK returns { "data": Preview }:
| Field | Meaning |
|---|---|
profiles | Valid, de-duplicated profile URLs in the request. |
already_added | Already watching on target_id. Always 0 without target_id. |
free | Would be added without using a slot: in the public graph, or already billed to your organization on another Target. |
uses_slots | Would each use one monitoring slot. |
over_by | How many more slots the request needs than remain. 0 means it fits. |
slots | { included, used, max, remaining }, the same numbers as quota.watch_slots on Get account. |
{
"data": {
"profiles": 214,
"already_added": 0,
"free": 61,
"uses_slots": 153,
"over_by": 0,
"slots": { "included": 1000, "used": 214, "max": 1000, "remaining": 786 }
}
}
Examples
curl --fail-with-body --max-time 30 -X POST "https://api.freshtalent.ai/v1/targets/preview" \
-H "Authorization: Bearer $FRESHTALENT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"urls":[
"https://www.linkedin.com/in/derek-morrow",
"linkedin.com/in/jane-doe"
]
}'
const response = await fetch("https://api.freshtalent.ai/v1/targets/preview", {
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", "linkedin.com/in/jane-doe"],
}),
});
const body = await response.json();
if (!response.ok) throw new Error(`${response.status}: ${JSON.stringify(body)}`);
console.log(body.data.uses_slots, body.data.over_by);
import json
import os
import urllib.request
payload = json.dumps({
"urls": ["https://www.linkedin.com/in/derek-morrow", "linkedin.com/in/jane-doe"],
}).encode()
request = urllib.request.Request(
"https://api.freshtalent.ai/v1/targets/preview",
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"]["uses_slots"], body["data"]["over_by"])
Errors and recovery
400 invalid_request: missingurls, more than 2000 entries, no valid profile URL, atarget_idthat is not a UUID, or atarget_idthat is not a manual Target. Fix the request.401 unauthorized,402 payment_required,403 upgrade_required: fix the API key or organization access. Manual Targets need a plan with monitoring.404 not_found:target_idis not in the authenticated organization.429/5xx: back off and retry; the call has no side effects.
Next
- Create target with
kind: "manual"once the list fits. - Add target people to grow an existing manual Target.