Introduction

Push leads into GenPage, read the personalised pages it generates, and keep your own system in sync.

Getting Started

1. Create an account

Visit https://app.genpage.ai and create your account.

2. Generate an API key

  1. Navigate to SettingsIntegrations
  2. Create a new API key and copy it — it is shown once
  3. Store it securely; you'll send it with every request

API keys start with sk-proj-, never expire, and are bound to the workspace they were created in. A key cannot read or write any other workspace, so create one key per workspace you integrate with. Generating a key requires the workspace to be on a Scale plan or higher. Delete a key from the same screen to revoke it immediately.

Call GET /hello-world-user at any time to check a key: it returns the account it belongs to and the workspace_id it is bound to.

3. Or connect an AI assistant instead

If you are wiring up Claude, ChatGPT, or another MCP-capable assistant, you do not need a key at all. Point it at the GenPage MCP server and it authenticates over OAuth: it sends you to GenPage, you choose which workspace to grant and approve, and it receives a token scoped to that one workspace. The assistant then has the same endpoints documented here, as tools.

Both credentials are equivalent to the API — bearer tokens, same permissions, same workspace binding. The difference is only how they are obtained and that OAuth tokens can be revoked from the dashboard without rotating a key.

Conventions

Content type. Send Content-Type: application/json for POST bodies. Responses are always JSON, errors included.

Errors. Failures return a JSON body with a message; validation failures add a per-field errors object.

{
  "message": "The workspace id field is required.",
  "errors": { "workspace_id": ["The workspace id field is required."] }
}
Status Meaning
401 Missing, malformed, or revoked API key
402 Not enough credits to run the requested generation
403 The key is valid but not authorized for this workspace
404 The campaign, job, or token does not exist
422 The request body or query string failed validation
429 Rate limit exceeded
503 The job exists but has not produced leads yet; retry

Rate limits. 120 requests per minute per API key. Every response carries X-RateLimit-Limit and X-RateLimit-Remaining; a 429 also carries Retry-After.

Asynchronous work. Importing leads is queued. The upsert endpoints return a job_id immediately — poll /leads/get-status until the status is completed, then call /leads/get-leads for the results.

Typical integration flow

Step 1: Confirm the workspace

Call /workspaces/get-list. A workspace-bound key returns exactly one workspace — that is the workspace_id every other call must use.

Step 2: Get campaigns and audiences

Call /campaigns/get-list and /audiences/get-list, and let the user pick which campaign and audience to add leads to. Audience 0 is the built-in "Default Audience" holding every lead not assigned to an audience of its own.

Step 3: Give the campaign a design, and publish it

A campaign carries the page design that every one of its leads' pages is built from. Campaigns created in the dashboard normally already have one — but a campaign created through /campaigns/create starts with none, and its pages render blank. This step is what prevents that, and it is the most common thing to miss.

Two ways to give it one:

  • Apply a template. /templates/get-list returns the designs available to the workspace — those built in the dashboard, plus GenPage's premade ones — and /templates/apply copies one onto the campaign. No credits, immediate.
  • Have the AI build one. POST /pages/generate with a prompt describing the page. It answers with a run_id; poll /pages/generate/status until success. This spends credits and takes appreciably longer than applying a template, but writes a page specific to what you describe. By default it edits the campaign's current design, so a second prompt refines rather than restarts; pass replace: true to begin from a blank page.

Either way, GET /pages/design returns the campaign's current HTML and CSS, so you can confirm a design exists — has_design: false means its pages would still be blank — or read back what the builder produced.

Both are destructive to the design already on the campaign. Pages generated earlier keep the design they were built with until they are regenerated.

Then publish it. A design is edited as a draft, and visitors are served the published snapshot — so neither applying a template nor generating a design puts anything live on its own. POST /pages/publish copies the draft over the published snapshot, and until you call it every generated link in the campaign shows a "not live yet" page. This is the single most common reason a link looks broken.

GET /pages/design reports both halves separately: has_design says a design exists, is_live says visitors can see it, and has_unpublished_changes says the draft has moved on from what is currently live. POST /pages/unpublish takes the pages offline again without deleting the design.

Step 4: Get the variables / columns

Call /workspaces/get-variable-list to get every existing variable for the workspace, and map your fields onto those keys. Keys that do not exist yet are accepted: upserting a lead with a new key creates a variable with that name.

Step 5: Upsert leads

Call /leads/upsert-leads (batch) or /leads/upsert-lead (single), passing the chosen campaign_id, an optional audience_id, and the leads as {"values": { ... }}.

To create a lead, values must include at least an email or a linkedin_profile_url. To update an existing one, identify it with lead_id or genpage_url. Both endpoints answer with a job_id.

Step 6: Check job status

Poll /leads/get-status?job_id=.... The status moves through pending / processing to completed or failed, alongside processed_rows and total_rows so you can show progress.

Step 7: Get the generated pages

Call /leads/get-leads?job_id=.... While the job is still running this answers 503 with {"status": "NO_LEADS"} — retry. Once leads exist, each entry carries a genpage_url: the personalised page GenPage generated for that lead.

Developer support

