Use cases // Find & enrich
Keep profiles fresh
NewLast verified
Check person and company profile freshness for free, compare the last update date, and refresh stale data with live API jobs and polling.
You have
The API
Person profile status
POST /v2/fetch/persons/check
sync responseCompany profile status
POST /v2/fetch/companies/check
sync responsePerson profile live
POST /v2/fetch/persons/live
async jobCompany profile live
POST /v2/fetch/companies/live
async job
You get
- credits per person status check
- 0
- credits per company status check
- 0
- credits per person live request, at job creation
- 2
- credits per company live request, at job creation
- 2
Free. Needs at least 2 credits in the workspace: below that, 402 NO_CREDITS.
Use your stored person or company profile URLs to check when Reverse Contact last fetched each profile. The status request is free and returns immediately. Refresh only stale or missing profiles with a live job, then retrieve the fresh data when the job ends.
Which endpoint
| Input you have | Endpoint | Cost | Mode |
|---|---|---|---|
| Person URL or id to check | Person profile status | Free. Your workspace needs at least 2 credits | Synchronous |
| Company URL or id to check | Company profile status | Free. Your workspace needs at least 2 credits | Synchronous |
| Stale or missing person profile | Person profile live | 2 credits when the job is created | Asynchronous |
| Stale or missing company profile | Company profile live | 2 credits when the job is created | Asynchronous |
How it works
Set RC_API_KEY to your API key and install the TypeScript SDK, Python SDK or CLI. The shell examples use jq. You can adjust the examples' 30-day freshness threshold to match your own policy.
Read the last update date for free
Read data.exists and data.lastUpdate from each status response. The lastUpdate field is an ISO 8601 timestamp, or null when the profile is absent. Keep these responses to skip live calls for fresh profiles in the next steps.
Code Examples
curl --fail-with-body -sS -X POST https://api.reversecontact.com/v2/fetch/persons/check \
-H "Authorization: Bearer $RC_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://www.social.com/in/janedoe"}' > person-status.json
curl --fail-with-body -sS -X POST https://api.reversecontact.com/v2/fetch/companies/check \
-H "Authorization: Bearer $RC_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://www.social.com/company/acme-corp"}' > company-status.json
jq .data person-status.json company-status.jsonimport ReverseContact from "@reverse-contact/sdk";
const client = new ReverseContact({ apiKey: process.env.RC_API_KEY });
const personStatus = await client.fetch.checkPerson({ url: "https://www.social.com/in/janedoe" });
const companyStatus = await client.fetch.checkCompany({ url: "https://www.social.com/company/acme-corp" });
console.log(personStatus.data, companyStatus.data);import os
from reversecontact import ReverseContact
with ReverseContact(api_key=os.environ["RC_API_KEY"]) as client:
person_status = client.fetch.check_person(url="https://www.social.com/in/janedoe")
company_status = client.fetch.check_company(url="https://www.social.com/company/acme-corp")
print(person_status.data, company_status.data)rc check person --url https://www.social.com/in/janedoe --json > person-status.json
rc check company --url https://www.social.com/company/acme-corp --json > company-status.json
jq .data person-status.json company-status.jsonRefresh the person only when needed
If the person is absent or lastUpdate is older than your threshold, start a live refresh and save the job id before waiting. Read the fresh person from data.result after the job succeeds.
Code Examples
if jq -e '.data | .exists == true and (.lastUpdate != null) and
((.lastUpdate | sub("\\.[0-9]+Z$"; "Z") | fromdateiso8601) >= (now - 30 * 86400))' person-status.json > /dev/null; then
echo "Cached profile is fresh; no live request"
else
curl --fail-with-body -sS -X POST https://api.reversecontact.com/v2/fetch/persons/live \
-H "Authorization: Bearer $RC_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://www.social.com/in/janedoe"}' > person-job.json
WEBHOOK_ID=$(jq -er .data.webhookId person-job.json)
printf 'Save this job id: %s\n' "$WEBHOOK_ID"
while :; do
result=$(curl --fail-with-body -sS --max-time 30 \
"https://api.reversecontact.com/v2/webhooks/$WEBHOOK_ID?wait=20" \
-H "Authorization: Bearer $RC_API_KEY") || break
case "$(printf '%s' "$result" | jq -r '.data.status')" in
succeeded) printf '%s' "$result" | jq '.data.result'; break ;;
errored) printf '%s' "$result" | jq '.data | {errorCode, creditsConsumed}'; break ;;
created|in_progress) sleep 2 ;;
*) printf '%s\n' "$result"; break ;;
esac
done
ficonst personCutoff = Date.now() - 30 * 24 * 60 * 60 * 1000;
const personData = personStatus.data;
if (!personData.exists || !personData.lastUpdate || Date.parse(personData.lastUpdate) < personCutoff) {
const job = await client.fetch.personLive({ url: "https://www.social.com/in/janedoe" });
console.log("Save this job id:", job.id);
const done = await job.wait();
console.log(done.data.result);
} else {
console.log("Cached profile is fresh; no live request");
}from datetime import datetime, timedelta, timezone
person_cutoff = datetime.now(timezone.utc) - timedelta(days=30)
person_data = person_status.data
if person_data is None:
raise RuntimeError("Status response is missing data")
person_updated = datetime.fromisoformat(str(person_data.last_update).replace("Z", "+00:00")) if person_data.last_update else None
if not person_data.exists or person_updated is None or person_updated < person_cutoff:
with ReverseContact(api_key=os.environ["RC_API_KEY"]) as client:
job = client.fetch.person_live(url="https://www.social.com/in/janedoe")
print("Save this job id:", job.id)
done = job.wait()
print(done.data.result if done.data else None)
else:
print("Cached profile is fresh; no live request")if jq -e '.data | .exists == true and (.lastUpdate != null) and
((.lastUpdate | sub("\\.[0-9]+Z$"; "Z") | fromdateiso8601) >= (now - 30 * 86400))' person-status.json > /dev/null; then
echo "Cached profile is fresh; no live request"
else
rc fetch person --url https://www.social.com/in/janedoe --live --wait --timeout 300
fiRefresh the company only when needed
If the company is absent or lastUpdate is older than your threshold, start a live refresh and save the job id before waiting. Read the fresh company from data.result after the job succeeds.
Code Examples
if jq -e '.data | .exists == true and (.lastUpdate != null) and
((.lastUpdate | sub("\\.[0-9]+Z$"; "Z") | fromdateiso8601) >= (now - 30 * 86400))' company-status.json > /dev/null; then
echo "Cached profile is fresh; no live request"
else
curl --fail-with-body -sS -X POST https://api.reversecontact.com/v2/fetch/companies/live \
-H "Authorization: Bearer $RC_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://www.social.com/company/acme-corp"}' > company-job.json
WEBHOOK_ID=$(jq -er .data.webhookId company-job.json)
printf 'Save this job id: %s\n' "$WEBHOOK_ID"
while :; do
result=$(curl --fail-with-body -sS --max-time 30 \
"https://api.reversecontact.com/v2/webhooks/$WEBHOOK_ID?wait=20" \
-H "Authorization: Bearer $RC_API_KEY") || break
case "$(printf '%s' "$result" | jq -r '.data.status')" in
succeeded) printf '%s' "$result" | jq '.data.result'; break ;;
errored) printf '%s' "$result" | jq '.data | {errorCode, creditsConsumed}'; break ;;
created|in_progress) sleep 2 ;;
*) printf '%s\n' "$result"; break ;;
esac
done
ficonst companyCutoff = Date.now() - 30 * 24 * 60 * 60 * 1000;
const companyData = companyStatus.data;
if (!companyData.exists || !companyData.lastUpdate || Date.parse(companyData.lastUpdate) < companyCutoff) {
const job = await client.fetch.companyLive({ url: "https://www.social.com/company/acme-corp" });
console.log("Save this job id:", job.id);
const done = await job.wait();
console.log(done.data.result);
} else {
console.log("Cached profile is fresh; no live request");
}from datetime import datetime, timedelta, timezone
company_cutoff = datetime.now(timezone.utc) - timedelta(days=30)
company_data = company_status.data
if company_data is None:
raise RuntimeError("Status response is missing data")
company_updated = datetime.fromisoformat(str(company_data.last_update).replace("Z", "+00:00")) if company_data.last_update else None
if not company_data.exists or company_updated is None or company_updated < company_cutoff:
with ReverseContact(api_key=os.environ["RC_API_KEY"]) as client:
job = client.fetch.company_live(url="https://www.social.com/company/acme-corp")
print("Save this job id:", job.id)
done = job.wait()
print(done.data.result if done.data else None)
else:
print("Cached profile is fresh; no live request")if jq -e '.data | .exists == true and (.lastUpdate != null) and
((.lastUpdate | sub("\\.[0-9]+Z$"; "Z") | fromdateiso8601) >= (now - 30 * 86400))' company-status.json > /dev/null; then
echo "Cached profile is fresh; no live request"
else
rc fetch company --url https://www.social.com/company/acme-corp --live --wait --timeout 300
fiWhat it costs
Person profile status and Company profile status cost 0 credits, but each requires at least 2 credits in the workspace. Below that balance, the API returns 402 NO_CREDITS. Status calls count toward your request rate limits.
Each live refresh consumes 2 credits when the job is created. A person-not-found or company-not-found failure remains billed. Other failures can be refunded under the rules on the live endpoint pages. Polling costs 0 credits and does not count toward the per-minute rate limit.
Good to know
Status reports the age of Reverse Contact's cache. If your stored copy needs updating but the cache is recent, use Person profile or Company profile for 1 credit when found instead of running Live. See Data freshness for when to check, fetch or refresh.
Keep live jobs in the background, as results can take tens of minutes. The SDK raises JobFailedError on failure and JobTimeoutError when the wait deadline passes. After a timeout, resume with the saved id using client.jobs.wait(jobId) or rc task. A timeout alone does not require a new paid refresh. Polling is recommended, and webhooks are optional.
FAQ
How do I check when a person or company profile was last updated?
Call Person profile status or Company profile status with the profile URL or id. The free response includes data.exists and data.lastUpdate, the timestamp of the last fetch from the source.
Why does a free profile status check return 402 NO_CREDITS?
Person profile status and Company profile status require at least 2 credits in the workspace even though the checks consume 0 credits. Below that balance, the API returns 402 NO_CREDITS.
How do I refresh only stale profiles with the API?
Compare data.lastUpdate against your own freshness threshold. Start Person profile live or Company profile live only when the cache is stale or missing, then retrieve data.result by polling.
How much does refreshing 200 profiles cost?
Starting 200 live profile jobs consumes 400 credits at creation, before any failure refunds. Profile status checks and polling are free.
Does a fresh status response update the profile stored in my CRM?
No. Profile status reports the age of Reverse Contact's cache. Retrieve that cached profile with Person profile or Company profile if your CRM copy needs updating. A cached profile costs 1 credit when found.