Download OpenAPI specification:
Read-only public API for your Dripify campaigns and leads, secured with an API key
(X-Api-Key header — generate one from Settings → API & Integrations).
Requests are limited to 60 per minute and 5,000 per day, per API key. Authenticated
responses carry X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset.
A rejected key is answered before the limiter runs, so a 401 carries none. Exceeding
the limit returns 429 with a Retry-After header giving the number of seconds to wait.
Lead listing, lookup, single-lead detail, activity log and conversation; send a message to a lead; list custom lead field definitions and set/unset a custom field value on a lead
| campaignId | integer <int64> Restrict results to leads belonging to this campaign. Applied only when leadListId is not provided: a lead list already belongs to a single campaign, so when both are supplied leadListId takes precedence and campaignId is ignored. The id is not validated: one that is unknown to your account simply matches no leads. |
| leadListId | integer <int64> Restrict results to leads belonging to this lead list. When both leadListId and campaignId are supplied, results are scoped to the lead list and campaignId is ignored. The id is not validated: one that is unknown to your account simply matches no leads. |
| status | string (LeadStatus) Enum: "READY_FOR_PROCESSING" "PROCESSING_ENDED" "PROCESS_CORRUPTED" "PROCESSING_PAUSED" Restrict results to leads with at least one campaign membership at this status. A lead in several campaigns is returned once. |
| tagId | integer <int64> Restrict results to leads carrying this tag. The id is not validated: one that is unknown to your account, or that isn't yours, simply matches no leads. |
| cursor | string <= 128 characters Opaque marker for the next page. Take it from the previous response's |
| limit | integer <int32> [ 1 .. 100 ] Default: 25 Maximum items to return. Values above 100 are rejected. |
{- "items": [
- {
- "id": 0,
- "linkedinProfileUrl": "string",
- "publicId": "string",
- "firstName": "string",
- "lastName": "string",
- "pictureUrl": "string",
- "occupation": "string",
- "location": "string",
- "blacklisted": true,
- "lastAction": {
- "sequenceEventType": "CONNECT_SENT",
- "createdAt": "2019-08-24T14:15:22Z"
}, - "tags": [
- {
- "id": 0,
- "name": "string"
}
]
}
], - "nextCursor": "string",
- "limit": 0
}The lookup value travels in the body so it never reaches an access log or a browser history. One value can match several leads, so the response is a list. Results are always limited to the caller's own leads.
A value matching more than 100 profiles is answered with 400 rather than a partial list, because a truncated match set could omit a lead you own. Use a more specific value, such as a personal address rather than a shared company one.
string <email> <= 320 characters Email address to match. Never echoed back in the response. | |
| linkedinUrl | string <= 2048 characters Full LinkedIn profile URL, for example |
{- "linkedinUrl": "string"
}[- {
- "id": 0,
- "linkedinProfileUrl": "string",
- "publicId": "string",
- "firstName": "string",
- "lastName": "string",
- "pictureUrl": "string",
- "occupation": "string",
- "title": "string",
- "company": "string",
- "location": "string",
- "city": "string",
- "country": "string",
- "website": "string",
- "connectionsCount": 0,
- "premium": true,
- "updatedAt": "2019-08-24T14:15:22Z",
- "email": "string",
- "emailBounced": true,
- "emailAlternative": "string",
- "emailAlternativeBounced": true,
- "emailManual": "string",
- "emailManualBounced": true,
- "phone": "string",
- "emailFoundAt": "2019-08-24T14:15:22Z",
- "emailAlternativeSearchedAt": "2019-08-24T14:15:22Z",
- "blacklisted": true,
- "lastAction": {
- "sequenceEventType": "CONNECT_SENT",
- "createdAt": "2019-08-24T14:15:22Z"
}, - "tags": [
- {
- "id": 0,
- "name": "string"
}
]
}
]| id required | integer <int64> The lead's ID. |
{- "id": 0,
- "linkedinProfileUrl": "string",
- "publicId": "string",
- "firstName": "string",
- "lastName": "string",
- "pictureUrl": "string",
- "occupation": "string",
- "title": "string",
- "company": "string",
- "location": "string",
- "city": "string",
- "country": "string",
- "website": "string",
- "connectionsCount": 0,
- "premium": true,
- "updatedAt": "2019-08-24T14:15:22Z",
- "email": "string",
- "emailBounced": true,
- "emailAlternative": "string",
- "emailAlternativeBounced": true,
- "emailManual": "string",
- "emailManualBounced": true,
- "phone": "string",
- "emailFoundAt": "2019-08-24T14:15:22Z",
- "emailAlternativeSearchedAt": "2019-08-24T14:15:22Z",
- "blacklisted": true,
- "leadInCampaigns": [
- {
- "campaignId": 0,
- "campaignName": "string",
- "leadInCampaignStatus": "READY_FOR_PROCESSING"
}
], - "tags": [
- {
- "id": 0,
- "name": "string"
}
]
}The lead's timeline events, newest first — the same events the Dripify UI shows for
this lead. error is present only on events that represent a failure.
| id required | integer <int64> The lead's ID. |
| cursor | string <= 128 characters Opaque marker for the next page. Take it from the previous response's |
| limit | integer <int32> [ 1 .. 100 ] Default: 25 Maximum items to return. Values above 100 are rejected. |
{- "items": [
- {
- "leadInUserId": 0,
- "campaignId": 0,
- "campaignName": "string",
- "sequenceEventType": "CONNECT_SENT",
- "error": "UNABLE_TO_WITHDRAW",
- "createdAt": "2019-08-24T14:15:22Z"
}
], - "nextCursor": "string",
- "limit": 0
}The lead's LinkedIn conversation: participants, read, starred and archived state, and who sent the last message and when.
A lead without a LinkedIn conversation answers 404.
| id required | integer <int64> The lead's ID. |
{- "conversationId": "string",
- "leadInUserId": 0,
- "updatedAt": "2019-08-24T14:15:22Z",
- "read": true,
- "unreadCount": 0,
- "starred": true,
- "archived": true,
- "participants": [
- {
- "firstName": "string",
- "lastName": "string",
- "pictureUrl": "string"
}
], - "lastMessage": {
- "direction": "LEAD",
- "createdAt": "2019-08-24T14:15:22Z"
}
}Sends message into the lead's existing LinkedIn conversation. The lead must already
have a conversation — this endpoint never starts a new one.
Sending pauses the lead's outbound automation: any campaign where this lead is currently
READY_FOR_PROCESSING is paused as a side effect of the send, the same way it is when a
message is sent from the Dripify inbox.
| leadId required | integer <int64> The lead's ID. |
| message required | string [ 1 .. 5000 ] characters The message text to send into the lead's existing LinkedIn conversation. |
{- "message": "string"
}{- "eventId": "string"
}The account's custom lead field definitions — use id to set or unset a value with the lead custom-field endpoints. Archived fields are not included.
[- {
- "id": 0,
- "name": "string"
}
]Sets value for customLeadFieldId on leadId, creating it if none is stored yet and
overwriting it otherwise — the caller never needs to know which happened.
leadId must be one of your own leads, or the request is answered with 404.
customLeadFieldId must be one of your own, non-archived custom lead fields — list valid
ids with GET /v1/open-api/custom-lead-fields — otherwise the request is answered with
404 or 409.
| leadId required | integer <int64> The lead's ID. |
| customLeadFieldId required | integer <int64> The custom lead field's ID. |
| value required | string <= 1000 characters The value to store for this custom lead field on this lead. |
{- "value": "string"
}{- "status": 0,
- "error": "string",
- "message": "string"
}Removes the value stored for customLeadFieldId on leadId, if any.
Unsetting is idempotent: a customLeadFieldId that does not exist, that you do not own,
or that has no value stored for this lead is skipped silently and still answered with 204.
leadId is not treated that way — a lead that does not exist or is not yours is answered
with 404, and nothing is removed.
| leadId required | integer <int64> The lead's ID. |
| customLeadFieldId required | integer <int64> The custom lead field's ID. |
{- "status": 0,
- "error": "string",
- "message": "string"
}The messages of a lead's LinkedIn conversation, newest first. They are read live from
LinkedIn on every call, so a response reflects the conversation as it is right now. Take
conversationId from the lead's conversation endpoint.
Pages hold up to 20 messages. A page with fewer than 20 messages is normally the last one,
but it still carries a nextCursor: the history ends at the first page that comes back
with no messages and no nextCursor.
| conversationId required | string <= 255 characters The conversation's ID, as returned by the lead's conversation endpoint. |
| cursor | string <= 128 characters Opaque marker for the next page. Take it from the previous response's |
{- "items": [
- {
- "eventId": "string",
- "conversationId": "string",
- "direction": "LEAD",
- "message": "string",
- "subject": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "editedAt": "2019-08-24T14:15:22Z",
- "attachments": [
- {
- "name": "string",
- "reference": "string",
- "mediaType": "string",
- "byteSize": 0
}
]
}
], - "nextCursor": "string"
}Adds every tag in addTagIds to every lead in leadInUserIds, in one call. Applying a
tag a lead already carries is a no-op, not an error.
Every id is checked before anything is written: a lead that does not exist or is not
yours, and a tag that does not exist or is not yours, are each answered with 404, and
nothing is applied. Create tags with POST /v1/open-api/tags and list them with
GET /v1/open-api/tags.
| leadInUserIds required | Array of integers <int64> [ 1 .. 1000 ] items [ items <int64 > ] The leads to tag. Every id must be one of your own leads. |
| addTagIds required | Array of integers <int64> [ 1 .. 50 ] items [ items <int64 > ] The tags to add. Every id must be one of your own tags. |
{- "leadInUserIds": [
- 0
], - "addTagIds": [
- 0
]
}{- "status": 0,
- "error": "string",
- "message": "string"
}Removes only the tags named in removeTagIds from every lead in leadInUserIds. Tags
those leads carry that are not named are left in place, and the tags themselves are not
deleted from your account — use the Tags endpoints for that.
Removal is idempotent: a tag id a lead does not carry, one that does not exist, and one belonging to another account are all skipped silently and still answered with 204. Lead ids are not treated that way — a lead that does not exist or is not yours is answered with 404, and nothing is removed.
| leadInUserIds required | Array of integers <int64> [ 1 .. 1000 ] items [ items <int64 > ] The leads to remove tags from. Every id must be one of your own leads. |
| removeTagIds required | Array of integers <int64> [ 1 .. 50 ] items [ items <int64 > ] The tags to remove. Ids that do not exist, or that you do not own, are skipped rather than rejected. |
{- "leadInUserIds": [
- 0
], - "removeTagIds": [
- 0
]
}{- "status": 0,
- "error": "string",
- "message": "string"
}| cursor | string <= 128 characters Opaque marker for the next page. Take it from the previous response's |
| limit | integer <int32> [ 1 .. 100 ] Default: 25 Maximum items to return. Values above 100 are rejected. |
{- "items": [
- {
- "id": 0,
- "name": "string",
- "status": "DRAFT",
- "locked": true,
- "createdAt": "2019-08-24T14:15:22Z"
}
], - "nextCursor": "string",
- "limit": 0
}| id required | integer <int64> The campaign's ID. |
| cursor | string <= 128 characters Opaque marker for the next page. Take it from the previous response's |
| limit | integer <int32> [ 1 .. 100 ] Default: 25 Maximum items to return. Values above 100 are rejected. |
{- "items": [
- {
- "id": 0,
- "name": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "totalLeadsCount": 0,
- "leadsNumberToCollect": 0,
- "searchStatus": "READY_FOR_SEARCH"
}
], - "nextCursor": "string",
- "limit": 0
}Counts and rates for one campaign, the same numbers the Dripify campaign screen shows.
Rates are percents rounded to one decimal place, so parse them as a decimal type. The
counters under leadStatusBreakdown are a live snapshot and need not add up to
totalLeads.
| id required | integer <int64> The campaign's ID. |
{- "campaignId": 0,
- "totalLeads": 0,
- "contactedLeads": 0,
- "leadStatusBreakdown": {
- "inProgress": 0,
- "finished": 0,
- "failed": 0,
- "blacklisted": 0,
- "gettingReady": 0,
- "waiting": 0,
- "paused": 0,
- "uploading": 0,
- "transferred": 0
}, - "acceptanceRate": 0.1,
- "acceptanceRateLeads": 0,
- "replyRate": 0.1,
- "replyRateLeads": 0,
- "leadListsCount": 0,
- "active": true,
- "searchActive": true,
- "transferActive": true
}Creates a new lead list in the campaign from the supplied LinkedIn identifiers — this
endpoint always creates a new list, it never appends to an existing one. Each item in
leads must supply exactly one of linkedinUrl or publicId; duplicates within the
same request are collapsed before the list is created.
Request bodies are strict across this API: any field not listed in the schema is rejected with 400 rather than ignored, so a misspelled field never passes silently.
Collection only starts once the campaign is ACTIVE — enabling/disabling a campaign is not part of the public API in v1 and must be done from the Dripify UI.
| id required | integer <int64> The campaign's ID. |
| name | string <= 120 characters Optional label for the created lead list. Defaults to a generated name. |
required | Array of objects (UploadLead) [ 1 .. 1000 ] items |
{- "name": "string",
- "leads": [
- {
- "linkedinUrl": "string",
- "publicId": "string",
- "customFields": [
- {
- "customLeadFieldId": 0,
- "value": "string"
}
]
}
]
}{- "leadList": {
- "id": 0,
- "name": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "totalLeadsCount": 0,
- "leadsNumberToCollect": 0,
- "searchStatus": "READY_FOR_SEARCH"
}, - "acceptedCount": 0,
- "duplicateCount": 0
}Appends resolved LinkedIn identifiers to an existing "Paste profile URLs" lead list. Unlike upload, this never creates a new list — it targets an existing one by id. Core rejects the append with a 400 if the list isn't a "Paste profile URLs" list, or if it's already at its configured capacity.
| id required | integer <int64> The lead list's ID. |
required | Array of objects (UploadLead) [ 1 .. 1000 ] items |
{- "leads": [
- {
- "linkedinUrl": "string",
- "publicId": "string",
- "customFields": [
- {
- "customLeadFieldId": 0,
- "value": "string"
}
]
}
]
}{- "leadList": {
- "id": 0,
- "name": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "totalLeadsCount": 0,
- "leadsNumberToCollect": 0,
- "searchStatus": "READY_FOR_SEARCH"
}, - "submittedCount": 0,
- "duplicateWithinRequestCount": 0
}| cursor | string <= 128 characters Opaque marker for the next page. Take it from the previous response's |
| limit | integer <int32> [ 1 .. 100 ] Default: 25 Maximum items to return. Values above 100 are rejected. |
{- "items": [
- {
- "id": 0,
- "name": "string",
- "colorId": 0,
- "createdAt": 0,
- "isDefault": true
}
], - "nextCursor": "string",
- "limit": 0
}| name required | string The tag's name. |
| colorId | integer <int32> The tag's color. Defaults to the account's default color when omitted. |
{- "name": "string",
- "colorId": 0
}{- "id": 0,
- "name": "string",
- "colorId": 0,
- "createdAt": 0,
- "isDefault": true
}Every team the API caller is a member of, with campaign rollup analytics inlined into each row.
| cursor | string <= 128 characters Opaque marker for the next page. Take it from the previous response's |
| limit | integer <int32> [ 1 .. 100 ] Default: 25 Maximum items to return. Values above 100 are rejected. |
{- "items": [
- {
- "id": 0,
- "name": "string",
- "membersCount": 0,
- "callerRole": "OWNER",
- "statistics": {
- "activeCampaignsCount": 0,
- "unreadMessagesCount": 0,
- "acceptanceRate": 0.1,
- "replyRate": 0.1
}
}
], - "nextCursor": "string",
- "limit": 0
}The members of one of your teams, each with the statistics the Dripify team screen shows.
You must be the team's OWNER or MANAGER; any other team answers 404. Ordering depends on
live subscription state, so treat nextCursor as short-lived.
| teamId required | integer <int64> The team's ID. |
| cursor | string <= 128 characters Opaque marker for the next page. Take it from the previous response's |
| limit | integer <int32> [ 1 .. 100 ] Default: 25 Maximum items to return. Values above 100 are rejected. |
{- "items": [
- {
- "userId": "string",
- "firstName": "string",
- "lastName": "string",
- "pictureUrl": "string",
- "role": "OWNER",
- "lastActiveAt": "2019-08-24T14:15:22Z",
- "statistics": {
- "activeCampaignsCount": 0,
- "acceptanceRate": 0.1,
- "replyRate": 0.1,
- "unreadMessagesCount": 0
}
}
], - "nextCursor": "string",
- "limit": 0
}