Need a test account? Contact us at team@genpage.ai and we'll help you get started.

Authenticating requests

To authenticate requests, include an Authorization header with the value "Bearer sk-proj-{YOUR_API_KEY}".

All authenticated endpoints are marked with a requires authentication badge in the documentation below.

Generate a key in the GenPage dashboard under Settings → Integrations. A key only works on the workspace it was created for.

There is a second way in. AI assistants connect through the GenPage MCP server, which authenticates with OAuth 2.1 rather than a key: the assistant sends you to GenPage, you pick a workspace and approve, and it receives a token scoped to that one workspace. Every endpoint below accepts either credential, and both are subject to the same workspace binding — so an OAuth token cannot reach a workspace you did not choose at consent, exactly as a key cannot reach one it was not created for.

Account

Get the credit balance for a workspace.

GET
https://backend.genpage.ai
/api/external/v1/account/credits
requires authentication

Enrichment and AI generation spend credits, so an integration can check what is left before starting work that would fail part-way through.

Credits are pooled across an account: remaining is what the whole pool has left, while workspace_used and workspace_limit describe this one workspace's share of it. A null workspace_limit means uncapped — the workspace can draw on the whole pool.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Query Parameters

workspace_id
integer
required

The workspace to report on.

Example:
55
Example request:
curl --request GET \
    --get "https://backend.genpage.ai/api/external/v1/account/credits?workspace_id=55" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:

Audiences

Get the list of audiences.

GET
https://backend.genpage.ai
/api/external/v1/audiences/get-list
requires authentication

This endpoint is used to get the list of audiences.

Audience 0 is the built-in "Default Audience": every lead in the workspace that has not been added to an audience of its own.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Query Parameters

workspace_id
integer
required

The workspace to list audiences for.

Example:
55
Example request:
curl --request GET \
    --get "https://backend.genpage.ai/api/external/v1/audiences/get-list?workspace_id=55" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:
[
    {
        "id": 0,
        "name": "Default Audience",
        "description": "Leads that have not been added to a specific audience",
        "color": null,
        "lead_count": 12,
        "project_id": 55,
        "created_at": "2025-01-01T00:00:00.000000Z",
        "updated_at": "2025-01-01T00:00:00.000000Z"
    },
    {
        "id": 1,
        "name": "Enterprise prospects",
        "description": null,
        "color": "#4F46E5",
        "lead_count": 340,
        "project_id": 55,
        "created_at": "2026-08-01T10:00:00.000000Z",
        "updated_at": "2026-08-01T10:00:00.000000Z"
    }
]
{
    "message": "Unauthenticated."
}
{
    "message": "Workspace not found or you do not have permission to access this workspace."
}

Create an audience.

POST
https://backend.genpage.ai
/api/external/v1/audiences/create
requires authentication

An audience is a named segment of leads. Create one to group leads before generating pages for them, or to keep a list you can link to a campaign.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
curl --request POST \
    "https://backend.genpage.ai/api/external/v1/audiences/create" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"workspace_id\": 55,
    \"name\": \"Enterprise prospects\",
    \"description\": \"Q3 outbound list\",
    \"color\": \"#4F46E5\",
    \"lead_ids\": [
        56789,
        56790
    ]
}"
Example response:
{
    "audience_id": 44,
    "name": "Enterprise prospects",
    "description": "Q3 outbound list",
    "lead_count": 2
}

Add leads to an audience.

POST
https://backend.genpage.ai
/api/external/v1/audiences/add-leads
requires authentication

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
curl --request POST \
    "https://backend.genpage.ai/api/external/v1/audiences/add-leads" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"workspace_id\": 55,
    \"audience_id\": 44,
    \"lead_ids\": [
        56789
    ]
}"
Example response:
{
    "audience_id": 44,
    "added": 1,
    "skipped": 0,
    "lead_count": 3
}

Remove leads from an audience. The leads themselves are not deleted.

POST
https://backend.genpage.ai
/api/external/v1/audiences/remove-leads
requires authentication

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
curl --request POST \
    "https://backend.genpage.ai/api/external/v1/audiences/remove-leads" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"workspace_id\": 55,
    \"audience_id\": 44,
    \"lead_ids\": [
        56789
    ]
}"
Example response:
{
    "audience_id": 44,
    "removed": 1,
    "lead_count": 2
}
POST
https://backend.genpage.ai
/api/external/v1/audiences/link-to-campaign
requires authentication

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
curl --request POST \
    "https://backend.genpage.ai/api/external/v1/audiences/link-to-campaign" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"workspace_id\": 55,
    \"audience_id\": 44,
    \"campaign_id\": 123
}"
Example response:
POST
https://backend.genpage.ai
/api/external/v1/audiences/unlink-from-campaign
requires authentication

Removes the link only — the audience, its leads, and any pages already generated for them are untouched.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
curl --request POST \
    "https://backend.genpage.ai/api/external/v1/audiences/unlink-from-campaign" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"workspace_id\": 55,
    \"audience_id\": 44,
    \"campaign_id\": 123
}"
Example response:

Delete an audience. The leads in it are kept.

