LeadPanther API Quickstart

This guide shows the shortest path from a valid API key to common API v1 calls.

Base URL:

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

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.

1. Set Your API Key

Use a redacted placeholder in scripts and examples:

export LEADPANTHER_API_KEY="lp_live_REDACTED"
export LEADPANTHER_BASE_URL="https://app.leadpanther.ai/api/v1"

2. Check API Metadata

GET / does not require a scope.

curl "$LEADPANTHER_BASE_URL"

Example response:

{
  "data": {
    "name": "LeadPanther API",
    "version": "v1"
  },
  "request_id": "req_000000000000000000000001"
}

3. Check The Authenticated Subject

GET /me requires a valid API key.

curl "$LEADPANTHER_BASE_URL/me" \
  -H "Authorization: Bearer $LEADPANTHER_API_KEY"

Example response:

{
  "data": {
    "owner": {
      "user_id": "00000000-0000-4000-8000-000000000001",
      "full_name": "Client A",
      "business_name": "Client A Company",
      "account_status": "active"
    },
    "actor_type": "direct_user",
    "scopes": ["posts:read", "posts:write", "lead_magnets:read"],
    "subject": {
      "user_id": "00000000-0000-4000-8000-000000000001"
    }
  },
  "request_id": "req_000000000000000000000002"
}

4. List Posts

Direct-user post listing uses GET /posts.

Required scope: posts:read

curl "$LEADPANTHER_BASE_URL/posts?limit=10&offset=0" \
  -H "Authorization: Bearer $LEADPANTHER_API_KEY"

Example response:

{
  "data": [
    {
      "id": "00000000-0000-4000-8000-000000000002",
      "text": "Public-safe example post copy.",
      "status": "draft",
      "scheduled_at": null,
      "metrics": null,
      "theme": null,
      "followups": null
    }
  ],
  "pagination": {
    "limit": 10,
    "offset": 0,
    "has_more": false
  },
  "request_id": "req_000000000000000000000003"
}

All list endpoints use limit and offset pagination. Unless otherwise documented, limit defaults to 50 and is capped at 100.

5. Create A Draft Post

Required scope: posts:write

curl "$LEADPANTHER_BASE_URL/posts" \
  -X POST \
  -H "Authorization: Bearer $LEADPANTHER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Public-safe LinkedIn post copy.",
    "status": "draft",
    "scheduled_at": null,
    "theme_id": null,
    "template_id": null,
    "images": [],
    "document_url": null,
    "document_type": "image",
    "notes": "Internal note for this draft.",
    "followups": null
  }'

Scheduled posts use "status": "scheduled" and require a future scheduled_at ISO datetime.

6. Create A Lead Magnet

Required scope: lead_magnets:write

curl "$LEADPANTHER_BASE_URL/lead-magnets" \
  -X POST \
  -H "Authorization: Bearer $LEADPANTHER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "delivery_mode": "hosted_content",
    "keyword": "GUIDE",
    "resource_name": "Example Guide",
    "description": "Short public-safe description.",
    "text_template": "Here is the guide: {{resource_link}}",
    "linked_posts": [],
    "confirm_missing_magnet_url": false,
    "confirm_legacy_placeholder": false,
    "hosted_page": {
      "title": "Example Guide",
      "markdown_content": "# Example Guide\n\nPublic-safe hosted content.",
      "external_resource_url": null,
      "cta_label": null,
      "cta_url": null,
      "status": "draft"
    }
  }'

Create and update responses return both the saved lead_magnet and a result object:

{
  "data": {
    "lead_magnet": {
      "id": "00000000-0000-4000-8000-000000000003",
      "keyword": "GUIDE",
      "delivery_mode": "hosted_content"
    },
    "result": {
      "status": "saved"
    }
  },
  "request_id": "req_000000000000000000000004"
}

7. Use Agency Client Routes

If you are posting, reading leads, or managing lead magnets for a client, use the nested route form.

Required scope for listing clients: clients:read

curl "$LEADPANTHER_BASE_URL/clients" \
  -H "Authorization: Bearer $LEADPANTHER_API_KEY"

Then call client-scoped resources with the returned client user_id:

curl "$LEADPANTHER_BASE_URL/clients/00000000-0000-4000-8000-000000000001/posts?limit=10" \
  -H "Authorization: Bearer $LEADPANTHER_API_KEY"

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.

8. Handle Errors

Example error response:

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

Use the response request_id when contacting LeadPanther support about an API call. If a call returns 403, check both the API key scope and the agency-client grant.

Scope Checklist

  • Read accessible clients: clients:read
  • Read posts: posts:read
  • Create, update, or delete posts: posts:write
  • Read lead magnets: lead_magnets:read
  • Create, update, or archive lead magnets: lead_magnets:write
  • Create upload URLs or delete media: media:write
  • Read post engagement or lead magnet analytics: analytics:read
  • Read leads: leads:read
  • Read inbound activity: activity:read

The leads:read scope can return personal data. The activity:read scope can return message or comment content and platform identifiers. Public examples are redacted and do not represent the full sensitivity of production data.