# NexaCloser developer documentation (full text) Source: https://docs.nexacloser.com · OpenAPI: https://docs.nexacloser.com/openapi.yaml --- # NexaCloser developer docs URL: https://docs.nexacloser.com/ ## What you can build Create or update a CRM contact from any server with one `POST`, with tags, custom fields, attribution and consent records. [Read the guide](/guides/contacts/). Connect Claude, Cursor or any MCP client to your workspace. tools across the CRM, messaging, calendar, automations and ad platforms. [Connect a client](/mcp/connect/). Register attendees from your own landing page and get each one's personal watch link. [Read the guide](/guides/webinar-registrants/). Receive data on a webhook URL to start automations, and call any HTTPS endpoint from an automation step. [Inbound](/guides/inbound-webhooks/) · [Outgoing](/guides/outgoing-webhooks/) ## Start here ## Machine-readable - OpenAPI 3.1 file: [`/openapi.yaml`](/openapi.yaml) · [`/openapi.json`](/openapi.json). Import it into Postman, Insomnia, code generators or AI tools. - [`/llms.txt`](/llms.txt): an index of these docs for AI tools, and [`/llms-full.txt`](/llms-full.txt) with every page in one file. --- # Quickstart URL: https://docs.nexacloser.com/getting-started/ This walks you from nothing to a contact in your CRM. It takes about five minutes. ## 1. Create a key 1. Sign in at [app.nexacloser.com](https://app.nexacloser.com) and open **Settings → API**. 2. Under **Organization API keys**, click **New key**. 3. Name it after the thing that will use it, for example `Website contact form`. 4. Pick **Organization key** (it keeps working when people leave your team) and the access level **Contacts: create & update only**. To try things out first, tick **Test key**: it checks every request but writes nothing. 5. Click **Create key** and copy the key. It is shown **once**. Only owners, admins and managers can create organization keys. Anyone on the team can create a personal key. See [API keys](/authentication/) for the differences. :::caution[Keep the key on your server] A key is a password for your workspace. Put it in an environment variable on your server. Never put it in browser JavaScript, a mobile app, a public repository, a URL or a chat message. ::: ## 2. Send a request ```bash curl -X POST https://api.nexacloser.com/v1/contacts \ -H "Authorization: Bearer $NEXACLOSER_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "email": "dana@example.com", "full_name": "Dana Levi", "source": "Website contact form", "tags": ["website"] }' ``` With a **test key** the answer is `200` and nothing is saved: ```json { "test": true, "valid": true, "would": "create_or_update", "normalized": { "email": "dana@example.com", "phone": null, "full_name": "Dana Levi", "source": "Website contact form", "tags": ["website"], "custom_fields": {}, "preferred_language": null, "attribution": {}, "consent": null }, "warnings": [] } ``` With a **live key** a new contact answers `201`: ```json { "id": "cnt_8hT2kQx91L", "created": true, "matched_by": null, "consent": [], "warnings": [] } ``` Send the same email again and you get `200` with `"created": false` and `"matched_by": "email"`: the existing contact was updated, not duplicated. ## 3. Check it in the app Open **Contacts** in NexaCloser. The contact is there, with source **API**, the tag `website` and `Website contact form` as its source channel. Any automation that starts on *contact created* has already run. ## Next - [Contacts API](/guides/contacts/): every field, consent and matching rules. - [Website form to CRM](/guides/website-form/): a complete server route for a contact form. - [Connect an AI client over MCP](/mcp/connect/). - [API reference](/api/) or the interactive [Swagger UI](/swagger/). --- # Conventions URL: https://docs.nexacloser.com/conventions/ ## Base URLs | What | URL | |---|---| | REST API | `https://api.nexacloser.com/v1` | | Inbound webhooks | `https://hook.nexacloser.com/` | | MCP server | `https://api.nexacloser.com/mcp` | | OAuth for MCP clients | `https://api.nexacloser.com/oauth/…` (discovered automatically) | Only HTTPS. Every REST path in these docs is relative to `https://api.nexacloser.com/v1`, so `POST /contacts` means `POST https://api.nexacloser.com/v1/contacts`. ## Requests - Send `Content-Type: application/json` and a JSON object body. Inbound webhooks also accept form fields. - Authenticate with `Authorization: Bearer `. See [API keys](/authentication/). - Call the API **from your server**. Keys are secrets, so the API does not answer browser requests from other sites (the [Swagger UI](/swagger/) on this site is the one exception). ## Ids Every object has a short id with a type prefix, for example: | Prefix | Object | |---|---| | `org_` | Workspace (organization) | | `cnt_` | Contact | | `dl_` | Deal | | `wbn_` | Webinar | | `wbr_` | Webinar registration | | `whk_` | Inbound webhook | | `whx_` | Inbound webhook execution | Treat ids as opaque strings. Do not parse them. ## Phone numbers Send phone numbers in E.164 form, for example `+14155550101` or `+972501234567`. A number without a country code is read with your workspace's country. NexaCloser stores the normalized number, and contacts are matched on it. ## Times Times are ISO 8601 strings in UTC, for example `2026-11-05T14:03:11Z`. A time you send with an offset (`+02:00`) is accepted. ## Responses and errors - Success responses are JSON. The status code says what happened: `200` done, `201` created. - Errors are JSON with an `error` field. Newer endpoints (contacts, webinar registrations) use stable lowercase codes such as `invalid_json` or `validation_failed`; a few older endpoints send a short English message such as `Unauthorized`. See [Errors](/reference/errors/). - Rate limit headers come with every authenticated response. See [Rate limits](/reference/rate-limits/). ## Versioning The API is versioned in the path (`/v1`). Fields may be **added** to responses and new optional request fields may appear at any time, so ignore fields you do not know. Breaking changes go to a new version and are announced in the [changelog](/changelog/). --- # API keys URL: https://docs.nexacloser.com/authentication/ Every REST call and every MCP call made with a key sends it in the `Authorization` header: ```http Authorization: Bearer nxa_3f9c… ``` Keys are created in the app under **Settings → API → Organization API keys**. ## Key types A key always belongs to **one workspace** (organization) and only ever acts on that workspace. It does not follow anyone's account switcher. | | Organization key | Personal key | |---|---|---| | Belongs to | The workspace | One team member, in one workspace | | Acts as | The workspace owner | That team member, with their permissions | | Who can create it | Owners, admins and managers | Any active team member | | Stops working when | It is revoked or rotated | It is revoked or rotated, or the member leaves the workspace | | Use it for | Integrations that run on their own: a website, a report, a backend job | A person's own tools, scripts or AI client | Use an **organization key** for anything unattended. A personal key dies with the person's seat, which is right for a person's tools and wrong for your website. ### Old personal keys A key made before 24 September 2026 shows on the same page as **Old personal API key** (`nxa_` + 32 characters). It acts on whichever workspace its owner has open at that moment, so switching accounts changes what connected tools see. It keeps working with full access, but replace it with an organization key. ## Access levels When you create a key you also choose what it may do: - **Full access**: every endpoint and every MCP tool, as the user the key acts as. - **Contacts: create & update only**: only `POST /v1/contacts`. Every other endpoint and the MCP server refuse it. You can also make a **test key** for the contacts endpoint. It validates every request and writes nothing. See [Access levels and test keys](/authentication/access-levels/). ## Shown once The full key is shown **only once**, right after you create or rotate it. NexaCloser stores only a hash, so nobody can show it again, not even support. After that the app shows the key's name, type, last four characters and when it was last used (updated at most once a minute). Lost a key? Rotate it. ## Rotate a key **Rotate** replaces the key with a new one that keeps the same name, type and access level. The old key stops working **immediately**, so update the systems that use it right after. - Organization keys: owners, admins and managers can rotate them. - Personal keys: only their owner can rotate them, because the new key acts as that person. ## Revoke a key **Revoke** turns the key off for good. Anything using it fails from the next request on. This cannot be undone. - Organization keys: owners, admins and managers. - Personal keys: their owner, or an owner, admin or manager of the workspace. Keys do not expire by themselves. Rotate them on your own schedule, and whenever someone who had a copy leaves. ## Keep keys safe - Store keys in environment variables or a secret manager, never in code or a repository. - One key per integration, named after it, so you can rotate or revoke one without touching the rest. - Give each integration the smallest access level that works: a website form needs **Contacts: create & update only**, not full access. - Never put a key in a URL. URLs end up in logs and browser history. ## Other credentials | Credential | Looks like | Used for | |---|---|---| | API key | `nxa_…` (test keys `nxa_test_…`) | REST API and MCP | | MCP server token | `mcps_…` | MCP clients without OAuth. See [MCP auth](/mcp/auth/) | | MCP OAuth token | `mcp_at_…` | Issued to MCP clients by the OAuth flow, 1 hour, refreshed by the client | | Webhook token | any secret | The `X-Webhook-Token` header of an [inbound webhook](/guides/inbound-webhooks/) | --- # Access levels and test keys URL: https://docs.nexacloser.com/authentication/access-levels/ New in November 2026. Pick the access level when you create the key in **Settings → API → New key**. ## Full access The default, and what every key created before November 2026 has. - Works on every REST endpoint and on the [MCP server](/mcp/). - Acts as the key's user: an organization key acts as the workspace owner, a personal key as its member, with that member's [permissions](/roles/). ## Contacts: create & update only For a website, a form tool or a partner system that only needs to send you leads. - Works on **one** endpoint: [`POST /v1/contacts`](/guides/contacts/). - Every other endpoint answers `401 unauthorized`, and the MCP server refuses it. - It can **write but not read**. The contacts endpoint returns the contact id and what happened, never the data of an existing contact. A leaked key can add or update contacts, but cannot list or export your CRM. ## Test keys A test key starts with `nxa_test_` and is always a *Contacts: create & update only* key. - `POST /v1/contacts` runs every check a live key runs and returns the same `422` errors. - It **writes nothing**: no contact, no tag, no consent record, no automation run. - It **reads no contact**, so it cannot tell you whether a contact already exists. (It does read your workspace's country and custom field list, to validate like a live key.) A valid request always gets `200` with `"test": true` and `"would": "create_or_update"`: ```json { "test": true, "valid": true, "would": "create_or_update", "normalized": { "email": "dana@example.com", "phone": "+14155550101", "full_name": "Dana Levi", "source": "Website contact form", "tags": ["website"], "custom_fields": { "visit_type": "first_visit" }, "preferred_language": null, "attribution": {}, "consent": null }, "warnings": ["unknown_custom_field:visit_type"] } ``` Use one while you build and test the integration, then swap in a live key. ## Which key for what | Integration | Key | |---|---| | Website contact or booking form | Organization key, **Contacts: create & update only** | | A partner or agency sending you leads | Organization key, **Contacts: create & update only**, one per partner | | Building or testing a form integration | **Test key** | | Landing page registering webinar attendees | Organization key, **Full access** | | A report or dashboard that reads data | Organization key, **Full access** | | Your own AI client | An [MCP server](/mcp/auth/) with OAuth, not an API key | --- # Contacts API URL: https://docs.nexacloser.com/guides/contacts/ `POST https://api.nexacloser.com/v1/contacts` creates a CRM contact, or updates the one that already exists. One call, no lookup first. Full schema: [API reference](/api/operations/upsertcontact/). ## Who can call it A key with **Full access** or **Contacts: create & update only**, sent as `Authorization: Bearer nxa_…`. Call it from your server. See [Access levels](/authentication/access-levels/). ## Request ```bash curl -X POST https://api.nexacloser.com/v1/contacts \ -H "Authorization: Bearer $NEXACLOSER_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "email": "dana@example.com", "phone": "+14155550101", "first_name": "Dana", "last_name": "Levi", "source": "Website contact form", "tags": ["website", "consult-request"], "custom_fields": { "visit_type": "first_visit", "contact_time": "morning" }, "attribution": { "utm_source": "google", "utm_medium": "cpc", "landing_url": "https://www.example.com/contact" }, "consent": { "granted": true, "channels": ["email", "sms"], "text": "I agree to receive emails and text messages from Example Clinic. Reply STOP to opt out.", "version": "2026-11-01", "at": "2026-11-05T14:03:11Z", "ip": "203.0.113.24", "page_url": "https://www.example.com/contact" } }' ``` ### Fields | Field | Type | Notes | |---|---|---| | `email` | string | At least one of `email` and `phone` is required. Stored lowercase. | | `phone` | string | E.164 is best (`+14155550101`). Without a country code, your workspace's country is assumed. Must come out as 9 to 15 digits. | | `full_name` | string | Or send `first_name` and `last_name`. | | `first_name`, `last_name` | string | | | `source` | string, up to 100 | A label for where the contact came from, e.g. `Website contact form`. Saved as the contact's **source channel**, only when the contact is **created**; an existing contact keeps its own. | | `tags` | string[], up to 20, each up to 50 | **Added** to the contact's tags. Never removes a tag. | | `custom_fields` | object, up to 50 keys | `field_key` → string, number, boolean or `null`. Keys match `^[a-z0-9_]{1,64}$`. Merged into existing values. | | `preferred_language` | `he`, `en` or `ru` | Language for messages to this contact. Omit to use the workspace default. | | `attribution` | object | Click and campaign data for this visit. See [Attribution](#attribution). | | `consent` | object | What the person agreed to. See [Consent](#consent). | The body may be up to 64 KB. A field the endpoint does not know is ignored and listed in `warnings` as `unknown_field:`, so a typo never fails silently. Every contact created through the API gets the CRM source **API**. Your `source` label shows as its source channel, so you can tell your website from a partner. ### Attribution Send what you know about the visit that produced the lead. The first touch is kept forever; the last touch is updated on every call. Values are trimmed and may be up to 2,048 characters. Accepted keys: `source_channel`, `utm_source`, `utm_medium`, `utm_campaign`, `utm_content`, `utm_term`, `utm_keyword`, `utm_matchtype`, `campaign_id`, `campaign_name`, `adset_id`, `adset_name`, `ad_id`, `ad_name`, `gclid`, `wbraid`, `gbraid`, `fbclid`, `fbc`, `fbp`, `ctwa_clid`, `msclkid`, `ttclid`, `referrer`, `landing_url`. Any other key is ignored and listed in `warnings` as `unknown_attribution_key:`. ### Custom fields Use the **Key** of a custom field, the English key you set when you created the field in the CRM, for example `visit_type`. A key with no field defined in your workspace is still saved on the contact, and the response lists it in `warnings` as `unknown_custom_field:visit_type`, so you can spot typos. Create the field in the app to see it on the contact card. ## What happens NexaCloser looks inside your workspace, among contacts that are not deleted: 1. **Same phone number?** That contact is updated. 2. Else **same email?** That contact is updated. 3. Else a new contact is **created**. On an update, values you send overwrite, empty values keep what is there, tags are added and custom fields are merged. The source channel and the first-touch attribution never change. If your workspace turned on **allow duplicate contacts**, every call creates a new contact. Automations run as if the contact came in any other way: a new contact fires your *contact created* automations, and tags it did not have before fire *tag added* automations. ## Response `201` when a contact was created, `200` when one was updated: ```json { "id": "cnt_8hT2kQx91L", "created": false, "matched_by": "email", "consent": [ { "channel": "email", "status": "granted" }, { "channel": "sms", "status": "withdrawn", "skipped": true } ], "warnings": [] } ``` | Field | Meaning | |---|---| | `id` | The contact id. Store it if you want to link back to the contact. | | `created` | `true` = new contact. `false` = an existing one was updated. | | `matched_by` | `phone`, `email`, or `null` when created. | | `consent` | One entry per channel when you sent `consent` with `granted: true`; empty otherwise. | | `warnings` | Notes that did not stop the request. | The response never contains other data of the contact, so a *Contacts: create & update only* key cannot be used to read your CRM. ## Consent Send `consent` when the person ticked an opt-in box on your form. NexaCloser keeps it as proof. | Field | Notes | |---|---| | `granted` | **Required**, boolean. `true` = they opted in. `false` = **nothing is recorded**. | | `channels` | `email`, `sms`, `whatsapp`. Default: `email` if you sent an email, `sms` and `whatsapp` if you sent a phone. | | `purpose` | `marketing` (default), `transactional`, `service_updates` or `surveys`. | | `text` | The exact wording the person saw. **Required** when `granted` is `true`. Up to 2,000 characters. | | `version` | Your label for that wording, up to 50 characters, e.g. `2026-11-01`. Change it whenever the wording changes. | | `language` | `he`, `en` or `ru`: the language of the wording. Default: the contact's `preferred_language`, else `en`. | | `at` | When they agreed, ISO 8601. Default: the time of the request. At most 5 minutes in the future. | | `ip` | The person's IP address (IPv4 or IPv6), not your server's. | | `user_agent` | The person's browser. | | `page_url` | The page with the form. | For each channel NexaCloser stores the consent, and adds an append-only audit record with the wording, version, time, page and the name of the key that sent it. Marketing sends check the stored consent before they go out. **An unticked box is not an opt-out.** `granted: false` stores nothing and changes nothing. Opting out is the person's own action: an unsubscribe link, replying STOP, or a change in the CRM. **An opt-out always wins.** If the person opted out of a channel earlier, a new `granted: true` from the API does not turn it back on. That channel comes back as `{ "channel": "sms", "status": "withdrawn", "skipped": true }`. The person has to opt in again themselves. If one channel cannot be stored it comes back as `{ "channel": "whatsapp", "status": "error" }`. The contact itself is still saved; send the request again to retry the consent. ## Test keys With a test key (`nxa_test_…`) the same request is fully validated, nothing is written and no contact is read. (It does read your workspace's country and custom field list, to validate the way a live key would.) Valid requests get `200` with what a live key would store: ```json { "test": true, "valid": true, "would": "create_or_update", "normalized": { "email": "dana@example.com", "phone": "14155550101", "full_name": "Dana Levi", "source": "Website contact form", "tags": ["website", "consult-request"], "custom_fields": { "visit_type": "first_visit", "contact_time": "morning" }, "preferred_language": null, "attribution": { "utm_source": "google", "utm_medium": "cpc", "landing_url": "https://www.example.com/contact" }, "consent": { "granted": true, "channels": ["email", "sms"], "purpose": "marketing", "text": "I agree to receive emails and text messages from Example Clinic. Reply STOP to opt out.", "version": "2026-11-01", "at": "2026-11-05T14:03:11.000Z", "language": "en", "ip": "203.0.113.24", "user_agent": null, "page_url": "https://www.example.com/contact" } }, "warnings": ["unknown_custom_field:visit_type", "unknown_custom_field:contact_time"] } ``` This is a real response to the request at the top of this page, from a workspace that has not created the `visit_type` and `contact_time` fields yet. `phone` comes back as digits with the country code, the way it will be stored. ## Errors | Status | `error` | What to do | |---|---|---| | `400` | `invalid_json` | The body is not valid JSON. | | `401` | `unauthorized` | Missing, wrong, revoked or rotated key, or the key's workspace cannot be found. | | `403` | `forbidden` | The key's access level does not include this endpoint. | | `405` | `method_not_allowed` | Use `POST`. | | `413` | `payload_too_large` | Keep the body under 64 KB. | | `422` | `validation_failed` | Fix the fields listed in `details`. Do not retry unchanged. | | `429` | `rate_limited` | Wait `Retry-After` seconds. | | `500` | `internal` | Retry with backoff. Repeating the call updates the same contact instead of adding one (unless your workspace allows duplicate contacts). | A `422` lists every problem at once: ```json { "error": "validation_failed", "details": [ { "field": "email", "code": "invalid_email" }, { "field": "custom_fields.visit_type", "code": "invalid_custom_field_value" }, { "field": "consent.text", "code": "consent_text_required" } ] } ``` | `code` | Meaning | |---|---| | `invalid_body` | The body is JSON but not an object (for example an array). | | `invalid_type` | A field has the wrong JSON type (for example a number where a string belongs). | | `email_or_phone_required` | Send at least one of them. | | `invalid_email` | Not a valid email address. | | `invalid_phone` | Not a phone number of 9 to 15 digits once read with your workspace's country. | | `invalid_language` | `preferred_language` or `consent.language` is not `he`, `en` or `ru`. | | `too_many_tags` | More than 20 tags. | | `invalid_tag` | A tag is not a non-empty string of up to 50 characters. | | `too_many_custom_fields` | More than 50 custom fields. | | `invalid_custom_field_key` | A key does not match `^[a-z0-9_]{1,64}$`. | | `invalid_custom_field_value` | A value is an object or an array. | | `consent_granted_required` | `consent` was sent without a boolean `granted`. | | `consent_text_required` | `consent.granted` is `true` but `consent.text` is missing. | | `invalid_consent_channel` | A channel other than `email`, `sms`, `whatsapp`. | | `invalid_consent_purpose` | A purpose other than the four listed. | | `invalid_consent_time` | `consent.at` is not an ISO 8601 time, or is more than 5 minutes in the future. | | `invalid_consent_ip` | `consent.ip` is not an IPv4 or IPv6 address. | | `field_too_long` | A text field is over its limit. | ## Limits 100 requests per 10 seconds and 200,000 per day, per key. See [Rate limits](/reference/rate-limits/). --- # Website form to CRM URL: https://docs.nexacloser.com/guides/website-form/ The browser posts the form to **your** server. Your server adds the key and calls NexaCloser. The key never reaches the browser. ```text Browser form ──POST──▶ your server route ──POST /v1/contacts──▶ NexaCloser (holds the key) ``` ## 1. Make a key In **Settings → API → New key**: an **Organization key** with access **Contacts: create & update only**. Make a **test key** too, for development. See [Access levels](/authentication/access-levels/). ## 2. Store it as an environment variable | Variable | Value | |---|---| | `NEXACLOSER_API_KEY` | The key (`nxa_…` live, `nxa_test_…` while testing) | | `NEXACLOSER_API_BASE_URL` | `https://api.nexacloser.com/v1` | Set them in your host's environment settings. Never commit them, never print them in logs. ## 3. The server route A Node.js example (Express style; the same logic works in any framework or language): ```js // POST /api/contact — called by the website form. Runs on the server only. const BASE = process.env.NEXACLOSER_API_BASE_URL || 'https://api.nexacloser.com/v1' const KEY = process.env.NEXACLOSER_API_KEY // The consent wording shown next to the checkbox, and its version. const CONSENT_TEXT = 'I agree to receive emails and text messages from Example Clinic. Reply STOP to opt out.' const CONSENT_VERSION = '2026-11-01' export async function contactRoute(req, res) { const f = req.body || {} if (!f.email && !f.phone) return res.status(400).json({ ok: false }) const body = { email: f.email || undefined, phone: f.phone || undefined, full_name: f.name || undefined, source: 'Website contact form', tags: ['website'], custom_fields: { visit_type: f.visit_type, contact_time: f.contact_time }, attribution: { utm_source: f.utm_source, utm_medium: f.utm_medium, utm_campaign: f.utm_campaign, landing_url: f.page_url, referrer: f.referrer, }, consent: { granted: f.marketing_opt_in === true, text: CONSENT_TEXT, version: CONSENT_VERSION, at: new Date().toISOString(), ip: req.ip, // the visitor's IP (behind a proxy: app.set('trust proxy', 1)) user_agent: req.get('user-agent'), page_url: f.page_url, }, } const r = await fetch(`${BASE}/contacts`, { method: 'POST', headers: { Authorization: `Bearer ${KEY}`, 'Content-Type': 'application/json' }, body: JSON.stringify(body), signal: AbortSignal.timeout(10_000), }) if (r.status === 201 || r.status === 200) return res.json({ ok: true }) if (r.status === 422) { const err = await r.json() console.warn('NexaCloser rejected the form', err.details) // field names and codes only return res.status(422).json({ ok: false }) } // 429 / 5xx: keep the lead and retry later (a queue or a cron), never drop it. console.error('NexaCloser unavailable', r.status) return res.status(502).json({ ok: false }) } ``` Notes: - `JSON.stringify` drops `undefined` values, so empty form fields are simply not sent. - `consent.granted` is `true` only when the visitor actually ticked the box. `false` records nothing, which is right: an unticked box is not an opt-out. Leave `consent` out if the form has no opt-in at all. - Do not log the request body: it holds personal data. - Use a test key until the form works end to end, then switch the variable to the live key. ## 4. Check it 1. With the **test key**, submit the form. Your route gets `200` with `"test": true`; fix any `422` it reports. 2. With the **live key**, submit it once with your own details. The contact appears under **Contacts** with tag `website`, source channel `Website contact form`, its custom fields and the consent record. 3. Submit again with the same email: the same contact is updated, not duplicated. --- # Webinar registrations URL: https://docs.nexacloser.com/guides/webinar-registrants/ `POST https://api.nexacloser.com/v1/webinar-registrants` registers people for one of your webinars as if they had used the hosted registration form: the contact is created or updated in the CRM, the attendee gets a session and a personal watch link, and the webinar's automations and reminders run. Full schema: [API reference](/api/operations/registerwebinarattendees/). Use a **Full access** organization key. ## Request ```bash curl -X POST https://api.nexacloser.com/v1/webinar-registrants \ -H "Authorization: Bearer $NEXACLOSER_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "webinar_id": "wbn_6RLC77yktP", "registrants": [ { "first_name": "Dana", "last_name": "Levi", "email": "dana@example.com", "phone": "+972501234567", "page_url": "https://www.example.com/webinar?utm_source=facebook", "consent": { "granted": true, "text_shown": "I agree to get webinar reminders by WhatsApp and SMS.", "source": "landing_page" } }, { "first_name": "Avi", "email": "avi@example.com" } ] }' ``` - Pick the webinar with `webinar_id` or `slug`. It must be active and belong to the key's workspace. - `registrants` is one object or an array of up to **100**. Bigger lists: loop on your side. - Every registrant needs an `email` or a `phone`. - **A registrant with a phone must carry `consent.granted: true`**, because reminders go out by WhatsApp and SMS. Without it that registrant is refused with `consent_required`; the others in the batch still go through. Email-only registrants need no consent object. - Also accepted: `full_name`, `phone_country_code`, `phone_national`, `country`, `url_parameters`, `custom_fields`, `utm_source`, `utm_medium`, `utm_campaign`, `utm_content`, `utm_term`, `referrer`, `locale`, `timezone`. If the webinar has a registration form, its rules apply too. ## Response The call answers `200` once the batch is processed. Each registrant succeeds or fails on its own: ```json { "results": [ { "index": 0, "ok": true, "registration_id": "wbr_5D2AkHpKwL", "personal_link_url": "https://app.nexacloser.com/j/wbr_5D2AkHpKwL.6b146474.59934ce894cb", "duplicate": false }, { "index": 1, "ok": false, "error": "consent_required" } ], "created": 1, "duplicates": 0, "failed": 1 } ``` - `index` is the registrant's position in your array. - `personal_link_url` is that attendee's own link to the webinar room. Send it to them if you send your own confirmation. - Registering the same person for the same session again succeeds with `"duplicate": true` and the **same** registration and link. Retrying a batch is safe. ### Errors for one registrant | `error` | Meaning | |---|---| | `consent_required` | The registrant has a phone and no `consent.granted: true`. | | `invalid_registrant` | The item is not an object. | | `email_or_phone_required` | Neither an email nor a phone. | | `valid email required` | The webinar's form asks for an email and this one is missing or invalid. | | `validation_failed` | The webinar's form rules rejected the answers. | | `webinar_full` | No seat left in the session. | | `internal` | Failed on our side. Retry that registrant. | ### Errors for the whole call | Status | `error` | |---|---| | `400` | `invalid_json`, `no_registrants`, `batch_too_large`, `webinar_required` | | `401` | `unauthorized` | | `403` | `forbidden`: the webinar belongs to another workspace | | `404` | `webinar_not_found`: no active webinar with that id or slug | | `405` | `method_not_allowed` | | `429` | `rate_limited` | ## Limits 600 registrants per minute and 100,000 per day, per key. A batch of 50 counts as 50. --- # Website analytics URL: https://docs.nexacloser.com/guides/website-analytics/ Websites with the NexaCloser tracking script report visitors to your workspace. One endpoint reads them back, picked by the `action` query parameter. Use a **Full access** key. Full schema: [API reference](/api/operations/websiteanalytics/). ## List your sites ```bash curl "https://api.nexacloser.com/v1/api-v1?action=get_sites" \ -H "Authorization: Bearer $NEXACLOSER_API_KEY" ``` ```json { "sites": [{ "site_id": "a1b2c3d4", "name": "Main website", "domain": "www.example.com" }], "user_id": "0e985456-cd0a-4417-acb0-6faffd37b88e" } ``` ## Read one site's numbers ```bash curl "https://api.nexacloser.com/v1/api-v1?action=get_analytics&site_id=a1b2c3d4&days=30" \ -H "Authorization: Bearer $NEXACLOSER_API_KEY" ``` ```json { "visitors": 12, "pageviews": 14, "sessions": 16, "conversion_rate": null, "top_page": { "url": "https://www.example.com/pricing", "views": 6 } } ``` - `days` is the window, 1 to 90 (default 1). - `conversion_rate` is form submits divided by form starts, in percent, or `null` when nobody started a form. ## Errors This is an older endpoint, so its errors are short English messages: | Status | `error` | |---|---| | `400` | `Missing site_id`, or `Unknown action` (the body lists the actions) | | `401` | `Unauthorized` | | `404` | `Site not found`: not a site of this workspace | | `429` | `rate_limited` | Requests count against your workspace's API limit: 100 per 10 seconds, 200,000 per day. --- # Inbound webhooks URL: https://docs.nexacloser.com/guides/inbound-webhooks/ An inbound webhook is a URL that accepts data from anything that can send an HTTP `POST`: Elementor, Wix, Make, Zapier, a lead form, your own code. Each request can start automations and, if you turn it on, create a contact and a lead. ## Create one 1. In the app, open **Automations → Webhooks** and click **New Webhook**. 2. Give it a name. Leave **Secret Token** empty and NexaCloser makes one for you. 3. Copy the **Webhook URL**. It looks like `https://hook.nexacloser.com/`. 4. In an automation, choose the **Webhook** trigger and pick this webhook. ## Send data ```bash curl -X POST https://hook.nexacloser.com/ \ -H "Content-Type: application/json" \ -H "X-Webhook-Token: " \ -d '{ "full_name": "Dana Levi", "email": "dana@example.com", "phone": "+972501234567", "form_name": "Contact us" }' ``` - Send the secret in the `X-Webhook-Token` header, never in the URL. - JSON, `application/x-www-form-urlencoded` and `multipart/form-data` bodies are read. Any other body is read as JSON if it is JSON, otherwise kept as one `raw` text field. - Bodies up to 1 MB. Answer: ```json { "success": true, "execution_id": "whx_8plFFIhUWR", "automations_triggered": 1 } ``` ## What happens - Every active automation with this webhook as its trigger starts, with your fields available as variables in its steps. - With **CRM Integration** turned on for the webhook (auto-create a lead each time), `phone`, `email` and `full_name` (or `name`), after the webhook's field mapping, become a CRM contact and a lead in the pipeline you chose. The contact is matched by phone, then email, like everywhere else. - Each request is stored on the webhook in the app, so you can see exactly what arrived. - **The same body sent twice within 2 minutes counts once.** The repeat answers with the first `execution_id` and `"deduped": true` and starts nothing, so senders that retry do not create doubles. ## Errors | Status | `error` | |---|---| | `400` | `Missing webhook slug` | | `401` | `Unauthorized — x-webhook-token header required`, or `Unauthorized` (wrong token) | | `404` | `Webhook not found`: no active webhook with this slug | | `413` | `payload_too_large` | | `429` | `rate_limited` | ## Limits Per webhook and sender IP: 100 requests per 10 seconds (200,000 per day) for a webhook with a secret token. A webhook without a secret is limited to 40 per minute and 5,000 per day, and anyone with its URL can post to it, so give every webhook a token. ## Webhooks or the Contacts API? Use an inbound webhook when a tool can only send a fixed payload (a form plugin, an ad platform) and you want an automation to decide what happens. Use the [Contacts API](/guides/contacts/) when you write the code: you get validation errors back, consent records and a contact id. --- # Outgoing webhooks URL: https://docs.nexacloser.com/guides/outgoing-webhooks/ To send data **out** of NexaCloser, add a **Custom Webhook** step to an automation. It sends an HTTP request to your URL whenever the automation reaches it, for example on every new lead or every won deal. ## Set it up 1. In an automation, add the **Custom Webhook** step. 2. Enter the URL, the method, the body (JSON, with `{{variables}}` from earlier steps) and any headers. Authorization can be a Bearer token or Basic auth. 3. Click **Test webhook**. Your endpoint must answer **HTTP 200 with a response body**. 4. Publish the automation. **The test is required.** A Custom Webhook step that has not passed a test, or whose URL, body or headers changed since its last passing test, does not run: the automation stops at that step with *Custom webhook must be tested successfully* or *re-test required*. Re-test after every change. ## What your endpoint gets - The method you chose (`POST` by default) with the JSON body you built, variables filled in. - The headers you set. ## Rules | Rule | Value | |---|---| | Scheme | **HTTPS only** | | Addresses | Public internet only. Private, local and internal addresses are refused, also after redirects or DNS changes. | | Redirects | Not followed | | Timeout | 15 seconds by default (5 to 30) | | Response size | Up to 1 MB; the first 1,000 characters are saved on the run | The step's result (`status_code` and the saved part of `response_body`) is available to later steps and is shown on the automation run. ## Make your endpoint reliable - Answer fast (under a few seconds) and do slow work after you answer. - Answer `200` with a short body such as `{"ok":true}`. - Check a secret header you configured on the step, so only NexaCloser can call your endpoint. --- # MCP server URL: https://docs.nexacloser.com/mcp/ NexaCloser runs a [Model Context Protocol](https://modelcontextprotocol.io) server. Connect an AI client to it and the client can look up contacts, move deals, book meetings, send WhatsApp messages, run automations and manage ad campaigns in your workspace, with your permissions. | | | |---|---| | Endpoint | `https://api.nexacloser.com/mcp` | | Transport | Streamable HTTP (JSON-RPC 2.0 over `POST`) | | Protocol version | `2025-06-18` | | Sign-in | OAuth 2.1 (automatic in most clients), an MCP server token, or an API key | | Tools | See the [tool reference](/mcp/tools/) | ## How it works 1. You create an **MCP server** in NexaCloser: a named, revocable identity for one AI client, for example *Claude Desktop* or *Cursor*. 2. You add `https://api.nexacloser.com/mcp` to the client. Clients that support OAuth open a NexaCloser sign-in page where you pick which MCP server to authorize. 3. The client lists the tools and calls them as you ask. Every call acts in your workspace. Step by step: [Connect an AI client](/mcp/connect/). ## What a client can see Tools act in **one workspace**: the one the MCP server or key belongs to. - **Contacts and deals** follow the same rules as the Contacts page in the app: deleted records are never shown, and a team member set to *Only see assigned records* sees only the contacts and deals assigned to them or created by them. Owners, admins and managers see the whole team. - **Automations, calendars, bookings, ad accounts and campaigns** are read across the workspace, teammates' included, and never across workspaces. - **Messages and ad changes** go out through the workspace's own connections (WhatsApp, SMS, Google, Meta, TikTok). A tool that needs a connection you have not set up answers with an error that says so. ## Read and write tools Every tool is either **read** (only looks at data) or **write** (changes data, sends a message or changes an ad account). The server marks read tools with `readOnlyHint: true` in `tools/list`, so clients can run them without asking you each time. A read-only MCP server (scope `mcp:read`) can call only read tools. Write tools that change ad accounts accept `dry_run: true` where shown in the [tool reference](/mcp/tools/), so the client can preview a change before making it. ## Errors A tool that fails still answers with HTTP `200` and a JSON-RPC result whose `isError` is `true`; the text says why (for example a missing connection, a tool the MCP server is not allowed to use, or a scope that is missing). A bad or missing credential answers HTTP `401` with JSON-RPC error `-32001 Unauthorized`. --- # Connect an AI client URL: https://docs.nexacloser.com/mcp/connect/ ## 1. Create an MCP server in NexaCloser 1. In the app, open **MCP servers** in the sidebar (also under **Settings → API → MCP Servers**). 2. Click **New MCP server** and name it after the client, for example `Claude Desktop`. 3. Tick **Read-only** if the client should only read data. It can then list and look up, but never send messages or change anything. Make one MCP server per client. You can revoke each one on its own, see when it was last used, and limit it to certain tools. ## 2. Add NexaCloser to your client ### Claude (claude.ai and Claude Desktop) 1. In Claude, open **Settings → Connectors** and add a **custom connector**. 2. Paste `https://api.nexacloser.com/mcp` as the URL and connect. 3. A NexaCloser page opens. Sign in, pick the MCP server you created and click **Authorize**. No key to copy: the connector signs in with OAuth and refreshes its own access. ### Claude Code ```bash claude mcp add --transport http nexacloser https://api.nexacloser.com/mcp ``` Then run `/mcp` inside Claude Code, pick **nexacloser** and sign in when the browser opens. ### Cursor Open the MCP server in NexaCloser, click **Create token** and copy the `mcps_…` token. Then add this to `~/.cursor/mcp.json` (or **Cursor Settings → MCP → Add new server**): ```json { "mcpServers": { "nexacloser": { "url": "https://api.nexacloser.com/mcp", "headers": { "Authorization": "Bearer mcps_YOUR_TOKEN" } } } } ``` If your Cursor version signs in to remote servers with OAuth, you can leave out `headers` and sign in the same way as in Claude. ### Make, n8n, scripts and other clients without OAuth Use the MCP server's **token** (`mcps_…`) as a Bearer token, exactly like the Cursor example. It carries the MCP server's read-only setting and tool limits. ### Clients that only run local (stdio) servers Bridge them with [`mcp-remote`](https://www.npmjs.com/package/mcp-remote): ```json { "mcpServers": { "nexacloser": { "command": "npx", "args": ["-y", "mcp-remote", "https://api.nexacloser.com/mcp", "--header", "Authorization: Bearer ${NEXACLOSER_MCP_TOKEN}"], "env": { "NEXACLOSER_MCP_TOKEN": "mcps_YOUR_TOKEN" } } } } ``` ## 3. Check it works Ask the client something only your CRM knows, for example *"How many contacts did we get this week?"*. Or call the server yourself: ```bash curl -s https://api.nexacloser.com/mcp \ -H "Authorization: Bearer $NEXACLOSER_MCP_TOKEN" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' ``` The answer lists every tool the token may use. ## Troubleshooting | Symptom | Cause and fix | |---|---| | The sign-in page says you have no MCP servers | Create one first (step 1), then connect again. | | `401` / `Unauthorized` | The token or key is wrong, rotated or revoked, or the MCP server was revoked. | | *Tool … requires scope mcp:write* | The MCP server is read-only. Make a read + write one for this client. | | *Tool … is not in this MCP server's allowed tools* | The MCP server has **Restrict Tools** on. Allow the tool on its page. | | *requires the … connection* | The MCP server's connection limits, or the workspace has not connected that service (Google, Meta, TikTok, WhatsApp, SMS). | --- # Auth, scopes and limits URL: https://docs.nexacloser.com/mcp/auth/ ## Three ways to sign in | Credential | Looks like | Best for | Scopes and limits | |---|---|---|---| | **OAuth 2.1** (recommended) | `mcp_at_…` access token, issued to the client | Claude, Claude Code and other OAuth clients | The MCP server's scopes, tool and connection limits | | **MCP server token** | `mcps_…` | Cursor, Make, n8n, scripts | The MCP server's scopes, tool and connection limits | | **API key** | `nxa_…` | Quick tests, existing integrations | Full access, no MCP limits | All three act in one workspace: the MCP server's or the key's. An OAuth token acts as the person who signed in and approved it; an MCP server token acts as the person who created the MCP server. Either way, with that person's [permissions](/roles/) and data visibility. A key with the access level *Contacts: create & update only*, and every test key, is refused by the MCP server. ## OAuth 2.1 Clients find everything on their own from `https://api.nexacloser.com/mcp`: | | | |---|---| | Protected resource metadata | `https://api.nexacloser.com/.well-known/oauth-protected-resource` | | Authorization server metadata | `https://api.nexacloser.com/.well-known/oauth-authorization-server` | | Dynamic client registration | `POST https://api.nexacloser.com/oauth/register` | | Authorize | `https://api.nexacloser.com/oauth/authorize` | | Token | `POST https://api.nexacloser.com/oauth/token` | | Revoke | `POST https://api.nexacloser.com/oauth/revoke` | - Authorization code flow with **PKCE (S256)**; public clients (`none`) and `client_secret_post`. - On the consent page the person signs in to NexaCloser, **picks an MCP server** and approves. The token is bound to that MCP server. - Access tokens last **1 hour**; clients renew them with the refresh token. Codes last 10 minutes. - Revoking the MCP server in NexaCloser cuts off every token issued for it at once. ## Scopes | Scope | Allows | |---|---| | `mcp:read` | Read tools only: look up and list contacts, deals, bookings, campaigns, reports. | | `mcp:write` | Read and write tools: send messages, create and move deals, book meetings, run automations, change ad campaigns. | A **read-only** MCP server grants `mcp:read`; a normal one grants both. Read or write is decided per tool, and the [tool reference](/mcp/tools/) marks each one. API keys skip the scope check. ## Limit an MCP server On the MCP server's page in NexaCloser: - **Restrict Tools**: allow only the tools you pick. Every other tool answers *not in this MCP server's allowed tools*. - **Restrict Connections**: allow only some outside services (for example Google Ads but not Meta). CRM tools are never limited by this. - **Token**: create, show or rotate the `mcps_…` token. Rotating stops the old token at once. - **Revoke**: disconnect every client of this MCP server for good. ## Rate limits MCP calls count against your workspace's API limit: **100 per 10 seconds** and **200,000 per day**. A `tools/call` of a write tool counts 2, everything else counts 1. Over the limit the server answers `429` with `Retry-After`. See [Rate limits](/reference/rate-limits/). ## API keys in URLs Some clients cannot send headers. The server also reads `?key=` from the URL, but avoid it: URLs are written to logs and stored by clients, so the key can leak. Use OAuth or an MCP server token instead. --- # Tool reference URL: https://docs.nexacloser.com/mcp/tools/ The NexaCloser MCP server has **216 tools**: 81 read and 135 write. Read tools only look at data. Write tools change data, send messages or spend money on ad platforms, so an MCP client will usually ask you before it runs one. | Group | Tools | Read | Write | |---|---|---|---| | [CRM: contacts, deals and tasks](/mcp/tools/crm/) | 19 | 11 | 8 | | [Messaging](/mcp/tools/messaging/) | 4 | 1 | 3 | | [Calendar and bookings](/mcp/tools/calendar/) | 4 | 3 | 1 | | [Automations](/mcp/tools/automations/) | 4 | 3 | 1 | | [Marketing (all ad platforms)](/mcp/tools/marketing/) | 8 | 8 | 0 | | [Google Ads](/mcp/tools/google-ads/) | 80 | 12 | 68 | | [Google Analytics, Search Console, Sheets and Drive](/mcp/tools/google-workspace/) | 18 | 14 | 4 | | [Meta Ads](/mcp/tools/meta-ads/) | 48 | 18 | 30 | | [TikTok Ads](/mcp/tools/tiktok-ads/) | 26 | 10 | 16 | | [AI and creative](/mcp/tools/ai-creative/) | 5 | 1 | 4 | ## Every tool ### CRM: contacts, deals and tasks [`nc_find_contact`](/mcp/tools/crm/#nc_find_contact) · [`nc_list_recent_contacts`](/mcp/tools/crm/#nc_list_recent_contacts) · [`nc_create_contact`](/mcp/tools/crm/#nc_create_contact) · [`nc_update_contact`](/mcp/tools/crm/#nc_update_contact) · [`nc_add_tag`](/mcp/tools/crm/#nc_add_tag) · [`nc_list_deals`](/mcp/tools/crm/#nc_list_deals) · [`nc_create_deal`](/mcp/tools/crm/#nc_create_deal) · [`nc_search_contacts`](/mcp/tools/crm/#nc_search_contacts) · [`nc_get_contact`](/mcp/tools/crm/#nc_get_contact) · [`nc_log_activity`](/mcp/tools/crm/#nc_log_activity) · [`nc_create_task`](/mcp/tools/crm/#nc_create_task) · [`nc_list_tasks`](/mcp/tools/crm/#nc_list_tasks) · [`nc_list_activities`](/mcp/tools/crm/#nc_list_activities) · [`nc_list_calls`](/mcp/tools/crm/#nc_list_calls) · [`nc_list_team_members`](/mcp/tools/crm/#nc_list_team_members) · [`nc_move_deal_stage`](/mcp/tools/crm/#nc_move_deal_stage) · [`nc_close_deal`](/mcp/tools/crm/#nc_close_deal) · [`nc_list_pipelines`](/mcp/tools/crm/#nc_list_pipelines) · [`nc_funnel_audit`](/mcp/tools/crm/#nc_funnel_audit) ### Messaging [`nc_send_email`](/mcp/tools/messaging/#nc_send_email) · [`nc_send_sms`](/mcp/tools/messaging/#nc_send_sms) · [`nc_send_whatsapp`](/mcp/tools/messaging/#nc_send_whatsapp) · [`nc_get_whatsapp_stats`](/mcp/tools/messaging/#nc_get_whatsapp_stats) ### Calendar and bookings [`nc_list_bookings`](/mcp/tools/calendar/#nc_list_bookings) · [`nc_create_booking`](/mcp/tools/calendar/#nc_create_booking) · [`nc_get_available_slots`](/mcp/tools/calendar/#nc_get_available_slots) · [`nc_list_event_types`](/mcp/tools/calendar/#nc_list_event_types) ### Automations [`nc_run_automation`](/mcp/tools/automations/#nc_run_automation) · [`nc_list_automations`](/mcp/tools/automations/#nc_list_automations) · [`nc_get_automation_run`](/mcp/tools/automations/#nc_get_automation_run) · [`nc_list_recent_runs`](/mcp/tools/automations/#nc_list_recent_runs) ### Marketing (all ad platforms) [`nc_get_marketing_stats`](/mcp/tools/marketing/#nc_get_marketing_stats) · [`nc_list_campaigns`](/mcp/tools/marketing/#nc_list_campaigns) · [`nc_get_campaign_metrics`](/mcp/tools/marketing/#nc_get_campaign_metrics) · [`nc_list_ads`](/mcp/tools/marketing/#nc_list_ads) · [`nc_get_ad_metrics`](/mcp/tools/marketing/#nc_get_ad_metrics) · [`nc_top_performing_ads`](/mcp/tools/marketing/#nc_top_performing_ads) · [`nc_list_marketing_connections`](/mcp/tools/marketing/#nc_list_marketing_connections) · [`nc_validate_landing_page_url`](/mcp/tools/marketing/#nc_validate_landing_page_url) ### Google Ads [`nc_set_campaign_status`](/mcp/tools/google-ads/#nc_set_campaign_status) · [`nc_set_ad_group_status`](/mcp/tools/google-ads/#nc_set_ad_group_status) · [`nc_set_ad_status`](/mcp/tools/google-ads/#nc_set_ad_status) · [`nc_update_campaign_budget`](/mcp/tools/google-ads/#nc_update_campaign_budget) · [`nc_update_ad_copy`](/mcp/tools/google-ads/#nc_update_ad_copy) · [`nc_add_negative_keyword`](/mcp/tools/google-ads/#nc_add_negative_keyword) · [`nc_create_customer_list`](/mcp/tools/google-ads/#nc_create_customer_list) · [`nc_add_contacts_to_customer_list`](/mcp/tools/google-ads/#nc_add_contacts_to_customer_list) · [`nc_send_offline_conversion`](/mcp/tools/google-ads/#nc_send_offline_conversion) · [`nc_google_ads_update_campaign_bidding_strategy`](/mcp/tools/google-ads/#nc_google_ads_update_campaign_bidding_strategy) · [`nc_google_ads_update_campaign_location_language`](/mcp/tools/google-ads/#nc_google_ads_update_campaign_location_language) · [`nc_google_ads_update_campaign_ad_schedule`](/mcp/tools/google-ads/#nc_google_ads_update_campaign_ad_schedule) · [`nc_google_ads_rename_campaign`](/mcp/tools/google-ads/#nc_google_ads_rename_campaign) · [`nc_google_ads_search_geo_targets`](/mcp/tools/google-ads/#nc_google_ads_search_geo_targets) · [`nc_google_ads_create_ad_group`](/mcp/tools/google-ads/#nc_google_ads_create_ad_group) · [`nc_google_ads_update_ad_group_status`](/mcp/tools/google-ads/#nc_google_ads_update_ad_group_status) · [`nc_google_ads_update_ad_group_bid`](/mcp/tools/google-ads/#nc_google_ads_update_ad_group_bid) · [`nc_google_ads_rename_ad_group`](/mcp/tools/google-ads/#nc_google_ads_rename_ad_group) · [`nc_google_ads_add_keyword_to_ad_group`](/mcp/tools/google-ads/#nc_google_ads_add_keyword_to_ad_group) · [`nc_google_ads_update_keyword_status`](/mcp/tools/google-ads/#nc_google_ads_update_keyword_status) · [`nc_google_ads_update_keyword_bid`](/mcp/tools/google-ads/#nc_google_ads_update_keyword_bid) · [`nc_google_ads_add_negative_keywords_to_ad_groups`](/mcp/tools/google-ads/#nc_google_ads_add_negative_keywords_to_ad_groups) · [`nc_google_ads_edit_responsive_search_ad`](/mcp/tools/google-ads/#nc_google_ads_edit_responsive_search_ad) · [`nc_google_ads_update_ad_status`](/mcp/tools/google-ads/#nc_google_ads_update_ad_status) · [`nc_google_ads_list_audience_segments`](/mcp/tools/google-ads/#nc_google_ads_list_audience_segments) · [`nc_google_ads_target_audience_segments`](/mcp/tools/google-ads/#nc_google_ads_target_audience_segments) · [`nc_google_ads_exclude_audience_segments`](/mcp/tools/google-ads/#nc_google_ads_exclude_audience_segments) · [`nc_google_create_search_campaign`](/mcp/tools/google-ads/#nc_google_create_search_campaign) · [`nc_google_create_ad_group`](/mcp/tools/google-ads/#nc_google_create_ad_group) · [`nc_google_create_responsive_search_ad`](/mcp/tools/google-ads/#nc_google_create_responsive_search_ad) · [`nc_google_create_negative_keyword_list`](/mcp/tools/google-ads/#nc_google_create_negative_keyword_list) · [`nc_google_apply_negative_keyword_list_to_campaigns`](/mcp/tools/google-ads/#nc_google_apply_negative_keyword_list_to_campaigns) · [`nc_google_rename_campaign`](/mcp/tools/google-ads/#nc_google_rename_campaign) · [`nc_google_rename_ad_group`](/mcp/tools/google-ads/#nc_google_rename_ad_group) · [`nc_google_keyword_planner`](/mcp/tools/google-ads/#nc_google_keyword_planner) · [`nc_google_run_gaql_query`](/mcp/tools/google-ads/#nc_google_run_gaql_query) · [`nc_google_ads_list_keywords`](/mcp/tools/google-ads/#nc_google_ads_list_keywords) · [`nc_google_ads_list_ad_copy`](/mcp/tools/google-ads/#nc_google_ads_list_ad_copy) · [`nc_google_ads_manage_portfolio_bidding_strategy`](/mcp/tools/google-ads/#nc_google_ads_manage_portfolio_bidding_strategy) · [`nc_google_ads_assign_portfolio_bidding_strategy`](/mcp/tools/google-ads/#nc_google_ads_assign_portfolio_bidding_strategy) · [`nc_google_ads_create_pmax_asset_group`](/mcp/tools/google-ads/#nc_google_ads_create_pmax_asset_group) · [`nc_google_ads_update_product_groups`](/mcp/tools/google-ads/#nc_google_ads_update_product_groups) · [`nc_google_ads_update_audience_signals`](/mcp/tools/google-ads/#nc_google_ads_update_audience_signals) · [`nc_google_ads_create_responsive_display_ad`](/mcp/tools/google-ads/#nc_google_ads_create_responsive_display_ad) · [`nc_google_ads_create_demand_gen_single_image_ad`](/mcp/tools/google-ads/#nc_google_ads_create_demand_gen_single_image_ad) · [`nc_google_ads_create_demand_gen_video_ad`](/mcp/tools/google-ads/#nc_google_ads_create_demand_gen_video_ad) · [`nc_google_ads_create_demand_gen_carousel_ad`](/mcp/tools/google-ads/#nc_google_ads_create_demand_gen_carousel_ad) · [`nc_google_ads_create_negative_keyword_list`](/mcp/tools/google-ads/#nc_google_ads_create_negative_keyword_list) · [`nc_google_ads_create_placement_exclusion_list`](/mcp/tools/google-ads/#nc_google_ads_create_placement_exclusion_list) · [`nc_google_ads_add_placements_to_exclusion_list`](/mcp/tools/google-ads/#nc_google_ads_add_placements_to_exclusion_list) · [`nc_google_ads_add_keywords_to_negative_list`](/mcp/tools/google-ads/#nc_google_ads_add_keywords_to_negative_list) · [`nc_google_ads_apply_exclusion_list_to_campaigns`](/mcp/tools/google-ads/#nc_google_ads_apply_exclusion_list_to_campaigns) · [`nc_google_ads_manage_ip_exclusions`](/mcp/tools/google-ads/#nc_google_ads_manage_ip_exclusions) · [`nc_google_ads_create_sitelink_assets`](/mcp/tools/google-ads/#nc_google_ads_create_sitelink_assets) · [`nc_google_ads_create_callout_assets`](/mcp/tools/google-ads/#nc_google_ads_create_callout_assets) · [`nc_google_ads_create_structured_snippet_assets`](/mcp/tools/google-ads/#nc_google_ads_create_structured_snippet_assets) · [`nc_google_ads_create_promotion_assets`](/mcp/tools/google-ads/#nc_google_ads_create_promotion_assets) · [`nc_google_ads_create_image_asset`](/mcp/tools/google-ads/#nc_google_ads_create_image_asset) · [`nc_google_ads_create_headline_assets`](/mcp/tools/google-ads/#nc_google_ads_create_headline_assets) · [`nc_google_ads_create_description_assets`](/mcp/tools/google-ads/#nc_google_ads_create_description_assets) · [`nc_google_ads_update_asset_status`](/mcp/tools/google-ads/#nc_google_ads_update_asset_status) · [`nc_google_ads_create_label`](/mcp/tools/google-ads/#nc_google_ads_create_label) · [`nc_google_ads_manage_label_assignment`](/mcp/tools/google-ads/#nc_google_ads_manage_label_assignment) · [`nc_google_ads_mutate`](/mcp/tools/google-ads/#nc_google_ads_mutate) · [`nc_google_ads_upload_conversion_adjustments`](/mcp/tools/google-ads/#nc_google_ads_upload_conversion_adjustments) · [`nc_google_ads_create_conversion_action`](/mcp/tools/google-ads/#nc_google_ads_create_conversion_action) · [`nc_google_ads_update_conversion_action`](/mcp/tools/google-ads/#nc_google_ads_update_conversion_action) · [`nc_google_ads_apply_recommendation`](/mcp/tools/google-ads/#nc_google_ads_apply_recommendation) · [`nc_google_ads_dismiss_recommendation`](/mcp/tools/google-ads/#nc_google_ads_dismiss_recommendation) · [`nc_google_ads_create_lead_form_asset`](/mcp/tools/google-ads/#nc_google_ads_create_lead_form_asset) · [`nc_google_ads_create_call_asset`](/mcp/tools/google-ads/#nc_google_ads_create_call_asset) · [`nc_google_ads_create_price_asset`](/mcp/tools/google-ads/#nc_google_ads_create_price_asset) · [`nc_google_ads_create_campaign_draft`](/mcp/tools/google-ads/#nc_google_ads_create_campaign_draft) · [`nc_google_ads_create_experiment`](/mcp/tools/google-ads/#nc_google_ads_create_experiment) · [`nc_google_ads_schedule_experiment`](/mcp/tools/google-ads/#nc_google_ads_schedule_experiment) · [`nc_google_ads_promote_experiment`](/mcp/tools/google-ads/#nc_google_ads_promote_experiment) · [`nc_google_ads_end_experiment`](/mcp/tools/google-ads/#nc_google_ads_end_experiment) · [`nc_google_ads_graduate_experiment`](/mcp/tools/google-ads/#nc_google_ads_graduate_experiment) · [`nc_google_ads_create_billing_setup`](/mcp/tools/google-ads/#nc_google_ads_create_billing_setup) · [`nc_google_ads_propose_account_budget`](/mcp/tools/google-ads/#nc_google_ads_propose_account_budget) ### Google Analytics, Search Console, Sheets and Drive [`nc_google_ga4_list_properties`](/mcp/tools/google-workspace/#nc_google_ga4_list_properties) · [`nc_google_ga4_run_report`](/mcp/tools/google-workspace/#nc_google_ga4_run_report) · [`nc_google_ga4_top_pages`](/mcp/tools/google-workspace/#nc_google_ga4_top_pages) · [`nc_google_ga4_traffic_sources`](/mcp/tools/google-workspace/#nc_google_ga4_traffic_sources) · [`nc_google_ga4_realtime_users`](/mcp/tools/google-workspace/#nc_google_ga4_realtime_users) · [`nc_google_gsc_list_sites`](/mcp/tools/google-workspace/#nc_google_gsc_list_sites) · [`nc_google_gsc_search_analytics`](/mcp/tools/google-workspace/#nc_google_gsc_search_analytics) · [`nc_google_gsc_top_queries`](/mcp/tools/google-workspace/#nc_google_gsc_top_queries) · [`nc_google_gsc_index_coverage`](/mcp/tools/google-workspace/#nc_google_gsc_index_coverage) · [`nc_google_sheets_list_spreadsheets`](/mcp/tools/google-workspace/#nc_google_sheets_list_spreadsheets) · [`nc_google_sheets_read_range`](/mcp/tools/google-workspace/#nc_google_sheets_read_range) · [`nc_google_sheets_append_row`](/mcp/tools/google-workspace/#nc_google_sheets_append_row) · [`nc_google_sheets_update_cells`](/mcp/tools/google-workspace/#nc_google_sheets_update_cells) · [`nc_google_sheets_create_spreadsheet`](/mcp/tools/google-workspace/#nc_google_sheets_create_spreadsheet) · [`nc_google_drive_list_files`](/mcp/tools/google-workspace/#nc_google_drive_list_files) · [`nc_google_drive_get_file_metadata`](/mcp/tools/google-workspace/#nc_google_drive_get_file_metadata) · [`nc_google_drive_download_file_content`](/mcp/tools/google-workspace/#nc_google_drive_download_file_content) · [`nc_google_drive_create_folder`](/mcp/tools/google-workspace/#nc_google_drive_create_folder) ### Meta Ads [`nc_meta_create_campaign`](/mcp/tools/meta-ads/#nc_meta_create_campaign) · [`nc_meta_create_ad_set`](/mcp/tools/meta-ads/#nc_meta_create_ad_set) · [`nc_meta_create_ad`](/mcp/tools/meta-ads/#nc_meta_create_ad) · [`nc_meta_upload_image`](/mcp/tools/meta-ads/#nc_meta_upload_image) · [`nc_meta_update_campaign_budget`](/mcp/tools/meta-ads/#nc_meta_update_campaign_budget) · [`nc_meta_pause_campaign`](/mcp/tools/meta-ads/#nc_meta_pause_campaign) · [`nc_meta_get_campaign_performance`](/mcp/tools/meta-ads/#nc_meta_get_campaign_performance) · [`nc_meta_create_custom_audience`](/mcp/tools/meta-ads/#nc_meta_create_custom_audience) · [`nc_meta_create_lookalike_audience`](/mcp/tools/meta-ads/#nc_meta_create_lookalike_audience) · [`nc_meta_upload_video`](/mcp/tools/meta-ads/#nc_meta_upload_video) · [`nc_meta_create_video_ad`](/mcp/tools/meta-ads/#nc_meta_create_video_ad) · [`nc_meta_create_carousel_ad`](/mcp/tools/meta-ads/#nc_meta_create_carousel_ad) · [`nc_meta_generate_ad_previews`](/mcp/tools/meta-ads/#nc_meta_generate_ad_previews) · [`nc_meta_search_targeting`](/mcp/tools/meta-ads/#nc_meta_search_targeting) · [`nc_meta_list_lead_forms`](/mcp/tools/meta-ads/#nc_meta_list_lead_forms) · [`nc_meta_retrieve_leads`](/mcp/tools/meta-ads/#nc_meta_retrieve_leads) · [`nc_meta_pixel_health`](/mcp/tools/meta-ads/#nc_meta_pixel_health) · [`nc_meta_ads_library_search`](/mcp/tools/meta-ads/#nc_meta_ads_library_search) · [`nc_meta_duplicate_campaign`](/mcp/tools/meta-ads/#nc_meta_duplicate_campaign) · [`nc_meta_rename_campaign`](/mcp/tools/meta-ads/#nc_meta_rename_campaign) · [`nc_meta_update_campaign_bidding_strategy`](/mcp/tools/meta-ads/#nc_meta_update_campaign_bidding_strategy) · [`nc_meta_list_campaigns`](/mcp/tools/meta-ads/#nc_meta_list_campaigns) · [`nc_meta_get_campaign_settings`](/mcp/tools/meta-ads/#nc_meta_get_campaign_settings) · [`nc_meta_duplicate_ad_set`](/mcp/tools/meta-ads/#nc_meta_duplicate_ad_set) · [`nc_meta_update_adset_bid_value`](/mcp/tools/meta-ads/#nc_meta_update_adset_bid_value) · [`nc_meta_update_adset_schedule`](/mcp/tools/meta-ads/#nc_meta_update_adset_schedule) · [`nc_meta_update_adset_placements`](/mcp/tools/meta-ads/#nc_meta_update_adset_placements) · [`nc_meta_update_adset_locations`](/mcp/tools/meta-ads/#nc_meta_update_adset_locations) · [`nc_meta_update_adset_language`](/mcp/tools/meta-ads/#nc_meta_update_adset_language) · [`nc_meta_update_adset_audiences`](/mcp/tools/meta-ads/#nc_meta_update_adset_audiences) · [`nc_meta_update_adset`](/mcp/tools/meta-ads/#nc_meta_update_adset) · [`nc_meta_rename_adset`](/mcp/tools/meta-ads/#nc_meta_rename_adset) · [`nc_meta_list_ad_sets`](/mcp/tools/meta-ads/#nc_meta_list_ad_sets) · [`nc_meta_get_adset_settings`](/mcp/tools/meta-ads/#nc_meta_get_adset_settings) · [`nc_meta_duplicate_ad`](/mcp/tools/meta-ads/#nc_meta_duplicate_ad) · [`nc_meta_create_catalog_ad`](/mcp/tools/meta-ads/#nc_meta_create_catalog_ad) · [`nc_meta_create_flexible_ad`](/mcp/tools/meta-ads/#nc_meta_create_flexible_ad) · [`nc_meta_create_ad_from_post`](/mcp/tools/meta-ads/#nc_meta_create_ad_from_post) · [`nc_meta_create_ad_from_creative`](/mcp/tools/meta-ads/#nc_meta_create_ad_from_creative) · [`nc_meta_list_ads`](/mcp/tools/meta-ads/#nc_meta_list_ads) · [`nc_meta_rename_ad`](/mcp/tools/meta-ads/#nc_meta_rename_ad) · [`nc_meta_get_ad_creative`](/mcp/tools/meta-ads/#nc_meta_get_ad_creative) · [`nc_meta_replace_ad_creative`](/mcp/tools/meta-ads/#nc_meta_replace_ad_creative) · [`nc_meta_list_account_pixels`](/mcp/tools/meta-ads/#nc_meta_list_account_pixels) · [`nc_meta_get_pixel_details`](/mcp/tools/meta-ads/#nc_meta_get_pixel_details) · [`nc_meta_get_pixel_stats`](/mcp/tools/meta-ads/#nc_meta_get_pixel_stats) · [`nc_meta_check_capi_health`](/mcp/tools/meta-ads/#nc_meta_check_capi_health) · [`nc_meta_list_custom_conversions`](/mcp/tools/meta-ads/#nc_meta_list_custom_conversions) ### TikTok Ads [`nc_tiktok_select_accounts`](/mcp/tools/tiktok-ads/#nc_tiktok_select_accounts) · [`nc_tiktok_list_pages`](/mcp/tools/tiktok-ads/#nc_tiktok_list_pages) · [`nc_tiktok_list_identities`](/mcp/tools/tiktok-ads/#nc_tiktok_list_identities) · [`nc_tiktok_list_posts`](/mcp/tools/tiktok-ads/#nc_tiktok_list_posts) · [`nc_tiktok_create_campaign`](/mcp/tools/tiktok-ads/#nc_tiktok_create_campaign) · [`nc_tiktok_update_campaign_status`](/mcp/tools/tiktok-ads/#nc_tiktok_update_campaign_status) · [`nc_tiktok_update_campaign_budget`](/mcp/tools/tiktok-ads/#nc_tiktok_update_campaign_budget) · [`nc_tiktok_rename_campaign`](/mcp/tools/tiktok-ads/#nc_tiktok_rename_campaign) · [`nc_tiktok_list_campaigns`](/mcp/tools/tiktok-ads/#nc_tiktok_list_campaigns) · [`nc_tiktok_create_ad_group`](/mcp/tools/tiktok-ads/#nc_tiktok_create_ad_group) · [`nc_tiktok_update_ad_group`](/mcp/tools/tiktok-ads/#nc_tiktok_update_ad_group) · [`nc_tiktok_update_ad_group_status`](/mcp/tools/tiktok-ads/#nc_tiktok_update_ad_group_status) · [`nc_tiktok_update_ad_group_budget`](/mcp/tools/tiktok-ads/#nc_tiktok_update_ad_group_budget) · [`nc_tiktok_rename_ad_group`](/mcp/tools/tiktok-ads/#nc_tiktok_rename_ad_group) · [`nc_tiktok_list_ad_groups`](/mcp/tools/tiktok-ads/#nc_tiktok_list_ad_groups) · [`nc_tiktok_create_image_ad`](/mcp/tools/tiktok-ads/#nc_tiktok_create_image_ad) · [`nc_tiktok_create_video_ad`](/mcp/tools/tiktok-ads/#nc_tiktok_create_video_ad) · [`nc_tiktok_create_ad_from_post`](/mcp/tools/tiktok-ads/#nc_tiktok_create_ad_from_post) · [`nc_tiktok_update_ad`](/mcp/tools/tiktok-ads/#nc_tiktok_update_ad) · [`nc_tiktok_update_ad_status`](/mcp/tools/tiktok-ads/#nc_tiktok_update_ad_status) · [`nc_tiktok_rename_ad`](/mcp/tools/tiktok-ads/#nc_tiktok_rename_ad) · [`nc_tiktok_generate_ad_preview`](/mcp/tools/tiktok-ads/#nc_tiktok_generate_ad_preview) · [`nc_tiktok_list_ads`](/mcp/tools/tiktok-ads/#nc_tiktok_list_ads) · [`nc_tiktok_search_targeting`](/mcp/tools/tiktok-ads/#nc_tiktok_search_targeting) · [`nc_tiktok_list_pixels`](/mcp/tools/tiktok-ads/#nc_tiktok_list_pixels) · [`nc_tiktok_search_music`](/mcp/tools/tiktok-ads/#nc_tiktok_search_music) ### AI and creative [`nc_generate_ad_image`](/mcp/tools/ai-creative/#nc_generate_ad_image) · [`nc_generate_ad_image_variants`](/mcp/tools/ai-creative/#nc_generate_ad_image_variants) · [`nc_generate_ad_copy`](/mcp/tools/ai-creative/#nc_generate_ad_copy) · [`nc_research_business_from_url`](/mcp/tools/ai-creative/#nc_research_business_from_url) · [`nc_create_skill`](/mcp/tools/ai-creative/#nc_create_skill) --- # Roles and permissions URL: https://docs.nexacloser.com/roles/ Everyone in a workspace has one **role**. The role decides which parts of the app they can open and what they can do there. On top of the role, each member has a **data scope** that decides whose records they see. Roles are managed under **Settings → Roles**; members get their role and data scope on their team member page. The full module-by-module list is in the [permissions matrix](/roles/permissions-matrix/). ## Built-in roles | Role | In short | |---|---| | **Owner** | The person who owns the workspace. Everything, including deleting the workspace. One per workspace. | | **Admin** | Everything except what only the owner can do. | | **Manager** | Full access like the owner. Cannot remove or demote an owner or admin, cannot invite someone as owner or admin, cannot delete the workspace. | | **Agent** | Day-to-day work: conversations, CRM, documents, calendar, meetings, WhatsApp and phone. Can view several other areas. No settings, billing, team, automations or marketing. | | **Viewer** | Can view every area, change nothing. Never sees billing or the finance book. | Owner, Admin and Manager always have full access: their permissions cannot be narrowed. ## Custom roles In **Settings → Roles** you can create your own role. Start from a template and adjust: | Template | Starts with | |---|---| | Manager | Full access | | Agent | The Agent permissions above | | Sales | CRM and conversations only: a lean menu for sales reps | | Limited | No operator panels; only student messages (welcome and tasks) | | Viewer | View only, everywhere | | Custom | Nothing; you switch on what you need | Permissions are set per **module** (CRM, Calendar, WhatsApp, Automations, Billing and so on) and per **action** in that module (view, create, edit, delete, export, send…). A module without *view* is hidden from the menu, and its pages are blocked even by direct link. ## Per-member overrides For one team member you can switch single actions on or off without making a new role. Overrides apply to Agent, Viewer and custom roles. They never apply to Owner, Admin or Manager. ## Data scope: only see assigned records Each member's data scope is **All** (default) or **Only see assigned records**. With *only assigned*, a member sees only the contacts and deals assigned to them or that they created, both in the app and in AI clients connected over MCP. Set it on the member's page under **Settings → Team**. ## Who manages what | Task | Who | |---|---| | Edit any role, including built-in ones | Owner | | Edit custom roles, Agent and Viewer | Admin, Manager | | Delete a built-in role | Nobody | | Create organization API keys | Owner, Admin, Manager | | Create a personal API key | Any active member | | Revoke a personal API key | Its owner, or an Owner, Admin or Manager | | Delete an MCP server | The person who created it, or the workspace's owner or an admin | How keys and MCP connections relate to roles: [API keys and roles](/roles/api-access/). --- # Permissions matrix URL: https://docs.nexacloser.com/roles/permissions-matrix/ What every built-in role and role template can do by default. **All** means every action of that module. A dash means no access, so the module is also hidden from the menu. :::note[Generated] This page is generated from the same role presets the **Settings → Roles** screen uses, on every docs build. Owner, Admin and Manager always have full access and cannot be narrowed. Every other role can be edited in a workspace, and single actions can be overridden for one team member, so a real workspace may differ from these defaults. ::: ## Core | Module | Actions | Owner, Admin, Manager | Agent | Viewer | Sales (template) | Limited (template) | |---|---|---|---|---|---|---| | Dashboard | View | **All** | **All** | **All** | — | — | | Conversations | View, Delete, Reply, Assign | **All** | View, Reply | View | View, Reply | — | | CRM | View, Create, Edit, Delete, Export, Import | **All** | View, Create, Edit | View | View, Create, Edit | — | | Calendar | View, Create, Edit, Delete | **All** | View, Create | View | — | — | ## Communications | Module | Actions | Owner, Admin, Manager | Agent | Viewer | Sales (template) | Limited (template) | |---|---|---|---|---|---|---| | WhatsApp | View, Send, Manage Templates, Manage Balance | **All** | View, Send | View | — | — | | Meetings | View, Host, Record, View Recordings, Delete Recording | **All** | View, Host, View Recordings | View | — | — | | Webinars | View, Host, Broadcast, Manage Registrants, View Recordings, Delete Recording | **All** | View, View Recordings | View | — | — | | Phone | View, Call | **All** | **All** | View | — | — | | SMS campaigns | View, Create, Edit, Delete | **All** | View | View | — | — | | Help desk | View, Create, Edit, Delete | **All** | View | View | — | — | | Notification templates | View, Create, Edit, Delete | **All** | View | View | — | — | | Student messages | View | **All** | — | **All** | — | **All** | ## Automation & Agents | Module | Actions | Owner, Admin, Manager | Agent | Viewer | Sales (template) | Limited (template) | |---|---|---|---|---|---|---| | Agents | View, Create, Edit, Delete | **All** | View | View | — | — | | Automations | View, Create, Edit, Delete, Activate | **All** | — | View | — | — | | Knowledge Base | View, Create, Edit, Delete | **All** | View | View | — | — | | Ask AI | View | **All** | **All** | **All** | — | — | | MCP | View, Manage | **All** | View | View | — | — | ## Marketing & Growth | Module | Actions | Owner, Admin, Manager | Agent | Viewer | Sales (template) | Limited (template) | |---|---|---|---|---|---|---| | Marketing | View, Create, Edit, Delete | **All** | — | View | — | — | | Email | View, Create, Edit, Delete | **All** | — | View | — | — | | Landing Pages | View, Create, Edit, Delete | **All** | — | View | — | — | | Forms | View, Create, Edit, Delete | **All** | View | View | — | — | | Websites | View, Create, Edit, Delete | **All** | View | View | — | — | | Social | View, Create, Edit, Delete | **All** | View | View | — | — | | Reputation | View, Create, Edit, Delete | **All** | View | View | — | — | | Creative studio | View, Create, Edit, Delete | **All** | View | View | — | — | | Voice Campaigns | View, Create, Edit, Delete | **All** | — | View | — | — | | Analytics | View, Export | **All** | — | View | — | — | | Call Monitoring | View | **All** | **All** | **All** | — | — | | Reports | View, Export | **All** | — | View | — | — | | Courses (LMS) | View, Author, Publish, Grade, Enroll Others, View Analytics | **All** | — | View | — | — | | E-commerce | View, Manage Products, Manage Orders, Sync | **All** | View | View | — | — | | Documents & Signatures | View, Create, Send, Delete, View Signed Documents, View Documents on the Lead Page | **All** | View, Create, Send | View | — | — | | Items | View, Create, Edit, Delete | **All** | View | View | — | — | | Community | View, Create, Edit, Delete | **All** | View | View | — | — | ## Platform | Module | Actions | Owner, Admin, Manager | Agent | Viewer | Sales (template) | Limited (template) | |---|---|---|---|---|---|---| | Integrations | View, Connect, Disconnect | **All** | — | View | — | — | | Marketplace | View, Install, Uninstall | **All** | — | View | — | — | | Storage | View, Upload, Delete, Share, Manage Quota | **All** | View, Upload | View | — | — | | Connected accounts | View, Connect, Disconnect | **All** | View | View | — | — | ## Administration | Module | Actions | Owner, Admin, Manager | Agent | Viewer | Sales (template) | Limited (template) | |---|---|---|---|---|---|---| | Settings | View, Edit | **All** | — | View | — | — | | Billing | View, Manage | **All** | — | — | — | — | | Payments | View, Create, Edit, Delete | **All** | View | View | — | — | | Finance book | View, Create, Edit, Delete | **All** | — | — | — | — | | Team | View, Invite, Manage Roles, Remove | **All** | — | View | — | — | ## Exceptions the matrix cannot show - **Viewer** never sees **Billing** or **Finance book**, and a workspace cannot grant those two back to a viewer. - **Documents → View Signed Documents** (the signed contract itself) is off for every role except Owner, Admin and Manager until a workspace turns it on for a role. - **Manager** has the same permissions as the owner, but cannot remove or demote an owner or admin, invite someone as owner or admin, or delete the organization. --- # API keys and roles URL: https://docs.nexacloser.com/roles/api-access/ A key or an MCP connection never has more rights than the person it acts as. Three things decide what a request may do: 1. **Who it acts as**: the key type. 2. **What the key may call**: its access level (API keys) or scopes (MCP). 3. **That person's role and data scope** in the workspace. ## Who it acts as | Credential | Acts as | |---|---| | Organization API key | The workspace **owner** | | Personal API key | The member who created it, while they are still on the team | | Old personal API key | Its owner, in whichever workspace they have open | | MCP over OAuth | The person who signed in and approved the client | | MCP server token (`mcps_…`) | The person who created the MCP server | ## What it may call | Credential | Allowed | |---|---| | API key, **Full access** | Every REST endpoint and every MCP tool | | API key, **Contacts: create & update only** | Only `POST /v1/contacts` (write, no read) | | Test key (`nxa_test_…`) | Only `POST /v1/contacts`, and it writes nothing | | MCP, scope `mcp:read` | Read tools | | MCP, scope `mcp:write` | Read and write tools | | MCP server with **Restrict Tools** / **Restrict Connections** | Only the tools and services allowed on it | ## What the person may see Tools and endpoints that read CRM data return what that person would see on the Contacts page: - Owners, admins and managers, and members with data scope **All**, see the whole workspace. - Members with **Only see assigned records** see only contacts and deals assigned to them or created by them. - Deleted records are never returned. Because an organization key acts as the owner, it sees everything in the workspace. Give it only to systems you trust, and prefer **Contacts: create & update only** for anything that just sends leads. --- # Errors URL: https://docs.nexacloser.com/reference/errors/ Errors are JSON with an `error` field: ```json { "error": "validation_failed", "details": [{ "field": "email", "code": "invalid_email" }] } ``` Newer endpoints use stable lowercase codes, safe to branch on. Older endpoints (website analytics, inbound webhooks) send a short English message instead; branch on the HTTP status there. ## Status codes | Status | Meaning | Retry? | |---|---|---| | `200` / `201` | Done / created | — | | `400` | The request is malformed (bad JSON, missing required parameter) | No, fix it | | `401` | No key, wrong key, revoked or rotated key, or a key that may not call this endpoint | No, fix the key | | `403` | The key is valid but not for this: another workspace's webinar, or an access level this endpoint does not accept | No | | `404` | Not found in this workspace | No | | `405` | Wrong HTTP method | No | | `413` | Body too large | No, send less | | `422` | Valid JSON, wrong fields; `details` lists each one | No, fix the fields | | `429` | Rate limit; wait `Retry-After` seconds | Yes, after the wait | | `5xx` | Our side | Yes, with exponential backoff | ## By endpoint ### `POST /v1/contacts` | Status | `error` | |---|---| | `400` | `invalid_json` | | `401` | `unauthorized` | | `403` | `forbidden` | | `405` | `method_not_allowed` | | `413` | `payload_too_large` | | `422` | `validation_failed`, with `details[].code` from the [list on the Contacts page](/guides/contacts/#errors) | | `429` | `rate_limited` | | `500` | `internal` | ### `POST /v1/webinar-registrants` | Status | `error` | |---|---| | `400` | `invalid_json`, `no_registrants`, `batch_too_large`, `webinar_required` | | `401` | `unauthorized` | | `403` | `forbidden` | | `404` | `webinar_not_found` | | `405` | `method_not_allowed` | | `429` | `rate_limited` | | `500` | `internal` | Per registrant, inside a `200`: `consent_required`, `invalid_registrant`, `email_or_phone_required`, `valid email required`, `validation_failed`, `webinar_full`, `internal`. ### `GET /v1/api-v1` (website analytics) `400 Missing site_id` · `400 Unknown action` · `401 Unauthorized` · `404 Site not found` · `429 rate_limited` ### Inbound webhooks (`hook.nexacloser.com`) `400 Missing webhook slug` · `401 Unauthorized — x-webhook-token header required` · `401 Unauthorized` · `404 Webhook not found` · `413 payload_too_large` · `429 rate_limited` ### MCP (`/mcp`) `401` with JSON-RPC error `-32001 Unauthorized`. Tool failures are `200` with `result.isError: true` and the reason as text. See [MCP](/mcp/#errors). ## Retrying safely - `POST /v1/contacts` matches on phone and email, so repeating it updates the same contact. - `POST /v1/webinar-registrants` returns the existing registration for a repeat (`duplicate: true`). - Inbound webhooks drop an identical body sent within 2 minutes (`deduped: true`). So retrying after a timeout or a `5xx` does not create doubles. The one exception is a workspace that allows duplicate contacts. --- # Rate limits URL: https://docs.nexacloser.com/reference/rate-limits/ Every limit has two windows: a short **burst** window and a rolling **day**. Going over either one answers `429`. | What | Counted per | Burst | Per day | |---|---|---|---| | `POST /v1/contacts` | API key | 100 per 10 seconds | 200,000 | | `POST /v1/webinar-registrants` | API key, per registrant | 600 per 60 seconds | 100,000 | | `GET /v1/api-v1` (website analytics) | Workspace | 100 per 10 seconds | 200,000 | | MCP (`/mcp`) | Workspace; a write tool call counts 2 | 100 per 10 seconds | 200,000 | | Inbound webhook with a secret token | Webhook and sender IP | 100 per 10 seconds | 200,000 | | Inbound webhook without a token | Webhook and sender IP | 40 per 60 seconds | 5,000 | Limits can be raised for a workspace that needs more. Contact support@nexacloser.com. ## Headers Successful responses carry the current state: | Header | Meaning | |---|---| | `X-RateLimit-Limit` | Requests allowed in the burst window | | `X-RateLimit-Remaining` | Requests left in the burst window | | `X-RateLimit-Reset` | When the burst window resets (Unix seconds) | | `X-RateLimit-Daily-Limit` | Requests allowed per day | | `X-RateLimit-Daily-Remaining` | Requests left today | | `X-RateLimit-Daily-Reset` | When the day window resets (Unix seconds) | ## When you get a 429 ```http HTTP/1.1 429 Too Many Requests Retry-After: 7 { "error": "rate_limited", "message": "Too many requests", "retry_after": 7 } ``` Wait `Retry-After` seconds, then retry. For bulk work, keep a steady pace below the burst limit instead of sending everything at once, and send webinar registrants in batches of up to 100. --- # Changelog URL: https://docs.nexacloser.com/changelog/ ## 2026-11-05 - **New:** [`POST /v1/contacts`](/guides/contacts/) creates or updates a CRM contact, with tags, custom fields, attribution and per-channel consent records. - **New:** API key access level **Contacts: create & update only**, for websites and partners that only send leads. See [Access levels](/authentication/access-levels/). - **New:** **Test keys** (`nxa_test_…`) for the contacts endpoint: full validation, nothing written. - **New:** this documentation site, with the [API reference](/api/), [Swagger UI](/swagger/), [OpenAPI file](/openapi.yaml), [MCP tool reference](/mcp/tools/) and [roles and permissions](/roles/). - The in-app API docs pages now open this site, and **Settings → API** links here. --- # AI and creative URL: https://docs.nexacloser.com/mcp/tools/ai-creative/ Generate ad images and copy, research a business, save skills. 5 tools: 1 read, 4 write. :::note[Generated] This page is generated from the MCP server source on every docs build. Names, descriptions and arguments are exactly what `tools/list` returns. ::: | Tool | Access | What it does | |---|---|---| | nc_generate_ad_image | write | Generate a single ad-creative image via Imagen 4 or Nano Banana Pro (Gemini API). | | nc_generate_ad_image_variants | write | Generate 5 aspect-ratio variants of the same prompt (1:1, 4:5, 9:16, 16:9, 1.91:1) — the Meta/Google ad-platform sweet spot. | | nc_generate_ad_copy | write | Generate ad copy with character limits enforced server-side. | | nc_research_business_from_url | read | Light, by-the-book research from a public URL. | | nc_create_skill | write | Save a new reusable skill that the user designed in this conversation. | ### `nc_generate_ad_image` write Needs `mcp:write` on an OAuth or MCP-server token. Generate a single ad-creative image via Imagen 4 or Nano Banana Pro (Gemini API). Auto-routes Hebrew/RTL prompts to Nano Banana Pro (better Hebrew text rendering). Returns a signed URL + image_asset_id. Re-uses cached images for identical (prompt, model, aspect) within 30 days. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `prompt` | string | yes | Describe the image in any language. Hebrew prompts auto-route to Nano Banana Pro for legible text rendering. | | `aspect_ratio` | string | | One of: `1:1`, `4:5`, `9:16`, `16:9`, `1.91:1`, `4:3`, `3:4` · Default: `"1:1"` | | `model` | string | | One of: `auto`, `imagen-4`, `nano-banana-pro` · Default: `"auto"` | | `seed` | integer | | Imagen only. Deterministic seed. |
### `nc_generate_ad_image_variants` write Needs `mcp:write` on an OAuth or MCP-server token. Generate 5 aspect-ratio variants of the same prompt (1:1, 4:5, 9:16, 16:9, 1.91:1) — the Meta/Google ad-platform sweet spot. Returns 5 signed URLs + asset_ids. Costs up to 5× nc_generate_ad_image. Caching applies per (prompt, model, aspect). Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `prompt` | string | yes | | | `model` | string | | One of: `auto`, `imagen-4`, `nano-banana-pro` · Default: `"auto"` |
### `nc_generate_ad_copy` write Needs `mcp:write` on an OAuth or MCP-server token. Generate ad copy with character limits enforced server-side. Returns Meta primary text (≤125), headline (≤40), description (≤27), Google RSA 5 headlines (≤30 each), 4 descriptions (≤90 each). Hebrew, English, or Russian based on the brief language. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `brief` | string | yes | Plain-language brief: product, audience, key benefit, tone. | | `language` | string | | One of: `he`, `en`, `ru`, `auto` · Default: `"auto"` | | `cta_type` | string | | Optional. e.g. SHOP_NOW, SIGN_UP, LEARN_MORE. |
### `nc_research_business_from_url` read Works with `mcp:read`. Light, by-the-book research from a public URL. Accepts a generic https website OR an Instagram profile URL (https://instagram.com/{handle}). Returns a structured business profile (business_type, location_guess, target_audience_guess, primary_offer_guess, brand_voice, top_3_products). For Instagram: uses Facebook's official instagram_oembed endpoint ONLY — no headless browsing, no cookie use, no scraping past first response. For websites: server-side fetch of the first 8KB of body text with an identifying User-Agent. Use BEFORE asking the agency to retype the client's brief; bake the result into the elicitation message.
| Argument | Type | Required | Description | |---|---|---|---| | `url` | string | yes | Public https URL: a website OR https://instagram.com/{handle}. |
### `nc_create_skill` write Needs `mcp:write` on an OAuth or MCP-server token. Save a new reusable skill that the user designed in this conversation. Use this when the Skill Creator has gathered: name (short), description (one line), system_prompt (the instructions the skill should carry), and optionally tool_allowlist (array of MCP tool names) and default_model (OpenRouter model id). Persists to ai_skills scoped to the calling org. Returns the new skill id + slug.
| Argument | Type | Required | Description | |---|---|---|---| | `name` | string | yes | Short human-readable name (e.g. "Weekly Marketing Report"). | | `description` | string | | One-line description shown in the picker. | | `system_prompt` | string | yes | The instructions the skill carries — prepended to every conversation it is attached to. | | `icon` | string | | Optional lucide icon name (sparkles, file-text, presentation, file, mail, calendar). Defaults to sparkles. | | `tool_allowlist` | string[] | | Optional list of nc_* tool names the skill restricts itself to. | | `default_model` | string | | Optional OpenRouter model id the skill prefers (e.g. anthropic/claude-sonnet-4). |
--- # Automations URL: https://docs.nexacloser.com/mcp/tools/automations/ Run automations and read their runs. 4 tools: 3 read, 1 write. :::note[Generated] This page is generated from the MCP server source on every docs build. Names, descriptions and arguments are exactly what `tools/list` returns. ::: | Tool | Access | What it does | |---|---|---| | nc_run_automation | write | Trigger an existing NexaCloser automation by id, passing arbitrary JSON as trigger_data. | | nc_list_automations | read | List all automations for the authenticated user with id, name, trigger type, active state, and total runs. | | nc_get_automation_run | read | Get the status + step_results of a specific automation run by id. | | nc_list_recent_runs | read | List the most recent automation runs across all automations. | ### `nc_run_automation` write Needs `mcp:write` on an OAuth or MCP-server token. Trigger an existing NexaCloser automation by id, passing arbitrary JSON as trigger_data. Returns the run id and final status.
| Argument | Type | Required | Description | |---|---|---|---| | `automation_id` | string | yes | | | `trigger_data` | object | | |
### `nc_list_automations` read Works with `mcp:read`. List all automations for the authenticated user with id, name, trigger type, active state, and total runs. Use this to discover automation_id values for nc_run_automation.
| Argument | Type | Required | Description | |---|---|---|---| | `active_only` | boolean | | When true, only return active automations. · Default: `false` |
### `nc_get_automation_run` read Works with `mcp:read`. Get the status + step_results of a specific automation run by id. Use after nc_run_automation to confirm what happened.
| Argument | Type | Required | Description | |---|---|---|---| | `run_id` | string | yes | |
### `nc_list_recent_runs` read Works with `mcp:read`. List the most recent automation runs across all automations. Includes status, started_at, completed_at, and error_message for failed runs.
| Argument | Type | Required | Description | |---|---|---|---| | `automation_id` | string | | Optional — filter to one automation | | `status` | string | | One of: `completed`, `failed`, `running`, `all` · Default: `"all"` | | `from` | string | | ISO: started at/after this moment. | | `to` | string | | ISO: started before this moment. | | `limit` | integer | | Default: `10` · Min 1 · Max 50 | | `offset` | integer | | Skip this many rows (paging). · Default: `0` · Min 0 |
--- # Calendar and bookings URL: https://docs.nexacloser.com/mcp/tools/calendar/ Event types, free slots and bookings. 4 tools: 3 read, 1 write. :::note[Generated] This page is generated from the MCP server source on every docs build. Names, descriptions and arguments are exactly what `tools/list` returns. ::: | Tool | Access | What it does | |---|---|---| | nc_list_bookings | read | List calendar bookings of the organization. | | nc_create_booking | write | Book an appointment on one of the user's calendar event types. | | nc_get_available_slots | read | The free booking times of one calendar event type: exactly what its public booking page offers (working hours, special days, minimum notice, the booking window, existing bookings and blocked time are already applied). | | nc_list_event_types | read | List the calendar event types (booking link options) configured for the authenticated user. | ### `nc_list_bookings` read Works with `mcp:read`. List calendar bookings of the organization. `upcoming: true` = from now on, soonest first; otherwise newest first. Filter by host (the rep whose calendar it is), status, contact or date range (start time). `total` is the full match count.
| Argument | Type | Required | Description | |---|---|---|---| | `upcoming` | boolean | | Only bookings starting from now, soonest first. | | `host` | string | | Rep whose calendar / provider the booking is on: user id, email or name, or "me". | | `status` | string | | e.g. confirmed / cancelled / completed / no_show. | | `contact_id` | string | | | | `from` | string | | ISO: starting at/after this moment. | | `to` | string | | ISO: starting before this moment. | | `limit` | integer | | Default: `20` · Min 1 · Max 100 | | `offset` | integer | | Skip this many rows (paging). · Default: `0` · Min 0 |
### `nc_create_booking` write Needs `mcp:write` on an OAuth or MCP-server token. Book an appointment on one of the user's calendar event types. Use nc_list_event_types to find an event_type_id. Provide date (YYYY-MM-DD), time (HH:MM, 24h, in the given timezone) and the customer's name; email/phone optional. Optional provider_id pins the booking to a specific team member's calendar. Returns the created booking, or an error if the slot conflicts.
| Argument | Type | Required | Description | |---|---|---|---| | `event_type_id` | string | yes | | | `date` | string | yes | YYYY-MM-DD | | `time` | string | yes | HH:MM, 24h, on the BUSINESS clock (the timezone calendar-availability returned for this event type) | | `timezone` | string | | Deprecated and ignored: date/time are always read on the business timezone. Leave unset. | | `customer_name` | string | yes | | | `customer_email` | string | | | | `customer_phone` | string | | | | `answers` | object | | Answers to the event type booking questions, keyed by question | | `provider_id` | string | | Optional service_providers.id to pin the booking to a specific team member |
### `nc_get_available_slots` read Works with `mcp:read`. The free booking times of one calendar event type: exactly what its public booking page offers (working hours, special days, minimum notice, the booking window, existing bookings and blocked time are already applied). Times are HH:MM on the business clock (`timezone`; `now` is the current business time). Offer only these times, then book one with nc_create_booking using the same event_type_id and the date and time as listed.
| Argument | Type | Required | Description | |---|---|---|---| | `event_type_id` | string | yes | | | `provider_id` | string | | Optional service_providers.id: only this team member's free times (pass the same one to nc_create_booking). | | `days` | integer | | How many days ahead, today included. The calendar's own booking window still applies. · Default: `14` · Min 1 · Max 31 | | `max_slots` | integer | | At most this many times in total, soonest first. · Default: `30` · Min 1 · Max 100 |
### `nc_list_event_types` read Works with `mcp:read`. List the calendar event types (booking link options) configured for the authenticated user. Use this to discover event_type_id values when scheduling a booking. No arguments. --- # CRM: contacts, deals and tasks URL: https://docs.nexacloser.com/mcp/tools/crm/ Contacts, deals, pipelines, tasks, timeline activities, calls and the team. 19 tools: 11 read, 8 write. :::note[Generated] This page is generated from the MCP server source on every docs build. Names, descriptions and arguments are exactly what `tools/list` returns. ::: | Tool | Access | What it does | |---|---|---| | nc_find_contact | read | Find a NexaCloser CRM contact by phone or email. | | nc_list_recent_contacts | read | List the most recently-created CRM contacts in the caller's organization (only contacts the caller may see; deleted contacts excluded). | | nc_create_contact | write | Create a new NexaCloser CRM contact. | | nc_update_contact | write | Update an existing NexaCloser CRM contact by id. | | nc_add_tag | write | Append one or more tags to a contact. | | nc_list_deals | read | List CRM deals the caller may see (org owners and members with "all data" see every rep's deals). | | nc_create_deal | write | Create a new CRM deal. | | nc_search_contacts | read | Search contacts by partial name, phone or email. | | nc_get_contact | read | Get the full record for one contact by id, including tags, notes, company, deals count and recent activity count. | | nc_log_activity | write | Log an activity (note / call / email / meeting / task) against a contact and/or deal. | | nc_create_task | write | Create a follow-up task on the team Tasks board. | | nc_list_tasks | read | THE tool for tasks / "overdue tasks of <rep>" / "how many tasks are late": lists the team Tasks board (the Tasks page in the app). | | nc_list_activities | read | List CRM timeline activities logged on contacts / deals (notes, calls, meetings, emails, WhatsApp, and legacy "task"-type timeline entries). | | nc_list_calls | read | List phone calls (dialer / inbound) the caller may see — org owners and members with "all data" see every rep. | | nc_list_team_members | read | List the organization's team: user id, name, email, role (owner / admin / manager / agent), data scope and status. | | nc_move_deal_stage | write | Move a deal to a new stage in its pipeline. | | nc_close_deal | write | Close a deal as won or lost. | | nc_list_pipelines | read | List all CRM pipelines for the authenticated user, including their stages. | | nc_funnel_audit | read | Walks the closed-loop attribution path for a single contact/deal. | ### `nc_find_contact` read Works with `mcp:read`. Find a NexaCloser CRM contact by phone or email. Returns the contact record (id, name, phone, email, status, tags) or { found: false } if no match.
| Argument | Type | Required | Description | |---|---|---|---| | `phone` | string | | Phone number (any format — auto-normalised) | | `email` | string | | Email address |
### `nc_list_recent_contacts` read Works with `mcp:read`. List the most recently-created CRM contacts in the caller's organization (only contacts the caller may see; deleted contacts excluded). Filter by assigned rep, status, tag or creation date. Defaults to 20. Returns `count` (this page) and `total` (every match — with no filters, the number on the Contacts page).
| Argument | Type | Required | Description | |---|---|---|---| | `assigned_to` | string | | Rep: user id, email or name (see nc_list_team_members), or "me". | | `status` | string | | Contact status, e.g. lead / customer. | | `tag` | string | | Only contacts carrying this tag. | | `created_after` | string | | ISO date/timestamp. | | `created_before` | string | | ISO date/timestamp. | | `limit` | integer | | Default: `20` · Min 1 · Max 100 | | `offset` | integer | | Skip this many rows (paging). · Default: `0` · Min 0 |
### `nc_create_contact` write Needs `mcp:write` on an OAuth or MCP-server token. Create a new NexaCloser CRM contact. Either phone or email is required. Existing contacts with the same phone are updated (upsert).
| Argument | Type | Required | Description | |---|---|---|---| | `full_name` | string | | | | `phone` | string | | | | `email` | string | | | | `source` | string | | Where the lead came from. One of whatsapp, manual, import, api, webhook, facebook, google, tiktok, linkedin, landing_page, meeting, instagram, messenger, embed_form, webinar, organic, booking, call, sms, x — or any other label, which is kept as the source channel. Omit for api. Set on create only: an existing contact keeps its first source. | | `notes` | string | | | | `tags` | string[] | | | | `attribution` | object | | Ad click / UTM data for this touch (utm_source, utm_medium, utm_campaign, utm_content, utm_term, gclid, fbclid, ttclid, campaign_id, adset_id, ad_id, landing_url, referrer). The first touch is kept forever; the last touch is updated. | | `preferred_language` | string | | Language for outbound messages to this contact (email/SMS/WhatsApp). he = Hebrew, en = English, ru = Russian. Omit to inherit the business default. · One of: `he`, `en`, `ru` |
### `nc_update_contact` write Needs `mcp:write` on an OAuth or MCP-server token. Update an existing NexaCloser CRM contact by id.
| Argument | Type | Required | Description | |---|---|---|---| | `contact_id` | string | yes | | | `full_name` | string | | | | `phone` | string | | | | `email` | string | | | | `notes` | string | | | | `status` | string | | | | `attribution` | object | | Ad click / UTM data for this touch (utm_source, utm_medium, utm_campaign, utm_content, utm_term, gclid, fbclid, ttclid, campaign_id, adset_id, ad_id, landing_url, referrer). The first touch is kept forever; the last touch is updated. | | `preferred_language` | string | | Language for outbound messages to this contact. he = Hebrew, en = English, ru = Russian. · One of: `he`, `en`, `ru` |
### `nc_add_tag` write Needs `mcp:write` on an OAuth or MCP-server token. Append one or more tags to a contact. Existing tags are preserved (set union).
| Argument | Type | Required | Description | |---|---|---|---| | `contact_id` | string | yes | | | `tags` | string[] | yes | Min items 1 |
### `nc_list_deals` read Works with `mcp:read`. List CRM deals the caller may see (org owners and members with "all data" see every rep's deals). Filter by rep, status (open / won / lost), pipeline, stage, contact, creation date or close date. Newest first. `total` is the full match count, for "how many" questions.
| Argument | Type | Required | Description | |---|---|---|---| | `assigned_to` | string | | Rep: user id, email or name (see nc_list_team_members), or "me". | | `status` | string | | One of: `open`, `won`, `lost`, `all` · Default: `"all"` | | `pipeline_id` | string | | | | `stage_id` | string | | | | `contact_id` | string | | | | `created_after` | string | | ISO date/timestamp. | | `created_before` | string | | ISO date/timestamp. | | `closed_after` | string | | ISO: won or lost at/after this moment. | | `closed_before` | string | | ISO: won or lost before this moment. | | `limit` | integer | | Default: `20` · Min 1 · Max 100 | | `offset` | integer | | Skip this many rows (paging). · Default: `0` · Min 0 |
### `nc_create_deal` write Needs `mcp:write` on an OAuth or MCP-server token. Create a new CRM deal. Requires contact_id and title; optionally pipeline_id, stage_id, value.
| Argument | Type | Required | Description | |---|---|---|---| | `contact_id` | string | yes | | | `title` | string | yes | | | `pipeline_id` | string | | | | `stage_id` | string | | Default: `"new"` | | `value` | number | | |
### `nc_search_contacts` read Works with `mcp:read`. Search contacts by partial name, phone or email. Fuzzy match across all three fields. Returns up to `limit` newest matches.
| Argument | Type | Required | Description | |---|---|---|---| | `query` | string | yes | Min length 2 | | `limit` | integer | | Default: `10` · Min 1 · Max 50 | | `offset` | integer | | Skip this many rows (paging). · Default: `0` · Min 0 |
### `nc_get_contact` read Works with `mcp:read`. Get the full record for one contact by id, including tags, notes, company, deals count and recent activity count.
| Argument | Type | Required | Description | |---|---|---|---| | `contact_id` | string | yes | |
### `nc_log_activity` write Needs `mcp:write` on an OAuth or MCP-server token. Log an activity (note / call / email / meeting / task) against a contact and/or deal. Becomes part of the timeline visible in the CRM.
| Argument | Type | Required | Description | |---|---|---|---| | `title` | string | yes | | | `description` | string | | | | `type` | string | | One of: `note`, `call`, `email`, `meeting`, `task`, `whatsapp` · Default: `"note"` | | `contact_id` | string | | | | `deal_id` | string | | | | `due_at` | string | | ISO timestamp for scheduled activities | | `dry_run` | boolean | | |
### `nc_create_task` write Needs `mcp:write` on an OAuth or MCP-server token. Create a follow-up task on the team Tasks board. Status defaults to "todo". Assigned to the caller unless assigned_to names a teammate. Optional priority and due_date.
| Argument | Type | Required | Description | |---|---|---|---| | `title` | string | yes | | | `description` | string | | | | `assigned_to` | string | | Teammate to assign: user id, email, or name (see nc_list_team_members). "me" or omitted = the caller. | | `contact_id` | string | | | | `deal_id` | string | | | | `due_date` | string | | ISO date or timestamp | | `priority` | string | | One of: `low`, `medium`, `high`, `urgent` · Default: `"medium"` | | `dry_run` | boolean | | |
### `nc_list_tasks` read Works with `mcp:read`. THE tool for tasks / "overdue tasks of <rep>" / "how many tasks are late": lists the team Tasks board (the Tasks page in the app). Org owners, admins and managers see every teammate's tasks; other members see the tasks assigned to them (and, unless limited to assigned data, the ones they created). Filter by assignee (user id, email or name), overdue, due-date range, contact, deal, priority. "open" = anything not done. Sorted by due date ascending. `total` is the full match count, for "how many" questions. Default 20.
| Argument | Type | Required | Description | |---|---|---|---| | `status` | string | | One of: `open`, `todo`, `in_progress`, `review`, `done`, `all` · Default: `"open"` | | `assigned_to` | string | | User id, email or name of a teammate (see nc_list_team_members), "me", "unassigned", or "all" (default). | | `overdue` | boolean | | Only tasks past their due date that are not done. | | `due_before` | string | | ISO date/timestamp: due before this moment. | | `due_after` | string | | ISO date/timestamp: due at or after this moment. | | `contact_id` | string | | | | `deal_id` | string | | | | `priority` | string | | One of: `low`, `medium`, `high`, `urgent` | | `limit` | integer | | Default: `20` · Min 1 · Max 100 | | `offset` | integer | | Skip this many rows (paging). · Default: `0` · Min 0 |
### `nc_list_activities` read Works with `mcp:read`. List CRM timeline activities logged on contacts / deals (notes, calls, meetings, emails, WhatsApp, and legacy "task"-type timeline entries). NOT the Tasks board: for tasks / overdue tasks of a rep use nc_list_tasks. Org owners and members with "all data" see every rep. Filter by rep (assigned to, or logged by when unassigned), type, contact, deal, open / overdue (due and not completed) and date range. Newest first; `total` is the full match count.
| Argument | Type | Required | Description | |---|---|---|---| | `assigned_to` | string | | Rep: user id, email or name (see nc_list_team_members), or "me". | | `type` | string | | One of: `note`, `call`, `email`, `meeting`, `task`, `whatsapp` | | `contact_id` | string | | | | `deal_id` | string | | | | `open` | boolean | | Only activities not completed yet. | | `overdue` | boolean | | Only activities past their due time and not completed. | | `from` | string | | ISO: created at/after this moment. | | `to` | string | | ISO: created before this moment. | | `limit` | integer | | Default: `20` · Min 1 · Max 100 | | `offset` | integer | | Skip this many rows (paging). · Default: `0` · Min 0 |
### `nc_list_calls` read Works with `mcp:read`. List phone calls (dialer / inbound) the caller may see — org owners and members with "all data" see every rep. Filter by rep, direction, status, disposition, contact or date range. Newest first. Returns `total` (full match count) and `total_duration_seconds` for the matching calls on this page.
| Argument | Type | Required | Description | |---|---|---|---| | `user` | string | | Rep who made / took the call: user id, email or name, or "me". | | `direction` | string | | One of: `inbound`, `outbound` | | `status` | string | | e.g. completed / no-answer / busy / failed / initiated. | | `disposition` | string | | | | `contact_id` | string | | | | `from` | string | | ISO: at/after this moment. | | `to` | string | | ISO: before this moment. | | `limit` | integer | | Default: `20` · Min 1 · Max 100 | | `offset` | integer | | Skip this many rows (paging). · Default: `0` · Min 0 |
### `nc_list_team_members` read Works with `mcp:read`. List the organization's team: user id, name, email, role (owner / admin / manager / agent), data scope and status. Use it to turn a teammate's name into the user id other tools take (e.g. nc_list_tasks assigned_to).
| Argument | Type | Required | Description | |---|---|---|---| | `status` | string | | One of: `active`, `all` · Default: `"active"` |
### `nc_move_deal_stage` write Needs `mcp:write` on an OAuth or MCP-server token. Move a deal to a new stage in its pipeline. Records the stage change in crm_deal_stage_history.
| Argument | Type | Required | Description | |---|---|---|---| | `deal_id` | string | yes | | | `stage_id` | string | yes | | | `dry_run` | boolean | | |
### `nc_close_deal` write Needs `mcp:write` on an OAuth or MCP-server token. Close a deal as won or lost. Sets status + closed_at and (for won) records the final value.
| Argument | Type | Required | Description | |---|---|---|---| | `deal_id` | string | yes | | | `outcome` | string | yes | One of: `won`, `lost` | | `final_value` | number | | Final closed-won value if different from deal.value | | `loss_reason` | string | | Free text — captured on lost deals | | `dry_run` | boolean | | |
### `nc_list_pipelines` read Works with `mcp:read`. List all CRM pipelines for the authenticated user, including their stages. Use this to discover pipeline_id and stage_id values for other tools. No arguments. ### `nc_funnel_audit` read Works with `mcp:read`. Walks the closed-loop attribution path for a single contact/deal. Answers 'which ad sourced this deal?' in one tool call. Pass exactly one of: contact_id, deal_id, phone, email. Returns timeline: first_touch, last_touch, conversions[], total_touches. Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `contact_id` | string | | | | `deal_id` | string | | | | `phone` | string | | | | `email` | string | | |
--- # Google Ads URL: https://docs.nexacloser.com/mcp/tools/google-ads/ Campaigns, ad groups, ads, keywords, assets, audiences, experiments and conversions. 80 tools: 12 read, 68 write. :::note[Generated] This page is generated from the MCP server source on every docs build. Names, descriptions and arguments are exactly what `tools/list` returns. ::: | Tool | Access | What it does | |---|---|---| | nc_set_campaign_status | write | Pause or enable a Google Ads campaign. | | nc_set_ad_group_status | write | Pause or enable a Google Ads ad group. | | nc_set_ad_status | write | Pause or enable an individual Google Ads ad (creative). | | nc_update_campaign_budget | write | Set a new daily budget on a Google Ads campaign. | | nc_update_ad_copy | write | Replace the headlines and descriptions of a Google Ads ResponsiveSearchAd. | | nc_add_negative_keyword | write | Add a campaign-level negative keyword on Google Ads. | | nc_create_customer_list | write | Create a CRM_BASED_USER_LIST (Customer Match audience) on Google Ads. | | nc_add_contacts_to_customer_list | write | Add contacts (hashed email + phone) to a Customer Match user list. customer_id is the Google Ads CID; user_list_resource_name comes from nc_create_customer_list. | | nc_send_offline_conversion | write | Upload a single offline click conversion to Google Ads. customer_id is the Google Ads CID (digits, no hyphens) — conversions operate at customer-id level. | | nc_google_ads_update_campaign_bidding_strategy | write | Set the bidding strategy on a Google Ads campaign. | | nc_google_ads_update_campaign_location_language | write | Add geo target and/or language criteria to a Google Ads campaign. | | nc_google_ads_update_campaign_ad_schedule | write | Set ad schedule criteria on a Google Ads campaign. | | nc_google_ads_rename_campaign | write | Rename a Google Ads campaign. | | nc_google_ads_search_geo_targets | read | Search Google Ads geo target constants by name (e.g. "Tel Aviv", "Israel"). | | nc_google_ads_create_ad_group | write | Create a Google Ads ad group under an existing campaign. | | nc_google_ads_update_ad_group_status | write | Set the status of a Google Ads ad group to ENABLED, PAUSED, or REMOVED. | | nc_google_ads_update_ad_group_bid | write | Update the CPC bid or Target CPA bid on a Google Ads ad group. | | nc_google_ads_rename_ad_group | write | Rename a Google Ads ad group. | | nc_google_ads_add_keyword_to_ad_group | write | Add a positive keyword to a Google Ads ad group. | | nc_google_ads_update_keyword_status | write | Set the status of a Google Ads keyword criterion to ENABLED, PAUSED, or REMOVED. | | nc_google_ads_update_keyword_bid | write | Change the max-CPC bid on an existing Google Ads keyword criterion. | | nc_google_ads_add_negative_keywords_to_ad_groups | write | Bulk-add negative keywords at the ad-group level. | | nc_google_ads_edit_responsive_search_ad | write | Edit a Responsive Search Ad: update headlines (3-15, max 30 chars), descriptions (2-4, max 90 chars), and/or final_urls. | | nc_google_ads_update_ad_status | write | Set the status of a Google Ads ad (adGroupAd) to ENABLED, PAUSED, or REMOVED. | | nc_google_ads_list_audience_segments | read | List Google Ads user lists (audience segments) in the account. | | nc_google_ads_target_audience_segments | write | Add audience targeting criteria (user list segments) to a campaign or ad group. scope is "campaign" or "ad_group". segment_resource_names from nc_google_ads_list_audience_segments. | | nc_google_ads_exclude_audience_segments | write | Add negative audience exclusion criteria to a campaign or ad group. | | nc_google_create_search_campaign | write | Create a Google Search campaign in PAUSED state. | | nc_google_create_ad_group | write | Create an ad group under an existing campaign. | | nc_google_create_responsive_search_ad | write | Create a Responsive Search Ad under an existing ad group. | | nc_google_create_negative_keyword_list | write | Create a Google Ads SharedSet of negative keywords (NEGATIVE_KEYWORDS type) and populate it. | | nc_google_apply_negative_keyword_list_to_campaigns | write | Attach an existing SharedSet (negative keyword list) to one or more campaigns. | | nc_google_rename_campaign | write | Rename an existing Google Ads campaign (update on `name` field, updateMask=name). | | nc_google_rename_ad_group | write | Rename an existing Google Ads ad group (update on `name` field, updateMask=name). | | nc_google_keyword_planner | read | Generate keyword ideas via Google Ads Keyword Planner. | | nc_google_run_gaql_query | read | Execute a Google Ads Query Language (GAQL) SELECT statement against the given customer. | | nc_google_ads_list_keywords | read | List Google Ads search keywords — active and/or paused — with match type, status, and Quality Score components: quality_score (1-10), landing_page_experience, expected_ctr, ad_relevance. | | nc_google_ads_list_ad_copy | read | List Google ads with their full creative copy: responsive search ad headlines and descriptions (with pinning), display paths, and final URLs, plus ad type and status. | | nc_google_ads_manage_portfolio_bidding_strategy | write | Create or update a reusable (portfolio / account-level) Google Ads bidding strategy with optional bid limits. | | nc_google_ads_assign_portfolio_bidding_strategy | write | Attach a portfolio bidding strategy to one or more campaigns. | | nc_google_ads_create_pmax_asset_group | write | Create an Asset Group under a Performance Max (PMax) campaign. | | nc_google_ads_update_product_groups | write | Replace the listing-group tree for a Shopping ad group. | | nc_google_ads_update_audience_signals | write | Add or remove audience segments on a PMax or Demand Gen asset group. segment_ids are Google Ads audience resource names, e.g. "userInterests/123" or "userLists/456". | | nc_google_ads_create_responsive_display_ad | write | Create a Responsive Display Ad (RDA) under an ad group. | | nc_google_ads_create_demand_gen_single_image_ad | write | Create a Demand Gen single-image ad under an ad group. | | nc_google_ads_create_demand_gen_video_ad | write | Create a Demand Gen video ad under an ad group using YouTube video IDs. | | nc_google_ads_create_demand_gen_carousel_ad | write | Create a Demand Gen carousel ad with 2-10 cards. | | nc_google_ads_create_negative_keyword_list | write | Create a Google Ads SharedSet of type NEGATIVE_KEYWORDS and populate it. | | nc_google_ads_create_placement_exclusion_list | write | Create a Google Ads SharedSet of type NEGATIVE_PLACEMENTS and populate it with URLs. | | nc_google_ads_add_placements_to_exclusion_list | write | Add placement URLs to an existing NEGATIVE_PLACEMENTS SharedSet. | | nc_google_ads_add_keywords_to_negative_list | write | Add keywords to an existing NEGATIVE_KEYWORDS SharedSet. | | nc_google_ads_apply_exclusion_list_to_campaigns | write | Attach a SharedSet (negative-keyword or placement-exclusion) to one or more campaigns by creating CampaignSharedSet links. | | nc_google_ads_manage_ip_exclusions | write | Add or remove IP address exclusions (IP_BLOCK campaign criteria) on a campaign. action=add: provide IP/CIDR strings. action=remove: provide the full campaign criterion resource names. | | nc_google_ads_create_sitelink_assets | write | Create sitelink assets and optionally attach them to campaigns or ad groups. | | nc_google_ads_create_callout_assets | write | Create callout assets (1-20 items, each max 25 chars) and optionally attach them to campaigns or ad groups. | | nc_google_ads_create_structured_snippet_assets | write | Create structured snippet assets and optionally attach them. header: Google predefined header (e.g. "Brands", "Services", "Models"). values: 3-10 items. | | nc_google_ads_create_promotion_assets | write | Create a promotion (discount/coupon) asset and optionally attach to campaigns. | | nc_google_ads_create_image_asset | write | Upload an image and create an IMAGE asset in Google Ads. | | nc_google_ads_create_headline_assets | write | Create one or more HEADLINE text assets (1-20 items, each max 30 chars). | | nc_google_ads_create_description_assets | write | Create one or more DESCRIPTION text assets (1-20 items, each max 90 chars). | | nc_google_ads_update_asset_status | write | Update the status (ENABLED/PAUSED/REMOVED) of an asset link within a campaign, ad group, or at customer level. scope: campaign \| ad_group \| customer. field_type: e.g. SITELINK, CALLOUT, STRUCTURED_SNIPPET. | | nc_google_ads_create_label | write | Create an account-level label in Google Ads. | | nc_google_ads_manage_label_assignment | write | Attach or detach a label from campaigns, ad groups, ads, keywords, or a customer. action: attach \| detach. scope: campaign \| ad_group \| ad \| keyword \| customer. resource_ids: bare numeric ids or full resource names. | | nc_google_ads_mutate | write | Generic Google Ads mutate escape-hatch. | | nc_google_ads_upload_conversion_adjustments | write | Retract, restate, or enhance conversions already reported to Google Ads. | | nc_google_ads_create_conversion_action | write | Define a new conversion action (what counts as a conversion). category must be a Google ConversionActionCategory: DEFAULT, PURCHASE, PAGE_VIEW, SIGNUP, SUBMIT_LEAD_FORM, PHONE_CALL_LEAD, BOOK_APPOINTMENT, CONTACT, DOWNLOAD, ADD_TO_CART, BEGIN_CHECKOUT, REQUEST_QUOTE (NOT "LEAD"/"SIGN_UP" — those are rejected). type e.g. WEBPAGE/UPLOAD_CLICKS/UPLOAD_CALLS/AD_CALL. | | nc_google_ads_update_conversion_action | write | Update an existing conversion action (rename, pause/enable, change default value/currency). | | nc_google_ads_apply_recommendation | write | Apply one or more Google Ads recommendations (found via GAQL `SELECT .. | | nc_google_ads_dismiss_recommendation | read | Dismiss one or more Google Ads recommendations so they stop surfacing. | | nc_google_ads_create_lead_form_asset | write | Create a lead-form asset and optionally attach it to campaigns. | | nc_google_ads_create_call_asset | write | Create a call (phone) asset and optionally attach it to campaigns. | | nc_google_ads_create_price_asset | write | Create a price asset (3-8 offerings) and optionally attach it to campaigns. | | nc_google_ads_create_campaign_draft | write | Create a campaign draft — a sandbox copy of an existing campaign where you can stage changes before testing them in an experiment. | | nc_google_ads_create_experiment | write | Create a Google Ads experiment (A/B test). | | nc_google_ads_schedule_experiment | read | Schedule (start) a Google Ads experiment that is set up. | | nc_google_ads_promote_experiment | read | Promote a Google Ads experiment — applies the treatment changes back onto the original (base) campaign. | | nc_google_ads_end_experiment | read | End (stop) a running Google Ads experiment. | | nc_google_ads_graduate_experiment | read | Graduate a Google Ads experiment — converts the experiment (trial) campaign into a standalone permanent campaign. | | nc_google_ads_create_billing_setup | write | MONEY-SENSITIVE. | | nc_google_ads_propose_account_budget | read | MONEY-SENSITIVE. | ### `nc_set_campaign_status` write Needs `mcp:write` on an OAuth or MCP-server token. Pause or enable a Google Ads campaign. Pass campaign_id from nc_list_campaigns. Use dry_run: true to preview the change without applying it. Requires marketing.edit permission.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | Google Ads connection id (uuid). Find via the connections list. | | `campaign_id` | string | yes | Google Ads platform_campaign_id (numeric, as string). Get from nc_list_campaigns. | | `status` | string | yes | New campaign status. · One of: `ENABLED`, `PAUSED` | | `dry_run` | boolean | | Preview only — does not call Google. Writes a dry_run row to marketing_mutations. |
### `nc_set_ad_group_status` write Needs `mcp:write` on an OAuth or MCP-server token. Pause or enable a Google Ads ad group. Pauses every ad inside it implicitly via Google. Use dry_run: true to preview. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_group_id` | string | yes | Google Ads platform_ad_group_id. | | `status` | string | yes | One of: `ENABLED`, `PAUSED` | | `dry_run` | boolean | | |
### `nc_set_ad_status` write Needs `mcp:write` on an OAuth or MCP-server token. Pause or enable an individual Google Ads ad (creative). Get ad_id from nc_list_ads. Use dry_run: true to preview. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_id` | string | yes | Google Ads platform_ad_id. | | `status` | string | yes | One of: `ENABLED`, `PAUSED` | | `dry_run` | boolean | | |
### `nc_update_campaign_budget` write Needs `mcp:write` on an OAuth or MCP-server token. Set a new daily budget on a Google Ads campaign. The amount is in the caller currency (e.g. ILS) — the edge converts to micros for Google. Use dry_run: true to preview. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `campaign_id` | string | yes | | | `daily_budget_amount` | number | yes | New daily budget in the campaign currency. e.g. 50 = ₪50 / day for ILS accounts. · Min 0.01 | | `dry_run` | boolean | | |
### `nc_update_ad_copy` write Needs `mcp:write` on an OAuth or MCP-server token. Replace the headlines and descriptions of a Google Ads ResponsiveSearchAd. Google constraints: 3–15 headlines (≤30 chars each), 2–4 descriptions (≤90 chars each). Use dry_run: true to preview. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_id` | string | yes | | | `headlines` | string[] | yes | Min items 3 · Max items 15 | | `descriptions` | string[] | yes | Min items 2 · Max items 4 | | `dry_run` | boolean | | |
### `nc_add_negative_keyword` write Needs `mcp:write` on an OAuth or MCP-server token. Add a campaign-level negative keyword on Google Ads. Requires marketing.edit. Use dry_run: true to preview.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `campaign_id` | string | yes | Google Ads platform_campaign_id. | | `text` | string | yes | Keyword text. | | `match_type` | string | | One of: `BROAD`, `PHRASE`, `EXACT` · Default: `"BROAD"` | | `dry_run` | boolean | | |
### `nc_create_customer_list` write Needs `mcp:write` on an OAuth or MCP-server token. Create a CRM_BASED_USER_LIST (Customer Match audience) on Google Ads. Note: customer_id is the Google Ads CID (digits, no hyphens), not an internal id — Customer Match operates at customer-id level, not campaign level. Use dry_run: true to preview. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | Google Ads CID (digits, no hyphens). | | `list_name` | string | yes | | | `description` | string | | | | `membership_lifespan_days` | integer | | 1..540, or 10000 for unlimited. · Min 1 · Max 10000 | | `dry_run` | boolean | | |
### `nc_add_contacts_to_customer_list` write Needs `mcp:write` on an OAuth or MCP-server token. Add contacts (hashed email + phone) to a Customer Match user list. customer_id is the Google Ads CID; user_list_resource_name comes from nc_create_customer_list. Uses Google's OfflineUserDataJob lifecycle. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | Google Ads CID (digits, no hyphens). | | `user_list_resource_name` | string | yes | Full resource name: customers/{cid}/userLists/{id} | | `contacts` | object[] | yes | Min items 1 | | `contacts[].email` | string | | | | `contacts[].phone` | string | | | | `dry_run` | boolean | | |
### `nc_send_offline_conversion` write Needs `mcp:write` on an OAuth or MCP-server token. Upload a single offline click conversion to Google Ads. customer_id is the Google Ads CID (digits, no hyphens) — conversions operate at customer-id level. Provide gclid OR enhanced_email/enhanced_phone (for enhanced conversions). Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | Google Ads CID (digits, no hyphens). | | `conversion_action_id` | string | yes | | | `gclid` | string | | | | `conversion_date_time` | string | yes | YYYY-MM-DD HH:MM:SS+HH:MM | | `conversion_value` | number | | | | `currency_code` | string | | | | `enhanced_email` | string | | | | `enhanced_phone` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_update_campaign_bidding_strategy` write Needs `mcp:write` on an OAuth or MCP-server token. Set the bidding strategy on a Google Ads campaign. Supports TARGET_CPA (requires target_cpa_micros), TARGET_ROAS (requires target_roas), MAXIMIZE_CONVERSIONS, MAXIMIZE_CLICKS, MANUAL_CPC. Use dry_run: true to preview. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | Google Ads connection id (uuid). | | `customer_id` | string | yes | Google Ads CID (digits, no hyphens). | | `campaign_id` | string | yes | Bare numeric campaign id or full resource name. | | `bidding_strategy_type` | string | yes | One of: `TARGET_CPA`, `TARGET_ROAS`, `MAXIMIZE_CONVERSIONS`, `MAXIMIZE_CLICKS`, `MANUAL_CPC` | | `target_cpa_micros` | number | | Required when bidding_strategy_type=TARGET_CPA. | | `target_roas` | number | | Required when bidding_strategy_type=TARGET_ROAS. e.g. 2.5 = 250%. | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_update_campaign_location_language` write Needs `mcp:write` on an OAuth or MCP-server token. Add geo target and/or language criteria to a Google Ads campaign. Pass geo_target_ids (e.g. ["2376"] for Israel) and/or language_ids (e.g. ["1037"] for Hebrew). Use nc_google_ads_search_geo_targets to look up IDs. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `campaign_id` | string | yes | | | `geo_target_ids` | string[] | | geoTargetConstant IDs, e.g. ["2376"] for Israel. | | `language_ids` | string[] | | languageConstant IDs, e.g. ["1037"] for Hebrew. | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_update_campaign_ad_schedule` write Needs `mcp:write` on an OAuth or MCP-server token. Set ad schedule criteria on a Google Ads campaign. Each slot specifies day, start_hour (0-23), end_hour (1-24), and optional bid_modifier (0.1-10). Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `campaign_id` | string | yes | | | `schedule` | object[] | yes | Min items 1 | | `schedule[].day` | string | yes | One of: `MONDAY`, `TUESDAY`, `WEDNESDAY`, `THURSDAY`, `FRIDAY`, `SATURDAY`, `SUNDAY` | | `schedule[].start_hour` | integer | yes | Min 0 · Max 23 | | `schedule[].end_hour` | integer | yes | Min 1 · Max 24 | | `schedule[].bid_modifier` | number | | Min 0.1 · Max 10 | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_rename_campaign` write Needs `mcp:write` on an OAuth or MCP-server token. Rename a Google Ads campaign. Requires marketing.edit. Use dry_run: true to preview.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `campaign_id` | string | yes | Bare numeric campaign id or full resource name. | | `new_name` | string | yes | Max length 255 | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_search_geo_targets` read Works with `mcp:read`. Search Google Ads geo target constants by name (e.g. "Tel Aviv", "Israel"). Returns resource_name and id for use in nc_google_ads_update_campaign_location_language. Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | Google Ads CID (needed for GAQL auth context). | | `query` | string | yes | Geo name to search, e.g. "Tel Aviv". | | `limit` | integer | | Max results, default 25. · Min 1 · Max 100 | | `login_customer_id` | string | | |
### `nc_google_ads_create_ad_group` write Needs `mcp:write` on an OAuth or MCP-server token. Create a Google Ads ad group under an existing campaign. Always created PAUSED. Use dry_run: true to preview. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `campaign_id` | string | yes | Bare numeric campaign id or full resource name. | | `name` | string | yes | Max length 255 | | `default_cpc_bid_amount` | number | | Default CPC bid in account currency. | | `ad_group_type` | string | | One of: `SEARCH_STANDARD`, `DISPLAY_STANDARD` | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_update_ad_group_status` write Needs `mcp:write` on an OAuth or MCP-server token. Set the status of a Google Ads ad group to ENABLED, PAUSED, or REMOVED. Accepts bare numeric ad group id or full resource name. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `ad_group_id` | string | yes | Bare numeric ad group id or full resource name. | | `status` | string | yes | One of: `ENABLED`, `PAUSED`, `REMOVED` | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_update_ad_group_bid` write Needs `mcp:write` on an OAuth or MCP-server token. Update the CPC bid or Target CPA bid on a Google Ads ad group. Provide exactly one of cpc_bid_micros or target_cpa_micros. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `ad_group_id` | string | yes | | | `cpc_bid_micros` | number | | New CPC bid in micros. Mutually exclusive with target_cpa_micros. | | `target_cpa_micros` | number | | New Target CPA in micros. Mutually exclusive with cpc_bid_micros. | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_rename_ad_group` write Needs `mcp:write` on an OAuth or MCP-server token. Rename a Google Ads ad group. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `ad_group_id` | string | yes | | | `new_name` | string | yes | Max length 255 | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_add_keyword_to_ad_group` write Needs `mcp:write` on an OAuth or MCP-server token. Add a positive keyword to a Google Ads ad group. Specify match_type: BROAD, PHRASE, or EXACT. Optionally set a per-keyword CPC bid in micros. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `ad_group_id` | string | yes | | | `text` | string | yes | Keyword text. | | `match_type` | string | yes | One of: `BROAD`, `PHRASE`, `EXACT` | | `cpc_bid_micros` | number | | Per-keyword CPC bid override in micros. | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_update_keyword_status` write Needs `mcp:write` on an OAuth or MCP-server token. Set the status of a Google Ads keyword criterion to ENABLED, PAUSED, or REMOVED. Pass the full criterion resource name. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `criterion_resource_name` | string | yes | Full resource name: customers/{cid}/adGroupCriteria/{agId}~{criterionId}. | | `status` | string | yes | One of: `ENABLED`, `PAUSED`, `REMOVED` | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_update_keyword_bid` write Needs `mcp:write` on an OAuth or MCP-server token. Change the max-CPC bid on an existing Google Ads keyword criterion. Pass the full criterion resource name and the new bid in micros (1 unit = 1,000,000). Match type can't be changed on an existing keyword — remove + re-add for that. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `criterion_resource_name` | string | yes | Full resource name: customers/{cid}/adGroupCriteria/{agId}~{criterionId}. | | `cpc_bid_micros` | integer | yes | New max-CPC bid in micros (e.g. 1500000 = 1.50). · Min 0 | | `login_customer_id` | string | | | | `validate_only` | boolean | | Google's native validate_only — sends the real payload to Google in check-only mode (applies nothing). | | `dry_run` | boolean | | |
### `nc_google_ads_add_negative_keywords_to_ad_groups` write Needs `mcp:write` on an OAuth or MCP-server token. Bulk-add negative keywords at the ad-group level. Each entry specifies ad_group_id, text, and optional match_type. All entries sent in one :mutate call. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `entries` | object[] | yes | Min items 1 | | `entries[].ad_group_id` | string | yes | | | `entries[].text` | string | yes | | | `entries[].match_type` | string | | One of: `BROAD`, `PHRASE`, `EXACT` | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_edit_responsive_search_ad` write Needs `mcp:write` on an OAuth or MCP-server token. Edit a Responsive Search Ad: update headlines (3-15, max 30 chars), descriptions (2-4, max 90 chars), and/or final_urls. Pass the full ad resource name. At least one field required. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `ad_resource_name` | string | yes | Full resource name: customers/{cid}/adGroupAds/{agId}~{adId}. | | `headlines` | string[] | | Min items 3 · Max items 15 | | `descriptions` | string[] | | Min items 2 · Max items 4 | | `final_urls` | string[] | | Min items 1 | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_update_ad_status` write Needs `mcp:write` on an OAuth or MCP-server token. Set the status of a Google Ads ad (adGroupAd) to ENABLED, PAUSED, or REMOVED. Pass the full ad resource name. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `ad_resource_name` | string | yes | Full resource name: customers/{cid}/adGroupAds/{agId}~{adId}. | | `status` | string | yes | One of: `ENABLED`, `PAUSED`, `REMOVED` | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_list_audience_segments` read Works with `mcp:read`. List Google Ads user lists (audience segments) in the account. Filter by type or search by name. Read-only. Requires marketing.edit connection.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `type_filter` | string | | Filter by user_list.type, e.g. CUSTOMER_LIST or USER_INTEREST. | | `search_query` | string | | Substring match on user list name. | | `limit` | integer | | Max results, default 50. · Min 1 · Max 200 | | `login_customer_id` | string | | |
### `nc_google_ads_target_audience_segments` write Needs `mcp:write` on an OAuth or MCP-server token. Add audience targeting criteria (user list segments) to a campaign or ad group. scope is "campaign" or "ad_group". segment_resource_names from nc_google_ads_list_audience_segments. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `scope` | string | yes | One of: `campaign`, `ad_group` | | `resource_id` | string | yes | Campaign or ad group id / resource name. | | `segment_resource_names` | string[] | yes | Min items 1 | | `bid_modifier` | number | | Min 0.1 · Max 10 | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_exclude_audience_segments` write Needs `mcp:write` on an OAuth or MCP-server token. Add negative audience exclusion criteria to a campaign or ad group. Same shape as nc_google_ads_target_audience_segments but negative:true. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `scope` | string | yes | One of: `campaign`, `ad_group` | | `resource_id` | string | yes | | | `segment_resource_names` | string[] | yes | Min items 1 | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_create_search_campaign` write Needs `mcp:write` on an OAuth or MCP-server token. Create a Google Search campaign in PAUSED state. Two quota ops: (1) creates the CampaignBudget, (2) creates the Campaign referencing it. Targeting (geo, language) is NOT applied here — add via separate criteria tools. Bidding strategies: MAXIMIZE_CLICKS (default), MANUAL_CPC, TARGET_CPA. Requires marketing.edit. Use dry_run: true to preview.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | Google Ads CID, digits only. | | `name` | string | yes | | | `daily_budget_amount` | number | yes | Daily budget in account currency. · Min 0.01 | | `bidding_strategy_type` | string | | One of: `MAXIMIZE_CLICKS`, `MANUAL_CPC`, `TARGET_CPA` · Default: `"MAXIMIZE_CLICKS"` | | `target_cpa_amount` | number | | Required if bidding_strategy_type=TARGET_CPA. | | `manual_cpc_enhanced_cpc` | boolean | | Required if bidding_strategy_type=MANUAL_CPC. | | `network_search` | boolean | | Default: `true` | | `network_partners` | boolean | | Default: `false` | | `start_date` | string | | YYYYMMDD | | `end_date` | string | | YYYYMMDD | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_create_ad_group` write Needs `mcp:write` on an OAuth or MCP-server token. Create an ad group under an existing campaign. Forced PAUSED. One quota op. Pass campaign_id as bare numeric platform id (the resource name is built server-side). Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `campaign_id` | string | yes | | | `name` | string | yes | | | `default_cpc_bid_amount` | number | | Default CPC bid in account currency. Required for MANUAL_CPC parent campaigns. | | `ad_group_type` | string | | One of: `SEARCH_STANDARD`, `DISPLAY_STANDARD` · Default: `"SEARCH_STANDARD"` | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_create_responsive_search_ad` write Needs `mcp:write` on an OAuth or MCP-server token. Create a Responsive Search Ad under an existing ad group. Forced PAUSED. Google constraints enforced: 3-15 headlines (≤30 chars each), 2-4 descriptions (≤90 chars each), final_urls must be https. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `ad_group_id` | string | yes | | | `headlines` | string[] | yes | Min items 3 · Max items 15 | | `descriptions` | string[] | yes | Min items 2 · Max items 4 | | `final_urls` | string[] | yes | Min items 1 | | `path1` | string | | Max length 15 | | `path2` | string | | Max length 15 | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_create_negative_keyword_list` write Needs `mcp:write` on an OAuth or MCP-server token. Create a Google Ads SharedSet of negative keywords (NEGATIVE_KEYWORDS type) and populate it. Two quota ops: SharedSet create + bulk SharedCriteria create. Apply via nc_google_apply_negative_keyword_list_to_campaigns. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `list_name` | string | yes | | | `keywords` | object[] | yes | Min items 1 | | `keywords[].text` | string | yes | | | `keywords[].match_type` | string | | One of: `BROAD`, `PHRASE`, `EXACT` · Default: `"BROAD"` | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_apply_negative_keyword_list_to_campaigns` write Needs `mcp:write` on an OAuth or MCP-server token. Attach an existing SharedSet (negative keyword list) to one or more campaigns. Bulk-creates CampaignSharedSet rows in a single :mutate (one quota op). Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `shared_set_resource_name` | string | yes | customers/{cid}/sharedSets/{id} | | `campaign_ids` | string[] | yes | Min items 1 | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_rename_campaign` write Needs `mcp:write` on an OAuth or MCP-server token. Rename an existing Google Ads campaign (update on `name` field, updateMask=name). One quota op. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `campaign_id` | string | yes | | | `new_name` | string | yes | | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_rename_ad_group` write Needs `mcp:write` on an OAuth or MCP-server token. Rename an existing Google Ads ad group (update on `name` field, updateMask=name). One quota op. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `ad_group_id` | string | yes | | | `new_name` | string | yes | | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_keyword_planner` read Works with `mcp:read`. Generate keyword ideas via Google Ads Keyword Planner. Seed by `keywords[]`, `url`, or both. Returns ideas with avg monthly searches, competition LOW|MEDIUM|HIGH, competition_index 0-100, and top-of-page bid range in micros. Default targeting: Israel + Hebrew (override via geo_target_constants + language).
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | | NexaCloser google_ads connection uuid (from nc_list_marketing_connections). Optional — auto-resolves when you have one active Google Ads connection. | | `customer_id` | string | | Google Ads CID, digits only (no hyphens). Optional — auto-resolves when you have one active Google ad account. | | `keywords` | string[] | | Seed keywords. At least one of keywords[] or url is required. | | `url` | string | | Seed page url (https). At least one of keywords[] or url is required. | | `language` | string | | Default 'languageConstants/1037' (Hebrew). Use 'languageConstants/1000' for English. | | `geo_target_constants` | string[] | | Default ['geoTargetConstants/2376'] (Israel). | | `network` | string | | One of: `GOOGLE_SEARCH`, `GOOGLE_SEARCH_AND_PARTNERS` · Default: `"GOOGLE_SEARCH_AND_PARTNERS"` | | `include_adult_keywords` | boolean | | Default: `false` | | `page_size` | integer | | Default: `100` · Min 1 · Max 1000 |
### `nc_google_run_gaql_query` read Works with `mcp:read`. Execute a Google Ads Query Language (GAQL) SELECT statement against the given customer. Covers anything the dedicated tools do not: keywords, quality score, ad copy, assets, budgets, search terms, etc. Read-only — DML is rejected. Returns the raw response rows.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | | NexaCloser google_ads connection uuid (from nc_list_marketing_connections). Optional — auto-resolves when you have one active Google Ads connection. | | `customer_id` | string | | Google Ads CID, digits only. Optional — auto-resolves when you have one active Google ad account. | | `query` | string | yes | GAQL SELECT statement, e.g. SELECT campaign.id, campaign.name FROM campaign LIMIT 50 | | `page_size` | integer | | Default: `1000` · Min 1 · Max 10000 | | `login_customer_id` | string | | Manager-account login customer id (optional). |
### `nc_google_ads_list_keywords` read Works with `mcp:read`. List Google Ads search keywords — active and/or paused — with match type, status, and Quality Score components: quality_score (1-10), landing_page_experience, expected_ctr, ad_relevance. Filter by campaign_id or ad_group_id. connection_id/customer_id auto-resolve when you have a single active Google Ads connection/account. Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | | Optional — auto-resolves; explicit uuids via nc_list_marketing_connections. | | `customer_id` | string | | Google Ads CID, digits only. Optional — auto-resolves. | | `status` | string | | ENABLED = active keywords, PAUSED = paused keywords. · One of: `ENABLED`, `PAUSED`, `ALL` · Default: `"ALL"` | | `campaign_id` | string | | Numeric Google campaign id filter (optional). | | `ad_group_id` | string | | Numeric Google ad group id filter (optional). | | `limit` | integer | | Default: `200` · Min 1 · Max 1000 | | `login_customer_id` | string | | Manager-account login customer id (optional). |
### `nc_google_ads_list_ad_copy` read Works with `mcp:read`. List Google ads with their full creative copy: responsive search ad headlines and descriptions (with pinning), display paths, and final URLs, plus ad type and status. Filter by campaign_id, ad_group_id, or status. connection_id/customer_id auto-resolve when you have a single active Google Ads connection/account. Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | | Optional — auto-resolves; explicit uuids via nc_list_marketing_connections. | | `customer_id` | string | | Google Ads CID, digits only. Optional — auto-resolves. | | `status` | string | | One of: `ENABLED`, `PAUSED`, `ALL` · Default: `"ALL"` | | `campaign_id` | string | | Numeric Google campaign id filter (optional). | | `ad_group_id` | string | | Numeric Google ad group id filter (optional). | | `limit` | integer | | Default: `100` · Min 1 · Max 500 | | `login_customer_id` | string | | Manager-account login customer id (optional). |
### `nc_google_ads_manage_portfolio_bidding_strategy` write Needs `mcp:write` on an OAuth or MCP-server token. Create or update a reusable (portfolio / account-level) Google Ads bidding strategy with optional bid limits. Supported types: TARGET_CPA, TARGET_ROAS, MAXIMIZE_CONVERSIONS, MAXIMIZE_CONVERSION_VALUE, MAXIMIZE_CLICKS, TARGET_IMPRESSION_SHARE, ENHANCED_CPC. Supply resource_name to UPDATE an existing strategy. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | Google Ads CID, digits only. | | `name` | string | yes | | | `strategy_type` | string | yes | One of: `TARGET_CPA`, `TARGET_ROAS`, `MAXIMIZE_CONVERSIONS`, `MAXIMIZE_CONVERSION_VALUE`, `MAXIMIZE_CLICKS`, `TARGET_IMPRESSION_SHARE`, `ENHANCED_CPC` | | `target_cpa_micros` | number | | Target CPA in micros (1 ILS = 1,000,000 micros). Required for TARGET_CPA. | | `target_roas` | number | | Target ROAS as a decimal (e.g. 3.5 for 350%). Required for TARGET_ROAS. | | `target_impression_share_location` | string | | One of: `ANYWHERE_ON_PAGE`, `TOP_OF_PAGE`, `ABSOLUTE_TOP_OF_PAGE` | | `target_impression_share_fraction` | number | | 0.0-1.0 fraction. · Min 0 · Max 1 | | `bid_ceiling_micros` | number | | Max CPC bid ceiling in micros. | | `bid_floor_micros` | number | | Min CPC bid floor in micros (TARGET_CPA only). | | `resource_name` | string | | Supply to UPDATE: customers/{cid}/biddingStrategies/{id}. | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_assign_portfolio_bidding_strategy` write Needs `mcp:write` on an OAuth or MCP-server token. Attach a portfolio bidding strategy to one or more campaigns. Campaigns must belong to the same customer. One quota op per campaign. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `bidding_strategy_resource_name` | string | yes | customers/{cid}/biddingStrategies/{id} | | `campaign_ids` | string[] | yes | Min items 1 | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_create_pmax_asset_group` write Needs `mcp:write` on an OAuth or MCP-server token. Create an Asset Group under a Performance Max (PMax) campaign. Requires 3-5 headlines, 1-5 long_headlines, 2-5 descriptions, business_name, and final_urls. Pass image asset resource names (from nc_google_ads_create_image_asset) for images/logos, or YouTube video IDs for videos. Forced PAUSED by default. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `campaign_id` | string | yes | Must be a PMax campaign. | | `name` | string | yes | | | `final_urls` | string[] | yes | Min items 1 | | `headlines` | string[] | yes | Min items 3 · Max items 5 | | `long_headlines` | string[] | yes | Min items 1 · Max items 5 | | `descriptions` | string[] | yes | Min items 2 · Max items 5 | | `business_name` | string | yes | Max length 25 | | `images` | string[] | | Asset resource names (marketing_image type). | | `logos` | string[] | | Asset resource names (logo type). | | `videos` | string[] | | YouTube video IDs or asset resource names. | | `status` | string | | One of: `ENABLED`, `PAUSED` · Default: `"PAUSED"` | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_update_product_groups` write Needs `mcp:write` on an OAuth or MCP-server token. Replace the listing-group tree for a Shopping ad group. Pass the full set of adGroupCriteria mutate operations that define the new tree. Google does an atomic swap. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `ad_group_id` | string | yes | | | `listing_group_operations` | object[] | yes | Raw adGroupCriteria mutate operations forming the listing-group tree. · Min items 1 | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_update_audience_signals` write Needs `mcp:write` on an OAuth or MCP-server token. Add or remove audience segments on a PMax or Demand Gen asset group. segment_ids are Google Ads audience resource names, e.g. "userInterests/123" or "userLists/456". Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `asset_group_id` | string | yes | | | `add_segment_ids` | string[] | | Audience segment resource names to add. | | `remove_segment_ids` | string[] | | Audience segment resource names to remove. | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_create_responsive_display_ad` write Needs `mcp:write` on an OAuth or MCP-server token. Create a Responsive Display Ad (RDA) under an ad group. Forced PAUSED. Pass asset resource names or https image URLs for marketing_images and square_images. Requires at least 1 marketing_image and 1 square_image. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `ad_group_id` | string | yes | | | `marketing_images` | string[] | yes | Asset resource names or https image URLs. · Min items 1 | | `square_images` | string[] | yes | Min items 1 | | `logo_images` | string[] | | | | `headlines` | string[] | yes | Min items 1 · Max items 5 | | `descriptions` | string[] | yes | Min items 1 · Max items 5 | | `business_name` | string | yes | Max length 25 | | `final_urls` | string[] | yes | Min items 1 | | `long_headline` | string | | Max length 90 | | `call_to_action_text` | string | | | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_create_demand_gen_single_image_ad` write Needs `mcp:write` on an OAuth or MCP-server token. Create a Demand Gen single-image ad under an ad group. Forced PAUSED. Pass an asset resource name or https URL for image. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `ad_group_id` | string | yes | | | `image` | string | yes | Asset resource name or https URL. | | `headlines` | string[] | yes | Min items 1 · Max items 5 | | `descriptions` | string[] | yes | Min items 1 · Max items 5 | | `business_name` | string | yes | Max length 25 | | `final_urls` | string[] | yes | Min items 1 | | `logo_image` | string | | | | `call_to_action` | string | | | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_create_demand_gen_video_ad` write Needs `mcp:write` on an OAuth or MCP-server token. Create a Demand Gen video ad under an ad group using YouTube video IDs. Forced PAUSED. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `ad_group_id` | string | yes | | | `video_ids` | string[] | yes | 11-char YouTube video IDs. · Min items 1 · Max items 5 | | `headlines` | string[] | yes | Min items 1 · Max items 5 | | `descriptions` | string[] | yes | Min items 1 · Max items 5 | | `business_name` | string | yes | Max length 25 | | `final_urls` | string[] | yes | Min items 1 | | `logo_image` | string | | Asset resource name or https URL. | | `call_to_action` | string | | | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_create_demand_gen_carousel_ad` write Needs `mcp:write` on an OAuth or MCP-server token. Create a Demand Gen carousel ad with 2-10 cards. Each card: image (asset rn or https URL), headline, final_url. Forced PAUSED. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `ad_group_id` | string | yes | | | `cards` | object[] | yes | Min items 2 · Max items 10 | | `cards[].image` | string | yes | Asset resource name or https URL. | | `cards[].headline` | string | yes | Max length 30 | | `cards[].final_url` | string | yes | | | `headline` | string | yes | Top-level carousel headline. · Max length 30 | | `description` | string | yes | Max length 90 | | `business_name` | string | yes | Max length 25 | | `final_url` | string | yes | Top-level default URL. | | `logo_image` | string | | | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_create_negative_keyword_list` write Needs `mcp:write` on an OAuth or MCP-server token. Create a Google Ads SharedSet of type NEGATIVE_KEYWORDS and populate it. Two quota ops (create set + add keywords). Returns shared_set_resource_name. Apply to campaigns via nc_google_ads_apply_exclusion_list_to_campaigns. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `name` | string | yes | | | `keywords` | object[] | yes | Min items 1 | | `keywords[].text` | string | yes | | | `keywords[].match_type` | string | | One of: `BROAD`, `PHRASE`, `EXACT` · Default: `"BROAD"` | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_create_placement_exclusion_list` write Needs `mcp:write` on an OAuth or MCP-server token. Create a Google Ads SharedSet of type NEGATIVE_PLACEMENTS and populate it with URLs. Two quota ops. Returns shared_set_resource_name. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `name` | string | yes | | | `placements` | string[] | yes | URLs e.g. "www.example.com" or YouTube channel URLs. · Min items 1 | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_add_placements_to_exclusion_list` write Needs `mcp:write` on an OAuth or MCP-server token. Add placement URLs to an existing NEGATIVE_PLACEMENTS SharedSet. One quota op. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `shared_set_resource_name` | string | yes | customers/{cid}/sharedSets/{id} | | `placements` | string[] | yes | Min items 1 | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_add_keywords_to_negative_list` write Needs `mcp:write` on an OAuth or MCP-server token. Add keywords to an existing NEGATIVE_KEYWORDS SharedSet. One quota op. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `shared_set_resource_name` | string | yes | | | `keywords` | object[] | yes | Min items 1 | | `keywords[].text` | string | yes | | | `keywords[].match_type` | string | | One of: `BROAD`, `PHRASE`, `EXACT` · Default: `"BROAD"` | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_apply_exclusion_list_to_campaigns` write Needs `mcp:write` on an OAuth or MCP-server token. Attach a SharedSet (negative-keyword or placement-exclusion) to one or more campaigns by creating CampaignSharedSet links. One quota op. Works for both NEGATIVE_KEYWORDS and NEGATIVE_PLACEMENTS sets. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `shared_set_resource_name` | string | yes | customers/{cid}/sharedSets/{id} | | `campaign_ids` | string[] | yes | Min items 1 | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_manage_ip_exclusions` write Needs `mcp:write` on an OAuth or MCP-server token. Add or remove IP address exclusions (IP_BLOCK campaign criteria) on a campaign. action=add: provide IP/CIDR strings. action=remove: provide the full campaign criterion resource names. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `campaign_id` | string | yes | | | `ip_addresses` | string[] | yes | add: IP/CIDR strings; remove: campaign criterion resource names. · Min items 1 | | `action` | string | yes | One of: `add`, `remove` | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_create_sitelink_assets` write Needs `mcp:write` on an OAuth or MCP-server token. Create sitelink assets and optionally attach them to campaigns or ad groups. Returns asset resource names. link_text max 25 chars, descriptions max 35 chars each. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `sitelinks` | object[] | yes | Min items 1 | | `sitelinks[].link_text` | string | yes | Max length 25 | | `sitelinks[].description1` | string | | Max length 35 | | `sitelinks[].description2` | string | | Max length 35 | | `sitelinks[].final_urls` | string[] | yes | Min items 1 | | `campaign_ids` | string[] | | Attach to these campaigns. | | `ad_group_ids` | string[] | | Attach to these ad groups. | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_create_callout_assets` write Needs `mcp:write` on an OAuth or MCP-server token. Create callout assets (1-20 items, each max 25 chars) and optionally attach them to campaigns or ad groups. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `texts` | string[] | yes | Min items 1 · Max items 20 | | `campaign_ids` | string[] | | | | `ad_group_ids` | string[] | | | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_create_structured_snippet_assets` write Needs `mcp:write` on an OAuth or MCP-server token. Create structured snippet assets and optionally attach them. header: Google predefined header (e.g. "Brands", "Services", "Models"). values: 3-10 items. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `header` | string | yes | Google predefined header e.g. "Brands", "Services", "Models". | | `values` | string[] | yes | Min items 3 · Max items 10 | | `campaign_ids` | string[] | | | | `ad_group_ids` | string[] | | | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_create_promotion_assets` write Needs `mcp:write` on an OAuth or MCP-server token. Create a promotion (discount/coupon) asset and optionally attach to campaigns. Provide percent_off (e.g. 15 for 15%) OR money_amount_off_micros. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `discount_modifier` | string | yes | One of: `UP_TO`, `NONE` | | `percent_off` | number | | e.g. 15 for 15% off. | | `money_amount_off_micros` | number | | Discount amount in micros (1 ILS = 1,000,000). | | `promotion_code` | string | | | | `occasion` | string | | PromotionExtensionOccasion enum e.g. CHRISTMAS, BLACK_FRIDAY. | | `language_code` | string | | Default: `"en"` | | `final_urls` | string[] | yes | Min items 1 | | `start_date` | string | | YYYY-MM-DD | | `end_date` | string | | YYYY-MM-DD | | `campaign_ids` | string[] | | | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_create_image_asset` write Needs `mcp:write` on an OAuth or MCP-server token. Upload an image and create an IMAGE asset in Google Ads. Provide image_url (public https, Google fetches it) OR image_data (base64, no data: prefix). Returns asset resource_name for use in PMax, Demand Gen, and RDA tools. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `name` | string | yes | Human-readable asset name. | | `image_url` | string | | Public https URL — Google fetches it. | | `image_data` | string | | Base64-encoded image bytes, no data: prefix. | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_create_headline_assets` write Needs `mcp:write` on an OAuth or MCP-server token. Create one or more HEADLINE text assets (1-20 items, each max 30 chars). Returns asset resource names. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `texts` | string[] | yes | Min items 1 · Max items 20 | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_create_description_assets` write Needs `mcp:write` on an OAuth or MCP-server token. Create one or more DESCRIPTION text assets (1-20 items, each max 90 chars). Returns asset resource names. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `texts` | string[] | yes | Min items 1 · Max items 20 | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_update_asset_status` write Needs `mcp:write` on an OAuth or MCP-server token. Update the status (ENABLED/PAUSED/REMOVED) of an asset link within a campaign, ad group, or at customer level. scope: campaign | ad_group | customer. field_type: e.g. SITELINK, CALLOUT, STRUCTURED_SNIPPET. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `asset_resource_name` | string | yes | customers/{cid}/assets/{id} | | `status` | string | yes | One of: `ENABLED`, `PAUSED`, `REMOVED` | | `scope` | string | yes | One of: `campaign`, `ad_group`, `customer` | | `field_type` | string | yes | e.g. SITELINK, CALLOUT, STRUCTURED_SNIPPET, PROMOTION. | | `parent_resource_name` | string | | Required for campaign/ad_group scope. Full resource name of the parent. | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_create_label` write Needs `mcp:write` on an OAuth or MCP-server token. Create an account-level label in Google Ads. Returns the label resource_name for use in nc_google_ads_manage_label_assignment. color: hex string e.g. "#FF0000". Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `name` | string | yes | | | `description` | string | | | | `color` | string | | Hex color e.g. "#FF0000". | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_manage_label_assignment` write Needs `mcp:write` on an OAuth or MCP-server token. Attach or detach a label from campaigns, ad groups, ads, keywords, or a customer. action: attach | detach. scope: campaign | ad_group | ad | keyword | customer. resource_ids: bare numeric ids or full resource names. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `label_resource_name` | string | yes | customers/{cid}/labels/{id} | | `action` | string | yes | One of: `attach`, `detach` | | `scope` | string | yes | One of: `campaign`, `ad_group`, `ad`, `keyword`, `customer` | | `resource_ids` | string[] | yes | Min items 1 | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_mutate` write Needs `mcp:write` on an OAuth or MCP-server token. Generic Google Ads mutate escape-hatch. Pass raw mutate operations for any resource type not yet covered by dedicated tools. All ops written to marketing_mutations audit log. Use dry_run: true to preview. CAUTION: operations are passed directly to the Google Ads API v20 with no semantic validation. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `resource` | string | yes | Google Ads API resource name e.g. "campaigns", "adGroups", "assets". | | `operations` | object[] | yes | Raw Google Ads API v20 mutate operation objects (create/update/remove). · Min items 1 | | `audit_resource_name` | string | | Human-readable name for the audit row. | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_upload_conversion_adjustments` write Needs `mcp:write` on an OAuth or MCP-server token. Retract, restate, or enhance conversions already reported to Google Ads. RETRACTION cancels a conversion (e.g. refund); RESTATEMENT changes its value; ENHANCEMENT attaches hashed first-party email/phone. Identify the original conversion by order_id OR gclid+conversion_date_time. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `adjustments` | object[] | yes | Min items 1 | | `adjustments[].conversion_action` | string | yes | Conversion action id or full resource name. | | `adjustments[].adjustment_type` | string | yes | One of: `RETRACTION`, `RESTATEMENT`, `ENHANCEMENT` | | `adjustments[].adjustment_date_time` | string | yes | "YYYY-MM-DD HH:MM:SS+HH:MM" | | `adjustments[].order_id` | string | | Order id of the original conversion (preferred). | | `adjustments[].gclid` | string | | Alternative to order_id; requires conversion_date_time. | | `adjustments[].conversion_date_time` | string | | Original conversion time; required with gclid. | | `adjustments[].adjusted_value` | number | | RESTATEMENT: new value in major units. | | `adjustments[].currency_code` | string | | | | `adjustments[].email` | string | | ENHANCEMENT: hashed here before upload. | | `adjustments[].phone` | string | | ENHANCEMENT: hashed here before upload. | | `validate_only` | boolean | | Google's native validate_only — checks without applying. | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_create_conversion_action` write Needs `mcp:write` on an OAuth or MCP-server token. Define a new conversion action (what counts as a conversion). category must be a Google ConversionActionCategory: DEFAULT, PURCHASE, PAGE_VIEW, SIGNUP, SUBMIT_LEAD_FORM, PHONE_CALL_LEAD, BOOK_APPOINTMENT, CONTACT, DOWNLOAD, ADD_TO_CART, BEGIN_CHECKOUT, REQUEST_QUOTE (NOT "LEAD"/"SIGN_UP" — those are rejected). type e.g. WEBPAGE/UPLOAD_CLICKS/UPLOAD_CALLS/AD_CALL. Optionally set a default value + currency and counting type. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `name` | string | yes | | | `category` | string | | Google ConversionActionCategory: DEFAULT, PURCHASE, PAGE_VIEW, SIGNUP, SUBMIT_LEAD_FORM, PHONE_CALL_LEAD, BOOK_APPOINTMENT, CONTACT, DOWNLOAD, ADD_TO_CART, BEGIN_CHECKOUT, REQUEST_QUOTE. NOT "LEAD"/"SIGN_UP". | | `type` | string | | e.g. WEBPAGE, UPLOAD_CLICKS, UPLOAD_CALLS, AD_CALL. Default UPLOAD_CLICKS. | | `status` | string | | One of: `ENABLED`, `PAUSED`, `HIDDEN` | | `default_value` | number | | | | `currency_code` | string | | | | `always_use_default_value` | boolean | | | | `counting_type` | string | | One of: `ONE_PER_CLICK`, `MANY_PER_CLICK` | | `click_through_lookback_window_days` | integer | | Min 1 · Max 90 | | `login_customer_id` | string | | | | `validate_only` | boolean | | Google's native validate_only — sends the real payload to Google in check-only mode (applies nothing). | | `dry_run` | boolean | | |
### `nc_google_ads_update_conversion_action` write Needs `mcp:write` on an OAuth or MCP-server token. Update an existing conversion action (rename, pause/enable, change default value/currency). Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `conversion_action_id` | string | yes | Id or full resource name. | | `name` | string | | | | `status` | string | | One of: `ENABLED`, `PAUSED`, `HIDDEN` | | `default_value` | number | | | | `currency_code` | string | | | | `always_use_default_value` | boolean | | | | `login_customer_id` | string | | | | `validate_only` | boolean | | Google's native validate_only — sends the real payload to Google in check-only mode (applies nothing). | | `dry_run` | boolean | | |
### `nc_google_ads_apply_recommendation` write Needs `mcp:write` on an OAuth or MCP-server token. Apply one or more Google Ads recommendations (found via GAQL `SELECT ... FROM recommendation`). Applies with Google's recommended defaults. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `resource_names` | string[] | yes | Recommendation resource names. · Min items 1 | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_dismiss_recommendation` read Works with `mcp:read`. Dismiss one or more Google Ads recommendations so they stop surfacing. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `resource_names` | string[] | yes | Min items 1 | | `login_customer_id` | string | | | | `dry_run` | boolean | | |
### `nc_google_ads_create_lead_form_asset` write Needs `mcp:write` on an OAuth or MCP-server token. Create a lead-form asset and optionally attach it to campaigns. Captures leads directly in the ad. fields e.g. FULL_NAME/EMAIL/PHONE_NUMBER/CITY/POSTAL_CODE (defaults to name+email+phone). Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `business_name` | string | yes | | | `headline` | string | yes | | | `description` | string | yes | | | `privacy_policy_url` | string | yes | | | `call_to_action_type` | string | | e.g. GET_QUOTE, APPLY_NOW, SIGN_UP, CONTACT_US. Default GET_QUOTE. | | `call_to_action_description` | string | yes | | | `fields` | string[] | | Input field types. | | `post_submit_headline` | string | | | | `post_submit_description` | string | | | | `campaign_ids` | string[] | | | | `login_customer_id` | string | | | | `validate_only` | boolean | | Google's native validate_only — sends the real payload to Google in check-only mode (applies nothing). | | `dry_run` | boolean | | |
### `nc_google_ads_create_call_asset` write Needs `mcp:write` on an OAuth or MCP-server token. Create a call (phone) asset and optionally attach it to campaigns. Optionally wire a call conversion action. country_code is ISO alpha-2 (e.g. IL, US). Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `phone_number` | string | yes | | | `country_code` | string | yes | ISO-3166-1 alpha-2, e.g. IL, US. | | `call_conversion_action` | string | | Optional conversion action id or resource name. | | `campaign_ids` | string[] | | | | `login_customer_id` | string | | | | `validate_only` | boolean | | Google's native validate_only — sends the real payload to Google in check-only mode (applies nothing). | | `dry_run` | boolean | | |
### `nc_google_ads_create_price_asset` write Needs `mcp:write` on an OAuth or MCP-server token. Create a price asset (3-8 offerings) and optionally attach it to campaigns. Each offering: header, description, price_micros, currency_code, unit (e.g. PER_MONTH), final_url. type e.g. SERVICES/BRANDS/PRODUCT_CATEGORIES. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `type` | string | | e.g. SERVICES, BRANDS, PRODUCT_CATEGORIES. Default SERVICES. | | `price_qualifier` | string | | e.g. FROM, UP_TO, AVERAGE. Default FROM. | | `language_code` | string | | e.g. 'en', 'he'. Default 'en'. | | `offerings` | object[] | yes | Min items 3 · Max items 8 | | `offerings[].header` | string | yes | | | `offerings[].description` | string | yes | | | `offerings[].price_micros` | integer | yes | Price in micros (1 unit = 1,000,000). | | `offerings[].currency_code` | string | yes | | | `offerings[].unit` | string | | e.g. PER_MONTH, PER_HOUR, PER_NIGHT. | | `offerings[].final_url` | string | yes | | | `campaign_ids` | string[] | | | | `login_customer_id` | string | | | | `validate_only` | boolean | | Google's native validate_only — sends the real payload to Google in check-only mode (applies nothing). | | `dry_run` | boolean | | |
### `nc_google_ads_create_campaign_draft` write Needs `mcp:write` on an OAuth or MCP-server token. Create a campaign draft — a sandbox copy of an existing campaign where you can stage changes before testing them in an experiment. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `base_campaign_id` | string | yes | Campaign id or resource name to copy. | | `name` | string | yes | | | `login_customer_id` | string | | | | `validate_only` | boolean | | Google's native validate_only — sends the real payload to Google in check-only mode (applies nothing). | | `dry_run` | boolean | | |
### `nc_google_ads_create_experiment` write Needs `mcp:write` on an OAuth or MCP-server token. Create a Google Ads experiment (A/B test). Optionally pass base_campaign_id + treatment_traffic_split (1-99) to auto-create the control arm (references the base campaign) and the treatment arm (Google builds the trial campaign). type e.g. SEARCH_CUSTOM/DISPLAY_CUSTOM. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `name` | string | yes | | | `type` | string | | e.g. SEARCH_CUSTOM, DISPLAY_CUSTOM. Default SEARCH_CUSTOM. | | `suffix` | string | | Appended to trial campaign names. Default "[experiment]". | | `description` | string | | | | `base_campaign_id` | string | | Control arm references this campaign (required to auto-create arms). | | `treatment_traffic_split` | integer | | % of traffic to the treatment arm. · Min 1 · Max 99 | | `login_customer_id` | string | | | | `validate_only` | boolean | | Google's native validate_only — sends the real payload to Google in check-only mode (applies nothing). | | `dry_run` | boolean | | |
### `nc_google_ads_schedule_experiment` read Works with `mcp:read`. Schedule (start) a Google Ads experiment that is set up. It begins running per its arms and traffic split. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `experiment_id` | string | yes | Experiment id or resource name. | | `login_customer_id` | string | | | | `validate_only` | boolean | | Google's native validate_only — sends the real payload to Google in check-only mode (applies nothing). | | `dry_run` | boolean | | |
### `nc_google_ads_promote_experiment` read Works with `mcp:read`. Promote a Google Ads experiment — applies the treatment changes back onto the original (base) campaign. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `experiment_id` | string | yes | | | `login_customer_id` | string | | | | `validate_only` | boolean | | Google's native validate_only — sends the real payload to Google in check-only mode (applies nothing). | | `dry_run` | boolean | | |
### `nc_google_ads_end_experiment` read Works with `mcp:read`. End (stop) a running Google Ads experiment. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `experiment_id` | string | yes | | | `login_customer_id` | string | | | | `validate_only` | boolean | | Google's native validate_only — sends the real payload to Google in check-only mode (applies nothing). | | `dry_run` | boolean | | |
### `nc_google_ads_graduate_experiment` read Works with `mcp:read`. Graduate a Google Ads experiment — converts the experiment (trial) campaign into a standalone permanent campaign. Requires budget_mappings pairing each experiment campaign with a campaign budget. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `experiment_id` | string | yes | | | `budget_mappings` | object[] | yes | Min items 1 | | `budget_mappings[].experiment_campaign_id` | string | yes | | | `budget_mappings[].campaign_budget_id` | string | yes | | | `login_customer_id` | string | | | | `validate_only` | boolean | | Google's native validate_only — sends the real payload to Google in check-only mode (applies nothing). | | `dry_run` | boolean | | |
### `nc_google_ads_create_billing_setup` write Needs `mcp:write` on an OAuth or MCP-server token. MONEY-SENSITIVE. Link a payments account to a Google Ads account (billing setup). Requires marketing.edit AND org-owner AND confirm:true. Pass either payments_account_resource_name, or payments_account_id + payments_profile_id.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `payments_account_resource_name` | string | | | | `payments_account_id` | string | | | | `payments_profile_id` | string | | | | `start_time_type` | string | | One of: `NOW`, `FOREVER` | | `confirm` | boolean | yes | Must be true — billing changes cost money. | | `login_customer_id` | string | | | | `validate_only` | boolean | | Google's native validate_only — sends the real payload to Google in check-only mode (applies nothing). | | `dry_run` | boolean | | |
### `nc_google_ads_propose_account_budget` read Works with `mcp:read`. MONEY-SENSITIVE. Propose an account budget (name + spending cap) against a billing setup. Omit spending_limit_micros for an uncapped (INFINITE) budget. Requires marketing.edit AND org-owner AND confirm:true.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `customer_id` | string | yes | | | `billing_setup_id` | string | yes | Billing setup id or resource name. | | `proposed_name` | string | yes | | | `spending_limit_micros` | integer | | Hard cap in micros. Omit for INFINITE. | | `start_time_type` | string | | One of: `NOW`, `FOREVER` | | `start_date_time` | string | | "YYYY-MM-DD HH:MM:SS" — overrides start_time_type. | | `end_time_type` | string | | One of: `FOREVER` | | `end_date_time` | string | | "YYYY-MM-DD HH:MM:SS" — overrides end_time_type. | | `confirm` | boolean | yes | Must be true — billing changes cost money. | | `login_customer_id` | string | | | | `validate_only` | boolean | | Google's native validate_only — sends the real payload to Google in check-only mode (applies nothing). | | `dry_run` | boolean | | |
--- # Google Analytics, Search Console, Sheets and Drive URL: https://docs.nexacloser.com/mcp/tools/google-workspace/ GA4 reports, Search Console data, Sheets and Drive files. 18 tools: 14 read, 4 write. :::note[Generated] This page is generated from the MCP server source on every docs build. Names, descriptions and arguments are exactly what `tools/list` returns. ::: | Tool | Access | What it does | |---|---|---| | nc_google_ga4_list_properties | read | List all GA4 properties accessible via the Google connection. | | nc_google_ga4_run_report | read | Run a GA4 Data API report for a property. | | nc_google_ga4_top_pages | read | Convenience: top pages by sessions (or another metric) for a GA4 property and date range. | | nc_google_ga4_traffic_sources | read | Convenience: source/medium + channel group breakdown for a GA4 property and date range. | | nc_google_ga4_realtime_users | read | Current realtime active users on a GA4 property, plus top pages by active users right now. | | nc_google_gsc_list_sites | read | List all sites verified in Google Search Console for this Google connection. | | nc_google_gsc_search_analytics | read | Query Google Search Console search analytics: clicks, impressions, CTR, position. | | nc_google_gsc_top_queries | read | Convenience: top search queries by impressions (or clicks) for a GSC site and date range. | | nc_google_gsc_index_coverage | read | Inspect indexing status of a URL in Google Search Console: coverage state, last crawl date, mobile usability issues. | | nc_google_sheets_list_spreadsheets | read | List Google Sheets spreadsheets accessible via the Google connection. | | nc_google_sheets_read_range | read | Read a cell range from a Google Sheets spreadsheet. | | nc_google_sheets_append_row | write | Append rows to a Google Sheets spreadsheet after the last row with data. | | nc_google_sheets_update_cells | write | Overwrite a specific cell range in Google Sheets. | | nc_google_sheets_create_spreadsheet | write | Create a new Google Sheets spreadsheet. | | nc_google_drive_list_files | read | List the Google Drive files NexaCloser can open: ones it created or that the user picked in Google Drive (drive.file access, not the whole Drive). | | nc_google_drive_get_file_metadata | read | Get metadata for a specific Drive file: name, mimeType, size, createdTime, modifiedTime, parents, webViewLink. | | nc_google_drive_download_file_content | read | Download Drive file content. | | nc_google_drive_create_folder | write | Create a new folder in Google Drive. | ### `nc_google_ga4_list_properties` read Works with `mcp:read`. List all GA4 properties accessible via the Google connection. Returns property IDs and display names. Requires analytics.readonly scope — if missing, returns reconnect_required.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | connections.id for a service=google OAuth connection. |
### `nc_google_ga4_run_report` read Works with `mcp:read`. Run a GA4 Data API report for a property. Returns rows with dimension + metric values. Useful for sessions, users, conversions, pageviews by date/channel/page/country.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `property_id` | string | yes | Numeric GA4 property ID (no "properties/" prefix). | | `dimensions` | string[] | yes | e.g. ["sessionDefaultChannelGroup","date"] | | `metrics` | string[] | yes | e.g. ["sessions","activeUsers","conversions"] | | `start_date` | string | yes | YYYY-MM-DD or "30daysAgo" | | `end_date` | string | yes | YYYY-MM-DD or "today" | | `row_limit` | integer | | Default: `1000` · Min 1 · Max 100000 | | `order_by_metric` | string | | Optional metric name to order by descending. |
### `nc_google_ga4_top_pages` read Works with `mcp:read`. Convenience: top pages by sessions (or another metric) for a GA4 property and date range.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `property_id` | string | yes | | | `start_date` | string | yes | | | `end_date` | string | yes | | | `metric` | string | | One of: `sessions`, `conversions`, `activeUsers`, `screenPageViews` · Default: `"sessions"` | | `row_limit` | integer | | Default: `25` · Min 1 · Max 100 |
### `nc_google_ga4_traffic_sources` read Works with `mcp:read`. Convenience: source/medium + channel group breakdown for a GA4 property and date range. Returns sessions, activeUsers, conversions per channel.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `property_id` | string | yes | | | `start_date` | string | yes | | | `end_date` | string | yes | | | `row_limit` | integer | | Default: `25` · Min 1 · Max 100 |
### `nc_google_ga4_realtime_users` read Works with `mcp:read`. Current realtime active users on a GA4 property, plus top pages by active users right now.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `property_id` | string | yes | |
### `nc_google_gsc_list_sites` read Works with `mcp:read`. List all sites verified in Google Search Console for this Google connection. Returns siteUrl and permissionLevel.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | |
### `nc_google_gsc_search_analytics` read Works with `mcp:read`. Query Google Search Console search analytics: clicks, impressions, CTR, position. Dimensions: query, page, country, device, date.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `site_url` | string | yes | GSC property URL, e.g. "https://example.com/" or "sc-domain:example.com". | | `start_date` | string | yes | YYYY-MM-DD | | `end_date` | string | yes | YYYY-MM-DD | | `dimensions` | string[] | | Items: `query`, `page`, `country`, `device`, `date`, `searchAppearance` · Default: `["query"]` | | `query_filter` | string | | Filter rows to queries containing this string. | | `row_limit` | integer | | Default: `1000` · Min 1 · Max 25000 | | `start_row` | integer | | Default: `0` · Min 0 |
### `nc_google_gsc_top_queries` read Works with `mcp:read`. Convenience: top search queries by impressions (or clicks) for a GSC site and date range.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `site_url` | string | yes | | | `start_date` | string | yes | | | `end_date` | string | yes | | | `order_by` | string | | One of: `impressions`, `clicks`, `position`, `ctr` · Default: `"impressions"` | | `row_limit` | integer | | Default: `50` · Min 1 · Max 500 |
### `nc_google_gsc_index_coverage` read Works with `mcp:read`. Inspect indexing status of a URL in Google Search Console: coverage state, last crawl date, mobile usability issues.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `site_url` | string | yes | GSC property the URL belongs to. | | `inspection_url` | string | yes | Exact URL to inspect. |
### `nc_google_sheets_list_spreadsheets` read Works with `mcp:read`. List Google Sheets spreadsheets accessible via the Google connection.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `query` | string | | Optional Drive fullText search to filter by name. | | `limit` | integer | | Default: `20` · Min 1 · Max 100 |
### `nc_google_sheets_read_range` read Works with `mcp:read`. Read a cell range from a Google Sheets spreadsheet. Returns a 2D array of values. Use A1 notation, e.g. "Sheet1!A1:D10".
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `spreadsheet_id` | string | yes | | | `range` | string | yes | A1 notation range, e.g. "Sheet1!A1:E20". |
### `nc_google_sheets_append_row` write Needs `mcp:write` on an OAuth or MCP-server token. Append rows to a Google Sheets spreadsheet after the last row with data. Values is a 2D array. Writes an audit row.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `spreadsheet_id` | string | yes | | | `range` | string | yes | Range indicating the sheet to append to, e.g. "Sheet1!A:A". | | `values` | array[] | yes | 2D array: [["Row1Col1","Row1Col2"],["Row2Col1","Row2Col2"]] · Min items 1 |
### `nc_google_sheets_update_cells` write Needs `mcp:write` on an OAuth or MCP-server token. Overwrite a specific cell range in Google Sheets. Values is a 2D array matching the range. Writes an audit row.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `spreadsheet_id` | string | yes | | | `range` | string | yes | A1 notation range to update, e.g. "Sheet1!B2:D4". | | `values` | array[] | yes | Min items 1 |
### `nc_google_sheets_create_spreadsheet` write Needs `mcp:write` on an OAuth or MCP-server token. Create a new Google Sheets spreadsheet. Optional sheet (tab) names. Returns spreadsheetId and URL. Writes an audit row.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `title` | string | yes | | | `sheets` | string[] | | Optional tab names. Default: ["Sheet1"]. · Default: `[]` |
### `nc_google_drive_list_files` read Works with `mcp:read`. List the Google Drive files NexaCloser can open: ones it created or that the user picked in Google Drive (drive.file access, not the whole Drive). Supports Drive query syntax and MIME type filter. Returns id, name, mimeType, modifiedTime, size, webViewLink.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `query` | string | | Drive search query, e.g. "name contains 'report'". | | `mime_type` | string | | Optional MIME type filter, e.g. "application/pdf". | | `limit` | integer | | Default: `20` · Min 1 · Max 100 |
### `nc_google_drive_get_file_metadata` read Works with `mcp:read`. Get metadata for a specific Drive file: name, mimeType, size, createdTime, modifiedTime, parents, webViewLink.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `file_id` | string | yes | |
### `nc_google_drive_download_file_content` read Works with `mcp:read`. Download Drive file content. Text files returned as text; binary as base64. Google Docs/Sheets/Slides are exported as plain text/CSV. Capped at 5MB.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `file_id` | string | yes | |
### `nc_google_drive_create_folder` write Needs `mcp:write` on an OAuth or MCP-server token. Create a new folder in Google Drive. Optionally nest inside a parent folder. Writes an audit row.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `name` | string | yes | | | `parent_id` | string | | Optional parent folder ID. Omit to create in My Drive root. |
--- # Marketing (all ad platforms) URL: https://docs.nexacloser.com/mcp/tools/marketing/ Spend, results and ads across every connected ad platform. 8 tools: 8 read, 0 write. :::note[Generated] This page is generated from the MCP server source on every docs build. Names, descriptions and arguments are exactly what `tools/list` returns. ::: | Tool | Access | What it does | |---|---|---| | nc_get_marketing_stats | read | Total ad spend + impressions/clicks/platform leads across ALL platforms combined, plus CRM leads (new and returning), won deals and won revenue, per channel and in total. | | nc_list_campaigns | read | List ad campaigns synced from Meta / Google / TikTok / LinkedIn. | | nc_get_campaign_metrics | read | Ad SPEND + performance (impressions, clicks, spend, reach, leads, conversions, CTR, CPC, CPM) from the user's synced Meta + Google + TikTok data. | | nc_list_ads | read | List individual ads (creatives) synced from ad platforms. | | nc_get_ad_metrics | read | Per-ad daily metrics over the last N days. | | nc_top_performing_ads | read | Shortcut: rank your ads by the metric that matters. | | nc_list_marketing_connections | read | List the user's connected marketing platforms (Google Ads, Facebook/Meta, TikTok, LinkedIn, etc). | | nc_validate_landing_page_url | read | Pre-flight check on a landing-page URL before launching an ad. | ### `nc_get_marketing_stats` read Works with `mcp:read`. Total ad spend + impressions/clicks/platform leads across ALL platforms combined, plus CRM leads (new and returning), won deals and won revenue, per channel and in total. Money is per currency (never added across currencies). Days are in the business time zone. Use for "total ad spend" or "what did the ads bring in". Defaults to the last 30 days; pass date_from/date_to (YYYY-MM-DD) for an exact day like today.
| Argument | Type | Required | Description | |---|---|---|---| | `days` | integer | | Default: `30` · Min 1 · Max 365 | | `model` | string | | Attribution model for CRM leads and revenue: last touch (default) or first touch. · One of: `last`, `first` | | `date_from` | string | | Optional YYYY-MM-DD (org-local). Overrides days. Use with date_to for an exact range like "today". | | `date_to` | string | | Optional YYYY-MM-DD (org-local), inclusive. |
### `nc_list_campaigns` read Works with `mcp:read`. List ad campaigns synced from Meta / Google / TikTok / LinkedIn. Includes status, objective, daily/lifetime budgets, and platform ids. Use this to discover campaign_id values for nc_get_campaign_metrics.
| Argument | Type | Required | Description | |---|---|---|---| | `platform` | string | | Filter by platform: meta \| google \| tiktok \| linkedin | | `status` | string | | Filter by campaign status (e.g. ACTIVE, PAUSED) | | `limit` | integer | | Default: `50` · Min 1 · Max 200 |
### `nc_get_campaign_metrics` read Works with `mcp:read`. Ad SPEND + performance (impressions, clicks, spend, reach, leads, conversions, CTR, CPC, CPM) from the user's synced Meta + Google + TikTok data. THE tool for "how much did I spend", "spend today", "how much on Meta/Google". Set platform to isolate a channel (meta=Facebook/Meta, google=Google Ads). Rolled-up totals per campaign when campaign_id is omitted. Needs NO connection_id/ad_account_id.
| Argument | Type | Required | Description | |---|---|---|---| | `campaign_id` | string | | Optional — internal marketing_campaigns.id | | `platform` | string | | Optional — isolate one channel: meta \| google \| tiktok \| linkedin | | `days` | integer | | Default: `30` · Min 1 · Max 365 | | `date_from` | string | | Optional YYYY-MM-DD (org-local). Overrides days. Use with date_to for an exact range like "today". | | `date_to` | string | | Optional YYYY-MM-DD (org-local), inclusive. | | `sort_by` | string | | Field to sort campaigns by (descending). Used only when campaign_id is omitted. · One of: `spend`, `clicks`, `impressions`, `leads`, `conversions`, `ctr`, `cpc` · Default: `"spend"` | | `limit` | integer | | Default: `20` · Min 1 · Max 100 |
### `nc_list_ads` read Works with `mcp:read`. List individual ads (creatives) synced from ad platforms. Optionally filter by campaign_id, platform, or status. Use to discover ad_id values for nc_get_ad_metrics.
| Argument | Type | Required | Description | |---|---|---|---| | `campaign_id` | string | | | | `platform` | string | | | | `status` | string | | | | `limit` | integer | | Default: `50` · Min 1 · Max 200 |
### `nc_get_ad_metrics` read Works with `mcp:read`. Per-ad daily metrics over the last N days. When ad_id is omitted, returns rolled-up totals per ad for the period — answers "which ad creative performs best".
| Argument | Type | Required | Description | |---|---|---|---| | `ad_id` | string | | Optional — internal marketing_ads.id | | `campaign_id` | string | | Optional — restrict to ads under a campaign | | `days` | integer | | Default: `30` · Min 1 · Max 365 | | `sort_by` | string | | One of: `spend`, `clicks`, `impressions`, `conversions`, `ctr`, `cpc` · Default: `"spend"` | | `limit` | integer | | Default: `20` · Min 1 · Max 100 |
### `nc_top_performing_ads` read Works with `mcp:read`. Shortcut: rank your ads by the metric that matters. Common asks: "best CTR ads this month", "lowest CPC ads", "most leads". Returns ad name + campaign + the chosen metric value + supporting stats.
| Argument | Type | Required | Description | |---|---|---|---| | `metric` | string | | ctr/conversions/clicks/impressions sort descending; cpc/spend sort ascending (lower is better for CPC, depends for spend). · One of: `ctr`, `cpc`, `conversions`, `clicks`, `impressions`, `spend` · Default: `"ctr"` | | `platform` | string | | Optional — filter to meta/google/tiktok/linkedin | | `days` | integer | | Default: `30` · Min 1 · Max 365 | | `min_impressions` | integer | | Drop ads with fewer impressions than this — avoids ranking statistical noise. · Default: `100` · Min 1 | | `limit` | integer | | Default: `10` · Min 1 · Max 50 |
### `nc_list_marketing_connections` read Works with `mcp:read`. List the user's connected marketing platforms (Google Ads, Facebook/Meta, TikTok, LinkedIn, etc). Returns connection ids — pass them as connection_id to other marketing tools. Use this BEFORE asking the user which account; the answer is usually already there.
| Argument | Type | Required | Description | |---|---|---|---| | `service` | string | | Filter by service: google_ads \| facebook \| tiktok \| linkedin \| airtable. Omit to return all marketing connections. | | `active_only` | boolean | | Default: `true` |
### `nc_validate_landing_page_url` read Works with `mcp:read`. Pre-flight check on a landing-page URL before launching an ad. Server-side fetches the URL, follows redirects, returns final status + redirect chain + optional domain match. Use BEFORE create-campaign tools to avoid Google/Meta rejecting ads for unreachable URLs. https:// only.
| Argument | Type | Required | Description | |---|---|---|---| | `url` | string | yes | Public https URL to check. | | `expected_domain` | string | | Optional. If provided, the final URL must resolve to this domain (e.g. nexacloser.com). | | `timeout_ms` | integer | | Default: `10000` · Min 1000 · Max 30000 |
--- # Messaging URL: https://docs.nexacloser.com/mcp/tools/messaging/ Send email, SMS and WhatsApp, and read WhatsApp delivery numbers. 4 tools: 1 read, 3 write. :::note[Generated] This page is generated from the MCP server source on every docs build. Names, descriptions and arguments are exactly what `tools/list` returns. ::: | Tool | Access | What it does | |---|---|---| | nc_send_email | write | Send an email through the authenticated user's active Google connection. | | nc_send_sms | write | Send an SMS via the org's configured Twilio/Telnyx pool. | | nc_send_whatsapp | write | Send a WhatsApp message via the org's active WABA (Cloud API) connection. | | nc_get_whatsapp_stats | read | WhatsApp template message numbers for the caller's organization: sent, delivered, read, quick-reply button taps, and messages Meta refused with the reason (e.g. 131049 = Meta's per-person marketing limit), with rates. | ### `nc_send_email` write Needs `mcp:write` on an OAuth or MCP-server token. Send an email through the authenticated user's active Google connection. Subject + body support plain text or HTML.
| Argument | Type | Required | Description | |---|---|---|---| | `to` | string | yes | | | `subject` | string | yes | | | `body` | string | yes | | | `cc` | string | | | | `bcc` | string | | |
### `nc_send_sms` write Needs `mcp:write` on an OAuth or MCP-server token. Send an SMS via the org's configured Twilio/Telnyx pool. Defaults the country to IL.
| Argument | Type | Required | Description | |---|---|---|---| | `to` | string | yes | | | `body` | string | yes | | | `from` | string | | |
### `nc_send_whatsapp` write Needs `mcp:write` on an OAuth or MCP-server token. Send a WhatsApp message via the org's active WABA (Cloud API) connection. Either a free-text body (session-window only) or a template_name + language for template sends.
| Argument | Type | Required | Description | |---|---|---|---| | `to` | string | yes | Phone number, any format | | `body` | string | | Free-text message body (24h session window) | | `template_name` | string | | Approved WABA template name for cold sends | | `template_language` | string | | Default: `"he"` | | `template_variables` | string[] | | Positional template variables | | `dry_run` | boolean | | When true, validate without sending |
### `nc_get_whatsapp_stats` read Works with `mcp:read`. WhatsApp template message numbers for the caller's organization: sent, delivered, read, quick-reply button taps, and messages Meta refused with the reason (e.g. 131049 = Meta's per-person marketing limit), with rates. Group by template, by automation step (e.g. "the 21:00 reminder of the re-registration automation") or by day. Defaults to the last 30 days, at most 92. Owners, admins and managers only.
| Argument | Type | Required | Description | |---|---|---|---| | `from` | string | | ISO: sent at/after this moment. Default: 30 days before `to`. | | `to` | string | | ISO: sent before this moment. Default: now. | | `group_by` | string | | One of: `template`, `automation_step`, `day` · Default: `"template"` | | `automation_id` | string | | Only messages sent by this automation (ids from nc_list_automations). | | `template` | string | | Only this template: its id or part of its name. | | `limit` | integer | | Most groups to return, largest first (group_by=day returns every day). · Min 1 · Max 200 |
--- # Meta Ads URL: https://docs.nexacloser.com/mcp/tools/meta-ads/ Facebook and Instagram campaigns, ad sets, ads, audiences, pixels and leads. 48 tools: 18 read, 30 write. :::note[Generated] This page is generated from the MCP server source on every docs build. Names, descriptions and arguments are exactly what `tools/list` returns. ::: | Tool | Access | What it does | |---|---|---| | nc_meta_create_campaign | write | Create a Meta Ads campaign. | | nc_meta_create_ad_set | write | Create a Meta ad set under an existing campaign. | | nc_meta_create_ad | write | Create a Meta ad under an existing ad set with a single-image link creative. | | nc_meta_upload_image | write | Upload an image to a Meta ad account. | | nc_meta_update_campaign_budget | write | Update the daily or lifetime budget on an existing Meta campaign. | | nc_meta_pause_campaign | write | Pause a running Meta campaign. | | nc_meta_get_campaign_performance | read | Read-only — fetch insights (impressions, clicks, spend, CTR, etc) for one Meta campaign. | | nc_meta_create_custom_audience | write | Create a Meta custom audience from a list of contacts (email/phone). | | nc_meta_create_lookalike_audience | write | Create a Meta lookalike audience from an existing custom audience. | | nc_meta_upload_video | write | Upload a video to a Meta ad account via URL-based ingestion. v0 supports `file_url` only (chunked upload deferred). | | nc_meta_create_video_ad | write | Create a single-video Meta ad under an existing ad set. | | nc_meta_create_carousel_ad | write | Create a Meta carousel ad with 2-10 cards under an existing ad set. | | nc_meta_generate_ad_previews | read | Render a preview of a Meta ad in a given ad format. | | nc_meta_search_targeting | read | Search Meta targeting options (interests, geos, employers, positions, schools, locales). | | nc_meta_list_lead_forms | read | List Meta Instant Forms for ONE ad account. | | nc_meta_retrieve_leads | read | Pull leads from an existing Meta lead form. | | nc_meta_pixel_health | read | Composite pixel diagnostic: pixel details + event stats + server-side (CAPI) traffic. | | nc_meta_ads_library_search | read | Search Meta's public Ads Library for active competitor ads. | | nc_meta_duplicate_campaign | write | Copy a Meta campaign (and optionally its ad sets and ads). | | nc_meta_rename_campaign | write | Rename a Meta campaign. | | nc_meta_update_campaign_bidding_strategy | write | Update the bid strategy (and optional bid cap or ROAS floor) on a Meta campaign. | | nc_meta_list_campaigns | read | List Meta campaigns on an ad account. | | nc_meta_get_campaign_settings | read | Fetch all settings for a single Meta campaign (objective, budgets, bid strategy, schedule, special_ad_categories, etc). | | nc_meta_duplicate_ad_set | write | Copy a Meta ad set. | | nc_meta_update_adset_bid_value | write | Update the bid cap (bid_amount) or ROAS floor (min_roas) on a Meta ad set. | | nc_meta_update_adset_schedule | write | Update the start_time or end_time on a Meta ad set. | | nc_meta_update_adset_placements | write | Set placement targeting on an ad set. mode=automatic restores all placements. mode=manual + placements[] specifies exact positions (format: platform.position, e.g. "facebook.feed", "instagram.stream", "audience_network.classic"). | | nc_meta_update_adset_locations | write | Replace geo targeting (include) or excluded locations (exclude) on an ad set. location items: { type: "country"\|"city"\|"region"\|"zip", key: string }. | | nc_meta_update_adset_language | write | Update language targeting (locales) on a Meta ad set. locale_ids: Meta integer locale ids (e.g. 6=English, 28=Hebrew). | | nc_meta_update_adset_audiences | write | Replace audience targeting (custom audiences, interests, behaviors, demographics) on a Meta ad set. | | nc_meta_update_adset | write | Low-level escape hatch: POST /{ad_set_id} with arbitrary Graph API params. | | nc_meta_rename_adset | write | Rename a Meta ad set. | | nc_meta_list_ad_sets | read | List Meta ad sets on an ad account. | | nc_meta_get_adset_settings | read | Fetch all settings for a single Meta ad set (targeting, budget, schedule, bid, etc). | | nc_meta_duplicate_ad | write | Copy a Meta ad. | | nc_meta_create_catalog_ad | write | Create a Dynamic Product Ads (DPA / Catalog) ad using a product set. | | nc_meta_create_flexible_ad | write | Create a flexible (multi-asset / Advantage+ creative) Meta ad with multiple image/video/text variations. | | nc_meta_create_ad_from_post | write | Turn an existing organic Facebook post or Instagram media into a Meta ad. | | nc_meta_create_ad_from_creative | write | Create a Meta ad referencing an existing saved ad creative by creative_id. | | nc_meta_list_ads | read | List Meta ads on an ad account. | | nc_meta_rename_ad | write | Rename a Meta ad. | | nc_meta_get_ad_creative | read | Fetch the creative spec for a Meta ad or standalone creative. | | nc_meta_replace_ad_creative | write | Swap the creative on a Meta ad for an existing creative by creative_id. | | nc_meta_list_account_pixels | read | List all Meta pixels on an ad account. | | nc_meta_get_pixel_details | read | Get detailed info for a single Meta pixel (code snippet, last_fired_time, owner, automatic_matching settings). | | nc_meta_get_pixel_stats | read | Get event statistics for a Meta pixel. | | nc_meta_check_capi_health | read | Check Conversions API (CAPI / server-side) health for a pixel. | | nc_meta_list_custom_conversions | read | List custom conversion definitions on a Meta ad account (rule-based conversions, pixel event filters, etc). | ### `nc_meta_create_campaign` write Needs `mcp:write` on an OAuth or MCP-server token. Create a Meta Ads campaign. Always created in PAUSED state — caller must approve before unpausing. Requires marketing.edit. Use dry_run: true to preview without calling Graph.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | NexaCloser connections.id for the Meta (facebook) connection. | | `ad_account_id` | string | yes | Meta ad account numeric id, no act_ prefix. | | `name` | string | yes | Max length 400 | | `objective` | string | yes | One of: `OUTCOME_TRAFFIC`, `OUTCOME_LEADS`, `OUTCOME_SALES`, `OUTCOME_AWARENESS`, `OUTCOME_ENGAGEMENT`, `OUTCOME_APP_PROMOTION` | | `daily_budget` | number | | Daily budget in account-currency minor units (e.g. ₪50 = 5000). | | `lifetime_budget` | number | | Mutually exclusive with daily_budget. | | `bid_strategy` | string | | Defaults to LOWEST_COST_WITHOUT_CAP. Do not use WITH_BID_CAP unless you will send bid_amount on every ad set. · One of: `LOWEST_COST_WITHOUT_CAP`, `LOWEST_COST_WITH_BID_CAP`, `COST_CAP`, `MINIMUM_ROAS` | | `special_ad_categories` | string[] | | | | `dry_run` | boolean | | |
### `nc_meta_create_ad_set` write Needs `mcp:write` on an OAuth or MCP-server token. Create a Meta ad set under an existing campaign. Always PAUSED on create. Omit daily_budget when the parent campaign uses CBO (campaign-level budget). Defaults bid_strategy to LOWEST_COST_WITHOUT_CAP. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_account_id` | string | yes | | | `campaign_id` | string | yes | Parent campaign id from nc_meta_create_campaign. | | `name` | string | yes | Max length 400 | | `daily_budget` | integer | | Account-currency minor units. Min 500. Omit when parent campaign already has daily_budget/lifetime_budget (CBO) — dual budget fails with Meta Invalid parameter. · Min 500 | | `optimization_goal` | string | yes | One of: `REACH`, `LINK_CLICKS`, `LANDING_PAGE_VIEWS`, `OFFSITE_CONVERSIONS`, `LEAD_GENERATION`, `IMPRESSIONS`, `POST_ENGAGEMENT`, `VIDEO_VIEWS`, `THRUPLAY` | | `billing_event` | string | yes | One of: `IMPRESSIONS`, `LINK_CLICKS`, `THRUPLAY` | | `bid_strategy` | string | | Defaults to LOWEST_COST_WITHOUT_CAP (no bid_amount). WITH_BID_CAP requires bid_amount. · One of: `LOWEST_COST_WITHOUT_CAP`, `LOWEST_COST_WITH_BID_CAP`, `COST_CAP`, `MINIMUM_ROAS` | | `bid_amount` | integer | | Required only for WITH_BID_CAP / COST_CAP. Minor units. · Min 1 | | `targeting` | object | yes | | | `targeting.geo_locations` | object | yes | | | `targeting.geo_locations.countries` | string[] | yes | Min items 1 | | `dry_run` | boolean | | |
### `nc_meta_create_ad` write Needs `mcp:write` on an OAuth or MCP-server token. Create a Meta ad under an existing ad set with a single-image link creative. Always PAUSED on create. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_account_id` | string | yes | | | `ad_set_id` | string | yes | | | `name` | string | yes | Max length 400 | | `creative` | object | yes | | | `creative.image_hash` | string | yes | Returned by nc_meta_upload_image. 32-64 char hex. | | `creative.page_id` | string | yes | Facebook Page id that owns the post. | | `creative.link` | string | yes | Destination URL, must start with https:// | | `creative.message` | string | yes | Primary text. · Max length 125 | | `creative.headline` | string | | Max length 40 | | `creative.description` | string | | Max length 27 | | `creative.call_to_action_type` | string | | One of: `LEARN_MORE`, `SHOP_NOW`, `SIGN_UP`, `BOOK_TRAVEL`, `DOWNLOAD`, `GET_QUOTE`, `CONTACT_US`, `APPLY_NOW` | | `dry_run` | boolean | | |
### `nc_meta_upload_image` write Needs `mcp:write` on an OAuth or MCP-server token. Upload an image to a Meta ad account. Returns { image_hash } usable in nc_meta_create_ad. Provide image_url (https) OR image_data (base64, ≤30 MB). Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_account_id` | string | yes | | | `image_url` | string | | Public https URL — Meta fetches it. | | `image_data` | string | | Base64-encoded bytes, no data: prefix. Max 30 MB decoded. | | `filename` | string | | Default: `"image.jpg"` | | `dry_run` | boolean | | |
### `nc_meta_update_campaign_budget` write Needs `mcp:write` on an OAuth or MCP-server token. Update the daily or lifetime budget on an existing Meta campaign. Status untouched. Provide exactly one of daily_budget or lifetime_budget. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `campaign_id` | string | yes | | | `daily_budget` | number | | Min 1 | | `lifetime_budget` | number | | Min 1 | | `dry_run` | boolean | | |
### `nc_meta_pause_campaign` write Needs `mcp:write` on an OAuth or MCP-server token. Pause a running Meta campaign. Idempotent. There is no resume tool — bringing a campaign back to ACTIVE is intentionally not exposed to the agent. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `campaign_id` | string | yes | | | `dry_run` | boolean | | |
### `nc_meta_get_campaign_performance` read Works with `mcp:read`. Read-only — fetch insights (impressions, clicks, spend, CTR, etc) for one Meta campaign. Defaults to last_30d.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `campaign_id` | string | yes | | | `date_preset` | string | | One of: `today`, `yesterday`, `this_week_mon_today`, `last_7d`, `last_14d`, `last_28d`, `last_30d`, `last_90d`, `this_month`, `last_month`, `this_quarter`, `maximum`, `lifetime` | | `time_range` | object | | | | `time_range.since` | string | | YYYY-MM-DD | | `time_range.until` | string | | YYYY-MM-DD | | `fields` | string[] | | |
### `nc_meta_create_custom_audience` write Needs `mcp:write` on an OAuth or MCP-server token. Create a Meta custom audience from a list of contacts (email/phone). Contacts are hashed client-side (SHA-256 of normalized lowercase email or E.164 phone) before upload — never send unhashed PII. Two quota ops (create + add users). Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_account_id` | string | yes | | | `name` | string | yes | | | `description` | string | | | | `contacts` | object[] | yes | Min items 1 | | `contacts[].email` | string | | | | `contacts[].phone` | string | | Any format; we normalize to E.164 (Israeli numbers auto-prefixed with 972). | | `customer_file_source` | string | | One of: `USER_PROVIDED_ONLY`, `PARTNER_PROVIDED_ONLY`, `BOTH_USER_AND_PARTNER_PROVIDED` · Default: `"USER_PROVIDED_ONLY"` | | `dry_run` | boolean | | |
### `nc_meta_create_lookalike_audience` write Needs `mcp:write` on an OAuth or MCP-server token. Create a Meta lookalike audience from an existing custom audience. Default country IL, default ratio 0.05 (5% of country pop). One quota op. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_account_id` | string | yes | | | `name` | string | yes | | | `source_audience_id` | string | yes | Existing custom audience id from nc_meta_create_custom_audience. | | `country` | string | | ISO-2 country code. Default 'IL'. | | `ratio` | number | | Default: `0.05` · Min 0.01 · Max 0.2 | | `description` | string | | | | `dry_run` | boolean | | |
### `nc_meta_upload_video` write Needs `mcp:write` on an OAuth or MCP-server token. Upload a video to a Meta ad account via URL-based ingestion. v0 supports `file_url` only (chunked upload deferred). Returns { video_id } usable in nc_meta_create_video_ad. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_account_id` | string | yes | | | `file_url` | string | yes | Public https URL to the video file (≤4 GB, MP4/MOV, ≤240s). | | `title` | string | | | | `description` | string | | | | `dry_run` | boolean | | |
### `nc_meta_create_video_ad` write Needs `mcp:write` on an OAuth or MCP-server token. Create a single-video Meta ad under an existing ad set. Forced PAUSED. Same shape as nc_meta_create_ad but with video_data instead of link_data. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_account_id` | string | yes | | | `ad_set_id` | string | yes | | | `name` | string | yes | Max length 400 | | `creative` | object | yes | | | `creative.video_id` | string | yes | From nc_meta_upload_video. | | `creative.page_id` | string | yes | | | `creative.message` | string | | Max length 125 | | `creative.link` | string | | https Destination URL. | | `creative.image_url` | string | | Optional video thumbnail. | | `creative.headline` | string | | Max length 40 | | `creative.call_to_action_type` | string | | One of: `LEARN_MORE`, `SHOP_NOW`, `SIGN_UP`, `BOOK_TRAVEL`, `DOWNLOAD`, `GET_QUOTE`, `CONTACT_US`, `APPLY_NOW`, `WATCH_MORE` | | `dry_run` | boolean | | |
### `nc_meta_create_carousel_ad` write Needs `mcp:write` on an OAuth or MCP-server token. Create a Meta carousel ad with 2-10 cards under an existing ad set. Each card has its own image/video, link, headline, description, and CTA. Forced PAUSED. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_account_id` | string | yes | | | `ad_set_id` | string | yes | | | `name` | string | yes | Max length 400 | | `creative` | object | yes | | | `creative.page_id` | string | yes | | | `creative.message` | string | | Primary text shown above the carousel. · Max length 125 | | `creative.child_attachments` | object[] | yes | Min items 2 · Max items 10 | | `creative.child_attachments[].image_hash` | string | | From nc_meta_upload_image. | | `creative.child_attachments[].video_id` | string | | From nc_meta_upload_video. Mutually exclusive with image_hash. | | `creative.child_attachments[].link` | string | yes | https destination for this card. | | `creative.child_attachments[].name` | string | | Card headline. | | `creative.child_attachments[].description` | string | | Card sub-text. | | `creative.child_attachments[].call_to_action_type` | string | | One of: `LEARN_MORE`, `SHOP_NOW`, `SIGN_UP`, `BOOK_TRAVEL`, `DOWNLOAD`, `GET_QUOTE`, `CONTACT_US`, `APPLY_NOW` | | `dry_run` | boolean | | |
### `nc_meta_generate_ad_previews` read Works with `mcp:read`. Render a preview of a Meta ad in a given ad format. Pass `creative` object OR `creative_id` (one required). Returns iframe HTML body strings. Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_account_id` | string | yes | | | `creative` | object | | Inline creative object (object_story_spec etc). | | `creative_id` | string | | Existing creative id (mutually exclusive with `creative`). | | `ad_format` | string | | One of: `DESKTOP_FEED_STANDARD`, `MOBILE_FEED_STANDARD`, `INSTAGRAM_STANDARD`, `INSTAGRAM_STORY`, `INSTAGRAM_REELS`, `AUDIENCE_NETWORK_OUTSTREAM_VIDEO`, `MESSENGER_MOBILE_INBOX_MEDIA` · Default: `"MOBILE_FEED_STANDARD"` |
### `nc_meta_search_targeting` read Works with `mcp:read`. Search Meta targeting options (interests, geos, employers, positions, schools, locales). Audience-research tool for the agent before creating ad sets.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_account_id` | string | yes | | | `q` | string | yes | Search query, e.g. "Israeli tech entrepreneurs" or "yoga". | | `type` | string | | One of: `adinterest`, `adgeolocation`, `adworkemployer`, `adworkposition`, `adeducationschool`, `adeducationmajor`, `adlocale` · Default: `"adinterest"` | | `limit` | integer | | Default: `25` · Min 1 · Max 100 |
### `nc_meta_list_lead_forms` read Works with `mcp:read`. List Meta Instant Forms for ONE ad account. Resolves that account's promote_pages, then GET /{page_id}/leadgen_forms — never dumps every Page on the personal OAuth login. Pass ad_account_id (or rely on the single active marketing_ad_accounts row). Optional page_id filters within those promote pages.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_account_id` | string | | Meta ad account numeric id (no act_ prefix). Scopes forms to that account's promote_pages. Required when the connection has multiple active ad accounts. | | `page_id` | string | | Optional Facebook Page id — must be in the ad account's promote_pages. | | `limit` | integer | | Default: `50` · Min 1 · Max 200 |
### `nc_meta_retrieve_leads` read Works with `mcp:read`. Pull leads from an existing Meta lead form. Complements the push-based meta-leadgen-webhook for backfills and for accounts that cannot configure webhooks.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `form_id` | string | yes | Meta lead form id (from nc_meta_list_lead_forms). | | `limit` | integer | | Default: `100` · Min 1 · Max 500 | | `since` | string | | Unix timestamp or ISO8601. | | `until` | string | | Unix timestamp or ISO8601. |
### `nc_meta_pixel_health` read Works with `mcp:read`. Composite pixel diagnostic: pixel details + event stats + server-side (CAPI) traffic. Returns aggregated event_count, events_by_type, and recommendations[] (e.g. "capi_not_configured_enable_server_side_tracking").
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `pixel_id` | string | yes | | | `days` | integer | | Default: `7` · Min 1 · Max 90 |
### `nc_meta_ads_library_search` read Works with `mcp:read`. Search Meta's public Ads Library for active competitor ads. Default country: Israel. Returns ad creative bodies, page names, delivery dates, publisher platforms.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `search_terms` | string | yes | | | `countries` | string[] | | ISO-2 codes. Default ["IL"]. | | `ad_active_status` | string | | One of: `ALL`, `ACTIVE`, `INACTIVE` · Default: `"ACTIVE"` | | `limit` | integer | | Default: `25` · Min 1 · Max 100 |
### `nc_meta_duplicate_campaign` write Needs `mcp:write` on an OAuth or MCP-server token. Copy a Meta campaign (and optionally its ad sets and ads). The copy is always created in PAUSED state. Returns new_campaign_id. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `campaign_id` | string | yes | Meta campaign id to copy. | | `name_suffix` | string | | Suffix appended to the new campaign name. · Default: `" (copy)"` | | `include_ad_sets` | boolean | | When true, copies all child ad sets (deep_copy). · Default: `false` | | `include_ads` | boolean | | When true, copies all child ads (deep_copy). Implies include_ad_sets. · Default: `false` | | `dry_run` | boolean | | |
### `nc_meta_rename_campaign` write Needs `mcp:write` on an OAuth or MCP-server token. Rename a Meta campaign. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `campaign_id` | string | yes | | | `new_name` | string | yes | Max length 400 | | `dry_run` | boolean | | |
### `nc_meta_update_campaign_bidding_strategy` write Needs `mcp:write` on an OAuth or MCP-server token. Update the bid strategy (and optional bid cap or ROAS floor) on a Meta campaign. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `campaign_id` | string | yes | | | `bid_strategy` | string | yes | One of: `LOWEST_COST_WITHOUT_CAP`, `LOWEST_COST_WITH_BID_CAP`, `COST_CAP`, `MINIMUM_ROAS` | | `bid_amount` | number | | Bid cap in account-currency minor units. Required for LOWEST_COST_WITH_BID_CAP / COST_CAP. · Min 1 | | `roas_average_floor` | number | | Target ROAS floor (e.g. 1.5 = 150%). Required for MINIMUM_ROAS. · Min 0.01 | | `dry_run` | boolean | | |
### `nc_meta_list_campaigns` read Works with `mcp:read`. List Meta campaigns on an ad account. Filters: status, date range, limit. Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_account_id` | string | yes | Meta ad account numeric id, no act_ prefix. | | `status` | string | | Filter by campaign status. · One of: `ACTIVE`, `PAUSED`, `DELETED`, `ARCHIVED` | | `since` | string | | YYYY-MM-DD start of date range filter. | | `until` | string | | YYYY-MM-DD end of date range filter. | | `limit` | integer | | Default: `50` · Min 1 · Max 200 |
### `nc_meta_get_campaign_settings` read Works with `mcp:read`. Fetch all settings for a single Meta campaign (objective, budgets, bid strategy, schedule, special_ad_categories, etc). Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `campaign_id` | string | yes | |
### `nc_meta_duplicate_ad_set` write Needs `mcp:write` on an OAuth or MCP-server token. Copy a Meta ad set. The copy is always created in PAUSED state. Returns new_ad_set_id. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_set_id` | string | yes | | | `name_suffix` | string | | Default: `" (copy)"` | | `dry_run` | boolean | | |
### `nc_meta_update_adset_bid_value` write Needs `mcp:write` on an OAuth or MCP-server token. Update the bid cap (bid_amount) or ROAS floor (min_roas) on a Meta ad set. Pass exactly one. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_set_id` | string | yes | | | `bid_amount` | number | | Bid cap in account-currency minor units. · Min 1 | | `min_roas` | number | | ROAS floor (roas_average_floor), e.g. 1.5. · Min 0.01 | | `dry_run` | boolean | | |
### `nc_meta_update_adset_schedule` write Needs `mcp:write` on an OAuth or MCP-server token. Update the start_time or end_time on a Meta ad set. Provide at least one. ISO 8601 or Unix timestamp accepted. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_set_id` | string | yes | | | `start_time` | string | | ISO 8601 or Unix timestamp. | | `end_time` | string | | ISO 8601 or Unix timestamp. | | `dry_run` | boolean | | |
### `nc_meta_update_adset_placements` write Needs `mcp:write` on an OAuth or MCP-server token. Set placement targeting on an ad set. mode=automatic restores all placements. mode=manual + placements[] specifies exact positions (format: platform.position, e.g. "facebook.feed", "instagram.stream", "audience_network.classic"). Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_set_id` | string | yes | | | `mode` | string | | One of: `automatic`, `manual` · Default: `"automatic"` | | `placements` | string[] | | Required when mode=manual. e.g. ["facebook.feed","instagram.stream"] | | `dry_run` | boolean | | |
### `nc_meta_update_adset_locations` write Needs `mcp:write` on an OAuth or MCP-server token. Replace geo targeting (include) or excluded locations (exclude) on an ad set. location items: { type: "country"|"city"|"region"|"zip", key: string }. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_set_id` | string | yes | | | `locations` | object[] | yes | Min items 1 | | `locations[].type` | string | | One of: `country`, `city`, `region`, `zip` · Default: `"country"` | | `locations[].key` | string | yes | Meta targeting key, e.g. "IL" for Israel. | | `action` | string | | One of: `include`, `exclude` · Default: `"include"` | | `dry_run` | boolean | | |
### `nc_meta_update_adset_language` write Needs `mcp:write` on an OAuth or MCP-server token. Update language targeting (locales) on a Meta ad set. locale_ids: Meta integer locale ids (e.g. 6=English, 28=Hebrew). Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_set_id` | string | yes | | | `locale_ids` | integer[] | yes | Meta locale integer ids. 6=English, 28=Hebrew. · Min items 1 | | `dry_run` | boolean | | |
### `nc_meta_update_adset_audiences` write Needs `mcp:write` on an OAuth or MCP-server token. Replace audience targeting (custom audiences, interests, behaviors, demographics) on a Meta ad set. Each field provided replaces the current value. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_set_id` | string | yes | | | `custom_audiences` | object[] | | | | `custom_audiences[].id` | string | yes | | | `interests` | object[] | | | | `interests[].id` | string | yes | | | `behaviors` | object[] | | | | `behaviors[].id` | string | yes | | | `demographics` | object | | | | `demographics.age_min` | integer | | Min 13 · Max 65 | | `demographics.age_max` | integer | | Min 13 · Max 65 | | `demographics.genders` | integer[] | | 1=male, 2=female · Items: `1`, `2` | | `demographics.relationship_statuses` | integer[] | | | | `demographics.life_events` | object[] | | | | `demographics.life_events[].id` | string | yes | | | `dry_run` | boolean | | |
### `nc_meta_update_adset` write Needs `mcp:write` on an OAuth or MCP-server token. Low-level escape hatch: POST /{ad_set_id} with arbitrary Graph API params. Use only for fields not covered by dedicated tools. Status changes are blocked — use nc_meta_pause_campaign instead. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_set_id` | string | yes | | | `params` | object | yes | Raw Graph API params to POST. status field is rejected. | | `dry_run` | boolean | | |
### `nc_meta_rename_adset` write Needs `mcp:write` on an OAuth or MCP-server token. Rename a Meta ad set. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_set_id` | string | yes | | | `new_name` | string | yes | Max length 400 | | `dry_run` | boolean | | |
### `nc_meta_list_ad_sets` read Works with `mcp:read`. List Meta ad sets on an ad account. Optionally filter by campaign_id and status. Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_account_id` | string | yes | | | `campaign_id` | string | | Optional — limit to ad sets under one campaign. | | `status` | string | | One of: `ACTIVE`, `PAUSED`, `DELETED`, `ARCHIVED` | | `limit` | integer | | Default: `50` · Min 1 · Max 200 |
### `nc_meta_get_adset_settings` read Works with `mcp:read`. Fetch all settings for a single Meta ad set (targeting, budget, schedule, bid, etc). Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_set_id` | string | yes | |
### `nc_meta_duplicate_ad` write Needs `mcp:write` on an OAuth or MCP-server token. Copy a Meta ad. The copy is always created in PAUSED state. Returns new_ad_id. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_id` | string | yes | | | `name_suffix` | string | | Default: `" (copy)"` | | `dry_run` | boolean | | |
### `nc_meta_create_catalog_ad` write Needs `mcp:write` on an OAuth or MCP-server token. Create a Dynamic Product Ads (DPA / Catalog) ad using a product set. Always PAUSED on create. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_account_id` | string | yes | | | `ad_set_id` | string | yes | | | `name` | string | yes | Max length 400 | | `product_set_id` | string | yes | Meta product set id from a catalog. | | `page_id` | string | yes | Facebook Page id for the ad. | | `message` | string | | Primary text shown above the catalog. · Max length 125 | | `link` | string | | Destination URL template (https). | | `dry_run` | boolean | | |
### `nc_meta_create_flexible_ad` write Needs `mcp:write` on an OAuth or MCP-server token. Create a flexible (multi-asset / Advantage+ creative) Meta ad with multiple image/video/text variations. Meta picks the best combination per impression. Always PAUSED on create. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_account_id` | string | yes | | | `ad_set_id` | string | yes | | | `name` | string | yes | Max length 400 | | `page_id` | string | yes | | | `image_hashes` | string[] | | Image hashes from nc_meta_upload_image. | | `video_ids` | string[] | | Video ids from nc_meta_upload_video. | | `bodies` | string[] | | Primary text variations. | | `titles` | string[] | | Headline variations. | | `descriptions` | string[] | | Description variations. | | `link` | string | | Destination URL (https). | | `cta_types` | string[] | | CTA type variations, e.g. ["LEARN_MORE","SIGN_UP"]. | | `dry_run` | boolean | | |
### `nc_meta_create_ad_from_post` write Needs `mcp:write` on an OAuth or MCP-server token. Turn an existing organic Facebook post or Instagram media into a Meta ad. Provide either fb_post_id (format: {page_id}_{post_id}) or ig_media_id. Always PAUSED on create. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_account_id` | string | yes | | | `ad_set_id` | string | yes | | | `name` | string | yes | Max length 400 | | `fb_post_id` | string | | Facebook Page post id: {page_id}_{post_id}. Mutually exclusive with ig_media_id. | | `ig_media_id` | string | | Instagram media id. Mutually exclusive with fb_post_id. | | `dry_run` | boolean | | |
### `nc_meta_create_ad_from_creative` write Needs `mcp:write` on an OAuth or MCP-server token. Create a Meta ad referencing an existing saved ad creative by creative_id. Always PAUSED on create. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_account_id` | string | yes | | | `ad_set_id` | string | yes | | | `name` | string | yes | Max length 400 | | `creative_id` | string | yes | Existing Meta ad creative id. | | `dry_run` | boolean | | |
### `nc_meta_list_ads` read Works with `mcp:read`. List Meta ads on an ad account. Optionally filter by ad_set_id, campaign_id, or status. Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_account_id` | string | yes | | | `ad_set_id` | string | | Optional — restrict to one ad set. | | `campaign_id` | string | | Optional — restrict to one campaign. | | `status` | string | | One of: `ACTIVE`, `PAUSED`, `DELETED`, `ARCHIVED` | | `limit` | integer | | Default: `50` · Min 1 · Max 200 |
### `nc_meta_rename_ad` write Needs `mcp:write` on an OAuth or MCP-server token. Rename a Meta ad. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_id` | string | yes | | | `new_name` | string | yes | Max length 400 | | `dry_run` | boolean | | |
### `nc_meta_get_ad_creative` read Works with `mcp:read`. Fetch the creative spec for a Meta ad or standalone creative. Pass ad_id (resolves attached creative) OR creative_id. Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_id` | string | | Meta ad id — resolves its attached creative. Mutually exclusive with creative_id. | | `creative_id` | string | | Existing creative id. Mutually exclusive with ad_id. |
### `nc_meta_replace_ad_creative` write Needs `mcp:write` on an OAuth or MCP-server token. Swap the creative on a Meta ad for an existing creative by creative_id. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_id` | string | yes | | | `new_creative_id` | string | yes | Creative id to attach to the ad. | | `dry_run` | boolean | | |
### `nc_meta_list_account_pixels` read Works with `mcp:read`. List all Meta pixels on an ad account. Returns id, name, code, last_fired_time, is_unavailable. Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_account_id` | string | yes | | | `limit` | integer | | Default: `25` · Min 1 · Max 100 |
### `nc_meta_get_pixel_details` read Works with `mcp:read`. Get detailed info for a single Meta pixel (code snippet, last_fired_time, owner, automatic_matching settings). Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `pixel_id` | string | yes | |
### `nc_meta_get_pixel_stats` read Works with `mcp:read`. Get event statistics for a Meta pixel. Returns total event counts grouped by event type or other aggregation. Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `pixel_id` | string | yes | | | `aggregation` | string | | Meta stats aggregation: event \| device_type \| browser_type \| hour. · Default: `"event"` | | `days` | integer | | Default: `7` · Min 1 · Max 90 |
### `nc_meta_check_capi_health` read Works with `mcp:read`. Check Conversions API (CAPI / server-side) health for a pixel. Returns health status, event counts, and a recommendations[] list. Use this before and after configuring CAPI to confirm events are flowing. Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `pixel_id` | string | yes | | | `days` | integer | | Default: `7` · Min 1 · Max 90 |
### `nc_meta_list_custom_conversions` read Works with `mcp:read`. List custom conversion definitions on a Meta ad account (rule-based conversions, pixel event filters, etc). Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `ad_account_id` | string | yes | | | `limit` | integer | | Default: `50` · Min 1 · Max 200 |
--- # TikTok Ads URL: https://docs.nexacloser.com/mcp/tools/tiktok-ads/ TikTok campaigns, ad groups, ads and posts. 26 tools: 10 read, 16 write. :::note[Generated] This page is generated from the MCP server source on every docs build. Names, descriptions and arguments are exactly what `tools/list` returns. ::: | Tool | Access | What it does | |---|---|---| | nc_tiktok_select_accounts | write | List TikTok advertiser accounts the connected user has access to. | | nc_tiktok_list_pages | read | List TikTok Instant Pages / Instant Forms / DM pages / storefront pages associated with an advertiser account. | | nc_tiktok_list_identities | read | List TikTok identities (TikTok accounts) available for an advertiser. | | nc_tiktok_list_posts | read | List organic TikTok posts available for Spark Ads Pull. | | nc_tiktok_create_campaign | write | Create a TikTok Ads campaign. | | nc_tiktok_update_campaign_status | write | Enable, disable, or delete a TikTok campaign. | | nc_tiktok_update_campaign_budget | write | Update the daily or lifetime budget on an existing TikTok campaign. | | nc_tiktok_rename_campaign | write | Rename a TikTok campaign. | | nc_tiktok_list_campaigns | read | List TikTok campaigns for an advertiser. | | nc_tiktok_create_ad_group | write | Create a TikTok ad group under an existing campaign. | | nc_tiktok_update_ad_group | write | Low-level escape-hatch to update any ad group field. | | nc_tiktok_update_ad_group_status | write | Enable, disable, or delete a TikTok ad group. | | nc_tiktok_update_ad_group_budget | write | Update the budget on an existing TikTok ad group. | | nc_tiktok_rename_ad_group | write | Rename a TikTok ad group. | | nc_tiktok_list_ad_groups | read | List TikTok ad groups for an advertiser, optionally filtered by campaign. | | nc_tiktok_create_image_ad | write | Create a TikTok image ad (single image or carousel). | | nc_tiktok_create_video_ad | write | Create a TikTok video ad (single video). | | nc_tiktok_create_ad_from_post | write | Create a TikTok Spark Ad from an existing organic post (Spark Ads Pull). | | nc_tiktok_update_ad | write | Low-level escape-hatch to update any ad field via the TikTok /ad/update/ endpoint. | | nc_tiktok_update_ad_status | write | Enable, disable, or delete a TikTok ad. | | nc_tiktok_rename_ad | write | Rename a TikTok ad creative. | | nc_tiktok_generate_ad_preview | read | Generate a preview URL for an existing TikTok ad. | | nc_tiktok_list_ads | read | List TikTok ads for an advertiser. | | nc_tiktok_search_targeting | read | Search or list TikTok targeting options for ad groups: interests, behaviours, demographics, geo locations, hashtags. | | nc_tiktok_list_pixels | read | List TikTok Pixels for an advertiser account. | | nc_tiktok_search_music | read | Search TikTok music tracks for use in image (carousel) ads. | ### `nc_tiktok_select_accounts` write Needs `mcp:write` on an OAuth or MCP-server token. List TikTok advertiser accounts the connected user has access to. Returns advertiser_id + name for each account. Use to discover which advertiser_id to pass to other nc_tiktok_* tools. Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | NexaCloser connections.id for the TikTok connection. |
### `nc_tiktok_list_pages` read Works with `mcp:read`. List TikTok Instant Pages / Instant Forms / DM pages / storefront pages associated with an advertiser account. Returns page_id + name + type. Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `advertiser_id` | string | yes | TikTok advertiser id. | | `page_size` | integer | | Default: `50` · Min 1 · Max 100 |
### `nc_tiktok_list_identities` read Works with `mcp:read`. List TikTok identities (TikTok accounts) available for an advertiser. Used for Spark Ads — identity_id is required when creating ads from organic posts. Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `advertiser_id` | string | yes | | | `page_size` | integer | | Default: `50` · Min 1 · Max 100 |
### `nc_tiktok_list_posts` read Works with `mcp:read`. List organic TikTok posts available for Spark Ads Pull. Returns item_id + cover + create_time + video_id for each post. Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `advertiser_id` | string | yes | | | `identity_id` | string | yes | TikTok identity id from nc_tiktok_list_identities. | | `page_size` | integer | | Default: `50` · Min 1 · Max 100 |
### `nc_tiktok_create_campaign` write Needs `mcp:write` on an OAuth or MCP-server token. Create a TikTok Ads campaign. Always created in DISABLE (paused) state — caller must approve before enabling. Use dry_run: true to preview. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `advertiser_id` | string | yes | | | `name` | string | yes | Max length 512 | | `objective_type` | string | yes | TikTok campaign objective. · One of: `TRAFFIC`, `LEAD_GENERATION`, `CONVERSIONS`, `APP_INSTALL`, `VIDEO_VIEWS`, `REACH`, `ENGAGEMENT`, `FOLLOWERS`, `CATALOG_SALES`, `SHOP_PURCHASES` | | `campaign_type` | string | | Default REGULAR_CAMPAIGN. Use SMART_PERFORMANCE_CAMPAIGN for Smart+ automation. · One of: `REGULAR_CAMPAIGN`, `IOS14_CAMPAIGN`, `SMART_PERFORMANCE_CAMPAIGN` | | `budget_mode` | string | | One of: `BUDGET_MODE_DAY`, `BUDGET_MODE_TOTAL`, `BUDGET_MODE_INFINITE` | | `budget` | number | | Daily or total budget in account currency. Required unless budget_mode=BUDGET_MODE_INFINITE. | | `dry_run` | boolean | | |
### `nc_tiktok_update_campaign_status` write Needs `mcp:write` on an OAuth or MCP-server token. Enable, disable, or delete a TikTok campaign. ENABLE = live, DISABLE = paused, DELETE = soft-delete. Use dry_run: true to preview. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `advertiser_id` | string | yes | | | `campaign_id` | string | yes | | | `operation_status` | string | yes | One of: `ENABLE`, `DISABLE`, `DELETE` | | `dry_run` | boolean | | |
### `nc_tiktok_update_campaign_budget` write Needs `mcp:write` on an OAuth or MCP-server token. Update the daily or lifetime budget on an existing TikTok campaign. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `advertiser_id` | string | yes | | | `campaign_id` | string | yes | | | `budget` | number | yes | New budget in account currency. | | `budget_mode` | string | | One of: `BUDGET_MODE_DAY`, `BUDGET_MODE_TOTAL` | | `dry_run` | boolean | | |
### `nc_tiktok_rename_campaign` write Needs `mcp:write` on an OAuth or MCP-server token. Rename a TikTok campaign. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `advertiser_id` | string | yes | | | `campaign_id` | string | yes | | | `new_name` | string | yes | Max length 512 | | `dry_run` | boolean | | |
### `nc_tiktok_list_campaigns` read Works with `mcp:read`. List TikTok campaigns for an advertiser. Supports status and objective_type filters. Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `advertiser_id` | string | yes | | | `page_size` | integer | | Default: `100` · Min 1 · Max 100 | | `filtering` | object | | Optional TikTok filter object, e.g. { "status": "CAMPAIGN_STATUS_ENABLE" }. |
### `nc_tiktok_create_ad_group` write Needs `mcp:write` on an OAuth or MCP-server token. Create a TikTok ad group under an existing campaign. Always created in DISABLE (paused) state. Supports standard, Search, and Smart+ campaign types. Use dry_run: true to preview. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `advertiser_id` | string | yes | | | `campaign_id` | string | yes | | | `name` | string | yes | Max length 512 | | `budget` | number | yes | Ad group budget in account currency. | | `budget_mode` | string | | One of: `BUDGET_MODE_DAY`, `BUDGET_MODE_TOTAL` · Default: `"BUDGET_MODE_DAY"` | | `placement_type` | string | | One of: `PLACEMENT_TYPE_AUTOMATIC`, `PLACEMENT_TYPE_NORMAL` · Default: `"PLACEMENT_TYPE_AUTOMATIC"` | | `optimization_goal` | string | | e.g. CLICK, REACH, CONVERSION, VIDEO_VIEW. | | `bid_price` | number | | | | `billing_event` | string | | e.g. CPC, CPM, oCPM. | | `audience` | object | | Raw TikTok audience targeting object (age, gender, geo locations, etc.). | | `schedule_start_time` | integer | | Unix timestamp (UTC). Defaults to now. | | `schedule_end_time` | integer | | Unix timestamp (UTC). Omit for no end date. | | `dry_run` | boolean | | |
### `nc_tiktok_update_ad_group` write Needs `mcp:write` on an OAuth or MCP-server token. Low-level escape-hatch to update any ad group field. Pass a raw TikTok ad group update payload in patch. The advertiser_id and adgroup_id are stamped automatically. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `advertiser_id` | string | yes | | | `adgroup_id` | string | yes | | | `patch` | object | yes | Raw TikTok /adgroup/update/ fields (excluding advertiser_id and adgroup_id). | | `dry_run` | boolean | | |
### `nc_tiktok_update_ad_group_status` write Needs `mcp:write` on an OAuth or MCP-server token. Enable, disable, or delete a TikTok ad group. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `advertiser_id` | string | yes | | | `adgroup_id` | string | yes | | | `operation_status` | string | yes | One of: `ENABLE`, `DISABLE`, `DELETE` | | `dry_run` | boolean | | |
### `nc_tiktok_update_ad_group_budget` write Needs `mcp:write` on an OAuth or MCP-server token. Update the budget on an existing TikTok ad group. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `advertiser_id` | string | yes | | | `adgroup_id` | string | yes | | | `budget` | number | yes | | | `budget_mode` | string | | One of: `BUDGET_MODE_DAY`, `BUDGET_MODE_TOTAL` | | `dry_run` | boolean | | |
### `nc_tiktok_rename_ad_group` write Needs `mcp:write` on an OAuth or MCP-server token. Rename a TikTok ad group. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `advertiser_id` | string | yes | | | `adgroup_id` | string | yes | | | `new_name` | string | yes | Max length 512 | | `dry_run` | boolean | | |
### `nc_tiktok_list_ad_groups` read Works with `mcp:read`. List TikTok ad groups for an advertiser, optionally filtered by campaign. Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `advertiser_id` | string | yes | | | `campaign_id` | string | | Filter to a specific campaign. | | `page_size` | integer | | Default: `100` · Min 1 · Max 100 |
### `nc_tiktok_create_image_ad` write Needs `mcp:write` on an OAuth or MCP-server token. Create a TikTok image ad (single image or carousel). Pass one image_id for single, multiple for carousel. Forced DISABLE on create. Use dry_run: true to preview. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `advertiser_id` | string | yes | | | `adgroup_id` | string | yes | | | `name` | string | yes | Max length 512 | | `image_ids` | string[] | yes | TikTok image_id values from the creative library. 1 = single image, 2+ = carousel. · Min items 1 | | `ad_text` | string | yes | Max length 100 | | `call_to_action` | string | | e.g. LEARN_MORE, SIGN_UP, SHOP_NOW, DOWNLOAD_NOW. | | `landing_page_url` | string | | | | `display_name` | string | | | | `identity_id` | string | | TikTok identity id for Spark Ads identity. | | `tiktok_page_id` | string | | TikTok page id (DM page, Instant Page, etc.). | | `dry_run` | boolean | | |
### `nc_tiktok_create_video_ad` write Needs `mcp:write` on an OAuth or MCP-server token. Create a TikTok video ad (single video). Forced DISABLE on create. Use nc_tiktok_create_ad_from_post for Spark Ads from organic posts. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `advertiser_id` | string | yes | | | `adgroup_id` | string | yes | | | `name` | string | yes | Max length 512 | | `video_id` | string | yes | TikTok video_id from the creative library. | | `ad_text` | string | yes | Max length 100 | | `call_to_action` | string | | | | `landing_page_url` | string | | | | `display_name` | string | | | | `identity_id` | string | | | | `tiktok_page_id` | string | | | | `image_id` | string | | Cover image id for the video thumbnail. | | `dry_run` | boolean | | |
### `nc_tiktok_create_ad_from_post` write Needs `mcp:write` on an OAuth or MCP-server token. Create a TikTok Spark Ad from an existing organic post (Spark Ads Pull). Requires the item_id from nc_tiktok_list_posts and an identity_id from nc_tiktok_list_identities. Forced DISABLE on create. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `advertiser_id` | string | yes | | | `adgroup_id` | string | yes | | | `name` | string | yes | Max length 512 | | `item_id` | string | yes | Organic post item_id from nc_tiktok_list_posts. | | `identity_id` | string | yes | TikTok identity id from nc_tiktok_list_identities. | | `call_to_action` | string | | | | `landing_page_url` | string | | | | `dry_run` | boolean | | |
### `nc_tiktok_update_ad` write Needs `mcp:write` on an OAuth or MCP-server token. Low-level escape-hatch to update any ad field via the TikTok /ad/update/ endpoint. Pass raw creative fields in patch (excluding ad_id). Supports both standard and Smart+ ads. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `advertiser_id` | string | yes | | | `ad_id` | string | yes | | | `patch` | object | yes | Raw TikTok /ad/update/ creative fields (excluding advertiser_id and ad_id). | | `dry_run` | boolean | | |
### `nc_tiktok_update_ad_status` write Needs `mcp:write` on an OAuth or MCP-server token. Enable, disable, or delete a TikTok ad. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `advertiser_id` | string | yes | | | `ad_id` | string | yes | | | `operation_status` | string | yes | One of: `ENABLE`, `DISABLE`, `DELETE` | | `dry_run` | boolean | | |
### `nc_tiktok_rename_ad` write Needs `mcp:write` on an OAuth or MCP-server token. Rename a TikTok ad creative. Requires marketing.edit.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `advertiser_id` | string | yes | | | `ad_id` | string | yes | | | `new_name` | string | yes | Max length 512 | | `dry_run` | boolean | | |
### `nc_tiktok_generate_ad_preview` read Works with `mcp:read`. Generate a preview URL for an existing TikTok ad. Returns a preview_url valid for ~24 hours. Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `advertiser_id` | string | yes | | | `ad_id` | string | yes | |
### `nc_tiktok_list_ads` read Works with `mcp:read`. List TikTok ads for an advertiser. Optionally filter by campaign_id or adgroup_id. Returns id, name, status, format, video_id, image_ids, ad_text, CTA, landing URL. Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `advertiser_id` | string | yes | | | `campaign_id` | string | | | | `adgroup_id` | string | | | | `page_size` | integer | | Default: `100` · Min 1 · Max 100 |
### `nc_tiktok_search_targeting` read Works with `mcp:read`. Search or list TikTok targeting options for ad groups: interests, behaviours, demographics, geo locations, hashtags. Use before creating ad groups to find valid targeting IDs. Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `advertiser_id` | string | yes | | | `targeting_type` | string | | Type of targeting to search/list. · One of: `INTEREST`, `BEHAVIOR`, `GEO`, `HASHTAG`, `LANGUAGE` | | `keyword` | string | | Optional search keyword to filter results. | | `page_size` | integer | | Default: `50` · Min 1 · Max 200 |
### `nc_tiktok_list_pixels` read Works with `mcp:read`. List TikTok Pixels for an advertiser account. Returns pixel_code, pixel_id, name, status. Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `advertiser_id` | string | yes | | | `page_size` | integer | | Default: `100` · Min 1 · Max 100 |
### `nc_tiktok_search_music` read Works with `mcp:read`. Search TikTok music tracks for use in image (carousel) ads. Returns music_id, title, artist, duration_ms. Read-only.
| Argument | Type | Required | Description | |---|---|---|---| | `connection_id` | string | yes | | | `advertiser_id` | string | yes | | | `keyword` | string | | Search keyword for track title or artist. | | `page_size` | integer | | Default: `50` · Min 1 · Max 100 |