POST
https://backend.genpage.ai
/api/external/v1/audiences/delete
requires authentication

Only the segment is removed. Unlike the dashboard's version, this endpoint has no option to delete the leads themselves: that is irreversible, and nothing about removing a grouping implies destroying the people in it. Leads that were only reachable through this audience remain in the workspace and are still findable with leads/search.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
curl --request POST \
    "https://backend.genpage.ai/api/external/v1/audiences/delete" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"workspace_id\": 55,
    \"audience_id\": 44
}"
Example response:
{
    "audience_id": 44,
    "leads_kept": 12,
    "message": "Audience deleted. Its leads were kept."
}

Authentication

Generate an API token. Should be done from the GenPage dashboard.

POST
https://backend.genpage.ai
/api/external/v1/generate-api-token
requires authentication

This endpoint returns the generated token to be used in the external integration. The token is bound to the workspace it was generated for and cannot be used against any other workspace. It never expires; delete it to revoke access.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
curl --request POST \
    "https://backend.genpage.ai/api/external/v1/generate-api-token" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"Zapier production\",
    \"workspace_id\": 55
}"
Example response:
{
    "token": "sk-proj-<Bearer token>"
}
{
    "message": "Unauthenticated."
}
{
    "message": "API key generation requires a Scale plan or higher."
}

List the API tokens of a workspace.

GET
https://backend.genpage.ai
/api/external/v1/get-api-tokens
requires authentication

Returns the workspace's own keys plus any legacy keys that were created before keys were bound to a workspace (those still work everywhere, so hiding them would leave the user unable to find and revoke them).

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Query Parameters

workspace_id
integer
required

The workspace to list keys for.

Example:
55
Example request:
curl --request GET \
    --get "https://backend.genpage.ai/api/external/v1/get-api-tokens?workspace_id=55" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:
{
    "tokens": [
        {
            "id": "9f1c...",
            "name": "Zapier production",
            "created_at": "2026-08-16T10:00:00.000000Z"
        }
    ]
}
{
    "message": "Unauthenticated."
}

Delete (revoke) an API token.

DELETE
https://backend.genpage.ai
/api/external/v1/delete-api-token
requires authentication

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Query Parameters

token_id
string
required

The id returned by get-api-tokens.

Example:
9f1c...
Example request:
curl --request DELETE \
    "https://backend.genpage.ai/api/external/v1/delete-api-token?token_id=9f1c..." \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:
{
    "message": "API token deleted successfully"
}
{
    "message": "API token not found"
}

Test authentication endpoint.

GET
https://backend.genpage.ai
/api/external/v1/hello-world
requires authentication

This endpoint is used to test the authentication.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json
Example request:
curl --request GET \
    --get "https://backend.genpage.ai/api/external/v1/hello-world" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:
{
    "message": "Hello World"
}
{
    "message": "Unauthenticated."
}

Test authentication and identify the key's owner.

GET
https://backend.genpage.ai
/api/external/v1/hello-world-user
requires authentication

Returns the account the API key belongs to, and the workspace the key is bound to (null for keys created before keys were workspace-bound, which may act on every workspace the account can reach).

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json
Example request:
curl --request GET \
    --get "https://backend.genpage.ai/api/external/v1/hello-world-user" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:
{
    "message": "Hello World",
    "user": {
        "id": 123,
        "name": "John Doe",
        "email": "john@example.com"
    },
    "workspace_id": 55
}
{
    "message": "Unauthenticated."
}

GenPages

Get the list of campaigns.

GET
https://backend.genpage.ai
/api/external/v1/campaigns/get-list
requires authentication

This endpoint is used to get the list of campaigns.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Query Parameters

workspace_id
integer
required

The workspace to list campaigns for.

Example:
55
Example request:
curl --request GET \
    --get "https://backend.genpage.ai/api/external/v1/campaigns/get-list?workspace_id=55" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:
[
    {
        "id": 1,
        "name": "Test Campaign 1",
        "slug": "test-campaign-1"
    },
    {
        "id": 2,
        "name": "Saas Outreach",
        "slug": "saas-outreach"
    }
]
{
    "message": "Unauthenticated."
}
{
    "message": "Workspace not found or you do not have permission to access this workspace."
}

Create a campaign.

POST
https://backend.genpage.ai
/api/external/v1/campaigns/create
requires authentication

A campaign holds the page template and branding that generated pages use. Create one when an integration needs its own campaign rather than reusing an existing one.

The campaign is created empty — it still needs a page design. Give it one over the API with templates/apply or pages/generate (or build one in the GenPage dashboard) and publish it. Generating pages against a campaign with no design will produce blank pages, so create-then-generate is not a complete flow on its own.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
curl --request POST \
    "https://backend.genpage.ai/api/external/v1/campaigns/create" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"workspace_id\": 55,
    \"name\": \"Enterprise Outreach\",
    \"branding_id\": 7,
    \"prompt\": \"outbound to fintech CTOs\"
}"
Example response:
{
    "campaign_id": 231,
    "name": "Enterprise Outreach",
    "slug": "enterprise-outreach",
    "note": "The campaign has no page design yet — apply a template (templates/apply) or generate a design (pages/generate) and publish it before generating pages."
}

