Get a lead
One lead with its contacts, deal, timeline notes, last interaction and connection strength, the surfaced draft, and the research behind each column.
curl -H "Authorization: Bearer $REVNU_API_TOKEN" https://revnu.com/api/v1/leads/sn7…Response
{ "lead": { …, fields, draft, research, contacts: [contact, …], contactsTruncated: false } }. Contacts are capped at 50, with contactsTruncated: true when there were more. linkedin is where the lead stands in a sequence with LinkedIn steps, or null, as described in LinkedIn sequence progress. The lead and each contact carry workflowRunId, the workflow run that created it, or null. 404 for an unknown or another account's lead.
owner is the name of the teammate who owns the lead, or null. deal is the lead's deal, { stage, amount, currency, closeDate, lostReason, openedAt, stageChangedAt, updatedBy }, or null. notes is the newest 10 entries of the lead's timeline, newest first: { id, kind, body, deal, author, authorName, source, createdAt, editedAt }, where kind is note (text from your team, the API or the agent) or deal (a stage change, with deal: { from, to }: from is absent when the deal opened, and to is absent when it was removed), and author is customer, agent or api. source is what the note was filed from, such as granola:<meeting id>, or null.
people lists the researched people at the company who aren't saved contacts yet, { name, title, email, linkedinUrl }; remove a wrong one with POST /leads/{id}/people/remove. handling is { stage, setBy, setByName, note, setAt } when someone on your team has taken the lead over, so Revnu isn't contacting it, and null otherwise.
interactions is how warm the relationship is, from Revnu's email and LinkedIn sends and the replies to them: { lastInteractionAt, lastChannel, lastOutboundAt, lastReplyAt, daysSinceLastInteraction, daysSinceLastReply, waitingOn, connectionStrength, strongestConnection }. A list row's top-level lastInteractionAt, lastReplyAt and waitingOn are here instead.
waitingOnisuswhen they replied after your last message,themwhen you wrote after their last reply, andnullbefore any reply.connectionStrengthcounts only two-way contact:very_strongis a reply in the last 14 days,strongin the last 60,goodan older reply,weaksends with no reply, andnoneno contact.strongestConnectionis{ name, email, via }for the person whose reply is newest, withviathe mailbox that wrote to them, ornull.
A contact is { id, workflowRunId, email, name, firstName, title, linkedinUrl, photoUrl, emailStatus, role, isPrimary, identityConfidence }, with null for anything not known.
draft is the surfaced draft, { subject, body } (each cut at 16,000 characters), or null when there is none. research is a list of entries, one per key the agent saved research under: { key, reasoning, sources: [{ url, title }], sourcesTruncated }, the agent's reasoning (cut at 8,000 characters) and up to 20 sources behind that value. A source whose URL is longer than 2,048 characters is left out rather than cut, and sourcesTruncated says when anything was left out. Keys with no visible column appear here too.
Frequently Asked Questions
How do I read a daily recommendation?
Each recommended lead is a row. List leads and take the id, then read the lead: fields has the fit and the Slack card reference where those columns are set up, contact is the person, draft or a research entry holds the message, and each research entry's sources has the links. The lead id is the stable id to track state against.
Which scope does this need?
leads:read. A token without it gets 403 with requiredScope in the body. GET /me shows a token's scopes.
Are responses cached?
No. Every response is Cache-Control: no-store, so what you read is current.