Skip to main content

Errors

Shape

{
"status": "fail",
"success": false,
"message": "Lead not found.",
"warning": ""
}

status is "fail" for 4xx and "error" for 5xx. A stack field appears only when the server runs with NODE_ENV=development.

Status codes

CodeMeaningWhat to do
400Validation failure, a missing required field, a duplicate, or a business-rule refusal. The most common error by far.Read message; fix the request.
401Missing, unknown or malformed API key — ExpiredSession_401.Check the apikey header.
403Refused action.Not usually reachable with an API key, since role and plan gating are skipped.
404No such resource, or no such path.Check the id and the path.
409Conflict — a uniqueness constraint.
429Usage limit reached (e.g. AIUsageLimitReached_429).Back off; check plan usage.
500Unhandled server error.Retry once, then report it.

:::note A lapsed subscription currently surfaces as a 500 authenticateAPIKey reads the plan off the company's active subscription without checking that one exists, so a company with no active subscription fails with a 500 and a message like Cannot read properties of null (reading 'planDetails') rather than a clean SubscriptionExpired_400. If you see that, check the subscription before looking anywhere else. :::

:::note 400 where you might expect 404 Many "not found" cases in LeadX are modelled as 400, not 404LeadNotFound_400 and ContactNotFound_400 both exist alongside 404 variants. Do not branch on 404 to detect a missing record. Match on the message, or treat any 4xx as "this request will not succeed as written". :::

Mongoose-level errors

Some failures are translated by the error handler rather than raised as named messages:

TriggerStatusmessage
Duplicate key400Duplicate field(s): email
Schema validation400Validation error: ...
Bad ObjectId or type400Invalid format for field lead: abc
Bad/expired JWT (session path only)401Invalid token. Please log in again

Named response messages

Internally, messages are looked up by a name like LeadCreated_201 or CampaignNotFound_404 in a ResponseMessage collection, which supplies both the text and the HTTP status. The numeric suffix reflects the intended status, but the stored record is authoritative — text is editable per deployment, so match on status codes and your own logic rather than parsing message strings.

If no record matches the name, the server falls back to 500 / "Something went wrong".

Handling errors well

const leadx = async (path, init = {}) => {
const res = await fetch(BASE + path, {
...init,
headers: { apikey: KEY, "Content-Type": "application/json", ...init.headers },
});

const body = await res.json().catch(() => ({}));

if (!res.ok) {
const err = new Error(body.message || `HTTP ${res.status}`);
err.status = res.status;
err.retryable = res.status >= 500 || res.status === 429;
throw err;
}
return body;
};

Retry 5xx and 429 with backoff. Never retry a 400 — it will fail identically.

:::warning Bulk endpoints return 200 with failures inside POST /lead/bulk and POST /contact/bulk report per-item failures in the body while returning 200. Check data.failed and data.errors. See Bulk operations. :::

Error name catalogue

Every non-success name currently raised by the API, grouped by the status its name encodes. Useful for mapping messages back to a cause during debugging.

400