Get performance metrics for a workspace's campaigns.

GET
https://backend.genpage.ai
/api/external/v1/campaigns/analytics
requires authentication

Reports how the generated pages are doing: how many were visited, how many visitors clicked, and how long they stayed.

visit_percentage is pages visited as a share of pages generated, so it measures reach rather than conversion. click_percentage is the share of unique visitors who clicked something.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Query Parameters

workspace_id
integer
required

The workspace to report on.

Example:
55
campaign_ids
integer[]

Limit to these campaigns. Defaults to all of them.

Example:
[123,124]
Example request:
curl --request GET \
    --get "https://backend.genpage.ai/api/external/v1/campaigns/analytics?workspace_id=55&campaign_ids[]=123&campaign_ids[]=124" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:
{
    "campaigns": [
        {
            "campaign_id": 123,
            "name": "Enterprise Outreach",
            "visit_percentage": 42.5,
            "click_percentage": 18.2,
            "average_time_on_page_seconds": 47,
            "pages_visited": 85,
            "unique_visitors": 71,
            "total_button_clicks": 19
        }
    ]
}

List the brandings in a workspace.

GET
https://backend.genpage.ai
/api/external/v1/brandings/get-list
requires authentication

A branding is the visual identity a campaign renders with — logo, colours, fonts. Call this to resolve a branding_id for campaigns/create; brandings themselves are built in the dashboard.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Query Parameters

workspace_id
integer
required

The workspace to list for.

Example:
55
Example request:
curl --request GET \
    --get "https://backend.genpage.ai/api/external/v1/brandings/get-list?workspace_id=55" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:
[
    {
        "branding_id": 7,
        "name": "Acme Corp",
        "is_default": true
    }
]

Get a campaign's current page design.

GET
https://backend.genpage.ai
/api/external/v1/pages/design
requires authentication

Returns the HTML and CSS the campaign renders. Every generated page is this design with the lead's variables substituted in, so this is what to read to see what the pages actually say.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Query Parameters

workspace_id
integer
required

The workspace the campaign belongs to.

Example:
55
campaign_id
integer
required

From campaigns/get-list.

Example:
231
Example request:
curl --request GET \
    --get "https://backend.genpage.ai/api/external/v1/pages/design?workspace_id=55&campaign_id=231" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:
{
    "campaign_id": 231,
    "has_design": true,
    "is_live": true,
    "has_unpublished_changes": false,
    "html": "<section>…</section>",
    "css": "body{…}",
    "updated_at": "2026-08-17T09:00:00.000000Z",
    "note": null
}
{
    "campaign_id": 231,
    "has_design": false,
    "is_live": false,
    "html": null,
    "css": null,
    "note": "This campaign has no design yet. Apply a template or generate one."
}

Ask the AI builder to design a campaign's page. Returns a run id.

POST
https://backend.genpage.ai
/api/external/v1/pages/generate
requires authentication

The builder writes its result straight onto the campaign, so once the run finishes, pages/design returns the new HTML and newly generated pages use it. Generation spends credits; with none left the request fails with 402.

By default the builder edits the campaign's existing design. Pass replace: true to have it start from a blank page instead.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
curl --request POST \
    "https://backend.genpage.ai/api/external/v1/pages/generate" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"workspace_id\": 55,
    \"campaign_id\": 231,
    \"prompt\": \"A landing page for fintech CTOs, with a hero, three benefits, and a demo CTA.\",
    \"replace\": false
}"
Example response:
{
    "run_id": "run_01H…",
    "status": "queued",
    "campaign_id": 231
}
{
    "message": "No credits remaining"
}

Check a design run's progress.

GET
https://backend.genpage.ai
/api/external/v1/pages/generate/status
requires authentication

status is one of queued, running, success, error, cancelled. On success, read the result with pages/design.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Query Parameters

workspace_id
integer
required

The workspace the run belongs to.

Example:
55
run_id
string
required

From pages/generate.

Example:
run_01H…
Example request:
curl --request GET \
    --get "https://backend.genpage.ai/api/external/v1/pages/generate/status?workspace_id=55&run_id=run_01H%E2%80%A6" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:
{
    "run_id": "run_01H…",
    "status": "running",
    "campaign_id": 231,
    "error": null
}

Publish a campaign's design, putting it live.

POST
https://backend.genpage.ai
/api/external/v1/pages/publish
requires authentication

A design is edited as a draft. Visitors are served the published snapshot, so a campaign whose design has never been published shows a "not live yet" page to anyone who opens a generated link. This copies the current draft over the published snapshot.

Publishing replaces what is currently live, and takes effect immediately for every page in the campaign — including ones generated earlier.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
curl --request POST \
    "https://backend.genpage.ai/api/external/v1/pages/publish" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"workspace_id\": 55,
    \"campaign_id\": 231
}"
Example response:
{
    "campaign_id": 231,
    "is_live": true,
    "published_at": "2026-08-17T09:00:00.000000Z",
    "message": "Design published. Pages in this campaign are now live."
}
{
    "message": "This campaign has no design to publish. Apply a template or generate one first."
}

