GenConvert API

Manage websites, campaigns and webhooks, and pull analytics data programmatically. Every endpoint below has a live "Try it" panel — paste your API key and call the real API right from this page.

Get your API key

Getting Started

The GenConvert API is a JSON REST API. Every request must be authenticated (see Authentication below), and every response — success or error — is JSON.

Base URL:

https://genconvert.com/api/panel

Quick example:

curl https://genconvert.com/api/panel/websites \
  -H "Authorization: Bearer gc_live_xxxxxxxxxxxxxxxxxxxxxxxx"

Authentication

Every API request is authenticated with an API key, sent as a bearer token:

Authorization: Bearer gc_live_xxxxxxxxxxxxxxxxxxxxxxxx
  • Create and revoke keys from Dashboard → Profile → API Keys.
  • The full key is shown exactly once, right after you create it — copy it then.
  • A key is read only or full access, chosen when you create it. A read-only key can call every GET endpoint and gets a 403 from anything that would create, change or delete something. A full-access key has the permissions of the account that created it.
  • Revoking a key takes effect immediately. Every key is also revoked when the account's password is reset or changed, or when you sign out everywhere.
  • A key that has not been used for 90 days stops working: its requests get a 401. It stays in your key list, marked as expired, and you can revoke it. A key you use regularly never expires.

Rate Limits

API key requests are limited to 300 requests per minute per account. If you go over, you'll get a 429 Too Many Requests response with a Retry-After header (seconds until the window resets).

Errors

Errors are returned as a JSON array of issues:

[
  { "code": "custom", "message": "please login", "path": [] }
]
StatusMeaning
400Bad Request — the request body or query params failed validation.
401Unauthorized — missing, invalid, revoked, or expired API key.
403Forbidden — the key is valid but not allowed to access this resource.
404Not Found.
429Too Many Requests — see Rate Limits above.
500Server Error.

Account

Read and update the account the API key belongs to.

GET /api/panel/user

Get your profile

Example response

{
  "id": "65f1a2b3c4d5e6f7a8b9c0aa",
  "name": "Jane Doe",
  "email": "jane@example.com",
  "referralCode": "JANE20",
  "plan": {
    "id": "65f1a2b3c4d5e6f7a8b9c0bb",
    "title": "Pro",
    "source": "PURCHASED",
    "price": 29,
    "status": "active",
    "planType": "subscription",
    "startDate": "2026-01-01T00:00:00.000Z",
    "endDate": "2026-02-01T00:00:00.000Z",
    "cancelAtEnd": false,
    "monthlyPageviews": 50000,
    "monthlyFormSubmission": 2000,
    "maxWebsites": 3,
    "maxCampaigns": 20,
    "maxTeamMembers": 3
  },
  "image": "https://lh3.googleusercontent.com/a/avatar.jpg",
  "stats": { "served": 12400, "conversions": 860, "convRate": 6.9 }
}

Try it

PUT /api/panel/profile/info

Update your name

This only updates the display name - there is no endpoint to change the account email through the API.

Example response

{
  "id": "65f1a2b3c4d5e6f7a8b9c0aa",
  "name": "Jane Doe",
  "email": "jane@example.com",
  "referralCode": "JANE20",
  "plan": { "...": "same shape as GET /api/panel/user" }
}

Try it

GET /api/panel/user/sessions

List active login sessions

⚠️ Returns the IP address, device and browser for every device currently signed in to the dashboard. Anyone holding this API key can see your login locations - only share the key with integrations you trust.

Example response

[
  {
    "id": "65f1a2b3c4d5e6f7a8b9c1a1",
    "device": "Mac",
    "browser": "Chrome",
    "ip": "203.0.113.42",
    "lastActive": "2026-02-10T09:15:00.000Z",
    "createdAt": "2026-01-20T08:00:00.000Z",
    "isCurrent": true
  }
]

Try it

GET /api/panel/user/stats

Get overall usage stats

Real-time views, conversions and revenue across every website on the account.

Example response

{
  "success": true,
  "data": { "views": 120, "conversions": 8, "revenue": 240.5, "convRate": 6.67 }
}

Try it

Websites

A website is the top-level resource everything else (campaigns, webhooks, analytics) hangs off of. Its id shows up in almost every other endpoint below.

GET /api/panel/websites

List your websites

Example response

[
{
  "id": "65f1a2b3c4d5e6f7a8b9c0d1",
  "domain": "example.com",
  "websiteName": "My Store",
  "type": "website",
  "status": "active",
  "enable": true,
  "team": [],
  "limits": {
    "popupCooldownMinutes": 30,
    "maxPopupsPerSession": 3,
    "maxPopupsPerDay": 6,
    "exitIntentCooldownHours": 24,
    "minTimeOnPageSeconds": 5
  },
  "scriptToken": "9f8e7d6c5b4a39281706f5e4d3c2b1a0",
  "user": "65f1a2b3c4d5e6f7a8b9c0aa",
  "stats": { "served": 1240, "conversions": 86, "convRate": 6.9 },
  "createdAt": "2026-01-15T10:00:00.000Z",
  "updatedAt": "2026-02-01T08:30:00.000Z"
}
]

