curl -X POST "https://app.lance.so/api/v1/operations/enrichment/batch" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"personIds": [
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8"
],
"field": "emails"
}'
const response = await fetch("/api/v1/operations/enrichment/batch", {
method: "POST",
headers: {
Authorization: "Bearer <token>",
"Content-Type": "application/json",
},
body: JSON.stringify({
personIds: [
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8",
],
field: "emails",
}),
});
const enrichments = await response.json();
interface Enrichment {
id: string;
createdAt: string;
updatedAt: string;
entityId: string;
entityType: "person" | "company" | "leadlist";
field: "phones" | "emails";
status: "pending" | "finished" | "failed" | "timeout" | "cancelled";
error: string | null;
dataFound: boolean | null;
createdBy: string;
orgId: string;
globalEnrichmentId: string | null;
creditTransactionId: string | null;
}
const response = await fetch("/api/v1/operations/enrichment/batch", {
method: "POST",
headers: {
Authorization: "Bearer <token>",
"Content-Type": "application/json",
},
body: JSON.stringify({
personIds: [
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8",
],
field: "emails",
}),
});
const enrichments: Enrichment[] = await response.json();
[
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z",
"entityId": "550e8400-e29b-41d4-a716-446655440000",
"entityType": "person",
"field": "emails",
"status": "pending",
"error": null,
"dataFound": null,
"createdBy": "user_abc123",
"orgId": "org_xyz789",
"globalEnrichmentId": null,
"creditTransactionId": null
},
{
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"createdAt": "2024-01-14T08:00:00.000Z",
"updatedAt": "2024-01-14T08:05:00.000Z",
"entityId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
"entityType": "person",
"field": "emails",
"status": "finished",
"error": null,
"dataFound": true,
"createdBy": "user_abc123",
"orgId": "org_xyz789",
"globalEnrichmentId": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"creditTransactionId": "d4e5f6a7-b8c9-0123-def1-234567890123"
}
]
{
"error": {
"code": "VALIDATION_ERROR",
"message": "At least one person ID is required"
}
}
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Maximum 100 person IDs allowed per batch"
}
}
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid input"
}
}
{
"error": {
"code": "INSUFFICIENT_CREDITS",
"message": "Insufficient credits for 5 enrichments. Required: 50 credits.",
"details": {
"operationType": "enrichment_email",
"count": 5,
"required": 50
}
}
}
{
"error": {
"code": "VALIDATION_ERROR",
"message": "User ID is missing"
}
}
Enrichment
Batch Enrichment
Trigger contact enrichment for multiple persons in a single batch request
POST
/
api
/
v1
/
operations
/
enrichment
/
batch
curl -X POST "https://app.lance.so/api/v1/operations/enrichment/batch" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"personIds": [
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8"
],
"field": "emails"
}'
const response = await fetch("/api/v1/operations/enrichment/batch", {
method: "POST",
headers: {
Authorization: "Bearer <token>",
"Content-Type": "application/json",
},
body: JSON.stringify({
personIds: [
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8",
],
field: "emails",
}),
});
const enrichments = await response.json();
interface Enrichment {
id: string;
createdAt: string;
updatedAt: string;
entityId: string;
entityType: "person" | "company" | "leadlist";
field: "phones" | "emails";
status: "pending" | "finished" | "failed" | "timeout" | "cancelled";
error: string | null;
dataFound: boolean | null;
createdBy: string;
orgId: string;
globalEnrichmentId: string | null;
creditTransactionId: string | null;
}
const response = await fetch("/api/v1/operations/enrichment/batch", {
method: "POST",
headers: {
Authorization: "Bearer <token>",
"Content-Type": "application/json",
},
body: JSON.stringify({
personIds: [
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8",
],
field: "emails",
}),
});
const enrichments: Enrichment[] = await response.json();
[
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z",
"entityId": "550e8400-e29b-41d4-a716-446655440000",
"entityType": "person",
"field": "emails",
"status": "pending",
"error": null,
"dataFound": null,
"createdBy": "user_abc123",
"orgId": "org_xyz789",
"globalEnrichmentId": null,
"creditTransactionId": null
},
{
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"createdAt": "2024-01-14T08:00:00.000Z",
"updatedAt": "2024-01-14T08:05:00.000Z",
"entityId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
"entityType": "person",
"field": "emails",
"status": "finished",
"error": null,
"dataFound": true,
"createdBy": "user_abc123",
"orgId": "org_xyz789",
"globalEnrichmentId": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"creditTransactionId": "d4e5f6a7-b8c9-0123-def1-234567890123"
}
]
{
"error": {
"code": "VALIDATION_ERROR",
"message": "At least one person ID is required"
}
}
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Maximum 100 person IDs allowed per batch"
}
}
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid input"
}
}
{
"error": {
"code": "INSUFFICIENT_CREDITS",
"message": "Insufficient credits for 5 enrichments. Required: 50 credits.",
"details": {
"operationType": "enrichment_email",
"count": 5,
"required": 50
}
}
}
{
"error": {
"code": "VALIDATION_ERROR",
"message": "User ID is missing"
}
}
This endpoint triggers enrichment for phone numbers or email addresses for multiple persons at once. It efficiently handles batch processing by reusing existing enrichments and only creating new ones where needed.
How It Works
The batch enrichment process is optimized to avoid duplicate work:- Check Existing: For each person, checks if a reusable enrichment already exists (pending or finished)
- Credit Validation: Verifies the organization has sufficient credits for new enrichments
- Create Pending: Creates pending enrichment records for persons without reusable enrichments
- Async Processing: Enrichments are processed asynchronously after the response is returned
Enrichments are processed asynchronously. The response returns immediately
with enrichment records in
pending status. Use the enrichment status
endpoint to poll for completion.Request
Body Parameters
string[]
required
Array of person UUIDs to enrich. Each ID must be a valid UUID v4.
Constraints: - Minimum: 1 person ID - Maximum: 100 person IDs per batch
Example:
["550e8400-e29b-41d4-a716-446655440000", "6ba7b810-9dad-11d1-80b4-00c04fd430c8"]string
required
The type of contact data to enrich. Allowed values: -
phones - Enrich
phone numbers - emails - Enrich email addressesResponse
Returns an array of enrichment objects. The array includes both reused existing enrichments and newly created pending enrichments.Enrichment[]
required
Array of enrichment objects for the requested persons.
Show Enrichment Object
Show Enrichment Object
string
required
Unique identifier (UUID) of the enrichment record.
string
required
ISO 8601 timestamp when the enrichment was created.
string
required
ISO 8601 timestamp when the enrichment was last updated.
string
required
The person UUID that this enrichment belongs to.
string
required
The type of entity being enriched. Always
person for this endpoint.string
required
The field being enriched (
phones or emails).string
required
Current status of the enrichment.Possible values:
pending- Enrichment is in progressfinished- Enrichment completed successfullyfailed- Enrichment failed with an errortimeout- Enrichment timed outcancelled- Enrichment was cancelled
string | null
required
Error message if the enrichment failed.
null for successful or pending enrichments.boolean | null
required
Whether contact data was found during enrichment.
null- Unknown (pending enrichment)true- Data was foundfalse- No data found for this contact
string
required
User ID who initiated the enrichment.
string
required
Organization ID the enrichment belongs to.
string | null
required
Reference to the global enrichment record if data was found.
null for pending or unsuccessful enrichments.string | null
required
Reference to the credit transaction for this enrichment.
null until credits are consumed.unknown | null
Optional enrichment payload value. Present for enrichments that return data (e.g., company summaries).
null or omitted for standard phone/email enrichments.Credits
Enrichment operations consume credits from your organization’s balance:- Email enrichment: Credits are deducted per successful enrichment
- Phone enrichment: Credits are deducted per successful enrichment
The endpoint validates credit availability before creating enrichments. If
insufficient credits are available, the request will fail with an
INSUFFICIENT_CREDITS error.curl -X POST "https://app.lance.so/api/v1/operations/enrichment/batch" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"personIds": [
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8"
],
"field": "emails"
}'
const response = await fetch("/api/v1/operations/enrichment/batch", {
method: "POST",
headers: {
Authorization: "Bearer <token>",
"Content-Type": "application/json",
},
body: JSON.stringify({
personIds: [
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8",
],
field: "emails",
}),
});
const enrichments = await response.json();
interface Enrichment {
id: string;
createdAt: string;
updatedAt: string;
entityId: string;
entityType: "person" | "company" | "leadlist";
field: "phones" | "emails";
status: "pending" | "finished" | "failed" | "timeout" | "cancelled";
error: string | null;
dataFound: boolean | null;
createdBy: string;
orgId: string;
globalEnrichmentId: string | null;
creditTransactionId: string | null;
}
const response = await fetch("/api/v1/operations/enrichment/batch", {
method: "POST",
headers: {
Authorization: "Bearer <token>",
"Content-Type": "application/json",
},
body: JSON.stringify({
personIds: [
"550e8400-e29b-41d4-a716-446655440000",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8",
],
field: "emails",
}),
});
const enrichments: Enrichment[] = await response.json();
[
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z",
"entityId": "550e8400-e29b-41d4-a716-446655440000",
"entityType": "person",
"field": "emails",
"status": "pending",
"error": null,
"dataFound": null,
"createdBy": "user_abc123",
"orgId": "org_xyz789",
"globalEnrichmentId": null,
"creditTransactionId": null
},
{
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"createdAt": "2024-01-14T08:00:00.000Z",
"updatedAt": "2024-01-14T08:05:00.000Z",
"entityId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
"entityType": "person",
"field": "emails",
"status": "finished",
"error": null,
"dataFound": true,
"createdBy": "user_abc123",
"orgId": "org_xyz789",
"globalEnrichmentId": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"creditTransactionId": "d4e5f6a7-b8c9-0123-def1-234567890123"
}
]
{
"error": {
"code": "VALIDATION_ERROR",
"message": "At least one person ID is required"
}
}
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Maximum 100 person IDs allowed per batch"
}
}
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid input"
}
}
{
"error": {
"code": "INSUFFICIENT_CREDITS",
"message": "Insufficient credits for 5 enrichments. Required: 50 credits.",
"details": {
"operationType": "enrichment_email",
"count": 5,
"required": 50
}
}
}
{
"error": {
"code": "VALIDATION_ERROR",
"message": "User ID is missing"
}
}
Error Codes
| Status Code | Error Code | Description |
|---|---|---|
400 | VALIDATION_ERROR | Invalid request body, missing required fields, or constraint violations |
401 | VALIDATION_ERROR | Missing user ID or organization ID (authentication required) |
402 | INSUFFICIENT_CREDITS | Organization does not have enough credits for the requested enrichments |
500 | INTERNAL_ERROR | Server error during enrichment processing |
Notes
- Reusable Enrichments: If a person already has a pending or finished enrichment for the requested field, the existing enrichment is returned instead of creating a new one
- Failed Enrichments: If a previous enrichment for a person failed, timed out, or was cancelled, a new enrichment will be created
- Async Processing: The actual enrichment work happens asynchronously after the API response. Poll the enrichment status endpoint to check for completion
- Batch Efficiency: Use this endpoint instead of individual enrichment requests when enriching multiple persons to reduce API calls and improve throughput