LeadPanther API Errors and Troubleshooting

Status: initial public guide for current API v1 behavior. Last updated: 2026-05-25.

Base URL

All current API v1 requests use this base URL:

https://app.leadpanther.ai/api/v1

Do not use https://api.leadpanther.ai/v1 for the LeadPanther app API. That is not the current API v1 base URL.

Error Envelope

Failed requests return an error envelope:

{
  "error": {
    "code": "forbidden",
    "message": "API key is missing a required scope."
  },
  "request_id": "req_000000000000000000000000"
}

The same request ID is also returned in the X-Request-Id response header. Use request_id when contacting LeadPanther support about an API call.

You may also send your own request ID:

X-Request-Id: req_example_001

Accepted request ID values are 1-128 characters and may contain letters, numbers, dots, underscores, colons, and hyphens.

Error Codes

CodeMeaningCommon causes
bad_requestThe request could not be accepted.Invalid JSON, invalid query parameters, missing required fields, invalid payload values, or unsupported request shape.
unauthorizedThe request is not authenticated.Missing bearer token, malformed Authorization header, invalid API key, revoked key, or inactive key.
forbiddenThe request is authenticated but not allowed.Missing scope, agency key without an active grant for the client, or access to a resource outside the API key subject.
not_foundThe requested route or resource was not found.Unknown path, wrong direct-vs-agency route, unsupported guessed endpoint, deleted/archived resource, or resource outside the accessible account.
conflictThe request conflicts with current resource state.Attempting to modify or delete a post in a state that does not allow the requested operation.
method_not_allowedThe path exists but does not support the HTTP method.Using POST, PATCH, or DELETE on a read-only route, or using GET on a write-only action.
not_implementedThe route or feature is not currently implemented.Calling a planned feature before it is available.
internal_errorThe server encountered an unexpected error.Retry later and include the request_id if reporting the issue.

Validation errors currently return a general bad_request response. A field-level error array is not currently part of the public API contract.

Authentication Problems

All authenticated endpoints require a bearer API key:

Authorization: Bearer lp_live_REDACTED

LeadPanther API v1 is currently available by approved API key. API keys are bearer tokens. Keep them server-side and never expose them in browser code.

If you receive unauthorized:

  • Confirm the Authorization header is present.
  • Confirm the value starts with Bearer followed by the API key.
  • Confirm the API key has not been copied with extra spaces, quotes, or line breaks.
  • Confirm the key is still active.
  • Do not send API keys from browser code, mobile clients, public repositories, logs, screenshots, or support tickets.

Supported key prefixes are currently lp_live_ and lp_test_. Public examples use redacted values only.

Scope Problems

Each endpoint requires the documented scope for that operation. The * scope satisfies any required scope.

Common scope checks:

TaskRequired scope
List or get clientsclients:read
Read postsposts:read
Create, update, or delete postsposts:write
Read lead magnetslead_magnets:read
Create, update, or archive lead magnetslead_magnets:write
Create upload URLs or delete uploaded mediamedia:write
Read post engagement or lead magnet analyticsanalytics:read
Read leadsleads:read
Read inbound activityactivity:read

If you receive forbidden, check both the API key scope and the account route being used.

Direct vs Agency Route Problems

Direct-user work uses direct routes:

/posts
/lead-magnets
/leads
/activity

Agency client work uses nested client routes:

/clients/{clientId}/posts
/clients/{clientId}/lead-magnets
/clients/{clientId}/leads
/clients/{clientId}/activity

For agency access, use the nested client routes. A valid agency API key alone is not enough; the agency must also have an active grant for the target client account.

Example agency request:

curl -sS \
  -H "Authorization: Bearer $LEADPANTHER_API_KEY" \
  -H "X-Request-Id: req_example_001" \
  "https://app.leadpanther.ai/api/v1/clients/00000000-0000-4000-8000-000000000001/posts?limit=10"

If an agency request returns 403, verify:

  • The API key includes the endpoint scope, such as posts:read.
  • The agency has an active grant for 00000000-0000-4000-8000-000000000001.
  • The request uses /clients/{clientId}/..., not the direct route.

If a client route returns 404, do not assume whether the client exists. Verify the client ID and the agency grant through an authorized workflow.

Wrong Route or Base URL

Unsupported guessed endpoints are not part of API v1. Do not use routes such as:

/accounts
/users
/lists
/campaigns
/organizations
/team
/workspaces

Use only documented paths under:

https://app.leadpanther.ai/api/v1

Examples:

GET https://app.leadpanther.ai/api/v1/me
GET https://app.leadpanther.ai/api/v1/posts
GET https://app.leadpanther.ai/api/v1/clients/00000000-0000-4000-8000-000000000001/posts

Pagination Problems

