Create or update a lead
/api/public/integrations/{slug}Upserts a lead into the workspace that owns the integration connection. Matching is on workspace + email, so sending the same address twice updates the existing lead instead of duplicating it. The connection slug is recorded as the lead source.
Authentication
Connection token in the `token` query parameter (minimum 16 characters). The token identifies exactly one connection and therefore exactly one workspace.
path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| slug | string | Required | Integration slug of the connection, for example `zapier`, `make` or `google-sheets`. |
query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| token | string | Required | Inbound token generated when the integration was connected. |
header parameters
| Name | Type | Required | Description |
|---|---|---|---|
| x-idempotency-key | string | Optional | Optional de-duplication key. Repeat deliveries with the same key are acknowledged without being processed twice. |
Request body fields
| Name | Type | Required | Description |
|---|---|---|---|
| string (email, max 320) | Required | Prospect email address. Stored lowercased. | |
| first_name | string (max 120) | Optional | Given name. |
| last_name | string (max 120) | Optional | Family name. |
| company | string (max 200) | Optional | Company name. |
| job_title | string (max 200) | Optional | Job title. |
| phone | string (max 60) | Optional | Phone number. |
| website | string (max 300) | Optional | Company website. |
Request body
{
"email": "ada@example.com",
"first_name": "Ada",
"last_name": "Lovelace",
"company": "Example Inc",
"job_title": "Head of Growth",
"phone": "+1 555 0100",
"website": "https://example.com"
}curl -X POST "https://munchreach.com/api/public/integrations/zapier?token=YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-H "x-idempotency-key: YOUR_IDEMPOTENCY_KEY" \
-d '{
"email": "ada@example.com",
"first_name": "Ada",
"last_name": "Lovelace",
"company": "Example Inc",
"job_title": "Head of Growth",
"phone": "+1 555 0100",
"website": "https://example.com"
}'{
"ok": true
}Error responses
{ "error": "Missing token" }No token, or shorter than 16 characters.
Send the full token from Settings → Integrations.
{ "error": "Invalid token" }No connection matches this slug and token.
Reconnect the integration and copy the new URL.
{ "error": "Connection disabled" }The connection exists but is disabled.
Re-enable it in the dashboard.
{ "error": "Invalid JSON body" }The body could not be parsed as JSON.
Send `Content-Type: application/json` with valid JSON.
{ "error": "Invalid payload", "details": [ … ] }A field failed validation. Up to five issues are returned.
Fix the reported fields; `email` must be a valid address.
{ "error": "Could not store the lead" }The lead could not be written.
Retry with the same `x-idempotency-key`.
- A duplicate delivery returns `200 { "ok": true, "deduplicated": true }` instead of writing again.
- When no `x-idempotency-key` header is sent, the key defaults to the connection id plus the lowercased email.
- Every attempt is written to the integration event log and is visible in Settings → Integrations.
Implementation: src/routes/api/public/integrations/$slug.ts