Take a campaign's pages offline.

POST
https://backend.genpage.ai
/api/external/v1/pages/unpublish
requires authentication

Clears the published snapshot. Every generated link in the campaign then shows a "not live yet" page. The design itself is untouched — it stays as a draft and can be published again.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
curl --request POST \
    "https://backend.genpage.ai/api/external/v1/pages/unpublish" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"workspace_id\": 55,
    \"campaign_id\": 231
}"
Example response:
{
    "campaign_id": 231,
    "is_live": false,
    "message": "Pages in this campaign are no longer live. The design is kept as a draft."
}

List the page templates available to a workspace.

GET
https://backend.genpage.ai
/api/external/v1/templates/get-list
requires authentication

Two kinds come back. workspace templates were built by this account in the GenPage dashboard; premade ones ship with GenPage and are available to everyone. Either can be applied to a campaign.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Query Parameters

workspace_id
integer
required

The workspace to list for.

Example:
55
search
string

Match on template name.

Example:
saas
Example request:
curl --request GET \
    --get "https://backend.genpage.ai/api/external/v1/templates/get-list?workspace_id=55&search=saas" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:
[
    {
        "template_id": 88,
        "name": "SaaS outbound",
        "description": "Hero, social proof, single CTA",
        "source": "workspace"
    },
    {
        "template_id": 12,
        "name": "Minimal landing",
        "description": null,
        "source": "premade"
    }
]

Apply a template's design to a campaign.

POST
https://backend.genpage.ai
/api/external/v1/templates/apply
requires authentication

Copies the page design onto the campaign, replacing whatever design it had. Use it right after creating a campaign — until a campaign has a design, the pages generated for it are blank.

This overwrites: a campaign that already has a design loses it, and pages generated afterwards use the new one. Pages already generated keep what they were built with until they are regenerated.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
curl --request POST \
    "https://backend.genpage.ai/api/external/v1/templates/apply" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"workspace_id\": 55,
    \"campaign_id\": 231,
    \"template_id\": 88
}"
Example response:
{
    "campaign_id": 231,
    "template_id": 88,
    "is_live": false,
    "message": "Template applied. Publish the design to make this campaign's pages live."
}
{
    "campaign_id": 231,
    "template_id": 88,
    "is_live": true,
    "message": "Template applied as a draft. The campaign is still serving its previously published design — publish to switch pages over to this one."
}
{
    "message": "Template not found"
}

Leads

Get the leads that were upserted by a job.

GET
https://backend.genpage.ai
/api/external/v1/zapier/get-leads-from-job
requires authentication

This endpoint is used to get the leads that were upserted by a job.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Query Parameters

job_id
string
required

The job id returned by an upsert endpoint.

Example:
9f1c8b2e-...
Example request:
curl --request GET \
    --get "https://backend.genpage.ai/api/external/v1/zapier/get-leads-from-job?job_id=9f1c8b2e-..." \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:
[
    {
        "lead_id": 56789,
        "genpage_url": "https://myworkspace.genpa.ge/aws-john",
        "name": "John Doe",
        "email": "john@aws.com",
        "company_name": "AWS"
    }
]
{
    "message": "Unauthenticated."
}
{
    "status": "NOT_FOUND"
}
{
    "status": "NO_LEADS",
    "message": "No leads have been processed for this job yet. Try again later."
}
GET
https://backend.genpage.ai
/api/external/v1/leads/search
requires authentication

Free-text search across name, email, and company, narrowed by campaign, audience, or how the lead has engaged with its page.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Query Parameters

workspace_id
integer
required

The workspace to search.

Example:
55
search
string

Matches name, email, or company.

Example:
acme
campaign_ids
integer[]

Only leads on these campaigns.

Example:
[1,2]
audience_ids
integer[]

Only leads in these audiences.

Example:
[3]
engagement
string[]

Filter by engagement: all, page_viewed, button_clicked, scroll_100_percent, form_submitted.

Example:
["form_submitted"]
limit
integer

How many to return, 1-100. Defaults to 25.

Example:
25
Example request:
curl --request GET \
    --get "https://backend.genpage.ai/api/external/v1/leads/search?workspace_id=55&search=acme&campaign_ids[]=1&campaign_ids[]=2&audience_ids[]=3&engagement[]=form_submitted&limit=25" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:

Get one lead, with every field and its enrichment state.

GET
https://backend.genpage.ai
/api/external/v1/leads/get
requires authentication

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Query Parameters

lead_id
integer
required

From search-leads or an upsert job.

Example:
56789
Example request:
curl --request GET \
    --get "https://backend.genpage.ai/api/external/v1/leads/get?lead_id=56789" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:
{
    "lead_id": 56789,
    "name": "John Doe",
    "email": "john@aws.com",
    "company_name": "AWS",
    "company_domain": "aws.com",
    "genpage_url": "https://myworkspace.genpa.ge/aws-john",
    "variables": {
        "linkedin_profile_url": "https://...",
        "pain_point": "..."
    },
    "audiences": [
        {
            "id": 3,
            "name": "Enterprise"
        }
    ],
    "pending_enrichments": [
        "company_domain"
    ],
    "created_at": "2026-08-16T10:00:00.000000Z"
}
{
    "message": "Lead not found"
}