ApiNotFound_400 · AppNotFound_400 · BadRequest_400 · ButtonExampleRequired_400 · ButtonTextTooLong_400 · CallLogNotFound_400 · CampaignAudienceEmpty_400 · CampaignCannotBeUpdated_400 · CampaignFailedManyTime_400 · CampaignNameAlreadyExists_400 · CampaignSMTPNotBelongToCompany_400 · CampaignSMTPNotFound_400 · CampaignSMTPRequired_400 · CampaignSegmentNotFound_400 · CampaignSegmentsRequired_400 · CampaignTemplateRequired_400 · CannotDeleteDefaultTeam_400 · CannotUpdateApprovedTemplate_400 · CannotUpdateUniqueKey_400 · ChatWidgetNameAlreadyExists_400 · ChatWidgetNotFound_400 · ClaudeConfigurationNotFound_400 · ClaudeNotAvailableInPlan_400 · ContactAlreadyExists_400 · ContactCategoryNameAlreadyExists_400 · ContactCategoryNotFound_400 · ContactDataRequired_400 · ContactNotFound_400 · CountryNotFound_400 · CouponInvalid_400 · CustomFieldNameAlreadyExists_400 · CustomFieldNotFound_400 · CustomSectionNameAlreadyExists_400 · CustomSectionNotFound_400 · DashboardNameAlreadyExists_400 · DomainTrackingNameAlreadyExists_400 · DomainTrackingNotFound_400 · DurationRequired_400 · EmptyFile_400 · FacebookAppIDRequired_400 · FacebookSecretRequired_400 · FacebookTokenRequired_400 · FileNotFound_400 · FileUploadFailed_400 · FormFieldsRequired_400 · FormIdOrTokenRequired_400 · FormIdRequired_400 · FormNameAlreadyExists_400 · FormNotFound_400 · FreePlanAlreadyUsed_400 · GeminiConfigurationNotFound_400 · GeminiNotAvailableInPlan_400 · GmailCodeRequired_400 · ImportAlreadyPaused_400 · ImportAlreadyRunning_400 · ImportFileFetchFailed_400 · ImportNotFound_400 · InstagramNoAccessToken_400 · InvalidAIType_400 · InvalidCampaignType_400 · InvalidClaudeConfiguration_400 · InvalidCredentials_400 · InvalidCustomFieldValue_400 · InvalidCustomField_400 · InvalidDataFormat_400 · InvalidEmailTemplate_400 · InvalidGeminiConfiguration_400 · InvalidImportStatus_400 · InvalidInput_400 · InvalidMapping_400 · InvalidMemberStatus_400 · InvalidPanel_400 · InvalidPayload_400 · InvalidRequest_400 · InvalidSectionId_400 · InvalidSystemField_400 · InvalidTemplateStatus_400 · InvalidVariables_400 · InvalidWhatsAppTemplate_400 · InvoiceNotGenerated_400 · JobIdRequired_400 · LeadIdOrTokenRequired_400 · LeadIdTokenStatusRequired_400 · LeadNotFound_400 · ManualPaymentDetailsNotFound_400 · MaximumLeadsExceeded_400 · MemberAlredyExists_400 · MemberNotAccepted_400 · MemberNotBlocked_400 · MemberNotInvited_400 · NoBrevoSelected_400 · NoCampaignSelected_400 · NoChatWidgetSelected_400 · NoCustomSectionSelected_400 · NoDefaultClaudeConfiguration_400 · NoDefaultGeminiConfiguration_400 · NoElasticemailSelected_400 · NoFile_400 · NoFormSelected_400 · NoGeminiConfigurationFound_400 · NoMailchimpSelected_400 · NoMessagesSent_400 · NoPostmarkSelected_400 · NoRecipientsSpecified_400 · NoRowsInFile_400 · NoSESSelected_400 · NoSMTPSelected_400 · NoSendgridSelected_400 · NoSparkpostSelected_400 · NoTeamSelected_400 · PageIdOrTokenRequired_400 · PageIdRequired_400 · PaymentNotFound_400 · PaypalDetailsNotFound_400 · PayuDetailsNotFound_400 · PhonepeDetailsNotFound_400 · PlanDoesNotIncludeThisFeature_400 · PlanMaxUsers_400 · PlanMinUsers_400 · PlanNotFound_400 · ProductServiceDataRequired_400 · ProductServiceNameAlreadyExists_400 · ProductServiceNotFound_400 · PromptRequired_400 · QueueLimitExceeded_400 · RazorpayDetailsNotFound_400 · RoleNameAlreadyExists_400 · RoleOrPermissionRequired_400 · RowFromGreaterThanRowTo_400 · RowFromOutOfRange_400 · SegmentNameAlreadyExists_400 · SegmentNotFound_400 · SettingsNotFound_400 · StateNotFound_400 · StripeDetailsNotFound_400 · SubscriptionExpired_400 · SubscriptionNotFound_400 · TagNameAlreadyExists_400 · TagNotFound_400 · TeamNameAlreadyExists_400 · TeamNotFound_400 · TemplateNameAlreadyExists_400 · UniqueKeyInvalid_400 · UnsupportedCampaignType_400 · UnsupportedFileType_400 · ValidationError_400 · transactionHistoryNotFound_400

401

ExpiredSession_401 · Unauthorized_401

403

PlanLimitExceeded_403 · PlanSubscriptionLimitExceeded_403 · UnauthorizedAction_403

404

BrevoNotFound_404 · CampaignNotFound_404 · ContactNotFound_404 · DashboardNotFound_404 · DefaultRoleNotFound_404 · ElasticemailNotFound_404 · EmailTemplateNotFound_404 · FileNotFound_404 · GmailNotFound_404 · InstagramAccountNotFound_404 · InstagramAppNotFound_404 · LeadActivityNotFound_404 · LeadNotFound_404 · MailchimpNotFound_404 · ManualCampaignNotFound_404 · MemberNotFound_404 · MetaTemplateNotFound_404 · NotFound_404 · OcrNotFound_404 · PostmarkNotFound_404 · ProductServiceNotFound_404 · ReportNotFound_404 · RoleNotFound_404 · SESNotFound_404 · SMTPNotFound_404 · SendgridNotFound_404 · SettingsNotFound_404 · SmtpNotFound_404 · SparkpostNotFound_404 · TelegramAppNotFound_404 · TemplateNotFound_404 · TimezoneNotFound_404 · WhatsAppTemplateNotFound_404 · WhatsappNotFound_404 · WidgetNotFound_404

409

DuplicateTimezone_409

429

AIUsageLimitReached_429

500

AIResponseParsingFailed_500 · AIResponseValidationFailed_500 · DefaultTeamNotFound_500 · EmailSendingFailed_500 · WebhookSubscriptionFailed_500