Try it

POST /api/panel/websites

Create a website

Example response

{
  "id": "65f1a2b3c4d5e6f7a8b9c0d1",
  "domain": "example.com",
  "websiteName": "My Store",
  "type": "website",
  "status": "active",
  "enable": true,
  "team": [],
  "limits": {
    "popupCooldownMinutes": 30,
    "maxPopupsPerSession": 3,
    "maxPopupsPerDay": 6,
    "exitIntentCooldownHours": 24,
    "minTimeOnPageSeconds": 5
  },
  "scriptToken": "9f8e7d6c5b4a39281706f5e4d3c2b1a0",
  "user": "65f1a2b3c4d5e6f7a8b9c0aa",
  "stats": { "served": 1240, "conversions": 86, "convRate": 6.9 },
  "createdAt": "2026-01-15T10:00:00.000Z",
  "updatedAt": "2026-02-01T08:30:00.000Z"
}

Try it

GET /api/panel/websites/{id}

Get a website

Path parameters

  • id (string, required) — The website ID.

Example response

{
  "id": "65f1a2b3c4d5e6f7a8b9c0d1",
  "domain": "example.com",
  "websiteName": "My Store",
  "type": "website",
  "status": "active",
  "enable": true,
  "team": [],
  "limits": {
    "popupCooldownMinutes": 30,
    "maxPopupsPerSession": 3,
    "maxPopupsPerDay": 6,
    "exitIntentCooldownHours": 24,
    "minTimeOnPageSeconds": 5
  },
  "scriptToken": "9f8e7d6c5b4a39281706f5e4d3c2b1a0",
  "user": "65f1a2b3c4d5e6f7a8b9c0aa",
  "stats": { "served": 1240, "conversions": 86, "convRate": 6.9 },
  "createdAt": "2026-01-15T10:00:00.000Z",
  "updatedAt": "2026-02-01T08:30:00.000Z"
}

Try it

PUT /api/panel/websites/{id}

Update a website

Path parameters

  • id (string, required) — The website ID.

Example response

{
  "id": "65f1a2b3c4d5e6f7a8b9c0d1",
  "domain": "example.com",
  "websiteName": "My Store",
  "type": "website",
  "status": "active",
  "enable": true,
  "team": [],
  "limits": {
    "popupCooldownMinutes": 30,
    "maxPopupsPerSession": 3,
    "maxPopupsPerDay": 6,
    "exitIntentCooldownHours": 24,
    "minTimeOnPageSeconds": 5
  },
  "scriptToken": "9f8e7d6c5b4a39281706f5e4d3c2b1a0",
  "user": "65f1a2b3c4d5e6f7a8b9c0aa",
  "stats": { "served": 1240, "conversions": 86, "convRate": 6.9 },
  "createdAt": "2026-01-15T10:00:00.000Z",
  "updatedAt": "2026-02-01T08:30:00.000Z"
}

Try it

DELETE /api/panel/websites/{id}

Delete a website

Path parameters

  • id (string, required) — The website ID.

Example response

true

Try it

POST /api/panel/websites/{id}/enable

Toggle popup delivery on/off

Flips the enable flag - disabling stops the embedded script from showing any popups.

Path parameters

  • id (string, required) — The website ID.

Example response

{
  "id": "65f1a2b3c4d5e6f7a8b9c0d1",
  "domain": "example.com",
  "websiteName": "My Store",
  "type": "website",
  "status": "active",
  "enable": true,
  "team": [],
  "limits": {
    "popupCooldownMinutes": 30,
    "maxPopupsPerSession": 3,
    "maxPopupsPerDay": 6,
    "exitIntentCooldownHours": 24,
    "minTimeOnPageSeconds": 5
  },
  "scriptToken": "9f8e7d6c5b4a39281706f5e4d3c2b1a0",
  "user": "65f1a2b3c4d5e6f7a8b9c0aa",
  "stats": { "served": 1240, "conversions": 86, "convRate": 6.9 },
  "createdAt": "2026-01-15T10:00:00.000Z",
  "updatedAt": "2026-02-01T08:30:00.000Z"
}

Try it

GET /api/panel/websites/{id}/dashboard-stats

Get dashboard summary stats

Path parameters

  • id (string, required) — The website ID.

Example response

{ "campainsCount": 3, "popupsCount": 42, "submissions": 17 }

Try it

Campaigns