Enrich existing leads, spending credits to research them.

POST
https://backend.genpage.ai
/api/external/v1/leads/enrich
requires authentication

Each type is a separate piece of research, and each costs credits per lead. Ask for only what the pages actually use.

  • linkedin_profile_url — scrape the lead's LinkedIn profile
  • company_domain — AI analysis of the company
  • person_analysis — AI analysis of the person
  • linkedin_posts_person — the person's recent posts
  • linkedin_posts_company — the company page's recent posts

A lead missing the inputs a type needs (no LinkedIn URL, no domain) is skipped rather than failing the batch — compare leads_to_enrich against what you sent, and check skipped_leads. Results land on the leads themselves; poll job_id with get-status, then read them back with get-lead.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
curl --request POST \
    "https://backend.genpage.ai/api/external/v1/leads/enrich" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"workspace_id\": 55,
    \"lead_ids\": [
        56789,
        56790
    ],
    \"enrichment_types\": [
        \"company_domain\"
    ]
}"
Example response:
{
    "job_id": "9f1c8b2e-...",
    "message": "Enrichment job started",
    "leads_to_enrich": 2,
    "skipped_leads": 0
}
{
    "message": "No valid leads found for the given IDs."
}
{
    "message": "No leads have the required fields for enrichment. LinkedIn Profile requires linkedin_profile_url, Company Research requires a company name, domain, or LinkedIn profile, Prospect Research requires a name or LinkedIn profile, LinkedIn Posts require a profile or company page.",
    "skipped_leads": [
        {
            "lead_id": 56790,
            "reason": "Missing required fields for enrichment"
        }
    ]
}

Upsert leads.

POST
https://backend.genpage.ai
/api/external/v1/leads/upsert-leads
requires authentication

This endpoint is used to upsert (update or insert) leads.

The leads are sent in the request body. The leads are an array of objects. The leads.*.values are key/value pairs with the values of the lead.


Required fields for creating or updating a lead

To create a new lead, at least one of:

  • email
  • linkedin_profile_url

To update an existing lead, at least one of:

  • lead_id (GenPage Lead ID)
  • genpage_url (GenPage URL)

Optional but strongly recommended fields

  • first_name
  • company_name
  • company_domain

The response is the job ID.

The job ID can be used to get the status of the job, and get all the leads that were upserted by this request.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
curl --request POST \
    "https://backend.genpage.ai/api/external/v1/leads/upsert-leads" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"from\": \"MyCompanyName\",
    \"campaign_id\": 1,
    \"audience_id\": 1,
    \"callback_url\": \"https:\\/\\/example.com\\/callback\",
    \"send_email\": false,
    \"is_generate_ai_analysis\": true,
    \"enrich_data\": false,
    \"generate_ai_variables\": false,
    \"leads\": [
        {
            \"values\": {
                \"last_name\": \"Doe\",
                \"company_domain\": \"amazon.com\",
                \"my_custom_variable\": \"My custom value\"
            }
        }
    ]
}"
Example response:
{
    "job_id": "9f1c8b2e-..."
}
{
    "message": "Unauthenticated."
}

Upsert (update or create) a single lead.

POST
https://backend.genpage.ai
/api/external/v1/leads/upsert-lead
requires authentication

This endpoint is used to upsert a single lead.

The "values" object requires at least one of the following fields, otherwise it will throw an error:

  • first_name
  • email
  • company_name
  • company_domain
  • linkedin_profile_url

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
curl --request POST \
    "https://backend.genpage.ai/api/external/v1/leads/upsert-lead" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"from\": \"MyCompanyName\",
    \"campaign_id\": 1,
    \"audience_id\": 1,
    \"callback_url\": \"https:\\/\\/example.com\\/callback\",
    \"send_email\": false,
    \"is_generate_ai_analysis\": true,
    \"enrich_data\": false,
    \"generate_ai_variables\": false,
    \"lead_id\": 16,
    \"genpage_url\": \"https:\\/\\/myworkspace.genpa.ge\\/aws-john\",
    \"values\": {
        \"first_name\": \"John\",
        \"email\": \"john@aws.com\",
        \"company_name\": \"Amazon Web Services\",
        \"linkedin_profile_url\": \"https:\\/\\/www.linkedin.com\\/in\\/john-doe-1234567890\"
    }
}"
Example response:
{
    "job_id": "9f1c8b2e-..."
}
{
    "message": "Missing required fields: first_name, email, company_name, company_domain, or linkedin_profile_url."
}
{
    "message": "Unauthenticated."
}
{
    "message": "Campaign not found"
}

Import leads into a workspace, without a campaign.

POST
https://backend.genpage.ai
/api/external/v1/leads/import-to-workspace
requires authentication

Use this when the leads are not tied to a landing page yet; link them to campaigns later through an audience.

