Customer API
Connect your tools to the leads, lists and jobs in your workspace. API access is available on every plan, including trial.
Authentication
Create a key in Settings → Account & security. Save it when it is shown, and choose only the permissions your tool needs. Revoke it there at any time.
GET /api/v1/leads?limit=50&status=good
Authorization: Bearer YOUR_API_KEYAll data belongs to the key’s workspace. Keys are hashed at rest. Session cookies do not authenticate API requests.
Credits and retries
Jobs follow the dashboard’s credit, cache and refund rules. Search reserves credits at creation; verification and enrichment reserve them when the worker claims a batch. Quotes are free.
Send an Idempotency-Key header for each new mutation. Reuse it when retrying the same request. Changed input returns 409. Poll the returned statusUrl for the durable result.
Limits are 60 requests per key and 300 per workspace each minute. Honor Retry-After on 429. Pages use limit (1–100) and offset; inspect hasMore. JSON bodies are limited to 262144 bytes.
Webhooks
Register an HTTPS receiver and choose events in Settings → Integrations. Payloads contain IDs, status and counts. Fetch full records through this API.
Verify the exact body with the timestamp and HMAC headers before processing. Receivers without a crypto node can forward those bytes and headers to the authenticated verification endpoint. Deduplicate effects by event ID, and acknowledge with 2xx after the effect commits.
Delivery logs include eight attempts with retry backoff. Ten consecutive exhausted deliveries disable an endpoint. Test ping and terminal redelivery use no credits. Logs are retained for 31 days.
Resources
Successful JSON responses wrap the result in data. Pages also include total, limit, offset and hasMore. Exports return a saved selection and an authenticated CSV download URL.
GET/api/v1/outreach/campaignsRead outreach campaigns list
Metadata and status only, under an explicit outreach:read grant. Existing keys do not gain this permission. Campaigns include saved drafts; drafts are not launched. Conversation IDs are opaque strings scoped to the campaign and must be URL encoded. Messages are ordered by due time and ID; accepted means Gmail accepted the send, not inbox delivery. bookingConfirmed records acknowledged initial event creation; meetingState and changeStatus describe subsequent changes. Offered links are not bookings. Full contact data requires leads:read. Gmail text, campaign briefs, review evidence and provider credentials are excluded. Sending, approval and Calendar changes stay in the app.
Permissions: outreach:read.
GET/api/v1/outreach/campaigns/{campaignId}Read outreach campaigns get
Metadata and status only, under an explicit outreach:read grant. Existing keys do not gain this permission. Campaigns include saved drafts; drafts are not launched. Conversation IDs are opaque strings scoped to the campaign and must be URL encoded. Messages are ordered by due time and ID; accepted means Gmail accepted the send, not inbox delivery. bookingConfirmed records acknowledged initial event creation; meetingState and changeStatus describe subsequent changes. Offered links are not bookings. Full contact data requires leads:read. Gmail text, campaign briefs, review evidence and provider credentials are excluded. Sending, approval and Calendar changes stay in the app.
Permissions: outreach:read.
GET/api/v1/outreach/campaigns/{campaignId}/conversationsRead outreach conversations list
Metadata and status only, under an explicit outreach:read grant. Existing keys do not gain this permission. Campaigns include saved drafts; drafts are not launched. Conversation IDs are opaque strings scoped to the campaign and must be URL encoded. Messages are ordered by due time and ID; accepted means Gmail accepted the send, not inbox delivery. bookingConfirmed records acknowledged initial event creation; meetingState and changeStatus describe subsequent changes. Offered links are not bookings. Full contact data requires leads:read. Gmail text, campaign briefs, review evidence and provider credentials are excluded. Sending, approval and Calendar changes stay in the app.
Permissions: outreach:read.
GET/api/v1/outreach/campaigns/{campaignId}/conversations/{conversationId}Read outreach conversations get
Metadata and status only, under an explicit outreach:read grant. Existing keys do not gain this permission. Campaigns include saved drafts; drafts are not launched. Conversation IDs are opaque strings scoped to the campaign and must be URL encoded. Messages are ordered by due time and ID; accepted means Gmail accepted the send, not inbox delivery. bookingConfirmed records acknowledged initial event creation; meetingState and changeStatus describe subsequent changes. Offered links are not bookings. Full contact data requires leads:read. Gmail text, campaign briefs, review evidence and provider credentials are excluded. Sending, approval and Calendar changes stay in the app.
Permissions: outreach:read.
GET/api/v1/outreach/campaigns/{campaignId}/conversations/{conversationId}/messagesRead outreach messages list
Metadata and status only, under an explicit outreach:read grant. Existing keys do not gain this permission. Campaigns include saved drafts; drafts are not launched. Conversation IDs are opaque strings scoped to the campaign and must be URL encoded. Messages are ordered by due time and ID; accepted means Gmail accepted the send, not inbox delivery. bookingConfirmed records acknowledged initial event creation; meetingState and changeStatus describe subsequent changes. Offered links are not bookings. Full contact data requires leads:read. Gmail text, campaign briefs, review evidence and provider credentials are excluded. Sending, approval and Calendar changes stay in the app.
Permissions: outreach:read.
GET/api/v1/outreach/campaigns/{campaignId}/meetingsRead outreach meetings list
Metadata and status only, under an explicit outreach:read grant. Existing keys do not gain this permission. Campaigns include saved drafts; drafts are not launched. Conversation IDs are opaque strings scoped to the campaign and must be URL encoded. Messages are ordered by due time and ID; accepted means Gmail accepted the send, not inbox delivery. bookingConfirmed records acknowledged initial event creation; meetingState and changeStatus describe subsequent changes. Offered links are not bookings. Full contact data requires leads:read. Gmail text, campaign briefs, review evidence and provider credentials are excluded. Sending, approval and Calendar changes stay in the app.
Permissions: outreach:read.
GET/api/v1/outreach/activityRead outreach activity list
Metadata and status only, under an explicit outreach:read grant. Existing keys do not gain this permission. Campaigns include saved drafts; drafts are not launched. Conversation IDs are opaque strings scoped to the campaign and must be URL encoded. Messages are ordered by due time and ID; accepted means Gmail accepted the send, not inbox delivery. bookingConfirmed records acknowledged initial event creation; meetingState and changeStatus describe subsequent changes. Offered links are not bookings. Full contact data requires leads:read. Gmail text, campaign briefs, review evidence and provider credentials are excluded. Sending, approval and Calendar changes stay in the app.
Permissions: outreach:read.
GET/api/v1/webhook-eventsRead committed webhook event metadata
Newest first, with optional event type filtering. Returns the immutable IDs, status and counts sent to subscribed endpoints, retained for 31 days. Test pings are excluded. Events before the workspace had a matching active subscriber are not backfilled. It exposes no signing secret, callback URL, delivery state or full lead data.
Permissions: webhooks:read.
GET/api/v1/webhooks/{endpointId}/deliveriesRead delivery and attempt logs
Read delivery and attempt logs
Permissions: webhooks:read.
POST/api/v1/webhooks/{endpointId}/pingQueue a signed test ping
Queued through the transactional outbox. Requires the current endpoint revision and an active grant. Replaying the same request queues nothing extra. Controls share a workspace budget of 20 per minute. Redelivery preserves eventId and creates a new delivery with eight attempts; receivers still deduplicate by eventId. Pending or running deliveries cannot be manually redelivered.
Permissions: webhooks:write.
Requires Idempotency-Key. Use a new key for new work.
{
"type": "object",
"properties": {
"expectedRevision": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
}
},
"required": [
"expectedRevision"
],
"additionalProperties": false
}POST/api/v1/webhooks/{endpointId}/deliveries/{deliveryId}/redeliverRedeliver a terminal event
Queued through the transactional outbox. Requires the current endpoint revision and an active grant. Replaying the same request queues nothing extra. Controls share a workspace budget of 20 per minute. Redelivery preserves eventId and creates a new delivery with eight attempts; receivers still deduplicate by eventId. Pending or running deliveries cannot be manually redelivered.
Permissions: webhooks:write.
Requires Idempotency-Key. Use a new key for new work.
{
"type": "object",
"properties": {
"expectedRevision": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
}
},
"required": [
"expectedRevision"
],
"additionalProperties": false
}POST/api/v1/webhooks/{endpointId}/verifyVerify exact raw webhook bytes
Send the exact raw body and X-Guffles-Delivery-Id, X-Guffles-Timestamp and X-Guffles-Signature headers. The helper checks a fresh HMAC timestamp against an owned current delivery without revealing the signing secret. It does not acknowledge processing; callers must make their subsequent side effects idempotent. At most 4096 raw bytes. Duplicate valid verification is allowed for retrying the receiver workflow.
Permissions: webhooks:read.
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"type": {
"type": "string",
"enum": [
"lead.created",
"list.updated",
"verification.completed",
"verification.failed",
"enrichment.completed",
"enrichment.failed",
"search.completed",
"search.failed",
"mission.completed",
"reply.received",
"meeting.booked",
"meeting.cancelled",
"lead.unsubscribed",
"lead.closed",
"webhook.test"
]
},
"version": {
"type": "string",
"const": "v1"
},
"occurredAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
},
"data": {
"type": "object",
"properties": {
"leadId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"listId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"jobId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"searchId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"missionId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"campaignId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"conversationId": {
"type": "string",
"minLength": 1,
"maxLength": 320
},
"bookingId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"changeId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"closureReason": {
"type": "string",
"enum": [
"not_interested",
"no_response",
"no_budget",
"wrong_person",
"left_company",
"meeting_booked",
"meeting_cancelled",
"unsubscribed",
"do_not_contact",
"bounced",
"other"
]
},
"status": {
"type": "string",
"maxLength": 40
},
"counts": {
"type": "object",
"propertyNames": {
"type": "string",
"maxLength": 40,
"pattern": "^[a-zA-Z]+$"
},
"additionalProperties": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
}
}
},
"additionalProperties": false
}
},
"required": [
"id",
"type",
"version",
"occurredAt",
"data"
],
"additionalProperties": false
}GET/api/v1/webhooksList webhook endpoints
Optional exact name and status filters. Deleted metadata is excluded unless includeDeleted=true; it never reveals callback paths or signing secrets. Newest first. Tombstone IDs can distinguish a new subscription from a retry of an earlier creation.
Permissions: webhooks:read.
GET/api/v1/webhooks/{endpointId}Read webhook endpoint metadata
Read webhook endpoint metadata
Permissions: webhooks:read.
POST/api/v1/webhooksWebhooks: create
HTTPS public endpoints only, with DNS checked at registration and each delivery. URLs and signing secrets are encrypted. Read responses show only the URL origin. Create or explicit secret rotation returns signingSecret; a creation retry can recover it only for the original caller and unchanged revision. Receipts contain metadata only. Update requires expectedRevision; URL changes and re-enabling rotate the secret. Revoking an API key pauses its bound endpoints. Deletion pauses all future delivery. Limit: 20 registered endpoints per workspace. Outreach subscriptions include reply.received, meeting.booked, meeting.cancelled, lead.unsubscribed and lead.closed; committed events carry IDs and bounded metadata only. Deletion uses an empty body.
Permissions: webhooks:write.
Requires Idempotency-Key. Use a new key for new work.
{
"type": "object",
"properties": {
"name": {
"default": "Webhook endpoint",
"type": "string",
"minLength": 1,
"maxLength": 100
},
"url": {
"type": "string",
"maxLength": 2000,
"format": "uri"
},
"events": {
"minItems": 1,
"maxItems": 14,
"type": "array",
"items": {
"type": "string",
"enum": [
"lead.created",
"list.updated",
"verification.completed",
"verification.failed",
"enrichment.completed",
"enrichment.failed",
"search.completed",
"search.failed",
"mission.completed",
"reply.received",
"meeting.booked",
"meeting.cancelled",
"lead.unsubscribed",
"lead.closed"
]
}
}
},
"required": [
"url",
"events"
],
"additionalProperties": false
}PATCH/api/v1/webhooks/{endpointId}Webhooks: update
HTTPS public endpoints only, with DNS checked at registration and each delivery. URLs and signing secrets are encrypted. Read responses show only the URL origin. Create or explicit secret rotation returns signingSecret; a creation retry can recover it only for the original caller and unchanged revision. Receipts contain metadata only. Update requires expectedRevision; URL changes and re-enabling rotate the secret. Revoking an API key pauses its bound endpoints. Deletion pauses all future delivery. Limit: 20 registered endpoints per workspace. Outreach subscriptions include reply.received, meeting.booked, meeting.cancelled, lead.unsubscribed and lead.closed; committed events carry IDs and bounded metadata only. Deletion uses an empty body.
Permissions: webhooks:write.
Requires Idempotency-Key. Use a new key for new work.
{
"type": "object",
"properties": {
"expectedRevision": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 100
},
"url": {
"type": "string",
"maxLength": 2000,
"format": "uri"
},
"events": {
"minItems": 1,
"maxItems": 14,
"type": "array",
"items": {
"type": "string",
"enum": [
"lead.created",
"list.updated",
"verification.completed",
"verification.failed",
"enrichment.completed",
"enrichment.failed",
"search.completed",
"search.failed",
"mission.completed",
"reply.received",
"meeting.booked",
"meeting.cancelled",
"lead.unsubscribed",
"lead.closed"
]
}
},
"enabled": {
"type": "boolean"
},
"rotateSigningSecret": {
"type": "boolean"
}
},
"required": [
"expectedRevision"
],
"additionalProperties": false
}DELETE/api/v1/webhooks/{endpointId}Webhooks: delete
HTTPS public endpoints only, with DNS checked at registration and each delivery. URLs and signing secrets are encrypted. Read responses show only the URL origin. Create or explicit secret rotation returns signingSecret; a creation retry can recover it only for the original caller and unchanged revision. Receipts contain metadata only. Update requires expectedRevision; URL changes and re-enabling rotate the secret. Revoking an API key pauses its bound endpoints. Deletion pauses all future delivery. Limit: 20 registered endpoints per workspace. Outreach subscriptions include reply.received, meeting.booked, meeting.cancelled, lead.unsubscribed and lead.closed; committed events carry IDs and bounded metadata only. Deletion uses an empty body.
Permissions: webhooks:write.
Requires Idempotency-Key. Use a new key for new work.
GET/api/v1/meRead the key's workspace and permissions
Read the key's workspace and permissions
Permissions: Any active workspace API key.
GET/api/v1/leadsList and filter owned leads
List and filter owned leads
Permissions: leads:read.
GET/api/v1/leads/{leadId}Read a prepared lead
Read a prepared lead
Permissions: leads:read.
GET/api/v1/listsList workspace lists
List workspace lists
Permissions: lists:read.
GET/api/v1/lists/{listId}Read a list
Read a list
Permissions: lists:read.
GET/api/v1/lists/{listId}/membersList member IDs
List member IDs
Permissions: lists:read.
POST/api/v1/listsLists: create
Members must already belong to this workspace. This operation does not import leads or grant entitlements. A list referenced by a Finder job cannot be deleted (409).
Permissions: lists:write.
Requires Idempotency-Key. Use a new key for new work.
{
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 200
}
},
"required": [
"name"
],
"additionalProperties": false
}PATCH/api/v1/lists/{listId}Lists: update
Members must already belong to this workspace. This operation does not import leads or grant entitlements. A list referenced by a Finder job cannot be deleted (409).
Permissions: lists:write.
Requires Idempotency-Key. Use a new key for new work.
{
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 200
}
},
"required": [
"name"
],
"additionalProperties": false
}DELETE/api/v1/lists/{listId}Lists: delete
Members must already belong to this workspace. This operation does not import leads or grant entitlements. A list referenced by a Finder job cannot be deleted (409).
Permissions: lists:write.
Requires Idempotency-Key. Use a new key for new work.
POST/api/v1/lists/{listId}/membersLists: members.add
Members must already belong to this workspace. This operation does not import leads or grant entitlements. A list referenced by a Finder job cannot be deleted (409).
Permissions: lists:write.
Requires Idempotency-Key. Use a new key for new work.
{
"type": "object",
"properties": {
"leadIds": {
"minItems": 1,
"maxItems": 5000,
"type": "array",
"items": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
}
}
},
"required": [
"leadIds"
],
"additionalProperties": false
}DELETE/api/v1/lists/{listId}/membersLists: members.remove
Members must already belong to this workspace. This operation does not import leads or grant entitlements. A list referenced by a Finder job cannot be deleted (409).
Permissions: lists:write.
Requires Idempotency-Key. Use a new key for new work.
{
"type": "object",
"properties": {
"leadIds": {
"minItems": 1,
"maxItems": 5000,
"type": "array",
"items": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
}
}
},
"required": [
"leadIds"
],
"additionalProperties": false
}POST/api/v1/searchesStart a Finder workflow
Uses the existing credit reservation. Optional verification, enrichment and list writes also require their respective write scopes. Business filters use display country/state names (United States, Texas); specify category or keyword. People filters use jobTitle and optional location, seniority, industry, size and emailStatus. Quotes/credits and complete followup status follow the dashboard rules. An enabled async Finder rollout is required.
Permissions: searches:write.
Requires Idempotency-Key. Use a new key for new work.
{
"type": "object",
"properties": {
"source": {
"type": "string",
"enum": [
"businesses",
"people"
]
},
"filters": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"requestedCount": {
"type": "integer",
"minimum": 1,
"maximum": 5000
},
"workflow": {
"type": "object",
"properties": {
"verificationEnabled": {
"type": "boolean"
},
"enrichmentEnabled": {
"type": "boolean"
},
"enrichmentScope": {
"type": "string",
"enum": [
"all",
"deliverable"
]
},
"qualificationEnabled": {
"default": false,
"type": "boolean"
},
"qualificationScope": {
"default": "all",
"type": "string",
"enum": [
"all",
"researched",
"verified_researched"
]
},
"listMode": {
"type": "string",
"enum": [
"none",
"existing",
"new"
]
},
"requestedListId": {
"anyOf": [
{
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
{
"type": "null"
}
]
},
"newListName": {
"anyOf": [
{
"type": "string",
"minLength": 1,
"maxLength": 120
},
{
"type": "null"
}
]
}
},
"required": [
"verificationEnabled",
"enrichmentEnabled",
"enrichmentScope",
"listMode",
"requestedListId",
"newListName"
],
"additionalProperties": false,
"description": "none requires null requestedListId and newListName; existing requires requestedListId and null newListName; new requires newListName and null requestedListId. Disabled qualification requires scope all; researched requires enrichment; verified_researched requires verification plus deliverable enrichment."
}
},
"required": [
"source",
"filters",
"requestedCount",
"workflow"
],
"additionalProperties": false
}POST/api/v1/verification/quoteQuote verification
Returns the dashboard's existing cache, eligibility and credit calculation; does not spend credits.
Permissions: verification:read.
{
"type": "object",
"properties": {
"source": {
"type": "string",
"enum": [
"businesses",
"people"
]
},
"force": {
"default": false,
"type": "boolean"
},
"leadIds": {
"minItems": 1,
"maxItems": 5000,
"type": "array",
"items": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
}
}
},
"required": [
"source",
"leadIds"
],
"additionalProperties": false
}POST/api/v1/verification/jobsStart verification
The existing worker reserves credits when claiming a batch. Fresh cached results are free. Verification charges one credit per two distinct fresh emails, rounded up per batch. Business enrichment costs one credit; people enrichment costs two. Existing skip/refund rules apply. Verification's optional enrichment requires enrichment:write; request identities are assigned by the server.
Permissions: verification:write.
Requires Idempotency-Key. Use a new key for new work.
{
"type": "object",
"properties": {
"source": {
"type": "string",
"enum": [
"businesses",
"people"
]
},
"force": {
"default": false,
"type": "boolean"
},
"leadIds": {
"minItems": 1,
"maxItems": 5000,
"type": "array",
"items": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
}
},
"enrichment": {
"default": {
"enabled": false,
"scope": "all"
},
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"scope": {
"type": "string",
"enum": [
"all",
"deliverable"
]
}
},
"required": [
"enabled",
"scope"
],
"additionalProperties": false
}
},
"required": [
"source",
"leadIds"
],
"additionalProperties": false
}POST/api/v1/enrichment/quoteQuote enrichment
Returns the dashboard's existing cache, eligibility and credit calculation; does not spend credits.
Permissions: enrichment:read.
{
"type": "object",
"properties": {
"source": {
"type": "string",
"enum": [
"businesses",
"people"
]
},
"scope": {
"type": "string",
"enum": [
"all",
"deliverable"
]
},
"leadIds": {
"minItems": 1,
"maxItems": 5000,
"type": "array",
"items": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
}
}
},
"required": [
"source",
"scope",
"leadIds"
],
"additionalProperties": false
}POST/api/v1/enrichment/jobsStart enrichment
The existing worker reserves credits when claiming a batch. Fresh cached results are free. Verification charges one credit per two distinct fresh emails, rounded up per batch. Business enrichment costs one credit; people enrichment costs two. Existing skip/refund rules apply. Verification's optional enrichment requires enrichment:write; request identities are assigned by the server.
Permissions: enrichment:write.
Requires Idempotency-Key. Use a new key for new work.
{
"type": "object",
"properties": {
"source": {
"type": "string",
"enum": [
"businesses",
"people"
]
},
"scope": {
"type": "string",
"enum": [
"all",
"deliverable"
]
},
"leadIds": {
"minItems": 1,
"maxItems": 5000,
"type": "array",
"items": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
}
}
},
"required": [
"source",
"scope",
"leadIds"
],
"additionalProperties": false
}GET/api/v1/searchesList searches
List searches
Permissions: searches:read.
GET/api/v1/searches/{jobId}Read searches status
Read searches status
Permissions: searches:read.
GET/api/v1/searches/{jobId}/resultsRead searches results
Read searches results
Permissions: searches:read, leads:read.
GET/api/v1/verification/jobsList verification/jobs
List verification/jobs
Permissions: verification:read.
GET/api/v1/verification/jobs/{jobId}Read verification/jobs status
Read verification/jobs status
Permissions: verification:read.
GET/api/v1/verification/jobs/{jobId}/itemsRead verification/jobs items
Read verification/jobs items
Permissions: verification:read, leads:read.
GET/api/v1/enrichment/jobsList enrichment/jobs
List enrichment/jobs
Permissions: enrichment:read.
GET/api/v1/enrichment/jobs/{jobId}Read enrichment/jobs status
Read enrichment/jobs status
Permissions: enrichment:read.
GET/api/v1/enrichment/jobs/{jobId}/itemsRead enrichment/jobs items
Read enrichment/jobs items
Permissions: enrichment:read, leads:read.
GET/api/v1/search-historyList saved search history
List saved search history
Permissions: searches:read.
GET/api/v1/search-history/{searchId}Read saved search history
Read saved search history
Permissions: searches:read.
GET/api/v1/search-history/{searchId}/resultsRead saved prepared results
Read saved prepared results
Permissions: searches:read, leads:read.
GET/api/v1/qualificationsRead qualification evidence
Read qualification evidence
Permissions: qualification:read.
GET/api/v1/qualifications/{qualificationId}Read a qualification result
Read a qualification result
Permissions: qualification:read.
GET/api/v1/exportsList export metadata
List export metadata
Permissions: exports:read.
GET/api/v1/exports/{exportId}Read export metadata
Read export metadata
Permissions: exports:read.
POST/api/v1/exportsSave a CSV export selection
Choose exactly one selection. listId also requires lists:read; searchId requires searches:read. The selection is saved once, export usage is recorded once and credits are unchanged. Download separately with exports:read and leads:read.
Permissions: exports:write, leads:read.
Requires Idempotency-Key. Use a new key for new work.
{
"type": "object",
"properties": {
"label": {
"default": "Guffles export",
"type": "string",
"minLength": 1,
"maxLength": 200
},
"leadIds": {
"minItems": 1,
"maxItems": 5000,
"type": "array",
"items": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
}
},
"listId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"searchId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
}
},
"additionalProperties": false,
"oneOf": [
{
"required": [
"leadIds"
]
},
{
"required": [
"listId"
]
},
{
"required": [
"searchId"
]
}
]
}GET/api/v1/exports/{exportId}/downloadDownload an authenticated CSV
Includes all prepared fields, person data, research, full qualification reason and all three drafted emails. Removed list members remain in the saved selection. A legacy export without a saved selection returns 410; lost workspace ownership returns 409. Data failures return an error before any successful CSV bytes.
Permissions: exports:read, leads:read.
Errors and exports
Errors return an error code and an X-Request-ID. 401 means the key is invalid; 403 means a permission is missing; 402 means insufficient credits; 409 means a conflict; 429 means a limit was reached.
CSV includes prepared business and person data, verification, research, the full qualification reason and all three draft emails. A legacy export without a saved selection returns 410. An export whose leads no longer belong to the workspace returns 409. Removed list members remain in a saved export selection.
See the OpenAPI document for complete request and response schemas. Create separate keys for separate tools so permissions and revocation stay clear.