
Prospect lists of businesses from Google Maps and their websites: target, count, export with emails.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Your Primavera API key as a Bearer token. Keys are created at https://primaverapp.com/dashboard/api (Pro or Agency subscription).
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Add places to a list from its original search; places already in the list are skipped. Priced as an export: 1 credit per place never delivered to the account (Agency: included under fair use). Paid: maxCredits (the most credits this call may spend, never exceeded) and idempotencyKey (a new UUID v4 for this operation) are required; without them nothing runs. To retry after an error or a timeout, send the same idempotencyKey with the same arguments: nothing is charged twice. Ask the user before calling it. Same call as POST /api/v1/lists/{id}/complete of the REST API.
Places to add from the original search (places already in the list are skipped).
Id of a list of the account (from create_list or list_lists).
The most credits this call may spend (required on every paid call, with an Idempotency-Key header). Never exceeded.
A new UUID v4 for this operation (sent as the Idempotency-Key of the API). Reuse it only to retry the very same call: the saved result comes back, nothing is charged twice.
This tool isn't marked read-only, so it may change something on the server or in an account you connected.
Pick your client. Values in capitals, like YOUR_TOKEN, are yours to fill in.
Run in a terminal
claude mcp add --transport http primavera https://primaverapp.com/api/mcp \ --header 'Authorization: Bearer YOUR_TOKEN'
Headers
Authorization (required): Your Primavera API key as a Bearer token. Keys are created at https://primaverapp.com/dashboard/api (Pro or Agency subscription).Add places to a list from its original search; places already in the list are skipped. Priced as an export: 1 credit per place never delivered to the account (Agency: included under fair use). Paid: maxCredits (the most credits this call may spend, never exceeded) and idempotencyKey (a new UUID v4 for this operation) are required; without them nothing runs. To retry after an error or a timeout, send the same idempotencyKey with the same arguments: nothing is charged twice. Ask the user before calling it. Same call as POST /api/v1/lists/{id}/complete of the REST API.
| Argument | Type | Description |
|---|---|---|
| rows* | integer | Places to add from the original search (places already in the list are skipped). |
| listId* | string | Id of a list of the account (from create_list or list_lists). |
| maxCredits* | integer | The most credits this call may spend (required on every paid call, with an Idempotency-Key header). Never exceeded. |
| idempotencyKey* | string | A new UUID v4 for this operation (sent as the Idempotency-Key of the API). Reuse it only to retry the very same call: the saved result comes back, nothing is charged twice. |
{
"type": "object",
"required": [
"listId",
"rows",
"maxCredits",
"idempotencyKey"
],
"properties": {
"rows": {
"type": "integer",
"maximum": 50000,
"minimum": 1,
"description": "Places to add from the original search (places already in the list are skipped)."
},
"listId": {
"type": "string",
"format": "uuid",
"description": "Id of a list of the account (from create_list or list_lists)."
},
"maxCredits": {
"type": "integer",
"maximum": 1000000000,
"minimum": 0,
"description": "The most credits this call may spend (required on every paid call, with an Idempotency-Key header). Never exceeded."
},
"idempotencyKey": {
"type": "string",
"format": "uuid",
"description": "A new UUID v4 for this operation (sent as the Idempotency-Key of the API). Reuse it only to retry the very same call: the saved result comes back, nothing is charged twice."
}
},
"additionalProperties": false
}Count the places of a search (the "search" returned by suggest_categories). Its input describes the search object in full (target, area, filters one by one, sort): read it to edit a search. Places already delivered to the account are left out unless search.excludeDelivered is false. When "exact" is false, say "≈ N". Free. Same call as POST /api/v1/search/count of the REST API.
| Argument | Type | Description |
|---|---|---|
| search* | object | The search, as returned by POST /categories/suggest (field "search"). Send it back as is, edited if needed. |
{
"type": "object",
"required": [
"search"
],
"properties": {
"search": {
"type": "object",
"properties": {
"area": {
"oneOf": [
{
"type": "object",
"required": [
"type"
],
"properties": {
"type": {
"type": "string",
"const": "country"
},
"withoutOverseas": {
"type": "boolean",
"const": true
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"type",
"codes"
],
"properties": {
"type": {
"type": "string",
"const": "region"
},
"codes": {
"type": "array",
"items": {
"type": "string",
"pattern": "^[A-Za-z0-9-]{1,40}$"
},
"maxItems": 20,
"minItems": 1
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"type",
"codes"
],
"properties": {
"type": {
"type": "string",
"const": "departement"
},
"codes": {
"type": "array",
"items": {
"type": "string",
"pattern": "^[A-Za-z0-9-]{1,40}$"
},
"maxItems": 110,
"minItems": 1
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"type",
"codes"
],
"properties": {
"type": {
"type": "string",
"const": "commune"
},
"codes": {
"type": "array",
"items": {
"type": "string",
"pattern": "^[A-Za-z0-9-]{1,40}$"
},
"maxItems": 1000,
"minItems": 1
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"type",
"codes"
],
"properties": {
"type": {
"type": "string",
"const": "postal"
},
"codes": {
"type": "array",
"items": {
"type": "string",
"pattern": "^[A-Za-z0-9 -]{2,10}$"
},
"maxItems": 1000,
"minItems": 1
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"type",
"lat",
"lng",
"km"
],
"properties": {
"km": {
"type": "number",
"maximum": 500,
"minimum": 0.1
},
"lat": {
"type": "number",
"maximum": 90,
"minimum": -90
},
"lng": {
"type": "number",
"maximum": 180,
"minimum": -180
},
"type": {
"type": "string",
"const": "radius"
}
},
"additionalProperties": false
}
],
"description": "The area, as returned by /areas (area field). Default: the whole country."
},
"sort": {
"enum": [
"default",
"reviews_desc",
"rating_desc",
"name_asc"
],
"type": "string",
"description": "Row order of previews and lists: 'default', 'reviews_desc', 'rating_desc', 'name_asc'."
},
"country": {
"enum": [
"af",
"za",
"al",
"dz",
"de",
"ad",
"ao",
"ai",
"ag",
"sa",
"ar",
"am",
"aw",
"au",
"at",
"az",
"bs",
"bh",
"bd",
"bb",
"be",
"bz",
"bj",
"bm",
"bt",
"bo",
"ba",
"bw",
"br",
"bn",
"bg",
"bf",
"bi",
"kh",
"cm",
"ca",
"cv",
"cl",
"cn",
"cy",
"co",
"km",
"cg",
"cd",
"kr",
"cr",
"ci",
"hr",
"cw",
"dk",
"dj",
"dm",
"eg",
"ae",
"ec",
"er",
"es",
"ee",
"sz",
"va",
"us",
"et",
"fj",
"fi",
"fr",
"ga",
"gm",
"ge",
"gh",
"gi",
"gr",
"gd",
"gl",
"gu",
"gt",
"gg",
"gn",
"gq",
"gw",
"gy",
"ht",
"hn",
"hu",
"cx",
"im",
"nf",
"ax",
"ky",
"cc",
"ck",
"fo",
"fk",
"mp",
"mh",
"pn",
"sb",
"tc",
"vg",
"vi",
"in",
"id",
"iq",
"ie",
"is",
"il",
"it",
"jm",
"jp",
"je",
"jo",
"kz",
"ke",
"kg",
"ki",
"xk",
"kw",
"la",
"ls",
"lv",
"lb",
"lr",
"ly",
"li",
"lt",
"lu",
"mk",
"mg",
"my",
"mw",
"mv",
"ml",
"mt",
"ma",
"mu",
"mr",
"mx",
"fm",
"md",
"mc",
"mn",
"me",
"ms",
"mz",
"mm",
"na",
"nr",
"np",
"ni",
"ne",
"ng",
"nu",
"no",
"nz",
"om",
"ug",
"uz",
"pk",
"pw",
"pa",
"pg",
"py",
"nl",
"bq",
"pe",
"ph",
"pl",
"pr",
"pt",
"qa",
"hk",
"mo",
"cf",
"do",
"ro",
"gb",
"rw",
"kn",
"sm",
"sx",
"vc",
"sh",
"lc",
"sv",
"ws",
"as",
"st",
"sn",
"rs",
"sc",
"sl",
"sg",
"sk",
"si",
"so",
"sd",
"ss",
"lk",
"se",
"ch",
"sr",
"sj",
"tj",
"tw",
"tz",
"td",
"cz",
"io",
"ps",
"th",
"tl",
"tg",
"tk",
"to",
"tt",
"tn",
"tm",
"tr",
"tv",
"ua",
"uy",
"vu",
"ve",
"vn",
"ye",
"zm",
"zw"
],
"type": "string",
"description": "ISO 3166-1 alpha-2 code, lower case (default fr). Only open countries are searchable."
},
"filters": {
"type": "object",
"properties": {
"naf": {
"type": "array",
"items": {
"type": "string",
"pattern": "^(?:[A-U]|\\d{2}(?:\\.\\d(?:\\d[A-Z]?)?)?)$"
},
"maxItems": 40,
"minItems": 1,
"description": "France only: NAF rev. 2 activity codes of any level (\"56\", \"56.10A\"). Keeps places whose company is known in the French registry."
},
"onePer": {
"type": "object",
"required": [
"by"
],
"properties": {
"by": {
"enum": [
"entreprise",
"groupe"
],
"type": "string"
},
"keep": {
"enum": [
"siege",
"classement"
],
"type": "string",
"default": "siege"
}
},
"description": "France only: { \"by\": \"entreprise\" | \"groupe\", \"keep\"?: \"siege\" | \"classement\" }: one place per company or group (head office first, or best ranked). Places without a known company all stay.",
"additionalProperties": false
},
"pixels": {
"type": "array",
"items": {
"type": "string",
"maxLength": 60,
"minLength": 1
},
"maxItems": 20,
"minItems": 1,
"description": "At least one of these advertising pixels (Meta Pixel, Google Ads…)."
},
"socials": {
"type": "array",
"items": {
"enum": [
"facebook",
"instagram",
"linkedin",
"youtube",
"twitter",
"tiktok",
"pinterest",
"threads"
],
"type": "string"
},
"maxItems": 8,
"minItems": 1,
"description": "Every listed social network is linked from the website: facebook, instagram, linkedin, youtube, twitter, tiktok, pinterest, threads."
},
"hasPhone": {
"type": "boolean",
"description": "true: places with a phone number."
},
"networks": {
"type": "object",
"required": [
"mode"
],
"properties": {
"ids": {
"type": "array",
"items": {
"type": "string",
"pattern": "^[a-z0-9_]{2,60}$"
},
"maxItems": 50,
"minItems": 1
},
"mode": {
"enum": [
"exclude",
"only"
],
"type": "string"
}
},
"description": "{ \"mode\": \"exclude\" | \"only\", \"ids\"?: [...] }: brands and networks (ids from GET /networks). Without ids, \"exclude\" removes every confirmed network (\"independent\" businesses).",
"additionalProperties": false
},
"ratingMax": {
"type": "number",
"maximum": 5,
"minimum": 1,
"description": "Google rating bounds."
},
"ratingMin": {
"type": "number",
"maximum": 5,
"minimum": 1,
"description": "Google rating bounds."
},
"hasWebsite": {
"type": "boolean",
"description": "true: places with a website; false: without."
},
"legalForms": {
"type": "array",
"items": {
"type": "string",
"pattern": "^(?:\\d|\\d{2}|\\d{4})$"
},
"maxItems": 30,
"minItems": 1,
"description": "France only: INSEE legal category codes (\"5\", \"57\", \"5710\")."
},
"reviewsMax": {
"type": "integer",
"minimum": 0,
"description": "Number of Google reviews bounds."
},
"reviewsMin": {
"type": "integer",
"minimum": 0,
"description": "Number of Google reviews bounds."
},
"emailStatus": {
"type": "array",
"items": {
"enum": [
"deliverable",
"catch_all",
"unverified"
],
"type": "string"
},
"maxItems": 3,
"minItems": 1,
"description": "Places with an email address: send [\"deliverable\",\"catch_all\",\"unverified\"] (all three). Prefer withEmail on /search/estimate and POST /lists."
},
"headcountMax": {
"type": "integer",
"maximum": 100000,
"minimum": 0,
"description": "France only: company headcount bounds (INSEE brackets fully inside the bounds)."
},
"headcountMin": {
"type": "integer",
"maximum": 100000,
"minimum": 0,
"description": "France only: company headcount bounds (INSEE brackets fully inside the bounds)."
},
"nameContains": {
"type": "string",
"maxLength": 100,
"minLength": 2,
"description": "Part of the name (accents and case ignored), 2 to 100 characters."
},
"ownEmailOnly": {
"type": "boolean",
"description": "Only places whose email address is not shared with other places (an address common to a whole network leads to the network, not to this place)."
},
"technologies": {
"type": "array",
"items": {
"type": "string",
"maxLength": 60,
"minLength": 1
},
"maxItems": 30,
"minItems": 1,
"description": "At least one of these website technologies (WordPress, Wix, Shopify…)."
},
"companyAgeMax": {
"type": "integer",
"maximum": 200,
"minimum": 1,
"description": "France only: company created at least / less than N years ago."
},
"companyAgeMin": {
"type": "integer",
"maximum": 200,
"minimum": 0,
"description": "France only: company created at least / less than N years ago."
},
"hotelStarsMin": {
"type": "integer",
"maximum": 5,
"minimum": 1,
"description": "Hotels: minimum stars."
},
"includeClosed": {
"type": "boolean",
"default": false,
"description": "Include permanently closed places (default false)."
},
"hasContactForm": {
"type": "boolean",
"description": "The website has a contact form."
},
"websiteReachable": {
"type": "boolean",
"description": "true: the website answered when last read."
},
"companyCategories": {
"type": "array",
"items": {
"enum": [
"PME",
"ETI",
"GE"
],
"type": "string"
},
"maxItems": 3,
"minItems": 1,
"description": "France only: \"PME\", \"ETI\", \"GE\" (INSEE company size category)."
},
"excludeServicePoints": {
"type": "boolean",
"default": true,
"description": "Remove service points (parcel lockers, charging stations, ATMs): nobody to talk to. Default true."
},
"hideHiddenCategories": {
"type": "boolean",
"default": true,
"description": "Hide categories nobody prospects (bus stops, car parks…). Default true."
}
},
"additionalProperties": false
},
"version": {
"type": "number",
"const": 1
},
"categories": {
"type": "object",
"properties": {
"ids": {
"type": "array",
"items": {
"type": "integer",
"exclusiveMinimum": 0
},
"maxItems": 2000,
"description": "Single category ids (from /categories), outside the groups."
},
"mode": {
"enum": [
"primary_or_generic",
"primary",
"any"
],
"type": "string",
"description": "'primary_or_generic' (default): the main category is in the list, or a secondary one when the main one is generic; 'primary': main category only; 'any': main or secondary (broader, less precise)."
},
"groups": {
"type": "array",
"items": {
"type": "object",
"required": [
"label",
"ids"
],
"properties": {
"ids": {
"type": "array",
"items": {
"type": "integer",
"exclusiveMinimum": 0
},
"maxItems": 600,
"minItems": 1
},
"label": {
"type": "string",
"maxLength": 60,
"minLength": 1
},
"prudence": {
"type": "boolean",
"const": true,
"description": "True when the engine added this group by prudence (a neighbouring activity, not the core of the request): a list delivers the core of the request first."
}
},
"additionalProperties": false
},
"maxItems": 8,
"description": "Category groups (label and category ids), disjoint, as returned by /categories/suggest. Remove a group to narrow the target."
},
"request": {
"type": "string",
"maxLength": 600,
"minLength": 1,
"description": "The target as the user wrote it: title of the search and default list name. Set by /categories/suggest."
},
"concepts": {
"type": "array",
"items": {
"type": "string",
"pattern": "^[a-z0-9_]{2,60}$"
},
"maxItems": 40,
"description": "Legacy trade ids of older searches. Prefer groups."
}
},
"description": "The target. Absent or empty: every category of the area.",
"additionalProperties": false
},
"excludeDelivered": {
"type": "boolean",
"default": true,
"description": "Leave out the places already delivered to your account: not counted, never billed twice. Default true."
},
"excludedConcepts": {
"type": "array",
"items": {
"type": "string",
"pattern": "^[a-z0-9_]{2,60}$"
},
"maxItems": 40,
"description": "Legacy trade ids to remove."
},
"excludedCategoryIds": {
"type": "array",
"items": {
"type": "integer",
"exclusiveMinimum": 0
},
"maxItems": 2000,
"description": "Categories to remove from the target."
}
},
"description": "The search, as returned by POST /categories/suggest (field \"search\"). Send it back as is, edited if needed.",
"additionalProperties": false
}
},
"additionalProperties": false
}Export the places of a search into a new list, with their contact details (up to 50,000 rows). Price: 1 credit per place never delivered to this account (Agency: included under fair use); withEmail: only places with an email address (found ones first, then guessed and verified ones); verifyEmails: plus 1 credit per address verified. maxCredits is never exceeded: send the "cost" of estimate_list, once the user agreed. One export at a time per account. While the list says "creating", follow it with get_list. Paid: maxCredits (the most credits this call may spend, never exceeded) and idempotencyKey (a new UUID v4 for this operation) are required; without them nothing runs. To retry after an error or a timeout, send the same idempotencyKey with the same arguments: nothing is charged twice. Ask the user before calling it. Same call as POST /api/v1/lists of the REST API.
| Argument | Type | Description |
|---|---|---|
| name* | string | List name, as shown in "My lists". |
| rows | integer | Rows wanted (at most 50000). With withEmail: email addresses wanted. Required unless wholeArea is true. |
| search* | object | The search, as returned by /categories/suggest (then narrowed with /areas, filters…). The "search" object returned by suggest_categories (target, area, filters, sort), sent as is or edited; its full schema is the "search" input of count_search. An invalid search is refused with invalid_request and the fields to fix. |
| wholeArea | boolean | Rarely searched area only (estimate returned kind "zone"): fill the list with the whole area instead of a number of rows. |
| withEmail | boolean | true = the "With email" choice of the app: places with an email address only; found addresses are delivered first, others are guessed on the websites then checked (1 credit per valid address), and the verification of the addresses is reserved at creation (1 credit per address, unused credits returned). |
| maxCredits* | integer | The most credits this call may spend (required on every paid call, with an Idempotency-Key header). Never exceeded. |
| verifyEmails | boolean | true = the "Verify emails" box of the app: the addresses this list delivers are verified (deliverable, risky, undeliverable), 1 credit per address, reserved at creation and inside maxCredits (send maxCredits ≥ export cost + rows); unused credits are returned. Up to 10000 rows; not for rarely searched areas; included in withEmail lists. |
| idempotencyKey* | string | A new UUID v4 for this operation (sent as the Idempotency-Key of the API). Reuse it only to retry the very same call: the saved result comes back, nothing is charged twice. |
{
"type": "object",
"required": [
"name",
"search",
"maxCredits",
"idempotencyKey"
],
"properties": {
"name": {
"type": "string",
"maxLength": 120,
"minLength": 1,
"description": "List name, as shown in \"My lists\"."
},
"rows": {
"type": "integer",
"maximum": 50000,
"minimum": 1,
"description": "Rows wanted (at most 50000). With withEmail: email addresses wanted. Required unless wholeArea is true."
},
"search": {
"type": "object",
"description": "The search, as returned by /categories/suggest (then narrowed with /areas, filters…). The \"search\" object returned by suggest_categories (target, area, filters, sort), sent as is or edited; its full schema is the \"search\" input of count_search. An invalid search is refused with invalid_request and the fields to fix."
},
"wholeArea": {
"type": "boolean",
"description": "Rarely searched area only (estimate returned kind \"zone\"): fill the list with the whole area instead of a number of rows."
},
"withEmail": {
"type": "boolean",
"description": "true = the \"With email\" choice of the app: places with an email address only; found addresses are delivered first, others are guessed on the websites then checked (1 credit per valid address), and the verification of the addresses is reserved at creation (1 credit per address, unused credits returned)."
},
"maxCredits": {
"type": "integer",
"maximum": 1000000000,
"minimum": 0,
"description": "The most credits this call may spend (required on every paid call, with an Idempotency-Key header). Never exceeded."
},
"verifyEmails": {
"type": "boolean",
"description": "true = the \"Verify emails\" box of the app: the addresses this list delivers are verified (deliverable, risky, undeliverable), 1 credit per address, reserved at creation and inside maxCredits (send maxCredits ≥ export cost + rows); unused credits are returned. Up to 10000 rows; not for rarely searched areas; included in withEmail lists."
},
"idempotencyKey": {
"type": "string",
"format": "uuid",
"description": "A new UUID v4 for this operation (sent as the Idempotency-Key of the API). Reuse it only to retry the very same call: the saved result comes back, nothing is charged twice."
}
},
"additionalProperties": false
}Rows, cost in credits and balance after, for a list of N rows of a search (up to 50,000). Tell the user the cost, then send "cost" as maxCredits to create_list with the same search, rows and withEmail. In a rarely searched area it returns kind "zone": the list fills itself after creation (create_list with maxCredits ≥ zoneEstimate.creditCap). Free. Same call as POST /api/v1/search/estimate of the REST API.
| Argument | Type | Description |
|---|---|---|
| rows | integer | Rows wanted in the list (default 500, at most 50000). |
| search* | object | The search, as returned by POST /categories/suggest (field "search"). Send it back as is, edited if needed. The "search" object returned by suggest_categories (target, area, filters, sort), sent as is or edited; its full schema is the "search" input of count_search. An invalid search is refused with invalid_request and the fields to fix. |
| withEmail | boolean | True: a list of places WITH an email address (found addresses first, then guessed and checked ones, each address checked at 1 credit). False: the email filter is removed. Absent: the search as is. |
{
"type": "object",
"required": [
"search"
],
"properties": {
"rows": {
"type": "integer",
"maximum": 50000,
"minimum": 1,
"description": "Rows wanted in the list (default 500, at most 50000)."
},
"search": {
"type": "object",
"description": "The search, as returned by POST /categories/suggest (field \"search\"). Send it back as is, edited if needed. The \"search\" object returned by suggest_categories (target, area, filters, sort), sent as is or edited; its full schema is the \"search\" input of count_search. An invalid search is refused with invalid_request and the fields to fix."
},
"withEmail": {
"type": "boolean",
"description": "True: a list of places WITH an email address (found addresses first, then guessed and checked ones, each address checked at 1 credit). False: the email filter is removed. Absent: the search as is."
}
},
"additionalProperties": false
}Estimate a job on a list before starting it: places eligible and the most credits it can spend. Jobs: executives (company executives, France and the United States only), summary (a 3-sentence summary of each website), question (a yes/no question asked to each website), filter (a criterion judged on the data we hold, no website read). Free. Same call as POST /api/v1/lists/{id}/jobs/estimate of the REST API.
| Argument | Type | Description |
|---|---|---|
| tool* | string | executives: company executives (France and the United States only); summary: 3-sentence summary of the website; question: a yes/no question asked to the website; filter: a criterion judged on the data we hold (no website read). |
| scope | any | Places the job runs on: the whole list (default), the places a finished qualification judged conforming, or those it could not decide. |
| listId* | string | Id of a list of the account (from create_list or list_lists). |
| question | string | tool "question" only. |
| criterion | string | tool "filter" only. |
{
"type": "object",
"required": [
"listId",
"tool"
],
"properties": {
"tool": {
"enum": [
"executives",
"summary",
"question",
"filter"
],
"type": "string",
"description": "executives: company executives (France and the United States only); summary: 3-sentence summary of the website; question: a yes/no question asked to the website; filter: a criterion judged on the data we hold (no website read)."
},
"scope": {
"oneOf": [
{
"type": "object",
"required": [
"kind"
],
"properties": {
"kind": {
"type": "string",
"const": "all"
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"kind",
"jobId"
],
"properties": {
"kind": {
"type": "string",
"const": "conforming"
},
"jobId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
"description": "A finished filter or question job of this list."
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"kind",
"jobId"
],
"properties": {
"kind": {
"type": "string",
"const": "undetermined"
},
"jobId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
"description": "A finished filter or question job of this list: only its \"undetermined\" places."
}
},
"additionalProperties": false
}
],
"description": "Places the job runs on: the whole list (default), the places a finished qualification judged conforming, or those it could not decide."
},
"listId": {
"type": "string",
"format": "uuid",
"description": "Id of a list of the account (from create_list or list_lists)."
},
"question": {
"type": "string",
"maxLength": 300,
"minLength": 5,
"description": "tool \"question\" only."
},
"criterion": {
"type": "string",
"maxLength": 300,
"minLength": 3,
"description": "tool \"filter\" only."
}
},
"additionalProperties": false
}Find an area from a place as written: region, département, commune, postal code, or a radius around a town ("Lyon", "33", "30 km around Nantes"). Use the "area" field of a result (or of "match" when its status is "resolved") as the area of suggest_categories or as search.area. Free. Same call as GET /api/v1/areas of the REST API.
| Argument | Type | Description |
|---|---|---|
| q* | string | A place as written: "Lyon", "31000", "Gironde", "within 30 km of Nantes", "the South-West". |
| level | string | Only this level of area. |
| limit | integer | Areas returned (default 10, at most 20). |
| country | string | Search this country only (ISO alpha-2, lower case). Default: every open country. |
| radiusKm | number | A radius around the place, in km (1 to 200). |
{
"type": "object",
"required": [
"q"
],
"properties": {
"q": {
"type": "string",
"maxLength": 120,
"minLength": 2,
"description": "A place as written: \"Lyon\", \"31000\", \"Gironde\", \"within 30 km of Nantes\", \"the South-West\"."
},
"level": {
"enum": [
"region",
"departement",
"commune"
],
"type": "string",
"description": "Only this level of area."
},
"limit": {
"type": "integer",
"maximum": 20,
"minimum": 1,
"description": "Areas returned (default 10, at most 20)."
},
"country": {
"enum": [
"af",
"za",
"al",
"dz",
"de",
"ad",
"ao",
"ai",
"ag",
"sa",
"ar",
"am",
"aw",
"au",
"at",
"az",
"bs",
"bh",
"bd",
"bb",
"be",
"bz",
"bj",
"bm",
"bt",
"bo",
"ba",
"bw",
"br",
"bn",
"bg",
"bf",
"bi",
"kh",
"cm",
"ca",
"cv",
"cl",
"cn",
"cy",
"co",
"km",
"cg",
"cd",
"kr",
"cr",
"ci",
"hr",
"cw",
"dk",
"dj",
"dm",
"eg",
"ae",
"ec",
"er",
"es",
"ee",
"sz",
"va",
"us",
"et",
"fj",
"fi",
"fr",
"ga",
"gm",
"ge",
"gh",
"gi",
"gr",
"gd",
"gl",
"gu",
"gt",
"gg",
"gn",
"gq",
"gw",
"gy",
"ht",
"hn",
"hu",
"cx",
"im",
"nf",
"ax",
"ky",
"cc",
"ck",
"fo",
"fk",
"mp",
"mh",
"pn",
"sb",
"tc",
"vg",
"vi",
"in",
"id",
"iq",
"ie",
"is",
"il",
"it",
"jm",
"jp",
"je",
"jo",
"kz",
"ke",
"kg",
"ki",
"xk",
"kw",
"la",
"ls",
"lv",
"lb",
"lr",
"ly",
"li",
"lt",
"lu",
"mk",
"mg",
"my",
"mw",
"mv",
"ml",
"mt",
"ma",
"mu",
"mr",
"mx",
"fm",
"md",
"mc",
"mn",
"me",
"ms",
"mz",
"mm",
"na",
"nr",
"np",
"ni",
"ne",
"ng",
"nu",
"no",
"nz",
"om",
"ug",
"uz",
"pk",
"pw",
"pa",
"pg",
"py",
"nl",
"bq",
"pe",
"ph",
"pl",
"pr",
"pt",
"qa",
"hk",
"mo",
"cf",
"do",
"ro",
"gb",
"rw",
"kn",
"sm",
"sx",
"vc",
"sh",
"lc",
"sv",
"ws",
"as",
"st",
"sn",
"rs",
"sc",
"sl",
"sg",
"sk",
"si",
"so",
"sd",
"ss",
"lk",
"se",
"ch",
"sr",
"sj",
"tj",
"tw",
"tz",
"td",
"cz",
"io",
"ps",
"th",
"tl",
"tg",
"tk",
"to",
"tt",
"tn",
"tm",
"tr",
"tv",
"ua",
"uy",
"vu",
"ve",
"vn",
"ye",
"zm",
"zw"
],
"type": "string",
"description": "Search this country only (ISO alpha-2, lower case). Default: every open country."
},
"radiusKm": {
"type": "number",
"maximum": 200,
"minimum": 1,
"description": "A radius around the place, in km (1 to 200)."
}
},
"additionalProperties": false
}Look up a single Google Maps category by name (French or English), with its number of places. To build a target, use suggest_categories instead; use this only to check or add one category id to search.categories.ids. Free. Same call as GET /api/v1/categories of the REST API.
| Argument | Type | Description |
|---|---|---|
| q | string | Category name, French or English (empty: the most frequent categories). |
| limit | integer | Categories returned (default 20, at most 50). |
| country | string | Counts are those of this country (default fr). |
{
"type": "object",
"required": [],
"properties": {
"q": {
"type": "string",
"maxLength": 100,
"description": "Category name, French or English (empty: the most frequent categories)."
},
"limit": {
"type": "integer",
"maximum": 50,
"minimum": 1,
"description": "Categories returned (default 20, at most 50)."
},
"country": {
"enum": [
"af",
"za",
"al",
"dz",
"de",
"ad",
"ao",
"ai",
"ag",
"sa",
"ar",
"am",
"aw",
"au",
"at",
"az",
"bs",
"bh",
"bd",
"bb",
"be",
"bz",
"bj",
"bm",
"bt",
"bo",
"ba",
"bw",
"br",
"bn",
"bg",
"bf",
"bi",
"kh",
"cm",
"ca",
"cv",
"cl",
"cn",
"cy",
"co",
"km",
"cg",
"cd",
"kr",
"cr",
"ci",
"hr",
"cw",
"dk",
"dj",
"dm",
"eg",
"ae",
"ec",
"er",
"es",
"ee",
"sz",
"va",
"us",
"et",
"fj",
"fi",
"fr",
"ga",
"gm",
"ge",
"gh",
"gi",
"gr",
"gd",
"gl",
"gu",
"gt",
"gg",
"gn",
"gq",
"gw",
"gy",
"ht",
"hn",
"hu",
"cx",
"im",
"nf",
"ax",
"ky",
"cc",
"ck",
"fo",
"fk",
"mp",
"mh",
"pn",
"sb",
"tc",
"vg",
"vi",
"in",
"id",
"iq",
"ie",
"is",
"il",
"it",
"jm",
"jp",
"je",
"jo",
"kz",
"ke",
"kg",
"ki",
"xk",
"kw",
"la",
"ls",
"lv",
"lb",
"lr",
"ly",
"li",
"lt",
"lu",
"mk",
"mg",
"my",
"mw",
"mv",
"ml",
"mt",
"ma",
"mu",
"mr",
"mx",
"fm",
"md",
"mc",
"mn",
"me",
"ms",
"mz",
"mm",
"na",
"nr",
"np",
"ni",
"ne",
"ng",
"nu",
"no",
"nz",
"om",
"ug",
"uz",
"pk",
"pw",
"pa",
"pg",
"py",
"nl",
"bq",
"pe",
"ph",
"pl",
"pr",
"pt",
"qa",
"hk",
"mo",
"cf",
"do",
"ro",
"gb",
"rw",
"kn",
"sm",
"sx",
"vc",
"sh",
"lc",
"sv",
"ws",
"as",
"st",
"sn",
"rs",
"sc",
"sl",
"sg",
"sk",
"si",
"so",
"sd",
"ss",
"lk",
"se",
"ch",
"sr",
"sj",
"tj",
"tw",
"tz",
"td",
"cz",
"io",
"ps",
"th",
"tl",
"tg",
"tk",
"to",
"tt",
"tn",
"tm",
"tr",
"tv",
"ua",
"uy",
"vu",
"ve",
"vn",
"ye",
"zm",
"zw"
],
"type": "string",
"description": "Counts are those of this country (default fr)."
}
},
"additionalProperties": false
}Look up a brand, franchise or network by name. Use its id in search.filters.networks ({ "mode": "only" | "exclude", "ids": [...] }); mode "exclude" without ids removes every known network (independent businesses only). Free. Same call as GET /api/v1/networks of the REST API.
| Argument | Type | Description |
|---|---|---|
| q* | string | Brand or network name ("Century 21", "McDonald's"). |
| limit | integer | Networks returned (default 10, at most 50). |
{
"type": "object",
"required": [
"q"
],
"properties": {
"q": {
"type": "string",
"maxLength": 60,
"minLength": 2,
"description": "Brand or network name (\"Century 21\", \"McDonald's\")."
},
"limit": {
"type": "integer",
"maximum": 50,
"minimum": 1,
"description": "Networks returned (default 10, at most 50)."
}
},
"additionalProperties": false
}Plan, credit balance, Agency fair use per country and rate limits of the Primavera account that owns the API key. Call it first: it tells what the account can afford. Free. Same call as GET /api/v1/account of the REST API.
No arguments.
{
"type": "object",
"required": [],
"properties": {},
"additionalProperties": false
}Progress of a job: status, places done and billed, credits spent; for a finished filter or question job, the places per verdict. Free. Same call as GET /api/v1/jobs/{id} of the REST API.
| Argument | Type | Description |
|---|---|---|
| jobId* | string | Id of a job (from start_list_job or get_list). |
{
"type": "object",
"required": [
"jobId"
],
"properties": {
"jobId": {
"type": "string",
"format": "uuid",
"description": "Id of a job (from start_list_job or get_list)."
}
},
"additionalProperties": false
}Status of a list (creating, ready, filling, failed), rows, credits spent, progress of the export, of the guessed email addresses and of the email verification (progress.emailCheck.unverified = what verify_list_emails would cost), contents and latest jobs. While it is not ready, call it again every 10 seconds or more. Free. Same call as GET /api/v1/lists/{id} of the REST API.
| Argument | Type | Description |
|---|---|---|
| listId* | string | Id of a list of the account (from create_list or list_lists). |
{
"type": "object",
"required": [
"listId"
],
"properties": {
"listId": {
"type": "string",
"format": "uuid",
"description": "Id of a list of the account (from create_list or list_lists)."
}
},
"additionalProperties": false
}Status of a prepared file. Once it is ready, "url" is a download link valid 120 seconds: download it at once or give it to the user, and call again for a new link. Free. Same call as GET /api/v1/lists/{id}/files/{fileId} of the REST API.
| Argument | Type | Description |
|---|---|---|
| fileId* | string | Id of a prepared file (from prepare_list_file). |
| listId* | string | Id of a list of the account (from create_list or list_lists). |
{
"type": "object",
"required": [
"listId",
"fileId"
],
"properties": {
"fileId": {
"type": "string",
"format": "uuid",
"description": "Id of a prepared file (from prepare_list_file)."
},
"listId": {
"type": "string",
"format": "uuid",
"description": "Id of a list of the account (from create_list or list_lists)."
}
},
"additionalProperties": false
}Rows of a ready list with every contact detail, page by page (nextCursor). Keep limit small (50 or less) and choose columns: large pages flood the conversation. For the whole list, use prepare_list_file. Free. Same call as GET /api/v1/lists/{id}/items of the REST API.
| Argument | Type | Description |
|---|---|---|
| limit | integer | |
| cursor | string | nextCursor of the previous page. |
| listId* | string | Id of a list of the account (from create_list or list_lists). |
| columns | string | Comma-separated column keys; default: every column of the CSV. |
{
"type": "object",
"required": [
"listId"
],
"properties": {
"limit": {
"type": "integer",
"default": 100,
"maximum": 1000,
"minimum": 1
},
"cursor": {
"type": "string",
"maxLength": 200,
"description": "nextCursor of the previous page."
},
"listId": {
"type": "string",
"format": "uuid",
"description": "Id of a list of the account (from create_list or list_lists)."
},
"columns": {
"type": "string",
"maxLength": 2000,
"description": "Comma-separated column keys; default: every column of the CSV."
}
},
"additionalProperties": false
}The figures of a search in one call: total, places with an email address, a phone number, a website, and the estimated number of email addresses. Free. Same call as POST /api/v1/search/metrics of the REST API.
| Argument | Type | Description |
|---|---|---|
| search* | object | The search, as returned by POST /categories/suggest (field "search"). Send it back as is, edited if needed. The "search" object returned by suggest_categories (target, area, filters, sort), sent as is or edited; its full schema is the "search" input of count_search. An invalid search is refused with invalid_request and the fields to fix. |
{
"type": "object",
"required": [
"search"
],
"properties": {
"search": {
"type": "object",
"description": "The search, as returned by POST /categories/suggest (field \"search\"). Send it back as is, edited if needed. The \"search\" object returned by suggest_categories (target, area, filters, sort), sent as is or edited; its full schema is the \"search\" input of count_search. An invalid search is refused with invalid_request and the fields to fix."
}
},
"additionalProperties": false
}The lists of the account, newest first, page by page (send nextCursor back as cursor). Free. Same call as GET /api/v1/lists of the REST API.
| Argument | Type | Description |
|---|---|---|
| limit | integer | |
| cursor | string | nextCursor of the previous page. |
{
"type": "object",
"required": [],
"properties": {
"limit": {
"type": "integer",
"default": 50,
"maximum": 100,
"minimum": 1
},
"cursor": {
"type": "string",
"maxLength": 200,
"description": "nextCursor of the previous page."
}
},
"additionalProperties": false
}Prepare the CSV file (every column) or the Excel file (the columns you choose) of a ready list. Then call get_list_file until the file is ready. A file stays available 7 days. Free. idempotencyKey (a new UUID v4) is required; reuse it only to retry the very same call. Same call as POST /api/v1/lists/{id}/files of the REST API.
| Argument | Type | Description |
|---|---|---|
| format* | string | |
| listId* | string | Id of a list of the account (from create_list or list_lists). |
| columns | array | xlsx only: column keys (see GET /lists/{id}/items, "columns"). A CSV always holds every column. |
| idempotencyKey* | string | A new UUID v4 for this operation (sent as the Idempotency-Key of the API). Reuse it only to retry the very same call: the saved result comes back, nothing is charged twice. |
{
"type": "object",
"required": [
"listId",
"format",
"idempotencyKey"
],
"properties": {
"format": {
"enum": [
"csv",
"xlsx"
],
"type": "string"
},
"listId": {
"type": "string",
"format": "uuid",
"description": "Id of a list of the account (from create_list or list_lists)."
},
"columns": {
"type": "array",
"items": {
"type": "string",
"maxLength": 60,
"minLength": 1
},
"maxItems": 100,
"description": "xlsx only: column keys (see GET /lists/{id}/items, \"columns\"). A CSV always holds every column."
},
"idempotencyKey": {
"type": "string",
"format": "uuid",
"description": "A new UUID v4 for this operation (sent as the Idempotency-Key of the API). Reuse it only to retry the very same call: the saved result comes back, nothing is charged twice."
}
},
"additionalProperties": false
}Up to 25 sample places of a search (name, city, category, rating, reviews). Contact details are booleans here: email addresses, phone numbers and websites only come with a list (create_list). Free. Same call as POST /api/v1/search/preview of the REST API.
| Argument | Type | Description |
|---|---|---|
| limit | integer | Rows returned (default 10, at most 25). |
| offset | integer | Rows to skip (default 0). |
| search* | object | The search, as returned by POST /categories/suggest (field "search"). Send it back as is, edited if needed. The "search" object returned by suggest_categories (target, area, filters, sort), sent as is or edited; its full schema is the "search" input of count_search. An invalid search is refused with invalid_request and the fields to fix. |
{
"type": "object",
"required": [
"search"
],
"properties": {
"limit": {
"type": "integer",
"maximum": 25,
"minimum": 1,
"description": "Rows returned (default 10, at most 25)."
},
"offset": {
"type": "integer",
"maximum": 10000,
"minimum": 0,
"description": "Rows to skip (default 0)."
},
"search": {
"type": "object",
"description": "The search, as returned by POST /categories/suggest (field \"search\"). Send it back as is, edited if needed. The \"search\" object returned by suggest_categories (target, area, filters, sort), sent as is or edited; its full schema is the \"search\" input of count_search. An invalid search is refused with invalid_request and the fields to fix."
}
},
"additionalProperties": false
}Start a job on a list; it runs in the background. Each place is billed on its result, never beyond maxCredits nor the estimate: send estimate.maxCredits of estimate_list_job, with the same tool, question, criterion and scope. Follow it with get_job; results land in get_list_items. Paid: maxCredits (the most credits this call may spend, never exceeded) and idempotencyKey (a new UUID v4 for this operation) are required; without them nothing runs. To retry after an error or a timeout, send the same idempotencyKey with the same arguments: nothing is charged twice. Ask the user before calling it. Same call as POST /api/v1/lists/{id}/jobs of the REST API.
| Argument | Type | Description |
|---|---|---|
| tool* | string | executives: company executives (France and the United States only); summary: 3-sentence summary of the website; question: a yes/no question asked to the website; filter: a criterion judged on the data we hold (no website read). |
| scope | any | Places the job runs on: the whole list (default), the places a finished qualification judged conforming, or those it could not decide. |
| listId* | string | Id of a list of the account (from create_list or list_lists). |
| question | string | tool "question" only. |
| criterion | string | tool "filter" only. |
| maxCredits* | integer | The most credits this call may spend (required on every paid call, with an Idempotency-Key header). Never exceeded. |
| idempotencyKey* | string | A new UUID v4 for this operation (sent as the Idempotency-Key of the API). Reuse it only to retry the very same call: the saved result comes back, nothing is charged twice. |
{
"type": "object",
"required": [
"listId",
"tool",
"maxCredits",
"idempotencyKey"
],
"properties": {
"tool": {
"enum": [
"executives",
"summary",
"question",
"filter"
],
"type": "string",
"description": "executives: company executives (France and the United States only); summary: 3-sentence summary of the website; question: a yes/no question asked to the website; filter: a criterion judged on the data we hold (no website read)."
},
"scope": {
"oneOf": [
{
"type": "object",
"required": [
"kind"
],
"properties": {
"kind": {
"type": "string",
"const": "all"
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"kind",
"jobId"
],
"properties": {
"kind": {
"type": "string",
"const": "conforming"
},
"jobId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
"description": "A finished filter or question job of this list."
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"kind",
"jobId"
],
"properties": {
"kind": {
"type": "string",
"const": "undetermined"
},
"jobId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
"description": "A finished filter or question job of this list: only its \"undetermined\" places."
}
},
"additionalProperties": false
}
],
"description": "Places the job runs on: the whole list (default), the places a finished qualification judged conforming, or those it could not decide."
},
"listId": {
"type": "string",
"format": "uuid",
"description": "Id of a list of the account (from create_list or list_lists)."
},
"question": {
"type": "string",
"maxLength": 300,
"minLength": 5,
"description": "tool \"question\" only."
},
"criterion": {
"type": "string",
"maxLength": 300,
"minLength": 3,
"description": "tool \"filter\" only."
},
"maxCredits": {
"type": "integer",
"maximum": 1000000000,
"minimum": 0,
"description": "The most credits this call may spend (required on every paid call, with an Idempotency-Key header). Never exceeded."
},
"idempotencyKey": {
"type": "string",
"format": "uuid",
"description": "A new UUID v4 for this operation (sent as the Idempotency-Key of the API). Reuse it only to retry the very same call: the saved result comes back, nothing is charged twice."
}
},
"additionalProperties": false
}Entry point for ANY target: call it before any search, and never invent category ids. Give the target in plain words, WITHOUT the place ("independent car repair shops", "restaurants that could use an online booking tool") and the area from find_areas. Primavera's engine picks the Google Maps categories in groups and counts them in the area. Returns "selection" (groups, categories left out and why, what the data cannot tell) and "search", the object that count_search, get_search_metrics, preview_search, estimate_list and create_list take: pass it on as is, or edited. Costs 100 credits (maxCredits ≥ 100), refunded when no selection comes back. A request too vague is refused with clarification_needed, refunded: ask the user the question in error.details, then call again with the answer. Paid: maxCredits (the most credits this call may spend, never exceeded) and idempotencyKey (a new UUID v4 for this operation) are required; without them nothing runs. To retry after an error or a timeout, send the same idempotencyKey with the same arguments: nothing is charged twice. Ask the user before calling it. Same call as POST /api/v1/categories/suggest of the REST API.
| Argument | Type | Description |
|---|---|---|
| area | any | Area to search, as returned by GET /areas (field "area"). Default: that of "search", else the whole country. |
| search | object | A search to refine: its area, filters, exclusions and groups are kept (the groups become the previous selection). The "search" object returned by suggest_categories (target, area, filters, sort), sent as is or edited; its full schema is the "search" input of count_search. An invalid search is refused with invalid_request and the fields to fix. |
| country | string | Country to search (default: that of "search", else fr). |
| request* | string | The target as the user would say it, WITHOUT the place: "independent car repair shops", "restaurants that could use a booking tool". What the client sells works too. |
| previous | any | The selection to update (default: the groups of "search"); null starts afresh. |
| maxCredits* | integer | Must be at least 100: the price of a suggestion. |
| idempotencyKey* | string | A new UUID v4 for this operation (sent as the Idempotency-Key of the API). Reuse it only to retry the very same call: the saved result comes back, nothing is charged twice. |
{
"type": "object",
"required": [
"request",
"maxCredits",
"idempotencyKey"
],
"properties": {
"area": {
"oneOf": [
{
"type": "object",
"required": [
"type"
],
"properties": {
"type": {
"type": "string",
"const": "country"
},
"withoutOverseas": {
"type": "boolean",
"const": true
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"type",
"codes"
],
"properties": {
"type": {
"type": "string",
"const": "region"
},
"codes": {
"type": "array",
"items": {
"type": "string",
"pattern": "^[A-Za-z0-9-]{1,40}$"
},
"maxItems": 20,
"minItems": 1
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"type",
"codes"
],
"properties": {
"type": {
"type": "string",
"const": "departement"
},
"codes": {
"type": "array",
"items": {
"type": "string",
"pattern": "^[A-Za-z0-9-]{1,40}$"
},
"maxItems": 110,
"minItems": 1
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"type",
"codes"
],
"properties": {
"type": {
"type": "string",
"const": "commune"
},
"codes": {
"type": "array",
"items": {
"type": "string",
"pattern": "^[A-Za-z0-9-]{1,40}$"
},
"maxItems": 1000,
"minItems": 1
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"type",
"codes"
],
"properties": {
"type": {
"type": "string",
"const": "postal"
},
"codes": {
"type": "array",
"items": {
"type": "string",
"pattern": "^[A-Za-z0-9 -]{2,10}$"
},
"maxItems": 1000,
"minItems": 1
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"type",
"lat",
"lng",
"km"
],
"properties": {
"km": {
"type": "number",
"maximum": 500,
"minimum": 0.1
},
"lat": {
"type": "number",
"maximum": 90,
"minimum": -90
},
"lng": {
"type": "number",
"maximum": 180,
"minimum": -180
},
"type": {
"type": "string",
"const": "radius"
}
},
"additionalProperties": false
}
],
"description": "Area to search, as returned by GET /areas (field \"area\"). Default: that of \"search\", else the whole country."
},
"search": {
"type": "object",
"description": "A search to refine: its area, filters, exclusions and groups are kept (the groups become the previous selection). The \"search\" object returned by suggest_categories (target, area, filters, sort), sent as is or edited; its full schema is the \"search\" input of count_search. An invalid search is refused with invalid_request and the fields to fix."
},
"country": {
"enum": [
"af",
"za",
"al",
"dz",
"de",
"ad",
"ao",
"ai",
"ag",
"sa",
"ar",
"am",
"aw",
"au",
"at",
"az",
"bs",
"bh",
"bd",
"bb",
"be",
"bz",
"bj",
"bm",
"bt",
"bo",
"ba",
"bw",
"br",
"bn",
"bg",
"bf",
"bi",
"kh",
"cm",
"ca",
"cv",
"cl",
"cn",
"cy",
"co",
"km",
"cg",
"cd",
"kr",
"cr",
"ci",
"hr",
"cw",
"dk",
"dj",
"dm",
"eg",
"ae",
"ec",
"er",
"es",
"ee",
"sz",
"va",
"us",
"et",
"fj",
"fi",
"fr",
"ga",
"gm",
"ge",
"gh",
"gi",
"gr",
"gd",
"gl",
"gu",
"gt",
"gg",
"gn",
"gq",
"gw",
"gy",
"ht",
"hn",
"hu",
"cx",
"im",
"nf",
"ax",
"ky",
"cc",
"ck",
"fo",
"fk",
"mp",
"mh",
"pn",
"sb",
"tc",
"vg",
"vi",
"in",
"id",
"iq",
"ie",
"is",
"il",
"it",
"jm",
"jp",
"je",
"jo",
"kz",
"ke",
"kg",
"ki",
"xk",
"kw",
"la",
"ls",
"lv",
"lb",
"lr",
"ly",
"li",
"lt",
"lu",
"mk",
"mg",
"my",
"mw",
"mv",
"ml",
"mt",
"ma",
"mu",
"mr",
"mx",
"fm",
"md",
"mc",
"mn",
"me",
"ms",
"mz",
"mm",
"na",
"nr",
"np",
"ni",
"ne",
"ng",
"nu",
"no",
"nz",
"om",
"ug",
"uz",
"pk",
"pw",
"pa",
"pg",
"py",
"nl",
"bq",
"pe",
"ph",
"pl",
"pr",
"pt",
"qa",
"hk",
"mo",
"cf",
"do",
"ro",
"gb",
"rw",
"kn",
"sm",
"sx",
"vc",
"sh",
"lc",
"sv",
"ws",
"as",
"st",
"sn",
"rs",
"sc",
"sl",
"sg",
"sk",
"si",
"so",
"sd",
"ss",
"lk",
"se",
"ch",
"sr",
"sj",
"tj",
"tw",
"tz",
"td",
"cz",
"io",
"ps",
"th",
"tl",
"tg",
"tk",
"to",
"tt",
"tn",
"tm",
"tr",
"tv",
"ua",
"uy",
"vu",
"ve",
"vn",
"ye",
"zm",
"zw"
],
"type": "string",
"description": "Country to search (default: that of \"search\", else fr)."
},
"request": {
"type": "string",
"maxLength": 600,
"minLength": 2,
"description": "The target as the user would say it, WITHOUT the place: \"independent car repair shops\", \"restaurants that could use a booking tool\". What the client sells works too."
},
"previous": {
"anyOf": [
{
"type": "object",
"required": [
"groups"
],
"properties": {
"groups": {
"type": "array",
"items": {
"type": "object",
"required": [
"label",
"ids"
],
"properties": {
"ids": {
"type": "array",
"items": {
"type": "integer",
"exclusiveMinimum": 0
},
"maxItems": 600,
"minItems": 1
},
"label": {
"type": "string",
"maxLength": 60,
"minLength": 1
},
"prudence": {
"type": "boolean",
"const": true,
"description": "True when the engine added this group by prudence (a neighbouring activity, not the core of the request): a list delivers the core of the request first."
}
},
"additionalProperties": false
},
"maxItems": 8
}
},
"additionalProperties": false
},
{
"type": "null"
}
],
"description": "The selection to update (default: the groups of \"search\"); null starts afresh."
},
"maxCredits": {
"type": "integer",
"minimum": 100,
"description": "Must be at least 100: the price of a suggestion."
},
"idempotencyKey": {
"type": "string",
"format": "uuid",
"description": "A new UUID v4 for this operation (sent as the Idempotency-Key of the API). Reuse it only to retry the very same call: the saved result comes back, nothing is charged twice."
}
},
"additionalProperties": false
}Verify the email addresses of a ready list (deliverable, risky, undeliverable): 1 credit per address that gets a verdict; the credits of the others are returned. maxCredits is the number of addresses you accept to verify: send progress.emailCheck.unverified of get_list. Paid: maxCredits (the most credits this call may spend, never exceeded) and idempotencyKey (a new UUID v4 for this operation) are required; without them nothing runs. To retry after an error or a timeout, send the same idempotencyKey with the same arguments: nothing is charged twice. Ask the user before calling it. Same call as POST /api/v1/lists/{id}/email-check of the REST API.
| Argument | Type | Description |
|---|---|---|
| listId* | string | Id of a list of the account (from create_list or list_lists). |
| maxCredits* | integer | The most credits this call may spend (required on every paid call, with an Idempotency-Key header). Never exceeded. |
| idempotencyKey* | string | A new UUID v4 for this operation (sent as the Idempotency-Key of the API). Reuse it only to retry the very same call: the saved result comes back, nothing is charged twice. |
{
"type": "object",
"required": [
"listId",
"maxCredits",
"idempotencyKey"
],
"properties": {
"listId": {
"type": "string",
"format": "uuid",
"description": "Id of a list of the account (from create_list or list_lists)."
},
"maxCredits": {
"type": "integer",
"maximum": 1000000000,
"minimum": 0,
"description": "The most credits this call may spend (required on every paid call, with an Idempotency-Key header). Never exceeded."
},
"idempotencyKey": {
"type": "string",
"format": "uuid",
"description": "A new UUID v4 for this operation (sent as the Idempotency-Key of the API). Reuse it only to retry the very same call: the saved result comes back, nothing is charged twice."
}
},
"additionalProperties": false
}We read every tool's name, description and inputs the way the model will, looking for instructions hidden from you. A clean result means no warning signs, not a guarantee. Scanned Nov 12, 2026.