The response depends on how the import ran. Queued imports (the default, and always the case when any enrichment or campaign is requested) answer with a job_id to poll on /leads/get-status. Immediate imports (sync: true with no enrichment and no campaigns) answer with the result directly and carry a job_id of null.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
curl --request POST \
    "https://backend.genpage.ai/api/external/v1/leads/import-to-workspace" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"workspace_id\": 55,
    \"leads\": [
        {
            \"values\": {
                \"first_name\": \"John\",
                \"email\": \"john@aws.com\",
                \"company_name\": \"Amazon Web Services\"
            }
        }
    ],
    \"from\": \"MyCompanyName\",
    \"send_email\": false,
    \"is_generate_ai_analysis\": false,
    \"is_generate_person_analysis\": false,
    \"is_scrape_person_posts\": false,
    \"is_scrape_company_posts\": false,
    \"enrich_data\": false,
    \"audience_id\": 3,
    \"sync\": false,
    \"campaign_ids\": [
        1,
        2
    ],
    \"generate_ai_variables\": false,
    \"trigger_audience_summary\": false
}"
Example response:
{
    "job_id": "9f1c8b2e-..."
}
{
    "job_id": null,
    "success": true,
    "imported_count": 2,
    "duplicate_count": 1,
    "lead_ids": [
        56789,
        56790
    ],
    "errors": []
}
{
    "message": "Workspace not found or you do not have permission to access this workspace."
}

Get the status of the job.

GET
https://backend.genpage.ai
/api/external/v1/leads/get-status
requires authentication

This endpoint is used to get the status of the job. Once the job is completed, the status will be "completed".

The status can be:

  • pending
  • processing
  • step_linkedin
  • step_import
  • completed
  • error

Once the job is completed, please use the getLeads endpoint to get all the leads that were upserted by this request.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Query Parameters

job_id
string
required

The job id returned by an upsert endpoint.

Example:
9f1c8b2e-...
Example request:
curl --request GET \
    --get "https://backend.genpage.ai/api/external/v1/leads/get-status?job_id=9f1c8b2e-..." \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:
{
    "status": "pending",
    "processed_rows": 10,
    "total_rows": 100
}
{
    "message": "Unauthenticated."
}
{
    "status": "not_found"
}

Get the leads that were upserted by a job.

GET
https://backend.genpage.ai
/api/external/v1/leads/get-leads
requires authentication

This endpoint is used to get the leads that were upserted by a job.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Query Parameters

job_id
string
required

The job id returned by an upsert endpoint.

Example:
9f1c8b2e-...
Example request:
curl --request GET \
    --get "https://backend.genpage.ai/api/external/v1/leads/get-leads?job_id=9f1c8b2e-..." \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:
[
    {
        "lead_id": 56789,
        "genpage_url": "https://myworkspace.genpa.ge/aws-john",
        "name": "John Doe",
        "email": "john@aws.com",
        "company_name": "AWS"
    }
]
{
    "message": "Unauthenticated."
}
{
    "status": "NOT_FOUND"
}
{
    "status": "NO_LEADS",
    "message": "No leads have been processed for this job yet. Try again later."
}

Workspaces

Get the list of workspaces.

GET
https://backend.genpage.ai
/api/external/v1/workspaces/get-list
requires authentication

This endpoint is used to get the list of workspaces the user has access to.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json
Example request:
curl --request GET \
    --get "https://backend.genpage.ai/api/external/v1/workspaces/get-list" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:
[
    {
        "id": 1,
        "name": "My Company Name",
        "slug": "my-company-name"
    },
    {
        "id": 2,
        "name": "SAAS Outreach",
        "slug": "saas-outreach"
    }
]
{
    "message": "Unauthenticated."
}

Get the list of variables (or columns) for a workspace.

GET
https://backend.genpage.ai
/api/external/v1/workspaces/get-variable-list
requires authentication

This endpoint retrieves all available variables/columns for a specific workspace. It returns both default variables (first_name, email, company_name, company_domain) and any custom variables that have been created for the workspace.

When updating or inserting a lead, you can use the variables/columns from this endpoint to add the values to the specific variable/column for the lead.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Query Parameters

workspace_id
integer
required

The workspace to list the variables of.

Example:
55
Example request:
curl --request GET \
    --get "https://backend.genpage.ai/api/external/v1/workspaces/get-variable-list?workspace_id=55" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:
[
    {
        "key": "linkedin_profile_url",
        "helpText": "LinkedIn profile URL (at least one of LinkedIn URL, Company Domain, or Email is required)"
    },
    {
        "key": "email",
        "helpText": "Email address (at least one of LinkedIn URL, Company Domain, or Email is required)"
    },
    {
        "key": "company_domain",
        "helpText": "Company domain (at least one of LinkedIn URL, Company Domain, or Email is required)"
    },
    {
        "key": "first_name",
        "helpText": "First name"
    },
    {
        "key": "company_name",
        "helpText": "Company name"
    },
    {
        "key": "My Custom Variable1"
    },
    {
        "key": "custom_variable2"
    }
]
{
    "message": "Unauthenticated."
}
{
    "message": "The given data was invalid.",
    "errors": {
        "workspace_id": [
            "The workspace id field is required."
        ]
    }
}

