Create a lead
/v1/leadsCreates a lead, and enrols it in a campaign when you send campaign_id. If a lead with the same email or LinkedIn URL already exists in your organization, that lead is enrolled instead of a new one being created.
Send the lead's fields nested under lead, or spread across the top level of the body; both are accepted. first_name and last_name are required, along with at least one of email or linkedin_url. Emails are trimmed and matched without regard to case; LinkedIn URLs are trimmed and matched exactly.
| Situation | Response |
|---|---|
| No matching lead | 201, with lead_created: true. The lead is created, and enrolled when you sent campaign_id. |
A matching lead, not yet in campaign_id |
200, with lead_created: false. The existing lead is enrolled, and lead is its stored record: the fields in your request don't update it. |
A matching lead already in campaign_id |
409 LEAD_ALREADY_IN_CAMPAIGN |
A matching lead, and no campaign_id |
409 LEAD_ALREADY_EXISTS |
| The contact is on your do-not-contact list | 409 LEAD_SUPPRESSED. Nothing is created or enrolled; details.suppressed_by is email, domain or linkedin_url. |
Send an Idempotency-Key so a retry after a timeout returns the original response instead of a 409.
An enrolment starts in the campaign's backlog. The lead is contacted once the campaign has sending capacity for it, not the moment this request returns.
Headers
AuthorizationstringRequiredBearerfollowed by a space and your API key, for exampleBearer vk_….Idempotency-KeystringAny unique string, such as a UUID, that makes retrying this request safe. A repeat with the same key for at least 24 hours returns the original response instead of doing the work again. Use a new key for each distinct request.
at most 255 characters
Request body
leadobjectRequiredLead data. May also be supplied as top-level fields.
Show 11 child attributesHide child attributes
first_namestringRequiredLead's first name
at most 2,000 charactersExample"Sarah"last_namestringRequiredLead's last name
at most 2,000 charactersExample"Johnson"annual_revenueinteger or nullCompany annual revenue in dollars
≥ 0Example5000000companystring or nullCompany name
at most 2,000 charactersExample"Acme Corp"company_websitestring or nullLead's company website URL
at most 2,000 charactersExample"https://acmecorp.com"custom_fieldsobject or nullCustom fields as key-value pairs
emailstring · email or nullLead's email address (required if linkedin_url not provided)
at most 2,000 charactersExample"sarah.johnson@acmecorp.com"employeesinteger or nullNumber of employees at the company
≥ 0Example150industrystring or nullIndustry sector
at most 2,000 charactersExample"Technology"linkedin_urlstring or nullLead's LinkedIn profile URL (required if email not provided)
at most 2,000 charactersExample"https://linkedin.com/in/sarahjohnson"titlestring or nullJob title
at most 2,000 charactersExample"VP of Sales"
campaign_idstring · uuid or nullUUID of the campaign to enrol the lead in. Omit to create the lead without enrolling it.
at most 2,000 charactersExample"550e8400-e29b-41d4-a716-446655440000"custom_fieldsobject or nullCustom fields for this campaign assignment (distinct from the lead's own custom_fields)
Response
200 / 201
messagestringRequiredExample"Lead successfully added to campaign"lead_idstringRequiredID of the created or existing lead
Example"a1b2c3d4-e5f6-7890-abcd-ef1234567890"campaign_idstring or nullCampaign the lead was enrolled in. Also available as enrollment.campaign_id
enrollmentobject or nullPresent when a campaign_id was supplied; null otherwise
Show 2 child attributesHide child attributes
sequence_lead_idstringRequiredID of the campaign sequence entry
Example"b2c3d4e5-f6a7-8901-bcde-f12345678901"campaign_idstringRequiredCampaign the lead was enrolled in
Example"550e8400-e29b-41d4-a716-446655440000"
leadobject or nullThe lead record as stored
lead_createdboolean or nulltrue when this request created the lead; false when a lead with this email or LinkedIn URL already existed and was enrolled
Exampletruesequence_lead_idstring or nullID of the campaign sequence entry. Also available as enrollment.sequence_lead_id
successbooleanDefaulttrue
Errors
Errors share one JSON body: success, error, message, optional details, and request_id.
| Status | Code | Meaning |
|---|---|---|
| 400 | VALIDATION_ERROR | The request didn't match the endpoint's schema: a missing or malformed field, a bad query parameter, or a value out of range. |
| 401 | UNAUTHORIZED | The |
| 401 | API_KEY_EXPIRED | The API key is past its expiry date. Create a new key in the Victoria AI app. |
| 403 | TRIAL_LEAD_CAP_REACHED | The organization is on a free trial and has used up its lead quota, so the lead wasn't created. |
| 403 | INSUFFICIENT_SCOPE | The API key doesn't have the scope this endpoint requires, such as |
| 403 | ORGANIZATION_DEACTIVATED | The organization that owns this API key has been deactivated. |
| 404 | CAMPAIGN_NOT_FOUND | No campaign with this ID exists in your organization. |
| 409 | LEAD_ALREADY_IN_CAMPAIGN | The lead already exists in your organization and is already enrolled in the campaign given by |
| 409 | LEAD_ALREADY_EXISTS | A lead with the same email or LinkedIn URL already exists in your organization. From Create a lead, this means the request named no |
| 409 | LEAD_SUPPRESSED | The contact is on your organization's do-not-contact list, so the lead wasn't created, enrolled or updated. |
| 409 | IDEMPOTENCY_KEY_REUSED | This |
| 409 | IDEMPOTENCY_IN_PROGRESS | The first request with this |
| 413 | PAYLOAD_TOO_LARGE | The request body is larger than 1 MB. |
| 429 | RATE_LIMITED | Too many requests for this API key: more than 100 a minute to one endpoint, or 600 a minute in total. Retry after the number of seconds in the |
| 500 | INTERNAL_ERROR | Something failed on our side. The response never includes internal details; quote its |
| 503 | UPSTREAM_TIMEOUT | A service the API depends on timed out. The request is safe to retry. |
| 503 | AUTH_UNAVAILABLE | The API key couldn't be checked because the authentication service was unavailable. The request is safe to retry. |
Response headers
| Header | Description |
|---|---|
X-Request-ID | Correlation ID for the request, also returned as |
RateLimit-Limit | Requests allowed to this endpoint per minute. |
RateLimit-Remaining | Requests you can still send to this endpoint right now. |
RateLimit-Reset | Seconds until the endpoint's full limit is available again. |
Retry-After | On a |
Idempotent-Replay |
|