Campaigns are the AI-generated popups running on a website - what they say, who they target, and when they show.

GET /api/panel/websites/{id}/campaigns

List campaigns for a website

Path parameters

  • id (string, required) — The website ID.

Query parameters

  • p (number) — Page number (1-indexed).
  • ps (number) — Page size.

Example response

{
  "items": [
{
  "id": "65f1a2b3c4d5e6f7a8b9c0e2",
  "websiteId": "65f1a2b3c4d5e6f7a8b9c0d1",
  "name": "Spring Sale Popup",
  "active": true,
  "prefrence": {
    "brand_tone": ["friendly", "urgent"],
    "userPrompt": "Promote our 20% spring sale to first-time visitors"
  },
  "devices": { "mac": true, "pc": true, "ios": true, "android": true },
  "priority": "medium",
  "triggers": { "delay": 10, "scrollDepth": 0, "exitIntent": true, "inactivity": 0 },
  "totalImpression": 0,
  "stats": { "served": 0, "conversions": 0, "convRate": 0 },
  "createdAt": "2026-02-10T12:00:00.000Z",
  "updatedAt": "2026-02-10T12:00:00.000Z"
}
  ],
  "total": 1,
  "page": 1,
  "pageSize": 20
}

Try it

POST /api/panel/websites/{id}/campaigns

Create a campaign

Only name and prefrence are required - everything else (devices, priority, triggers, design, ...) falls back to sensible defaults.

Path parameters

  • id (string, required) — The website ID.

Example response

{
  "id": "65f1a2b3c4d5e6f7a8b9c0e2",
  "websiteId": "65f1a2b3c4d5e6f7a8b9c0d1",
  "name": "Spring Sale Popup",
  "active": true,
  "prefrence": {
    "brand_tone": ["friendly", "urgent"],
    "userPrompt": "Promote our 20% spring sale to first-time visitors"
  },
  "devices": { "mac": true, "pc": true, "ios": true, "android": true },
  "priority": "medium",
  "triggers": { "delay": 10, "scrollDepth": 0, "exitIntent": true, "inactivity": 0 },
  "totalImpression": 0,
  "stats": { "served": 0, "conversions": 0, "convRate": 0 },
  "createdAt": "2026-02-10T12:00:00.000Z",
  "updatedAt": "2026-02-10T12:00:00.000Z"
}

Try it

GET /api/panel/websites/{id}/campaigns/{campId}

Get a campaign

Path parameters

  • id (string, required) — The website ID.
  • campId (string, required) — The campaign ID.

Example response

{
  "id": "65f1a2b3c4d5e6f7a8b9c0e2",
  "websiteId": "65f1a2b3c4d5e6f7a8b9c0d1",
  "name": "Spring Sale Popup",
  "active": true,
  "prefrence": {
    "brand_tone": ["friendly", "urgent"],
    "userPrompt": "Promote our 20% spring sale to first-time visitors"
  },
  "devices": { "mac": true, "pc": true, "ios": true, "android": true },
  "priority": "medium",
  "triggers": { "delay": 10, "scrollDepth": 0, "exitIntent": true, "inactivity": 0 },
  "totalImpression": 0,
  "stats": { "served": 0, "conversions": 0, "convRate": 0 },
  "createdAt": "2026-02-10T12:00:00.000Z",
  "updatedAt": "2026-02-10T12:00:00.000Z"
}

Try it

PUT /api/panel/websites/{id}/campaigns/{campId}

Update a campaign

Path parameters

  • id (string, required) — The website ID.
  • campId (string, required) — The campaign ID.

Example response

{
  "id": "65f1a2b3c4d5e6f7a8b9c0e2",
  "websiteId": "65f1a2b3c4d5e6f7a8b9c0d1",
  "name": "Spring Sale Popup",
  "active": true,
  "prefrence": {
    "brand_tone": ["friendly", "urgent"],
    "userPrompt": "Promote our 20% spring sale to first-time visitors"
  },
  "devices": { "mac": true, "pc": true, "ios": true, "android": true },
  "priority": "medium",
  "triggers": { "delay": 10, "scrollDepth": 0, "exitIntent": true, "inactivity": 0 },
  "totalImpression": 0,
  "stats": { "served": 0, "conversions": 0, "convRate": 0 },
  "createdAt": "2026-02-10T12:00:00.000Z",
  "updatedAt": "2026-02-10T12:00:00.000Z"
}

Try it

DELETE /api/panel/websites/{id}/campaigns/{campId}

Delete a campaign

Path parameters

  • id (string, required) — The website ID.
  • campId (string, required) — The campaign ID.

Example response

true

Try it

PUT /api/panel/websites/{id}/campaigns/{campId}/popup

Update a campaign's popup design

