Skip to main content

Job Change API

Find the contacts at your accounts who changed jobs or got promoted, with the old and new title, as structured JSON.

POST/v1/contacts/search

curl -X POST https://signals.autobound.ai/v1/contacts/search \  -H "X-API-KEY: $AUTOBOUND_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "company_domains": ["salesforce.com"],    "signal_types": ["work-milestones"],    "signal_subtypes": ["promotion"],    "limit": 1  }'

Replace $AUTOBOUND_API_KEY with your key from the portal.

What's in each record

One record per job change, promotion or work anniversary, tied to a contact and their company. These are example values. About job change signals →

signal_subtype
promotionThe event, one of 3 values
detected_at
2026-07-14T13:22:44ZWhen Autobound found it (UTC)
data.new_job_title
VP of Corporate StrategyThe new title
data.previous_job_title
Senior Director, Strategy & OperationsThe title before
data.event_date
2026-01-05When the change happened

Also in this record: months_since_event, new_job_description, previous_job_description, company_name, company_domain, previous_company_name, previous_company_domain, new_job_location, previous_job_location, founded_new_company, work_anniversary_year, confidence

signal_ida41c7de2-6f38-4b9a-8c15-2d90e4f7a638

Every field in a job change signalThe data fields of the example records. The API reference has the full schema.Show all 37 fields

Green rows are filled in the record selected above: Jennifer Park, Promotion.

Signal

signal_idstring, filled in the selected example
Stable id. GET /v1/signals/{id} returns the signal
signal_typestring, filled in the selected example
Always "work-milestones" here
signal_subtypestring, filled in the selected example
The event within the type
signal_namestring
Display name. Often empty: use data.summary
detected_atdatetime, filled in the selected example
When Autobound found it (UTC)
associationstring, filled in the selected example
"company" or "contact"

Job change

data.event_datedate, filled in the selected example
When the change happened
data.months_since_eventinteger, filled in the selected example
Months since the change
data.new_job_titlestring, filled in the selected example
The new title
data.new_job_descriptionstring, filled in the selected example
What the new role covers
data.previous_job_titlestring, filled in the selected example
The title before
data.previous_job_descriptionstring, filled in the selected example
What the old role covered
data.company_namestring, filled in the selected example
The current employer
data.company_domainstring, filled in the selected example
The current employer's domain
data.previous_company_namestring | null, filled in the selected example
The employer before. null for a promotion
data.previous_company_domainstring | null, filled in the selected example
That employer's domain
data.new_job_locationstring, filled in the selected example
Where the new role is
data.previous_job_locationstring, filled in the selected example
Where the old role was
data.founded_new_companyboolean, filled in the selected example
true when the person started a company
data.work_anniversary_yearinteger | null, filled in the selected example
Years at the company, for an anniversary
data.confidencenumber, filled in the selected example
Score from 0 to 1

Contact

contact.full_namestring | null
The person
contact.first_namestring | null
First name
contact.last_namestring | null
Last name
contact.job_titlestring | null
Current title
contact.emailstring | null
Work email, when known
contact.linkedin_urlstring | null, filled in the selected example
LinkedIn profile
contact.citystring | null
City
contact.statestring | null
State or region
contact.countrystring | null
Country

Company

company.namestring, filled in the selected example
The company the signal is about
company.domainstring, filled in the selected example
Root domain. The join key
company.linkedin_urlstring, filled in the selected example
Company LinkedIn page. May be a relative path
company.industriesstring[]
Industry labels, when known
company.employee_count_*integer
Headcount low and high, when known
company.revenuestring
Revenue range, when known
company.descriptionstring | null
Short description. Often null

Pricing and limits

You pay in credits for what a call returns. A call that returns no results is free.

See all plans →
Search contacts
2creditsper contact returnedPOST /v1/contacts/search
Free to start
1,000free credits at signup
Self-serve plans
$19Starter: 1,900 creditsPacks up to $4,999.
Rate limit
300requests per minutePer account, shared by all keys.

Questions

How do I act on job change signals?

Run contacts/search with signal_types ["work-milestones"], signal_subtypes ["jobChange"] and your account domains in company_domains. Each result is a person with the new and previous job title and a LinkedIn URL. Run it weekly, send new champions to the account owner, and reach out while the person is new in the role.

Why does company enrich return a 400 for work-milestones?

work-milestones is a contact-level type, and companies/enrich returns company-level signals. The 400 response includes a contacts/search body you can send as is. If you mix contact and company types in one enrich call, the contact types are dropped with a warning.

Does it include promotions?

Yes. Use signal_subtypes ["promotion"], or ["jobChange", "promotion"] for both. The third subtype is workAnniversary.

Make this call with your own key

One key works for all 35 signal types. 2 credits per contact returned. Up to 100 company domains per call. Calls with no results are free.

1,000 free credits to start.

Or use it from Claude Code, Cursor or any MCP client

Add the server, run /mcp to sign in, then ask: “Who at salesforce.com changed jobs or got promoted this quarter?”

claude mcp add --transport http autobound https://mcp.autobound.ai/mcp

Use it in Claude via MCP →