Confirm a publication sign-up
The leads.confirm operation: POST /api/v1/public/{brandSlug}/leads/confirm in the REST API and the leads_confirm tool in the MCP server.
/api/v1/public/{brandSlug}/leads/confirmConfirms a "Tell me when it's published" sign-up (leads.create with kind: "jurisdiction_notify") with the
token from its confirmation email: double opt-in. The token is the proof; no other key is needed. Only the
latest link sent works, for 7 days. Once confirmed, the jurisdiction_notify job sends one email when the
jurisdiction's page is published.
Confirming twice changes nothing and answers the same, even after the 7 days. The website calls this from the
page the link opens, when the visitor presses Confirm: opening the page alone confirms nothing, so a mail
scanner that follows links can't confirm on the visitor's behalf. Works only on the platform brand (ownrecord).
Public: the website calls it, no API key needed.
At a glance
- REST:
POST /api/v1/public/{brandSlug}/leads/confirm - MCP tool:
leads_confirm - Operation ID:
leads.confirm - Scope: Brand
- Permission:
customers:write - Risk tier:
write - Dry run: Not supported
- Idempotency:
Idempotency-Keyrequired - Modes: Test and live
- Authentication: None (a public endpoint, rate-limited per IP address)
- Since: M13
Request
Path parameters
| Field | Type | Description |
|---|---|---|
brandSlug | string | The platform brand's slug (ownrecord): leads belong to Ownrecord's own brand. |
Body
A JSON object (Content-Type: application/json):
| Field | Type | Required | Description |
|---|---|---|---|
token | string | Yes | The token from the confirmation link (?token= of /notify/confirm), exactly as it is. |
Response
200 OK with a JSON object:
| Field | Type | Description |
|---|---|---|
object | "lead_confirmation" | |
status | "confirmed" | |
jurisdictionId | string | The jurisdiction the sign-up waits for, e.g. HR. |
jurisdictionName | string | Its name, e.g. Croatia. |
pagePath | string | Its page on the website, e.g. /jurisdictions/hr. |
message | string | What to tell the visitor. |
Examples
Confirm from the email
POST /api/v1/public/ownrecord/leads/confirm
Idempotency-Key: 3f1c9a52-7d0e-4b8f-9a61-0c2d5e8b7f14
Content-Type: application/json
{
"token": "q9VhN3bXk2mR7tY4wP8sZ1cL6fJ0dG5aE-uB_nH3oKx"
}
Response (200):
{
"object": "lead_confirmation",
"status": "confirmed",
"jurisdictionId": "HR",
"jurisdictionName": "Croatia",
"pagePath": "/jurisdictions/hr",
"message": "Your email address is confirmed. We'll send you one email when this page is published, and nothing else."
}
Errors
| Code | HTTP status | When | What to do |
|---|---|---|---|
lead_confirmation_invalid | 400 | The token doesn't belong to a sign-up: mistyped, replaced by a newer link, or the sign-up was deleted. | Use the link exactly as it is in the email. Only the latest link we sent works; sign up again on the jurisdiction's page to get a new one. |
lead_confirmation_expired | 400 | The link is more than 7 days old and wasn't confirmed; sign up again for a new one. | Links work for 7 days. Sign up again on the jurisdiction's page to get a new one; it's sent at most once an hour. |
resource_not_found | 404 | brandSlug isn't the platform brand. | Check the ID and that your credentials are scoped to the right organization, entity, brand and mode. |
It can also return these common errors: validation_failed, api_version_unsupported, invalid_json, unsupported_media_type, scope_required, idempotency_key_required, idempotency_key_reused, idempotency_in_progress, dry_run_not_supported, rate_limited, internal_error.