The request body is the full popup design object itself (not wrapped) - colors, layout, steps, copy. The easiest way to get a valid one is to copy the design field from "Get a campaign" above, edit it, and send it back.

Path parameters

  • id (string, required) — The website ID.
  • campId (string, required) — The campaign ID.

Example response

{
  "id": "65f1a2b3c4d5e6f7a8b9c0e2",
  "websiteId": "65f1a2b3c4d5e6f7a8b9c0d1",
  "name": "Spring Sale Popup",
  "active": true,
  "prefrence": {
    "brand_tone": ["friendly", "urgent"],
    "userPrompt": "Promote our 20% spring sale to first-time visitors"
  },
  "devices": { "mac": true, "pc": true, "ios": true, "android": true },
  "priority": "medium",
  "triggers": { "delay": 10, "scrollDepth": 0, "exitIntent": true, "inactivity": 0 },
  "design": { "...": "the full popup design object, updated" },
  "totalImpression": 0,
  "stats": { "served": 0, "conversions": 0, "convRate": 0 },
  "createdAt": "2026-02-10T12:00:00.000Z",
  "updatedAt": "2026-02-10T12:00:00.000Z"
}

Try it

Forms & Popups

Read the lead-capture forms, their submissions, and the AI-generated popups running on a website.

GET /api/panel/websites/{id}/campforms

List form campaigns

The lead-capture form definitions (newsletter, feedback, discount, ...) configured for a website.

Path parameters

  • id (string, required) — The website ID.

Example response

[
  {
    "id": "65f1a2b3c4d5e6f7a8b9c5a1",
    "siteId": "65f1a2b3c4d5e6f7a8b9c0d1",
    "campaignId": "65f1a2b3c4d5e6f7a8b9c0e2",
    "campaignTitle": "Spring Sale Popup",
    "type": "newsletter",
    "createdAt": "2026-02-10T12:00:00.000Z",
    "updatedAt": "2026-02-10T12:00:00.000Z"
  }
]

Try it

GET /api/panel/websites/{id}/forms

List form submissions

Add ?t=csv or ?t=json to download all matching submissions as a file instead of a paginated JSON response.

Path parameters

  • id (string, required) — The website ID.

Query parameters

  • p (number) — Page number (1-indexed).
  • ps (number) — Page size.
  • c (string) — Filter by campaign ID.
  • status (string) — Filter by submission status.
  • startDate (string) — Start of the date range (YYYY-MM-DD).
  • endDate (string) — End of the date range (YYYY-MM-DD).

Example response