All list endpoints use limit and offset pagination unless an endpoint documents otherwise. The default limit is generally 50; the maximum is generally 100.

Example:

curl -sS \
  -H "Authorization: Bearer $LEADPANTHER_API_KEY" \
  "https://app.leadpanther.ai/api/v1/leads?limit=50&offset=0"

List responses include pagination metadata:

{
  "data": [],
  "pagination": {
    "limit": 50,
    "offset": 0,
    "has_more": false
  },
  "request_id": "req_000000000000000000000000"
}

Posts Troubleshooting

Create and update requests use posts:write. Read requests use posts:read.

Common causes of bad_request or conflict:

  • Scheduled posts require a future scheduled_at timestamp.
  • Post text should fit LinkedIn's effective 3000-character limit.
  • Document posts require document_url and cannot include images.
  • Publishing posts cannot be edited.
  • Published posts can only update theme_id, template_id, and notes.
  • Published or publishing posts cannot be deleted through the API.

Lead Magnets Troubleshooting

Create, update, and archive requests use lead_magnets:write. Read requests use lead_magnets:read.

Common causes of bad_request:

  • delivery_mode must be hosted_content, gated_external, or external_link.
  • delivery_mode=hosted_content and delivery_mode=gated_external require hosted_page.
  • Published hosted content requires non-empty page content.
  • Published gated external content requires a valid external resource URL.
  • external_link requires a valid resource_link on create.
  • cta_label and cta_url must be provided together or omitted together.

DELETE /lead-magnets/{id} archives a lead magnet in current API v1 behavior.

Media Troubleshooting

Media upload is a two-step flow:

  1. Call LeadPanther to create a signed upload URL.
  2. Upload the file to the returned storage URL.

Create upload URLs and delete uploaded media with media:write.

Allowed content types:

  • image/jpeg
  • image/png
  • image/gif
  • image/webp
  • application/pdf

Maximum file sizes:

  • Images: 5 MB
  • PDFs: 15 MB

Upload URL responses include short-lived sensitive values such as upload_url and token. Do not log or share those values. Public examples should redact them:

{
  "data": {
    "upload_url": "REDACTED_SIGNED_UPLOAD_URL",
    "token": "REDACTED_UPLOAD_TOKEN",
    "path": "00000000-0000-4000-8000-000000000001/images/api-v1/00000000-0000-4000-8000-000000000006.png",
    "bucket": "content-images",
    "max_file_size": 5242880
  },
  "request_id": "req_000000000000000000000000"
}

Leads and Activity Privacy

leads:read can return personal data, including LinkedIn profile URLs, names, headlines, submitted emails, work emails, personal emails, submitted form names, sources, intent signals, qualification status, and timestamps.

activity:read can return message/comment content, author information, LinkedIn profile URLs, keywords, source-specific statuses, platform message IDs, chat IDs, comment IDs, and other source metadata.

Public examples are redacted and do not represent the full sensitivity of production data. Do not put real lead names, real emails, real message text, platform IDs, client IDs, or production IDs into public docs, tickets, screenshots, or logs.

Redacted lead example:

{
  "data": [
    {
      "id": "00000000-0000-4000-8000-000000000004",
      "linkedin_profile_url": "https://www.linkedin.com/in/example-profile",
      "name": "Example Person",
      "emails": {
        "submitted": "person@example.com",
        "work": null,
        "personal": null
      },
      "latest_keyword": "GUIDE",
      "has_intent": true,
      "qualification_status": "qualified"
    }
  ],
  "pagination": {
    "limit": 50,
    "offset": 0,
    "has_more": false
  },
  "request_id": "req_000000000000000000000000"
}

Redacted activity example:

{
  "data": [
    {
      "id": "00000000-0000-4000-8000-000000000005",
      "source": "comment",
      "author_name": "Example Person",
      "content": "REDACTED_MESSAGE_CONTENT",
      "keyword": "GUIDE",
      "status": "matched",
      "metadata": {
        "post_id": "00000000-0000-4000-8000-000000000002",
        "comment_id": "REDACTED_PLATFORM_COMMENT_ID"
      }
    }
  ],
  "pagination": {
    "limit": 50,
    "offset": 0,
    "has_more": false
  },
  "request_id": "req_000000000000000000000000"
}

Current vs Planned

The following are current API v1 boundaries:

  • API keys are provisioned privately for now.
  • Rate limits are not yet a published contract.
  • Idempotency keys are planned, not currently guaranteed.
  • Webhook endpoints are planned, not currently available.
  • SDKs are planned or future, not currently available.
  • /lead-magnet-posts is not currently implemented.
  • webhooks:write may appear as a scope, but no public v1 webhook route is currently implemented.

Do not build production behavior that depends on undocumented rate limits, unpublished idempotency semantics, planned webhook routes, planned SDKs, or guessed endpoints.