Skip to content
View as Markdown

Retrieve a conversion ​

GET /v1/leads/{lead_id}/conversion

Returns the conversion row of one lead, exactly as the list returns it.

Scope: leads:read

The same row, field visibility included, as GET /v1/campaigns/{campaign_id}/conversions. The lead must belong to a campaign the key may reach and be one the key's member can see in DialEcho, otherwise 404.

Path parameters ​

NameTypeRequiredDescription
lead_idUUIDYesThe lead.

Response ​

Status: 200 OK

NameTypeDescription
lead_idUUIDThe lead.
campaign_idUUIDThe lead's campaign.
created_attimestampWhen the lead was created in DialEcho (RFC 3339, UTC).
contactobjectThe lead's details as GET /v1/leads/{lead_id} returns them, with the same field visibility: a field the member's role hides is null, one it masks comes back masked.
contact.first_namestring | nullFirst name.
contact.last_namestring | nullLast name.
contact.emailstring | nullEmail address.
contact.phonestring | nullPhone number in E.164 (+14155550132); a stored number that is not a valid phone number is returned as stored.
contact.citystring | nullCity.
contact.statestring | nullState.
contact.postal_codestring | nullZIP or postal code.
contact.email_sha256string | nullSHA-256 (lowercase hex) of the email trimmed and lowercased: Meta's hashed em. null without an email, or unless the member sees the email in full.
contact.phone_sha256string | nullSHA-256 (lowercase hex) of the number's digits with country code and no + (14155550132): Meta's hashed ph. null without a valid number, or unless the member sees the phone in full.
attributionobject | nullThe attribution stored on the lead under the 16 attribution keys POST /v1/leads accepts (utm_source, utm_medium, utm_campaign, utm_term, utm_content, utm_id, adset_id, ad_id, fbclid, fbc, fbp, gclid, meta_event_id, page_url, form_name, referrer), whether sent through the API or set another way such as an import. Every key is present, null when never set. The whole object is null when the member's role hides custom fields; when it masks them, set values read Restricted.
milestonesobjectHow far the lead got. Timestamps are RFC 3339 in UTC; null until the lead reaches the milestone.
milestones.first_call_attimestamp | nullWhen the first outbound call to the lead by one of the campaign's AI agents started: a POST /v1/calls call, a campaign or a pipeline agent's call. Calls by your team and calls the lead made are not counted.
milestones.first_call_outcomestring | nullHow that call went: reached (a real conversation), answered (picked up but no conversation), voicemail, no_answer (not answered, busy or not connected) or in_progress. One of in_progress, reached, answered, voicemail, no_answer.
milestones.appointment_booked_attimestamp | nullWhen the lead's first appointment in the campaign was booked, however it was booked, even if it was later moved or cancelled.
milestones.appointment_attimestamp | nullWhen the appointment is or was scheduled: the first one that was held; if none was held, the latest one not cancelled; if all were cancelled, the latest one.
milestones.appointment_statusstring | nullThat appointment's status. Attendance your team records decides (shown up is held, no-show is no_show); otherwise held when your team's appointment call reached the lead and no_show when your team recorded nobody answered. An unanswered call with nothing recorded leaves it scheduled. One of scheduled, held, no_show, cancelled.
milestones.appointment_held_attimestamp | nullFor a held appointment, when the call that reached the lead started; for one only marked as shown up, its scheduled start.
milestones.closed_attimestamp | nullWhen the card entered the Won stage it is in now (a deal reopened and won again reports the latest win). null unless card.deal_status is won.
milestones.lost_attimestamp | nullThe same for a Lost stage. null unless card.deal_status is lost.
cardobject | nullThe card GET /v1/leads/{lead_id} returns as card, or null if the lead has none the member can open: its main card (the deal), or, for a member who may open only a follow-through card of the lead, that card with its own pipeline, stage, deal_status, closed_at and lost_at and the deal value it shares with the main card. Nothing of a card the member may not open is shown. Always shown, whatever the member's field visibility.
card.idUUIDThe card.
card.pipeline_idstring | nullThe card's pipeline.
card.pipeline_namestring | nullThe pipeline's name.
card.stagestring | nullSlug of the current stage.
card.stage_namestring | nullName of the current stage.
card.deal_statusstringabandoned when your team marked the deal abandoned, otherwise the outcome set on the card's stage in DialEcho (Won, Lost or Open), whatever the stage is called. A follow-through card the deal moves into after it is won is reported only to a member who may open that card and not the main card. One of open, won, lost, abandoned.
card.deal_valuenumber | nullThe deal value, shared by the main card and its follow-through cards, or null.

Example request ​

curl

bash
curl "https://development.agencydevworks.ai/v1/leads/aaaaaaaa-0000-4000-8000-000000000002/conversion" \
  -H "Authorization: Bearer dei_your_key"

JavaScript

js
const response = await fetch("https://development.agencydevworks.ai/v1/leads/aaaaaaaa-0000-4000-8000-000000000002/conversion", {
  headers: {
    "Authorization": "Bearer dei_your_key",
  },
});
const data = await response.json();

Example response ​

Status: 200 OK

json
{
  "lead_id": "aaaaaaaa-0000-4000-8000-000000000002",
  "campaign_id": "cccccccc-0000-4000-8000-000000000001",
  "created_at": "2026-11-03T10:21:07Z",
  "contact": {
    "first_name": "Sam",
    "last_name": null,
    "email": "sam@example.com",
    "phone": "+18035550142",
    "city": null,
    "state": "SC",
    "postal_code": null,
    "email_sha256": "cd25a6171969f2a3c6e35c7667e3908ef1bd2424241db04411a0eec454ca6c16",
    "phone_sha256": "70d177f4d52fc4982e5a28ed456060c15b9e4654a415c25be1eb9ade17a0a2ea"
  },
  "attribution": {
    "form_name": "quote-step-1",
    "page_url": "https://www.example.com/get-a-quote",
    "referrer": null,
    "utm_source": "google",
    "utm_medium": "cpc",
    "utm_campaign": "fall-promo",
    "utm_term": null,
    "utm_content": null,
    "utm_id": null,
    "adset_id": null,
    "ad_id": null,
    "fbclid": null,
    "fbc": null,
    "fbp": null,
    "gclid": "Cj0KCQexampleGclid",
    "meta_event_id": null
  },
  "milestones": {
    "first_call_at": "2026-11-03T10:21:30Z",
    "first_call_outcome": "voicemail",
    "appointment_booked_at": null,
    "appointment_at": null,
    "appointment_status": null,
    "appointment_held_at": null,
    "closed_at": null,
    "lost_at": null
  },
  "card": {
    "id": "dddddddd-0000-4000-8000-000000000001",
    "pipeline_id": "eeeeeeee-0000-4000-8000-000000000001",
    "pipeline_name": "Sales",
    "stage": "contacted",
    "stage_name": "Contacted",
    "deal_status": "open",
    "deal_value": null
  }
}

Errors ​

HTTPCodeWhen
403insufficient_scopeThe key does not have leads:read.
404not_foundThe lead does not exist or the key cannot reach it.
422invalid_requestlead_id is not a UUID.
503dependency_unavailableThe report or the access check is temporarily unavailable. Retry the same request with backoff.

Every endpoint can also answer 401 invalid_api_key, 429 rate_limited and 503 dependency_unavailable. See Errors in the overview.