{
  "items": [
    {
      "id": "65f1a2b3c4d5e6f7a8b9c5b1",
      "campaignId": "65f1a2b3c4d5e6f7a8b9c0e2",
      "popupId": "65f1a2b3c4d5e6f7a8b9c5c1",
      "actionType": "newsletter",
      "formData": { "email": "visitor@example.com" },
      "userMetadata": {
        "ipAddress": "203.0.113.10",
        "pageUrl": "https://example.com/",
        "device": "mobile",
        "country": "US"
      },
      "createdAt": "2026-02-10T12:00:00.000Z",
      "updatedAt": "2026-02-10T12:00:00.000Z"
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 20
}

Try it

GET /api/panel/websites/{id}/popups

List AI-generated popups

Path parameters

  • id (string, required) — The website ID.

Query parameters

  • p (number) — Page number (1-indexed).
  • ps (number) — Page size.
  • days (number) — Stats lookback window in days, 1-365 (default 30).

Example response

{
  "items": [
    {
      "id": "65f1a2b3c4d5e6f7a8b9c5c1",
      "siteId": "65f1a2b3c4d5e6f7a8b9c0d1",
      "campaignId": "65f1a2b3c4d5e6f7a8b9c0e2",
      "campaign": { "name": "Spring Sale Popup" },
      "type": "newsletter",
      "popups": { "...": "AI-generated popup copy" },
      "sparkline": [1, 2, 0, 3, 1],
      "enable": true,
      "stats": { "served": 340, "conversions": 22, "convRate": 6.5 },
      "createdAt": "2026-02-10T12:00:00.000Z",
      "updatedAt": "2026-02-10T12:00:00.000Z"
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 20
}

Try it

Team

Invite, promote, or remove a website's team members.

POST /api/panel/websites/{id}/team

Invite a team member

Returns a signup link - the invite isn't added to the team until they accept it.

Path parameters

  • id (string, required) — The website ID.

Example response

{ "link": "https://genconvert.com/signup?invite=eyJhbGciOi..." }

Try it

PUT /api/panel/websites/{id}/team/{memberId}

Update a team member's role

The owner's role can't be changed this way.

Path parameters

  • id (string, required) — The website ID.
  • memberId (string, required) — The user ID of the team member.

Example response

{
  "id": "65f1a2b3c4d5e6f7a8b9c0d1",
  "domain": "example.com",
  "websiteName": "My Store",
  "type": "website",
  "status": "active",
  "enable": true,
  "team": [],
  "limits": {
    "popupCooldownMinutes": 30,
    "maxPopupsPerSession": 3,
    "maxPopupsPerDay": 6,
    "exitIntentCooldownHours": 24,
    "minTimeOnPageSeconds": 5
  },
  "scriptToken": "9f8e7d6c5b4a39281706f5e4d3c2b1a0",
  "user": "65f1a2b3c4d5e6f7a8b9c0aa",
  "stats": { "served": 1240, "conversions": 86, "convRate": 6.9 },
  "createdAt": "2026-01-15T10:00:00.000Z",
  "updatedAt": "2026-02-01T08:30:00.000Z"
}

Try it

DELETE /api/panel/websites/{id}/team/{memberId}

Remove a team member

The owner can't be removed.

Path parameters

  • id (string, required) — The website ID.
  • memberId (string, required) — The user ID of the team member.

Example response

{
  "id": "65f1a2b3c4d5e6f7a8b9c0d1",
  "domain": "example.com",
  "websiteName": "My Store",
  "type": "website",
  "status": "active",
  "enable": true,
  "team": [],
  "limits": {
    "popupCooldownMinutes": 30,
    "maxPopupsPerSession": 3,
    "maxPopupsPerDay": 6,
    "exitIntentCooldownHours": 24,
    "minTimeOnPageSeconds": 5
  },
  "scriptToken": "9f8e7d6c5b4a39281706f5e4d3c2b1a0",
  "user": "65f1a2b3c4d5e6f7a8b9c0aa",
  "stats": { "served": 1240, "conversions": 86, "convRate": 6.9 },
  "createdAt": "2026-01-15T10:00:00.000Z",
  "updatedAt": "2026-02-01T08:30:00.000Z"
}

Try it

Webhooks

Webhooks push events (form submissions, campaign changes, referral activity, ...) from GenConvert to a URL you control, in real time.

EventFires when…
form.submittedFires for every popup form submission, regardless of type.
newsletter.submittedA visitor subscribed via a newsletter popup.
feedback.submittedA visitor submitted a feedback popup.
discount.submittedA visitor claimed a discount code popup.
campaign.createdA new campaign was created for this website.
campaign.pausedA campaign was switched off.
campaign.resumedA paused campaign was switched back on.
referral.signed_upSomeone you referred created an account.
referral.convertedSomeone you referred became a paying customer.
referral.payout_requestedYou requested a referral payout withdrawal.
referral.payout_approvedYour referral payout withdrawal was paid out.
plan.changedYour account plan or subscription changed.
GET /api/panel/websites/{id}/webhooks

List webhooks for a website

Path parameters

  • id (string, required) — The website ID.

Example response

[
{
  "id": "65f1a2b3c4d5e6f7a8b9c0f3",
  "userId": "65f1a2b3c4d5e6f7a8b9c0aa",
  "siteId": "65f1a2b3c4d5e6f7a8b9c0d1",
  "campaignId": null,
  "name": "Zapier Integration",
  "description": "",
  "url": "https://hooks.zapier.com/hooks/catch/xxxxx/yyyyy/",
  "secret": "whsec_1a2b3c4d5e6f7g8h9i0j",
  "headers": { "X-Api-Key": "sk_live_..." },
  "events": ["form.submitted", "newsletter.submitted"],
  "active": true,
  "disabledReason": null,
  "createdAt": "2026-02-10T12:00:00.000Z",
  "updatedAt": "2026-02-10T12:00:00.000Z"
}
]

Try it

POST /api/panel/websites/{id}/webhooks

Create a webhook

Path parameters

  • id (string, required) — The website ID.

Example response

{
  "id": "65f1a2b3c4d5e6f7a8b9c0f3",
  "userId": "65f1a2b3c4d5e6f7a8b9c0aa",
  "siteId": "65f1a2b3c4d5e6f7a8b9c0d1",
  "campaignId": null,
  "name": "Zapier Integration",
  "description": "",
  "url": "https://hooks.zapier.com/hooks/catch/xxxxx/yyyyy/",
  "secret": "whsec_1a2b3c4d5e6f7g8h9i0j",
  "headers": { "X-Api-Key": "sk_live_..." },
  "events": ["form.submitted", "newsletter.submitted"],
  "active": true,
  "disabledReason": null,
  "createdAt": "2026-02-10T12:00:00.000Z",
  "updatedAt": "2026-02-10T12:00:00.000Z"
}

Try it

PUT /api/panel/websites/{id}/webhooks/{webhookId}

Update a webhook

Path parameters

  • id (string, required) — The website ID.
  • webhookId (string, required) — The webhook ID.

Example response

{
  "id": "65f1a2b3c4d5e6f7a8b9c0f3",
  "userId": "65f1a2b3c4d5e6f7a8b9c0aa",
  "siteId": "65f1a2b3c4d5e6f7a8b9c0d1",
  "campaignId": null,
  "name": "Zapier Integration",
  "description": "",
  "url": "https://hooks.zapier.com/hooks/catch/xxxxx/yyyyy/",
  "secret": "whsec_1a2b3c4d5e6f7g8h9i0j",
  "headers": { "X-Api-Key": "sk_live_..." },
  "events": ["form.submitted", "newsletter.submitted"],
  "active": true,
  "disabledReason": null,
  "createdAt": "2026-02-10T12:00:00.000Z",
  "updatedAt": "2026-02-10T12:00:00.000Z"
}

Try it

DELETE /api/panel/websites/{id}/webhooks/{webhookId}

Delete a webhook

Path parameters

  • id (string, required) — The website ID.
  • webhookId (string, required) — The webhook ID.

Example response

true

Try it

POST /api/panel/websites/{id}/webhooks/{webhookId}/test

Send a test event

Fires a one-off webhook.test delivery so you can verify your endpoint receives it.

Path parameters

  • id (string, required) — The website ID.
  • webhookId (string, required) — The webhook ID.

Example response

{
  "id": "65f1a2b3c4d5e6f7a8b9c104",
  "endpointId": "65f1a2b3c4d5e6f7a8b9c0f3",
  "event": "webhook.test",
  "status": "delivered",
  "attempts": 1,
  "maxAttempts": 5,
  "nextAttemptAt": "2026-02-10T12:05:00.000Z",
  "lastAttemptAt": "2026-02-10T12:00:01.000Z",
  "lastError": null,
  "lastResponseStatusCode": 200,
  "deliveredAt": "2026-02-10T12:00:01.000Z",
  "sentBody": {},
  "sentHeaders": { "content-type": "application/json" },
  "createdAt": "2026-02-10T12:00:00.000Z"
}

Try it

GET /api/panel/websites/{id}/webhooks/{webhookId}/deliveries

List delivery attempts

Path parameters

  • id (string, required) — The website ID.
  • webhookId (string, required) — The webhook ID.

Query parameters

  • p (number) — Page number (1-indexed).
  • ps (number) — Page size.

Example response

{
  "items": [
    {
      "id": "65f1a2b3c4d5e6f7a8b9c104",
      "endpointId": "65f1a2b3c4d5e6f7a8b9c0f3",
      "event": "form.submitted",
      "status": "delivered",
      "attempts": 1,
      "maxAttempts": 5,
      "nextAttemptAt": "2026-02-10T12:05:00.000Z",
      "lastAttemptAt": "2026-02-10T12:00:01.000Z",
      "lastError": null,
      "lastResponseStatusCode": 200,
      "deliveredAt": "2026-02-10T12:00:01.000Z",
      "sentBody": { "submissionId": "..." },
      "sentHeaders": { "content-type": "application/json" },
      "createdAt": "2026-02-10T12:00:00.000Z"
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 20
}

Try it

POST /api/panel/websites/{id}/webhooks/{webhookId}/secret

Rotate the signing secret

Path parameters

  • id (string, required) — The website ID.
  • webhookId (string, required) — The webhook ID.

Example response

{
  "id": "65f1a2b3c4d5e6f7a8b9c0f3",
  "userId": "65f1a2b3c4d5e6f7a8b9c0aa",
  "siteId": "65f1a2b3c4d5e6f7a8b9c0d1",
  "campaignId": null,
  "name": "Zapier Integration",
  "description": "",
  "url": "https://hooks.zapier.com/hooks/catch/xxxxx/yyyyy/",
  "secret": "whsec_1a2b3c4d5e6f7g8h9i0j",
  "headers": { "X-Api-Key": "sk_live_..." },
  "events": ["form.submitted", "newsletter.submitted"],
  "active": true,
  "disabledReason": null,
  "createdAt": "2026-02-10T12:00:00.000Z",
  "updatedAt": "2026-02-10T12:00:00.000Z"
}

Try it

POST /api/panel/websites/{id}/webhooks/{webhookId}/deliveries/{deliveryId}/retry

Retry a failed delivery

Only deliveries with status "dead" (permanently failed) can be retried.

Path parameters

  • id (string, required) — The website ID.
  • webhookId (string, required) — The webhook ID.
  • deliveryId (string, required) — The delivery ID to retry.

Example response

{
  "id": "65f1a2b3c4d5e6f7a8b9c104",
  "endpointId": "65f1a2b3c4d5e6f7a8b9c0f3",
  "event": "form.submitted",
  "status": "queued",
  "attempts": 3,
  "maxAttempts": 5,
  "nextAttemptAt": "2026-02-10T12:10:00.000Z",
  "lastAttemptAt": "2026-02-10T12:05:00.000Z",
  "lastError": "connect ETIMEDOUT",
  "lastResponseStatusCode": null,
  "deliveredAt": null,
  "sentBody": { "submissionId": "..." },
  "sentHeaders": { "content-type": "application/json" },
  "createdAt": "2026-02-10T12:00:00.000Z"
}

Try it

Analytics

Read-only reporting endpoints for a website’s popup performance over a date range.

GET /api/panel/websites/{id}/analytics/chart

Impressions/conversions over time

Path parameters

  • id (string, required) — The website ID.

Query parameters

  • startDate (string, required) — Start of the date range (YYYY-MM-DD).
  • endDate (string, required) — End of the date range (YYYY-MM-DD).
  • device (string) — Filter by device.
  • pageType (string) — Filter by page type.
  • campaignId (string) — Filter by campaign.
  • utmSource (string) — Filter by utm_source.

Example response

{ "data": [ { "date": "2026-02-01", "served": 120, "conversions": 8 } ] }

Try it

GET /api/panel/websites/{id}/analytics/cache-roi

AI cache cost savings

Path parameters

  • id (string, required) — The website ID.

Query parameters

  • startDate (string, required) — Start of the date range (YYYY-MM-DD).
  • endDate (string, required) — End of the date range (YYYY-MM-DD).

Example response

{ "data": { "cacheHits": 340, "cacheMisses": 60, "estimatedSavingsUsd": 4.12 } }

Try it

GET /api/panel/websites/{id}/analytics/funnel

Popup view → conversion funnel

Path parameters

  • id (string, required) — The website ID.

Query parameters

  • startDate (string, required) — Start of the date range (YYYY-MM-DD).
  • endDate (string, required) — End of the date range (YYYY-MM-DD).

Example response

{ "data": { "shown": 1200, "engaged": 430, "converted": 86 } }

Try it

GET /api/panel/websites/{id}/analytics/heatmap

Time-of-day / day-of-week heatmap

Path parameters

  • id (string, required) — The website ID.

Query parameters

  • startDate (string, required) — Start of the date range (YYYY-MM-DD).
  • endDate (string, required) — End of the date range (YYYY-MM-DD).
  • metric (string) — Which metric to plot (default convRate).

Example response

{ "data": [ { "day": 1, "hour": 14, "value": 6.9 } ], "maxValue": 6.9, "metric": "convRate" }

Try it

GET /api/panel/websites/{id}/analytics/segments

Breakdown by segment

Path parameters

  • id (string, required) — The website ID.

Query parameters

  • startDate (string, required) — Start of the date range (YYYY-MM-DD).
  • endDate (string, required) — End of the date range (YYYY-MM-DD).
  • groupBy (string) — Dimension to group by (default device).
  • limit (number) — Max groups returned, 1-20 (default 6).

Example response

{ "data": [ { "group": "mobile", "served": 720, "conversions": 52 } ] }

Try it

Tickets

Open and reply to support tickets on the account.

GET /api/panel/tickets

List your tickets

Query parameters

  • p (number) — Page number (1-indexed).
  • ps (number) — Page size.

Example response

{
  "items": [
{
  "id": "65f1a2b3c4d5e6f7a8b9c2a1",
  "subject": "Popup not showing on mobile",
  "status": "open",
  "priority": "medium",
  "posts": [
    {
      "id": "65f1a2b3c4d5e6f7a8b9c2a2",
      "content": "The exit-intent popup never fires on iOS Safari.",
      "isAdmin": false,
      "createdAt": "2026-02-10T12:00:00.000Z",
      "updatedAt": "2026-02-10T12:00:00.000Z"
    }
  ],
  "createdAt": "2026-02-10T12:00:00.000Z",
  "updatedAt": "2026-02-10T12:00:00.000Z"
}
  ],
  "total": 1,
  "page": 1,
  "pageSize": 20
}

Try it

POST /api/panel/tickets

Open a ticket

Example response

{
  "id": "65f1a2b3c4d5e6f7a8b9c2a1",
  "subject": "Popup not showing on mobile",
  "status": "open",
  "priority": "medium",
  "posts": [
    {
      "id": "65f1a2b3c4d5e6f7a8b9c2a2",
      "content": "The exit-intent popup never fires on iOS Safari.",
      "isAdmin": false,
      "createdAt": "2026-02-10T12:00:00.000Z",
      "updatedAt": "2026-02-10T12:00:00.000Z"
    }
  ],
  "createdAt": "2026-02-10T12:00:00.000Z",
  "updatedAt": "2026-02-10T12:00:00.000Z"
}

Try it

GET /api/panel/tickets/{id}

Get a ticket

Path parameters

  • id (string, required) — The ticket ID.

Example response

{
  "id": "65f1a2b3c4d5e6f7a8b9c2a1",
  "subject": "Popup not showing on mobile",
  "status": "open",
  "priority": "medium",
  "posts": [
    {
      "id": "65f1a2b3c4d5e6f7a8b9c2a2",
      "content": "The exit-intent popup never fires on iOS Safari.",
      "isAdmin": false,
      "createdAt": "2026-02-10T12:00:00.000Z",
      "updatedAt": "2026-02-10T12:00:00.000Z"
    }
  ],
  "createdAt": "2026-02-10T12:00:00.000Z",
  "updatedAt": "2026-02-10T12:00:00.000Z"
}

Try it

POST /api/panel/tickets/{id}

Reply to a ticket

Adds a reply and reopens the ticket (sets status back to open).

Path parameters

  • id (string, required) — The ticket ID.

Example response

{
  "id": "65f1a2b3c4d5e6f7a8b9c2a1",
  "subject": "Popup not showing on mobile",
  "status": "open",
  "priority": "medium",
  "posts": [
    {
      "id": "65f1a2b3c4d5e6f7a8b9c2a2",
      "content": "The exit-intent popup never fires on iOS Safari.",
      "isAdmin": false,
      "createdAt": "2026-02-10T12:00:00.000Z",
      "updatedAt": "2026-02-10T12:00:00.000Z"
    }
  ],
  "createdAt": "2026-02-10T12:00:00.000Z",
  "updatedAt": "2026-02-10T12:00:00.000Z"
}

Try it

Invoices

Read the account's billing history.

GET /api/panel/invoices

List invoices

Query parameters

  • p (number) — Page number (1-indexed).
  • ps (number) — Page size.

Example response

{
  "items": [
{
  "id": "65f1a2b3c4d5e6f7a8b9c3a1",
  "user": "65f1a2b3c4d5e6f7a8b9c0aa",
  "polarOrderId": "ord_1a2b3c4d",
  "invoiceNumber": "INV-2026-0042",
  "description": "GenConvert Pro - Monthly",
  "amountCents": 2900,
  "amount": 29,
  "currency": "usd",
  "status": "paid",
  "pdfUrl": "https://polar.sh/invoices/ord_1a2b3c4d.pdf",
  "paidAt": "2026-02-01T00:00:00.000Z",
  "createdAt": "2026-02-01T00:00:00.000Z",
  "updatedAt": "2026-02-01T00:00:00.000Z"
}
  ],
  "total": 1
}

Try it

GET /api/panel/invoices/{id}

Get an invoice

Path parameters

  • id (string, required) — The invoice ID.

Example response

{
  "id": "65f1a2b3c4d5e6f7a8b9c3a1",
  "user": "65f1a2b3c4d5e6f7a8b9c0aa",
  "polarOrderId": "ord_1a2b3c4d",
  "invoiceNumber": "INV-2026-0042",
  "description": "GenConvert Pro - Monthly",
  "amountCents": 2900,
  "amount": 29,
  "currency": "usd",
  "status": "paid",
  "pdfUrl": "https://polar.sh/invoices/ord_1a2b3c4d.pdf",
  "paidAt": "2026-02-01T00:00:00.000Z",
  "createdAt": "2026-02-01T00:00:00.000Z",
  "updatedAt": "2026-02-01T00:00:00.000Z"
}

Try it

Plans

Read plan change history and current usage against plan limits.

GET /api/panel/plans/history

Get plan change history

Query parameters

  • o (number) — Number of records to skip (default 0).

Example response

[
  {
    "id": "65f1a2b3c4d5e6f7a8b9c6a1",
    "plan": {
      "id": "65f1a2b3c4d5e6f7a8b9c0bb",
      "title": "Pro",
      "source": "PURCHASED",
      "price": 29,
      "status": "active",
      "planType": "subscription",
      "startDate": "2026-01-01T00:00:00.000Z",
      "endDate": "2026-02-01T00:00:00.000Z",
      "maxWebsites": 3,
      "maxCampaigns": 20,
      "maxTeamMembers": 3
    },
    "paymentProcessorData": {},
    "createdAt": "2026-01-01T00:00:00.000Z",
    "updatedAt": "2026-01-01T00:00:00.000Z"
  }
]

Try it

GET /api/panel/plans/stats

Get current plan usage

Example response

{
  "websites": 2,
  "campaigns": 5,
  "showPopupsThisMonth": 12400,
  "generatedPopupsThisMonth": 340,
  "generatedPopupsWithOwnKeyThisMonth": 12,
  "formSubmissionThisMonth": 86,
  "teamSize": 3
}

Try it