Zapier

Test authentication endpoint.

GET
https://backend.genpage.ai
/api/external/v1/zapier/test
requires authentication

This endpoint is used to test the authentication.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json
Example request:
curl --request GET \
    --get "https://backend.genpage.ai/api/external/v1/zapier/test" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:
{
    "message": "Hello World",
    "user": {
        "id": 123,
        "name": "John Doe",
        "email": "john@example.com"
    }
}
{
    "message": "Unauthenticated."
}

Create a lead through Zapier.

POST
https://backend.genpage.ai
/api/external/v1/zapier/upsert-lead
requires authentication

Set is_test to true to have the endpoint answer with a sample page URL without importing anything — this is what Zapier calls when the user tests the step while building a Zap.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
curl --request POST \
    "https://backend.genpage.ai/api/external/v1/zapier/upsert-lead" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"workspace_id\": 55,
    \"campaign_id\": 123,
    \"is_test\": false,
    \"linkedin_profile_url\": \"https:\\/\\/www.linkedin.com\\/in\\/williamhgates\\/\",
    \"company_domain\": \"example.com\",
    \"email\": \"test@example.com\",
    \"callback_url\": \"https:\\/\\/example.com\\/callback\",
    \"custom_data\": {
        \"key\": \"value\"
    }
}"
Example response:
{
    "message": "Job started!",
    "job_id": "9f1c8b2e-..."
}
{
    "message": "Job started!",
    "genpage_url": "https://myworkspace.genpa.ge/aws-john"
}
{
    "message": "Campaign not found"
}

Create a lead through Zapier (no callback required).

POST
https://backend.genpage.ai
/api/external/v1/zapier/upsert-lead-basic
requires authentication

Same as upsert-lead, but the callback URL is optional: use this when the Zap does not need GenPage to call back once the page has been generated.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Body Parameters

Example request:
curl --request POST \
    "https://backend.genpage.ai/api/external/v1/zapier/upsert-lead-basic" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"workspace_id\": 55,
    \"campaign_id\": 123,
    \"is_test\": false,
    \"callback_url\": \"https:\\/\\/example.com\\/callback\",
    \"generate_ai_variables\": true,
    \"linkedin_profile_url\": \"https:\\/\\/www.linkedin.com\\/in\\/williamhgates\\/\",
    \"company_domain\": \"example.com\",
    \"email\": \"test@example.com\",
    \"custom_data\": {
        \"key\": \"value\"
    }
}"
Example response:
{
    "message": "Job started!",
    "job_id": "9f1c8b2e-..."
}
{
    "message": "Campaign not found"
}

Poll for leads created in a campaign.

GET
https://backend.genpage.ai
/api/external/v1/zapier/get-leads
requires authentication

Returns the newest leads first. Pass created_after and/or last_lead_id from the previous poll to only get what is new since then.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Query Parameters

workspace_id
integer
required

The workspace to read from.

Example:
55
campaign_id
integer
required

The campaign to read from.

Example:
123
created_after
string

Only return leads created at or after this timestamp.

Example:
2026-08-01T00:00:00Z
last_lead_id
integer

Only return leads with an id greater than this.

Example:
4200
limit
integer

How many leads to return, 1-100. Defaults to 50.

Example:
50
is_test
boolean

Return the most recent lead when the filters match nothing, so a Zap test has sample data.

Example:
false
Example request:
curl --request GET \
    --get "https://backend.genpage.ai/api/external/v1/zapier/get-leads?workspace_id=55&campaign_id=123&created_after=2026-08-01T00%3A00%3A00Z&last_lead_id=4200&limit=50&is_test=" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:
[
    {
        "id": 56789,
        "created_at": "2026-08-16T10:00:00.000000Z",
        "genpage_url": "https://myworkspace.genpa.ge/aws-john",
        "name": "John Doe",
        "email": "john@aws.com",
        "company_name": "AWS",
        "domain": "aws.com",
        "company_name_slug": "aws"
    }
]

Poll for recent form submissions.

GET
https://backend.genpage.ai
/api/external/v1/zapier/get-form-submissions
requires authentication

Without workspace_id this returns submissions from every workspace the API key can reach, newest first.

Headers

Authorization
Example:
Bearer sk-proj-{YOUR_API_KEY}
Content-Type
Example:
application/json
Accept
Example:
application/json

Query Parameters

workspace_id
integer

The workspace to read from.

Example:
55
campaign_id
integer

Only return submissions from this campaign.

Example:
123
limit
integer

How many submissions to return, 1-100. Defaults to 50.

Example:
50
Example request:
curl --request GET \
    --get "https://backend.genpage.ai/api/external/v1/zapier/get-form-submissions?workspace_id=55&campaign_id=123&limit=50" \
    --header "Authorization: Bearer sk-proj-{YOUR_API_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
Example response:
[
    {
        "id": 91,
        "form_id": "contact",
        "page_url": "https://myworkspace.genpa.ge/aws-john",
        "ip_address": "203.0.113.10",
        "created_at": "2026-08-16T10:00:00+00:00",
        "email": "john@aws.com"
    }
]