Cordex in Claude, ChatGPT and other AI assistants
Cordex has a remote MCP server. Through it, AI assistants operate your account the way the in-app Copilot does: they look up contacts and conversations, move CRM deals, create campaigns and automations and build reports, always within the permissions you approve.
Server URL
https://app.cordex.ai/api/mcpStreamable HTTP transport. OAuth 2.1 with PKCE, with Dynamic Client Registration (DCR) or a Client ID Metadata Document (CIMD).
What you need
A Cordex account (sign up at app.cordex.ai/signup) and an assistant that supports remote MCP connectors.
How to connect
Claude (claude.ai, Desktop and mobile)
Open Settings › Connectors, search the directory for "Cordex" or click Add custom connector and paste https://app.cordex.ai/api/mcp. Click Connect, sign in to Cordex, pick the company and approve the permissions.
ChatGPT
Search for "Cordex" in ChatGPT apps. Until the app is available to you, turn on developer mode in Settings › Apps, create an app with the URL https://app.cordex.ai/api/mcp, choose OAuth and approve the permissions in the Cordex window.
Claude Code
Run the command below, then use /mcp inside Claude Code to authenticate in the browser.
claude mcp add --transport http cordex https://app.cordex.ai/api/mcpCursor and VS Code
Add the server to mcp.json. The editor opens the browser for the OAuth sign-in on the first call.
{
"mcpServers": {
"cordex": {
"url": "https://app.cordex.ai/api/mcp"
}
}
}Grok
At grok.com/connectors, click New connector › Custom, paste https://app.cordex.ai/api/mcp and complete the authorization.
Mistral Le Chat
In Connectors › Add connector › Custom MCP connector, paste https://app.cordex.ai/api/mcp and choose OAuth.
Perplexity
In Settings › Connectors › Add custom connector, paste https://app.cordex.ai/api/mcp and authorize.
Other clients (API key)
Clients without OAuth can use an API key created in Settings › API and MCP, sent in the Authorization: Bearer cdx_… header.
Permissions
On the consent screen you choose full access or, per module, read only or read and write. Tools that only read data are marked read-only; tools that delete or cancel something are marked destructive, and the assistant asks for confirmation before using them.
Available tools
233 tools across 12 modules.
Organization · 5 read · 4 write
integrations_list— List integrations within the current organization.integrations_overview— List the organization's integration connections with how many agents use each one.integrations_upsert— Create or update an organization's integration connection record; OAuth is handled separately.members_invite— Invite an administrator to the current organization by email.members_list— List members within the current organization.members_remove— Remove a current organization member, preserving at least one administrator.org_get— Get org within the current organization.org_update— Update org within the current organization.usage_summary— Read-only AI usage of the organization: requests, tokens and USD cost summed by month, source and model.
Contacts · 6 read · 8 write
contacts_create— Create contacts within the current organization.contacts_delete— Delete a contact and its conversations; its deals are kept without a contact.contacts_deleteMatching— Delete every contact matching the contacts.overview filter (query, platform, tags; none = all contacts) except excludeIds, like contacts.delete: their conversations are deleted and their deals kept without a contact. At most 5000 per call. expectedCount (the number the person confirmed) makes the call fail when the match changed.contacts_duplicates— Find groups of contacts that look like the same person (same e-mail, phone digits or WhatsApp number).contacts_get— Get contacts within the current organization.contacts_identities_add— Link a contact to a channel identity in the current organization.contacts_identities_remove— Remove a channel identity from a contact in the current organization.contacts_list— List contacts within the current organization.contacts_merge— Atomically move identities, conversations and deals from the source contact to the target, then delete the source.contacts_overview— Page contacts for screens: search text, channel platform filter, tags (contacts with any of them), sort, identities, open deals and last activity, plus the total.contacts_search— Search contacts by name, email or phone within the current organization.contacts_setCampaignOptOut— Mark whether a contact receives campaigns. Contacts who reply SAIR/PARAR/STOP to a campaign are opted out automatically; optedOut:false lets them receive campaigns again.contacts_tags— List the tags used on this organization's contacts with how many contacts carry each, most used first.contacts_update— Update contacts within the current organization.
CRM · 12 read · 20 write
custom_fields_create— Create custom fields within the current organization.custom_fields_delete— Delete a custom field definition and remove its stored values from contacts or deals.custom_fields_get— Get custom fields within the current organization.custom_fields_list— List custom fields within the current organization.custom_fields_update— Update custom fields within the current organization.deal_views_create— Save a view of a pipeline's deals for the current user (shared: true shows it to the whole organization). Open it at /crm?pipeline=<pipelineId>&view=<id>. config = {layout: kanban|table|calendar, filter: {match: all|any, rules: [{field, op, value?}]}, sort: [{field, dir: asc|desc}] (max 3, in priority order), cardFields: [field] (kanban card, in order), columns: [{field, width?}] (table, in order), calendar: {dateField, span: month|week}}; omitted keys keep their defaults. field = title|stage|value|owner|contact|expectedCloseDate|createdAt|updatedAt or custom.<key> of a deal custom field; the title is always shown, so leave it out of cardFields and columns. op by field type: text (title, contact, custom text) contains|notContains|is|empty|notEmpty; number (value in reais, custom number) eq|gt|lt|between [a,b]|empty|notEmpty; date (expectedCloseDate, createdAt, updatedAt, custom date) relative (today|thisWeek|thisMonth|overdue|next7|next30)|before|after (YYYY-MM-DD)|between [from,to]|empty|notEmpty; stage anyOf|noneOf [stage ids of this pipeline]; owner anyOf|noneOf [user ids or "me"]|empty|notEmpty; select anyOf|noneOf [options]|empty|notEmpty; multiselect hasAny|hasAll|hasNone [options]|empty|notEmpty; boolean isTrue|isFalse. All operators: contains, notContains, is, eq, gt, lt, between, before, after, relative, anyOf, noneOf, hasAny, hasAll, hasNone, isTrue, isFalse, empty, notEmpty.deal_views_delete— Delete a saved deal view the current user created.deal_views_get— Get one saved deal view the current user can use.deal_views_list— List the saved deal views of a pipeline the current user can use: their own in tab order, then colleagues' shared ones.deal_views_reorder— Reorder the current user's own deal view tabs of a pipeline; ids must contain each of their own views there exactly once.deal_views_update— Change a saved deal view the current user created: name, shared, or config (top-level config keys given replace the stored ones; the rest are kept). config = {layout: kanban|table|calendar, filter: {match: all|any, rules: [{field, op, value?}]}, sort: [{field, dir: asc|desc}] (max 3, in priority order), cardFields: [field] (kanban card, in order), columns: [{field, width?}] (table, in order), calendar: {dateField, span: month|week}}; omitted keys keep their defaults. field = title|stage|value|owner|contact|expectedCloseDate|createdAt|updatedAt or custom.<key> of a deal custom field; the title is always shown, so leave it out of cardFields and columns. op by field type: text (title, contact, custom text) contains|notContains|is|empty|notEmpty; number (value in reais, custom number) eq|gt|lt|between [a,b]|empty|notEmpty; date (expectedCloseDate, createdAt, updatedAt, custom date) relative (today|thisWeek|thisMonth|overdue|next7|next30)|before|after (YYYY-MM-DD)|between [from,to]|empty|notEmpty; stage anyOf|noneOf [stage ids of this pipeline]; owner anyOf|noneOf [user ids or "me"]|empty|notEmpty; select anyOf|noneOf [options]|empty|notEmpty; multiselect hasAny|hasAll|hasNone [options]|empty|notEmpty; boolean isTrue|isFalse. All operators: contains, notContains, is, eq, gt, lt, between, before, after, relative, anyOf, noneOf, hasAny, hasAll, hasNone, isTrue, isFalse, empty, notEmpty.deals_create— Create deals within the current organization.deals_delete— Delete deals within the current organization.deals_get— Get deals within the current organization.deals_history— List a deal's latest 500 activity log entries oldest first: its own create/update/move events (each output is the full deal after the change) and conversation.created for its current contact. Kept for 90 days.deals_list— List deals within the current organization.deals_move— Move a deal to a stage belonging to the same pipeline.deals_overview— List deals with their contact for screens, filtered by id, pipeline, stage, owner, contact or text.deals_update— Update deals within the current organization.pipelines_configure— Set up a pipeline that has no deals yet in one step: optional new name and the full ordered list of stages (replaces all current stages). Needs at least one open and one won stage. Refused when the pipeline has deals or an automation, flow or saved view points to its stages; edit stages one by one then.pipelines_create— Create pipelines within the current organization.pipelines_delete— Delete a pipeline with its stages and deals.pipelines_ensureDefault— Create the default sales pipeline when the organization has none; returns the pipelines.pipelines_get— Get pipelines within the current organization.pipelines_list— List pipelines within the current organization.pipelines_update— Update pipelines within the current organization.stages_create— Create a stage; without a position it is appended after the pipeline's last stage.stages_delete— Delete a stage; when it still has deals, moveDealsTo must name another stage of the same pipeline.stages_get— Get stages within the current organization.stages_list— List stages within the current organization.stages_reorder— Reorder all stages of one pipeline; ids must contain every stage exactly once.stages_update— Update stages within the current organization.
Agents · 11 read · 21 write
agents_create— Create agents within the current organization.agents_delete— Delete an agent; inboxes it handles fall back to no handler and its conversations to no assignee.agents_get— Get agents within the current organization.agents_integrations_attach— Attach agents integrations within the current organization.agents_integrations_detach— Detach agents integrations within the current organization.agents_knowledge_attach— Attach a knowledge base to an agent: from its next reply the agent searches it (search_knowledge tool) before answering questions the documents cover, and cites document and page.agents_knowledge_detach— Detach a knowledge base from an agent; the base and its documents stay.agents_list— List agents within the current organization.agents_skills_attach— Attach agents skills within the current organization.agents_skills_detach— Detach agents skills within the current organization.agents_update— Update agents within the current organization.agents_usage— List the inboxes handled by an agent and count the conversations assigned to it, before deleting it.knowledge_bases_create— Create a knowledge base: a named library of documents (manuals, policies, FAQs) that agents can search. Then add files (knowledge.sources.addFile) or web pages (knowledge.sources.addUrl) and attach it to agents with agents.knowledge.attach.knowledge_bases_delete— Delete a knowledge base with all its sources and passages, and detach it from every agent.knowledge_bases_get— Get one knowledge base with its source counts and the agents it is attached to.knowledge_bases_list— List the organization's knowledge bases with how many sources each holds and how many are ready, processing or failed. Agents search the bases attached to them (agents.knowledge.attach).knowledge_bases_update— Rename a knowledge base or change its description.knowledge_search— Search knowledge bases the way an agent does: hybrid search (meaning plus exact words such as product models and error codes) over the given base, or over every base attached to the given agent. Returns the best passages with document title, page and URL.knowledge_sources_addUrl— Add a public web page or a linked PDF (up to 50 MB, scanned pages included), or every page of a sitemap.xml (up to 200 pages of the same site), to a knowledge base. Only public https addresses are fetched; the source becomes searchable when its status is ready. Use knowledge.sources.resync to fetch it again later.knowledge_sources_delete— Delete a knowledge source and its passages; agents stop finding it immediately.knowledge_sources_get— Get one knowledge source with its status, page and passage counts, detected product models and summary.knowledge_sources_list— List the sources (files, pages, sitemaps) of a knowledge base with their processing status: pending and processing are still being read, ready ones are searchable, failed ones carry the error.knowledge_sources_resync— Read a knowledge source again (fetch the page or sitemap again, or reprocess a file), for example after a failure or when the site changed.skills_create— Create a private skill: a name, a short description of when an agent should use it, and a Markdown body with the instructions. Attach it to an agent with agents.skills.attach.skills_delete— Delete a private skill and detach it from every agent that uses it.skills_get— Get one private skill with its Markdown body and whether its published marketplace snapshot is out of date (publicationDirty).skills_install— Copy a published marketplace snapshot into the current organization's private skill library.skills_list— List this organization's private skills: reusable Markdown instructions (name, description, body) that AI agents follow once a skill is attached with agents.skills.attach.skills_marketplace_list— List explicitly published public skill snapshots across organizations.skills_publish— Publish an explicit public marketplace snapshot of a private skill; later private edits stay private.skills_unpublish— unpublish skills within the current organization.skills_update— Change the name, description or Markdown body of a private skill. Agents that use it follow the new text from their next reply; a published marketplace snapshot only changes with skills.publish.
Flows · 2 read · 8 write
flows_create— Create flows within the current organization.flows_delete— Delete flows within the current organization.flows_get— Get flows within the current organization.flows_list— List flows within the current organization.flows_publish— Publish the current draft as a new immutable flow version and activate it.flows_run_skipWait— skipWait flows run within the current organization.flows_run_start— Start a published flow in a conversation from its start node, replacing any running flow; restart=true also restarts the same flow.flows_run_stop— Stop the flow running in a conversation; the user who stops it becomes the assignee so the bot does not resume.flows_saveDraft— Save a flow graph as a draft without changing published versions; flows.publish validates it. Graph: {nodes:[{id,type,position:{x,y},data}], edges:[{id,source,target,sourceHandle?}]}. Node data by type: start {}; message {text} (supports {{contact.firstName}}, {{contact.name}} and captured {{var}}); question {text, buttons:[{id,label<=20 chars}] (max 3), saveAs?}; agent {agentId, goal, variables:[{name,description?}], exits:[{id,label,when}], maxTurns}; condition {branches:[{id,label,variable,operator:equals|not_equals|contains|gt|lt|is_set,value?}], elseLabel}; action {kind, label, params} with string params (they accept {{var}}): set_variable {name,value}; add_tag {tag}; update_contact_field {field: name|email|phone|<custom field key>, value}; create_deal {pipeline, stage, title?, valueCents?}; move_deal {stage, pipeline?} (moves the contact deal in that stage's pipeline); handoff {target:human|copilot, userId?, message?}; end {outcome:resolved|abandoned|converted}. Edges: exactly one start; start/message/action need a default edge (no sourceHandle); question edges use sourceHandle=button id, on_invalid or on_timeout; agent edges use exit id and a required 'fallback'; condition edges use branch id and 'else'; end/handoff have no outgoing edges.flows_update— Update flows within the current organization.
Channels · 18 read · 16 write
channels_abandon— Cancel a connection the user started and has not finished: disconnect it, then remove it locally.channels_configureWebhook— Enable the Cordex webhook on an owned WhatsApp session or restore its saved original configuration.channels_connectComplete— Complete a schema-described connection action for an owned pending channel.channels_connectOptions— List safe choices for an owned pending connection.channels_connectStart— Start a new Cordex channel connection.channels_delete— Delete channels within the current organization.channels_disconnect— disconnect for an owned Cordex channel.channels_get— Get channels within the current organization.channels_groups_list— List the WhatsApp groups of an owned WhatsApp QR channel, including names and participant counts, to configure allowed inbox groups. Read-only.channels_importExisting— Import an operator-authorized connected account without moving its profile.channels_list— List channels within the current organization.channels_messagingLimit— Meta's messaging limit for an official WhatsApp channel: tier (the organization's highest), limit (unique business-initiated recipients per rolling 24h, null when unlimited), budget (90% of it, what campaigns use), used (recipients counted now, manual templates included), oldestAt (when the oldest counted recipient frees a slot), quality rating and when the tier was read (refreshed after 6h). Read-only.channels_numbers_search— Read available phone numbers and prices.channels_numbers_unconnected— Read the numbers this organization bought that no WhatsApp account uses yet. Read-only.channels_permissions_status— Whether an Instagram or Facebook channel was authorized for comments and Direct messages; `missing` lists the areas to grant by reconnecting. Read-only.channels_qr— qr for an owned Cordex channel.channels_removalImpact— Count the conversations and messages that removing an owned channel would delete.channels_remove— Remove a disconnected channel locally with its inbox, conversations and messages; contacts and deals stay and the provider account is not touched.channels_status— status for an owned Cordex channel.channels_templates_create— Submit a new WhatsApp template for review (custom components) or create a pre-approved library template (libraryTemplateName; omit components). Media headers take a public https URL only, in example.header_handle. Variables {{1}}.. or {{name}} need examples. Carousel and limited_time_offer are MARKETING only; otp buttons AUTHENTICATION only.channels_templates_delete— Delete a template, irreversible: the name is locked for 30 days. Pass language to delete one variant, or allLanguages true to delete every variant.channels_templates_get— Get one template variant with its components, rejectedReason and quality. Pass language when the name has several variants. Read-only.channels_templates_library— Look up a pre-approved WhatsApp library template by exact name to preview its body, parameters and buttons before creating it. Read-only.channels_templates_list— List WhatsApp message templates of an owned official WhatsApp channel with status, category, language and a body preview. Status changes asynchronously (PENDING to APPROVED or REJECTED); call again to refresh. Read-only.channels_templates_update— Edit an APPROVED, REJECTED or PAUSED template variant. Component edits send it back to review; name, language and category cannot change; approved templates can be edited once per 24h.channels_update— Update channels within the current organization.channels_whatsappFlows_list— List the WhatsApp Flows of an owned official WhatsApp channel, to attach one to a template flow button. Read-only.comments_reply— Reply publicly under an Instagram or Facebook comment (comment.received); everyone who sees the post sees the reply.comments_replyPrivately— Send a Direct message to the author of an Instagram or Facebook comment (comment.received). Meta allows one private reply per comment, within 7 days of it. Optional buttons (1-3) are {type:'postback',title,payload} or {type:'web_url',title,url}.inboxes_create— Create an inbox for a channel in this organization. One inbox per channel; allowedGroupIds selects up to 50 WhatsApp group ids (...@g.us), default empty (no groups); groupsAll lets every group in, including future ones; groupMentionOnly makes the handler answer in groups only when the number is @mentioned or replied to.inboxes_get— Get inboxes within the current organization.inboxes_list— List inboxes within the current organization.inboxes_update— Update inbox routing/settings. allowedGroupIds selects up to 50 WhatsApp group ids (...@g.us); [] disables groups unless groupsAll; omitting it preserves selection. groupsAll=true lets every group in, including future ones. groupMentionOnly=true makes the handler answer in groups only when the number is @mentioned or replied to; other group messages stay as context. Groups use the inbox's own handler. Use channels.groups.list to discover groups.posts_list— List the most recent posts (25 per account, newest first) of the organization's connected Instagram and Facebook channels, including posts without comments. `id` is the platform post id that comment.received carries as postId. `search` filters by caption. Read-only.
Conversations · 7 read · 10 write
conversations_assign— Assign a conversation to a current member, an organization agent, the copilot, or no assignee. Assigning anyone while a flow runs stops that flow.conversations_filter— Filter conversations like the inbox screen, across the whole organization, newest activity first. Returns { items, total }; items have the conversations.overview shape. tab: mine (assigned to the caller) | unassigned | all | bots (agent, copilot or a running flow). channelId and status are the quick filters. filter: { match: all|any, rules: [{ field, op, value }] }, max 20 rules, combined with the quick filters by AND. Fields and ops: messageText (any visible message, 3-200 chars) and contact (name, phone or e-mail) contains|notContains; assignee anyOf|noneOf [user:<id> | agent:<id> | flow:<id> | copilot | none]; channel anyOf|noneOf [channel ids]; status anyOf|noneOf [open|pending|snoozed|resolved]; campaign anyOf|noneOf [campaign ids]; createdAt, lastMessageAt, lastInboundAt (customer's last message) relative (today|yesterday|last7|last30|thisMonth|lastMonth)|before|after (YYYY-MM-DD)|between [from,to] inclusive, as days in timeZone; conversations without that activity never match dates; tags (contact tags) hasAny|hasAll|hasNone [tags]; awaitingReply (customer spoke last, not resolved) and isTest isTrue|isFalse. timeZone is an IANA zone such as America/Sao_Paulo.conversations_get— Get conversations within the current organization.conversations_list— List conversations within the current organization.conversations_messagingWindow— Whether free-form messages can be sent: official WhatsApp only allows them within 24h of the contact's last message; otherwise use messages.sendTemplate. Read-only.conversations_overview— List conversations with contact, inbox, channel and last message. lastMessageBefore/After filter any visible message activity; lastInboundBefore means the customer has been silent since that ISO timestamp, and lastInboundAfter selects recent customer activity. Null activity timestamps never match these filters.conversations_setFlowStep— Set a conversation to an existing node of a published flow version and optionally update variables.conversations_setStatus— Set a conversation status to open, pending, snoozed, or resolved.conversations_startWithTemplate— Start (or continue) an official WhatsApp conversation with a contact by sending an APPROVED template. Give contactId, or phone in international format with a leading + (e.g. +5511999990000). Returns conversationId; the reply arrives in the same conversation. Same parameters as messages.sendTemplate.conversations_startWithText— Start (or continue) a WhatsApp conversation on a QR-connected WhatsApp channel by sending a free-text message; official WhatsApp channels need conversations.startWithTemplate instead. Give contactId, or phone in international format with a leading + (e.g. +5511999990000); the number must be on WhatsApp. Returns conversationId; the reply arrives in the same conversation.messages_list— List messages of a conversation. latest:true returns the newest page in chronological order; includeId extends it back to that message (plus some context), up to 1000 messages.messages_retry— retry messages within the current organization.messages_search— Search message text across all conversations of this organization (case-insensitive substring, at least 3 characters), newest first. Optional channelId and conversation status filters. Returns messageId, conversationId, text, createdAt, contact and channel.messages_send— Persist an outbound message, then enqueue delivery after the database commit; pending messages survive queue failures.messages_sendTemplate— Send an APPROVED WhatsApp template in an existing official WhatsApp conversation; it works when the 24h window is closed. headerParams/bodyParams are values in order of appearance (an object keyed by variable name for named templates); buttonParams fill dynamic URL suffixes, copy_code coupons and flow tokens by button index; headerMedia overrides the approved media (public https URL only); headerLocation is required for location headers. The template is checked against the live one before it is queued.web_sessions_create— Create a test customer conversation with an agent or flow in the Web channel.web_sessions_send— Speak as the customer in an existing Web test session; routes through normal inbound processing.
Automations · 6 read · 6 write
automations_catalog— Discover automation event names, operations, rule operators, variables, limits and organization timezone. Call before creating an automation. Supply operation to get that operation's input JSON schema.automations_create— Create an automation (Quando → Se → Então). Check automations.templates first and prefer automations.createFromTemplate when a template fits; otherwise call automations.catalog first. Trigger: event (any operation name that changes data, or message.received / conversation.created / contact.created / comment.received), schedule (5-field cron in the org timezone, optional forEach over a list operation) or manual. Steps: operation (any registry operation; input JSON accepts {{variables}}) or wait (duration like 1h, 3d). Optional per step: if (rules), onFalse skip|stop, once (template key). Created disabled unless enabled:true. once executes a step at most once per key across all runs; trigger.dedupe prevents duplicate runs per key; trigger.when filters immutable trigger/item data before run creation.automations_createFromTemplate— Install a marketplace template (see automations.templates) as an automation. fill maps slot keys to values: resolve real ids with read tools first; texts are message bodies. Auto pipeline/stage slots stay consistent: a given stageId brings its pipeline, a given pipelineId its first stage, neither the default pipeline and its first stage. name and prompt default to the localized ones; prompt is only accepted by AI templates. Created disabled unless enabled:true, which requires every non-auto slot to be filled. Adjust it afterwards with automations.update.automations_delete— Delete an automation and cascade deletion of its runs and once marks.automations_get— Get an automation definition, activation state, latest run and seven-day execution statistics by id.automations_list— List this organization's automations, optionally filtering enabled; includes latest run and seven-day total, done and failed counts.automations_run— Manually run an automation, including disabled ones, with optional trigger payload, item and isTest marker. Bypasses trigger.when; step if/once and trigger dedupe still apply. The run is queued after commit; inspect automations.runs.get for results.automations_runs_get— Get an execution's full definition snapshot, variables, step log, error and execution timing by run id.automations_runs_list— List automation executions newest first, optionally filtering automationId, status and isTest. Includes automation name and trigger payload; use runs.get for full log and snapshot.automations_setEnabled— Enable or disable an automation. Enabling from disabled resets schedule state and activates from now. Disabling cancels pending and waiting runs in the same transaction.automations_templates— List the curated automation marketplace (ready-made templates) in a language (pt-BR default, en, es), optionally by category or free text. Each item has key, category, title, description, needsInput, slots (what still has to be filled: ids of pipeline/stage/flow/agent/user, an approved WhatsApp template name, message texts or a keyword) and the full definition. Check it before building an automation from scratch and install a fitting one with automations.createFromTemplate.automations_update— Update supplied name, trigger or steps of an automation; omitted sections are preserved and the complete merged definition is validated. Changing trigger type resets schedule state. Existing runs keep their original definition snapshot.
Reports · 5 read · 7 write
reports_catalog— Discover what Relatorios (reports) can measure: sources (conversations, messages, deals, contacts, ads) with their fields, kinds, allowed aggregations and filter operators (including this organization's custom fields as custom.<key>), periods, buckets, ready-made presets, dashboard templates and the organization timezone. Call before building a query or dashboard.reports_dashboards_create— Create a dashboard for the current user (shared: true shows it to the whole organization, read-only for others). Start from a template (anuncios, atendimento, vendas, contatos) or give a config; locale (pt-BR default, en, es) sets the language of a template's widget titles; with neither it starts empty. Open it at /reports/<id>. config = {filters: {period, channelIds, assigneeIds, pipelineIds, networks (ads source only: meta|google|tiktok|linkedin|pinterest|x|reddit|openai)}, widgets: [{id, title, viz: kpi|line|bar|area|pie|donut|table|funnel, query, layout: {x 0-11, y, w 1-12, h 1-12} on a 12-column grid, options: {compare: none|previousPeriod, format: number|currency|duration|percent, stacked?, colors?}}]} (max 30 widgets). KPI widgets are w 3 h 2, charts w 6 h 4. Invalid configs return issues with paths such as widgets.0.query.measures.0.field.reports_dashboards_delete— Delete a dashboard the current user owns, with all its widgets. Colleagues' shared dashboards cannot be deleted; this cannot be undone.reports_dashboards_duplicate— Copy a dashboard the current user can see (their own or a shared one) into a new private dashboard they own. The copy is named "<name> (cópia)" unless name is given (locale en/es changes the suffix to "(copy)"/"(copia)").reports_dashboards_get— Get one dashboard (with its config) the current user owns or that is shared with them.reports_dashboards_list— List the dashboards the current user can use: their own first (by position), then colleagues' shared ones. Each has id, name, shared, position, ownerId and config.reports_dashboards_update— Change a dashboard the current user owns: name, shared, position (tab order) or config (a given config replaces the stored one; use reports.widgets.* to edit single widgets). config = {filters: {period, channelIds, assigneeIds, pipelineIds, networks (ads source only: meta|google|tiktok|linkedin|pinterest|x|reddit|openai)}, widgets: [{id, title, viz: kpi|line|bar|area|pie|donut|table|funnel, query, layout: {x 0-11, y, w 1-12, h 1-12} on a 12-column grid, options: {compare: none|previousPeriod, format: number|currency|duration|percent, stacked?, colors?}}]} (max 30 widgets). KPI widgets are w 3 h 2, charts w 6 h 4.reports_query— Run a report and return {columns, rows, truncated, period, previous?, labels?}. Columns are g0.. (groups) then m0.. (measures); labels maps assignee/owner ids to names. Read-only. Give either a query or a preset, optionally dashboard-style filters {period, channelIds, assigneeIds, pipelineIds, networks} (period overrides the query range) and compare: true to also get the previous period rows. A query = {source: conversations|messages|deals|contacts|ads, measures: [{agg: count|sum|avg|median|min|max|distinct, field?}] (1-6; field required except for count), groupBy?: [{field, bucket?: day|week|month|quarter|year}] (max 2, bucket only on date fields), filters?: [{field, op, value?}], period: {field?, range}, sort?: {by: m0..m5|g0|g1, dir}, limit?: 1-500, includeTest?: boolean}. range = today|yesterday|last7|last30|last90|thisWeek|thisMonth|thisQuarter|thisYear|lastMonth or {from: YYYY-MM-DD, to: YYYY-MM-DD}; period.field defaults to the source's creation date (use closedAt for deals closed in the period, resolvedAt for resolved conversations). ads = ad facts (metrics per ad per day, attributed conversations and deals, platform leads): group by network, account, campaign, adSet, ad, currency, date; sum spend/impressions/reach/clicks/conversions/conversionValue/platformLeads/messagingStarted/conversations/leads/deals/won/revenue; avg ctr/cpc/cpm/cpaReal/roasReal/roasPlatform (ratio of sums); count needs a field. Money measures are split by currency (a currency group is added); revenue is BRL; roasReal uses BRL accounts only; roasReal and cpaReal count only won deals whose first touch has a known ad campaign, so they can be lower than the won/revenue totals. reach is a sum of daily reach, not unique people. Charts of ads money support one measure (use a table for several); conversations/leads/deals/won cannot be filtered. Missing platform metrics are null, not 0. Filter an ads report by network with filters.networks. Fields, aggregations and operators per source come from reports.catalog: call it first. preset = one of: conv.volume, conv.byChannel, conv.byAssignee, conv.byStatus, conv.frt.median, conv.resolution.avg, msgs.volume, deals.wonValue, deals.winRate, deals.funnel, deals.byOwner, contacts.new, contacts.byTag, ads.spend, ads.spendByDay, ads.funnelByNetwork, ads.roasByNetwork, ads.topAds, ads.conversations.reports_records— Drill down into the records (up to 50: id, title, subtitle, createdAt, href) behind a report, optionally narrowed to one group or time bucket with bucket: {field, value} (field must be one of the query's groupBy fields; value is the group value as returned in rows, e.g. "2026-03-02" for a day). Read-only. A query = {source: conversations|messages|deals|contacts|ads, measures: [{agg: count|sum|avg|median|min|max|distinct, field?}] (1-6; field required except for count), groupBy?: [{field, bucket?: day|week|month|quarter|year}] (max 2, bucket only on date fields), filters?: [{field, op, value?}], period: {field?, range}, sort?: {by: m0..m5|g0|g1, dir}, limit?: 1-500, includeTest?: boolean}. range = today|yesterday|last7|last30|last90|thisWeek|thisMonth|thisQuarter|thisYear|lastMonth or {from: YYYY-MM-DD, to: YYYY-MM-DD}; period.field defaults to the source's creation date (use closedAt for deals closed in the period, resolvedAt for resolved conversations). ads = ad facts (metrics per ad per day, attributed conversations and deals, platform leads): group by network, account, campaign, adSet, ad, currency, date; sum spend/impressions/reach/clicks/conversions/conversionValue/platformLeads/messagingStarted/conversations/leads/deals/won/revenue; avg ctr/cpc/cpm/cpaReal/roasReal/roasPlatform (ratio of sums); count needs a field. Money measures are split by currency (a currency group is added); revenue is BRL; roasReal uses BRL accounts only; roasReal and cpaReal count only won deals whose first touch has a known ad campaign, so they can be lower than the won/revenue totals. reach is a sum of daily reach, not unique people. Charts of ads money support one measure (use a table for several); conversations/leads/deals/won cannot be filtered. Missing platform metrics are null, not 0. Filter an ads report by network with filters.networks. Fields, aggregations and operators per source come from reports.catalog: call it first. preset = one of: conv.volume, conv.byChannel, conv.byAssignee, conv.byStatus, conv.frt.median, conv.resolution.avg, msgs.volume, deals.wonValue, deals.winRate, deals.funnel, deals.byOwner, contacts.new, contacts.byTag, ads.spend, ads.spendByDay, ads.funnelByNetwork, ads.roasByNetwork, ads.topAds, ads.conversations.reports_widgets_add— Add a widget to a dashboard the current user owns. Give title, viz, query and optional options; the id is generated. Without layout the widget goes next to the last row when it fits in the 12 columns, else below the existing ones at x 0 (size w 6 h 4, or w 3 h 2 for kpi). Returns {widgetId, dashboard}. A query = {source: conversations|messages|deals|contacts|ads, measures: [{agg: count|sum|avg|median|min|max|distinct, field?}] (1-6; field required except for count), groupBy?: [{field, bucket?: day|week|month|quarter|year}] (max 2, bucket only on date fields), filters?: [{field, op, value?}], period: {field?, range}, sort?: {by: m0..m5|g0|g1, dir}, limit?: 1-500, includeTest?: boolean}. range = today|yesterday|last7|last30|last90|thisWeek|thisMonth|thisQuarter|thisYear|lastMonth or {from: YYYY-MM-DD, to: YYYY-MM-DD}; period.field defaults to the source's creation date (use closedAt for deals closed in the period, resolvedAt for resolved conversations). ads = ad facts (metrics per ad per day, attributed conversations and deals, platform leads): group by network, account, campaign, adSet, ad, currency, date; sum spend/impressions/reach/clicks/conversions/conversionValue/platformLeads/messagingStarted/conversations/leads/deals/won/revenue; avg ctr/cpc/cpm/cpaReal/roasReal/roasPlatform (ratio of sums); count needs a field. Money measures are split by currency (a currency group is added); revenue is BRL; roasReal uses BRL accounts only; roasReal and cpaReal count only won deals whose first touch has a known ad campaign, so they can be lower than the won/revenue totals. reach is a sum of daily reach, not unique people. Charts of ads money support one measure (use a table for several); conversations/leads/deals/won cannot be filtered. Missing platform metrics are null, not 0. Filter an ads report by network with filters.networks. Fields, aggregations and operators per source come from reports.catalog: call it first.reports_widgets_remove— Remove a widget from a dashboard the current user owns. Returns the dashboard.reports_widgets_update— Change a widget of a dashboard the current user owns. patch may hold title, viz, query, layout and options (each given key replaces the stored one). Returns the dashboard. A query = {source: conversations|messages|deals|contacts|ads, measures: [{agg: count|sum|avg|median|min|max|distinct, field?}] (1-6; field required except for count), groupBy?: [{field, bucket?: day|week|month|quarter|year}] (max 2, bucket only on date fields), filters?: [{field, op, value?}], period: {field?, range}, sort?: {by: m0..m5|g0|g1, dir}, limit?: 1-500, includeTest?: boolean}. range = today|yesterday|last7|last30|last90|thisWeek|thisMonth|thisQuarter|thisYear|lastMonth or {from: YYYY-MM-DD, to: YYYY-MM-DD}; period.field defaults to the source's creation date (use closedAt for deals closed in the period, resolvedAt for resolved conversations). ads = ad facts (metrics per ad per day, attributed conversations and deals, platform leads): group by network, account, campaign, adSet, ad, currency, date; sum spend/impressions/reach/clicks/conversions/conversionValue/platformLeads/messagingStarted/conversations/leads/deals/won/revenue; avg ctr/cpc/cpm/cpaReal/roasReal/roasPlatform (ratio of sums); count needs a field. Money measures are split by currency (a currency group is added); revenue is BRL; roasReal uses BRL accounts only; roasReal and cpaReal count only won deals whose first touch has a known ad campaign, so they can be lower than the won/revenue totals. reach is a sum of daily reach, not unique people. Charts of ads money support one measure (use a table for several); conversations/leads/deals/won cannot be filtered. Missing platform metrics are null, not 0. Filter an ads report by network with filters.networks. Fields, aggregations and operators per source come from reports.catalog: call it first.
Campaigns · 4 read · 7 write
campaigns_audiencePreview— Preview who a campaign audience reaches on a channel: total, eligible, skipped by reason (no_phone, opted_out, duplicate) and a sample of 20 eligible contacts. QR needs a channel identity or a 10+ digit phone; official WhatsApp needs a known WhatsApp number or a phone with a leading +. Groups are never recipients.campaigns_cancel— Cancel a campaign for good: recipients not sent yet are skipped (reason cancelled); messages already queued still go.campaigns_create— Create a draft campaign; campaigns.launch starts it. The channel must be connected: WhatsApp QR sends message {kind:'text', text (supports {{nome}}, {{primeiro_nome}}, {{telefone}}, {{email}}, {{campo.<key>}} and spintax {Oi|Olá}), media?: {key, type, name?} from the media upload}; official WhatsApp (the Meta API) sends {kind:'template', name, language, bodyParams?: {<variable>: {source:'field', field} | {source:'fixed', value}}, headerMedia?}. audience: {tags?, query?, platform?} (as contacts.overview filters) or an explicit {contactIds}, with excludeIds; check it with campaigns.audiencePreview. cadence defaults to the careful preset (on for QR, off for official). replyTo (a member, an agent, or a published flow that replies enter at its start) gets the conversations the campaign opens; default is you.campaigns_delete— Delete a campaign and its recipient list (sent messages stay in their conversations). A running campaign must be paused or cancelled first.campaigns_get— Get a campaign: message, audience, cadence, replyTo, schedule, status with wait/pause reason, channel, cumulative recipient counts and progress {total, done}.campaigns_launch— Start a draft campaign: freezes the audience now (eligible contacts in name order, at most 5000; the rest listed as skipped with a reason) and sends now, or at scheduledAt when it is in the future. Fails with no eligible recipients.campaigns_list— List this organization's campaigns (bulk WhatsApp sends), newest first, with channel, status, wait/pause reason and recipient counts. Counts are cumulative for the funnel: sent includes delivered, delivered includes read, read includes replied; pending, queued, failed and skipped are exclusive.campaigns_pause— Pause a running or scheduled campaign; campaigns.resume continues where it stopped.campaigns_recipients— Page a campaign's recipients in send order with contact, shown status (pending, queued, sent, delivered, read, replied, failed, skipped), skip reason, error code, rendered text, conversation and the first reply. The status filter is cumulative like the counts (sent also returns delivered, read and replied).campaigns_resume— Resume a paused campaign (manually or automatically paused) from the next pending recipient, sending now; one paused before its schedule goes back to scheduled.campaigns_update— Update a draft or scheduled campaign (name, channelId, message, audience, cadence, replyTo, scheduledAt). A scheduled campaign refreezes its recipients when the audience or channel changes.
Ads · 25 read · 24 write
ads_accounts_list— List the ad accounts of the connected ad networks: network, name, currency, timezone, whether it is usable (and why not), whether it is selected for sync, sync state and last sync time. Only selected ad accounts are synced.ads_accounts_select— Choose which ad accounts of a connection Cordex syncs: accountIds is the complete selected set (ids from ads.accounts.list); the others are deselected and stop syncing. On networks where the provider scopes accounts by API (Meta, Google and others), de-selecting an account also deletes the provider's synced history (about 90 days) for it, so confirm with the user first. Unusable accounts cannot be selected.ads_accounts_sync— Ask Cordex to refresh the campaigns, ads and metrics of the selected ad accounts (all of them, or only accountIds from ads.accounts.list). The refresh runs in the background within about a minute; it does not wait for it. Respects each network's rate limits.ads_audiences_create— Create an audience on one ad account. kind customer_list turns CRM contacts (source {kind:'crm', tags, query, platform}) into a list: only contacts that have not opted out and have an email (or phone where the network matches on it) are sent, uploaded in the background (ads_audiences_get shows size and sync state; size appears hours later). kind lookalike (source {kind:'lookalike', seedAudienceId, country, ratio or size}) builds on another audience of the same account; website (pixelId, retentionDays, urlContains) and engagement (source, sourceIds, event, retentionDays) audiences need the pixel or ids from ads.identities.list. ads.networks.describe lists which kinds each network supports and their rules. syncMode daily keeps a customer list topped up with new contacts. Not safe to repeat: if the answer is lost the audience may exist anyway, so check ads.audiences.list before creating it again.ads_audiences_delete— Permanently delete an audience at the ad network and in Cordex. Ads that target it lose it, and editable ad drafts have it removed. Refused while a lookalike audience built from it exists, while it is being rebuilt, for audiences created in the ad network's own manager, and on networks that cannot delete that type.ads_audiences_estimate— Estimate, before creating a customer list from CRM contacts, how many people each ad account could receive: eligible = contacts matching the source that have not opted out; usable = distinct emails (and phones where the network matches on phone, like Meta) the upload would send. warnings: belowMinimum (the network needs at least `minimum` matched people to serve ads, e.g. Google 5000, Meta and X 100), replaceUpload (LinkedIn replaces the whole list on every sync), overMax (more than the network keeps: the upload is rejected, so reduce the source below `maximum`), noUsable, notSupported (with reason). Read-only; numbers are counts of contacts, not of people the network will match.ads_audiences_get— Get one saved audience with its size, match rate, sync state and what depends on it: seedOf (lookalike audiences built from it), drafts (editable ad drafts that target it) and adsUsing (synced ad sets that mention it, null when it has no network id yet). Size and status are re-read from the ad network when older than 15 minutes.ads_audiences_list— List saved audiences (customer lists built from CRM contacts, lookalike, website-visitor and engagement audiences, plus those created in the ad network's own manager) with their size, match rate and sync state. size and matchRate are null until the ad network reports them (can take hours). `networks` says, for each connected ad network, which audience types it supports and why not when it does not. Reads the ad network's list at most every 10 minutes; pass refresh true to force it.ads_audiences_rebuild— Recreate a customer list from the current CRM contacts so contacts that opted out or were erased are really removed, then delete the old list at the ad network. Confirm with the user first: ads that targeted the old list lose it (adsUsing is how many synced ad sets mention it). Runs in the background; ads_audiences_get shows the progress. On networks where every sync already replaces the whole list this just queues a sync (mode replace).ads_audiences_sync— Upload the CRM contacts that matches a customer list's source and are not in it yet, in the background (contacts that opted out or have no usable email are skipped). Only grows the list: contacts removed or opted out since stay at the ad network until ads.audiences.rebuild.ads_audiences_update— Rename an audience (only on ad networks that allow renaming; see actions.rename in ads.audiences.get) or change a customer list's syncMode (manual or daily). Audiences created in the ad network's own manager are read-only.ads_campaigns_list— List ad campaigns across the connected ad networks as a tree: campaign, then ad set (group), then ad. Only selected ad accounts of connected networks are included. Each node has its status badge, whether its own on/off switch is on, budget and its level, objective, performance metrics over the date range (spend, impressions, clicks, ctr, cpc, cpm, results, leads, messagingStarted), CRM columns (conversations, leads, deals, won, revenue, roas) and per-action capabilities (pause, resume, budget, rename, duplicate, delete: enabled or the reason it is not). Money is in each ad account's own currency and is never summed across currencies: totals are one row per currency. A metric the network does not report is null, not 0. CRM columns come from Cordex attribution (last paid ad click within 30 days) and are all null when no sale or conversation has been attributed to an ad yet; roas is revenue divided by spend only for BRL campaigns (null with roasNote 'currency' otherwise). Default range: last 30 days; archived/deleted campaigns are hidden unless status is 'archived' or 'all'.ads_connections_disconnect— Disconnect an ad network connection. Its ad accounts are deselected (sync stops) but campaigns, ads and metrics already synced are kept.ads_connections_list— List the ad network connections of this organization: one entry per network (Meta, Google, TikTok, LinkedIn, Pinterest, X, Reddit, OpenAI) with the live connection (status connecting, connected, needs_reconnect or error, display name, sync state, counts of ad accounts and selected ad accounts) or null when that network is not connected.ads_conversion_destinations_list— List where conversions can be sent: for each connected ad account, the pixels, conversion actions, rules or event sets it can receive (destinations, null when the ad network cannot receive conversions, with capi saying why), plus the connected WhatsApp numbers and whether they already have a conversions dataset, and the networks that cannot receive conversions at all. A failure reading one account is reported in that account's error and does not hide the others. Use the destination ids with ads.conversion_rules.create.ads_conversion_events_list— The conversion send log, newest first: for each event the rule, trigger, status (pending, sent, failed with the ad network's reason and failures, skipped with why: no ad click found, other network, outside the window, opted out, missing identifiers...), value, the deal and contact involved and the network's trace id for support. Never includes the contact's email or phone. Page with nextCursor.ads_conversion_rules_create— Create conversion rules that report real CRM results to ad networks. One trigger (deal_won, deal_stage with a stageId, tag_added with a tag, conversation_started) and 1 to 8 destinations (pipe capi: an ad account plus a destinationId from ads.conversion_destinations.list; pipe whatsapp: a connected WhatsApp number, Meta Click-to-WhatsApp ads only, which may set up its conversions dataset at the network). One rule is created per destination, together or not at all. eventName defaults per trigger and network; windowDays defaults to 30 (7 for WhatsApp and Reddit, at most 90); value comes from the deal unless valueSource is fixed or none. testCode sends every event to the network's test view. Rules start enabled and send real conversions: confirm with the user first. Networks without conversions support (X) are refused. Deal values are in BRL, so a deal-valued rule reports BRL (use valueSource fixed for another currency). Google conversions carry no consent signal, which is only required for audiences in the EEA/UK.ads_conversion_rules_delete— Delete one conversion rule and, with it, its send log. Events already sent to the ad network stay there. Pause the rule (enabled false) instead to keep the log.ads_conversion_rules_get— Get one conversion rule with its test code (if any) and its 20 most recent events from the send log.ads_conversion_rules_list— List conversion rules: each one sends a CRM event (deal won, deal reaching a stage, a tag added, a conversation started) to one ad network destination, only for contacts whose ad click came from that network within the rule's window. Each row has its destination, event, the identifiers it sends, window, value setting, whether it is in test mode (the test code itself is never listed) and the sent/failed/skipped counts of the last 30 days. `networks` says which ad networks can receive conversions and why not when one cannot.ads_conversion_rules_update— Change one conversion rule: name, enabled, eventName, windowDays, value settings, the trigger, or testCode (null leaves test mode). The destination cannot be changed: create a new rule instead. Same limits as ads.conversion_rules.create.ads_conversions_dispatch— Send again conversion events that failed or are still pending (1 to 50 ids from ads.conversion_events.list). The same event id is reused, so the ad network never counts one twice. Events already sent or skipped cannot be re-sent. Returns each event's new status and reason.ads_conversions_test— Send one test conversion for a rule so the user can see it in the ad network's test view. Only where the network has a test mode (Meta pixel and WhatsApp, Pinterest, Reddit); elsewhere it is refused, because a test there would be a real conversion. Needs a test code (from the network's test events screen), given here or saved on the rule. Without contactId a synthetic visitor with a made-up address (no real person's data) is used (not for WhatsApp, which needs a contact that came from a Click-to-WhatsApp ad). The test is logged as a test event.ads_create— Create an ad on its network from a draft saved with ads.drafts.save (validate it first with ads.validate). It is always created paused, with the draft's countries, and only once per draft even if called again. It runs in the background: the result says submitting, and the new campaign appears in ads.campaigns.list as pending review within about a minute; a failure is stored on the draft (ads.drafts.get). Activating it later with ads.objects.set_status starts spending: confirm with the user.ads_drafts_delete— Delete an ad draft. Only drafts that were not sent (status draft) or whose submission failed can be deleted; drafts being sent or already created cannot.ads_drafts_get— Get one ad draft: network, ad account, objective, name, the whole form, its cdxRef, status (draft, submitting, submitted or failed), the error of a failed attempt and the result of a submitted one.ads_drafts_list— List ad drafts, most recently edited first: id, network, ad account, objective, name, cdxRef, status (draft, submitting, submitted, failed), error and result. Filter by status.ads_drafts_save— Create or update an ad draft (pass id to update). `form` follows the fields of ads.networks.describe for that network and objective: budget amount is a whole number in the ad account currency; countries default to Brazil (OpenAI: United States); images and videos are public https URLs in creative.imageUrl / creative.videoUrl. The form is replaced as a whole on every save. Returns the draft id, its cdxRef and the issues still blocking ads.create, each tagged with the wizard step. Nothing is sent to the ad network.ads_forms_create— Create a native lead form on Meta or LinkedIn for lead-generation ads. Forms cannot be edited after creation (create a new one instead). LinkedIn cannot prefill profile fields, so ask for email and phone as questions. Use the returned id as leadGenFormId in ads.drafts.save. The form's network must match the account's network. Not safe to repeat: if the answer is lost the form may exist anyway, so check ads.forms.list before creating again.ads_forms_get— Get one lead form of an ad account with its questions (keys, labels, answer options) and how many leads and deals it produced in the last 30 days. Lead forms cannot be edited: to change one, create a new form from it.ads_forms_list— List the native lead forms of an ad account (Meta, LinkedIn) with their status, how many leads and deals each produced in the last 30 days and the campaign that used it. supported false means the account's ad network has no lead forms. delivery says whether leads arrive instantly (webhook) or are fetched periodically (poll). Use a form's id as leadGenFormId in ads.drafts.save.ads_identities_list— List the Facebook pages, pixels, lead forms, posts, boards, organizations or connected WhatsApp numbers (whatsapp, for click-to-WhatsApp ads) an ad can use on an ad account, so ids need not be typed by hand. supported false means this ad network cannot list that kind: ask the user for the id instead.ads_leads_get— Get one ad lead (id from ads.leads.list) with every answer the person gave in the form, the consents they accepted, and the contact, deal, ad and campaign it is linked to.ads_leads_list— List the leads received from ad lead forms with the Cordex contact and deal each one created. Filter by network, form, ad account, import status or date range (yyyy-mm-dd). Newest first.ads_leads_settings_get— Get what happens when an ad lead arrives: the pipeline stage where its deal is created (if any), the deal owner, and the WhatsApp template conversation started with the lead (if any).ads_leads_settings_update— Choose what happens when an ad lead arrives: create a deal in a pipeline stage, set its owner, and optionally start a WhatsApp conversation with an approved template. Replaces the whole setting; send deal null, ownerUserId null and whatsapp null to only create the contact.ads_networks_describe— Describe the ad networks Cordex manages (Meta, Google, TikTok, LinkedIn, Pinterest, X, Reddit, OpenAI): what each one can create, edit, pause, duplicate or delete per level, its objectives, budget rules and minimums, default countries, which metrics it reports (others are null) and how sales are attributed. Read it before acting on a network.ads_objects_delete— Delete an ad campaign, ad set or ad. Depending on the network this removes it for good or only archives it (the result says which: mode delete or archive); either way it stops delivering and reporting. Prefer pausing with ads.objects.set_status unless the user clearly wants it gone, and confirm first.ads_objects_duplicate— Duplicate an ad campaign, ad set or ad on its network. The copy is always created paused. Send the same idempotencyKey to retry safely without creating a second copy; leave it out for a new one (it is returned). Not available on every network: see ads.networks.describe.ads_objects_get— Get one ad object (campaign, ad set or ad) by its Cordex id: its fields, status badge, capabilities, its parents (campaign, ad set), its direct children with their metrics, and performance metrics over the date range plus a daily series. Money is in the ad account's currency; a metric the network does not report is null.ads_objects_set_status— Pause or activate an ad campaign, ad set or ad on its ad network. Activating starts spending the company's budget immediately: confirm with the user first. Each level has its own switch (pausing a campaign does not change its children). On X an ad's switch is its line item's, so the whole line item pauses or resumes. Disabled per network or state as ads.networks.describe and the capabilities of ads.objects.get say. The result says which level was switched.ads_objects_update_budget— Change the budget of an ad campaign, ad set or ad. amount is a whole number in the ad account's own currency (not cents) and type is daily or lifetime. This changes real spend: confirm the amount with the user first. Cordex applies it at the level where the network keeps the budget (for example the ad set on TikTok, LinkedIn and Pinterest); levels that cannot hold a budget are refused with the reason. Some networks have a minimum budget in USD.ads_reach_estimate— Estimate how many people an audience reaches. Pass draftId to use an ad draft's countries and targeting, or accountId with countries and targeting. Returns estimate null when the ad network gives no estimate; ready false means it is still being calculated, ask again in a few seconds.ads_targeting_search— Find targeting ids (locations, interests, languages, keywords) for an ad account, to use in an ad draft's targeting. dimension is one of location, age, gender, language, interest or keyword, limited to what the account's network can target (see ads.networks.describe). Keyword returns keyword ideas with their average monthly searches. countryCode (ISO 2 letters) narrows the search and defaults to the network's default country.ads_touches_list— List the ad clicks Cordex attributed to contacts (WhatsApp ads, lead forms, tracking links), newest first. With contactId, attributed marks the touch that counts for that contact: the last paid touch within 30 days.ads_tracking_links_create— Create a Cordex tracking link to use as an ad's destination on any network. Each click is recorded with the network's click id and UTM tags; links to WhatsApp carry a short code in the prefilled message so the conversation is attributed to the ad. The destination must be an https site or a WhatsApp number; it cannot be changed later. Optionally tie the link to an ad object (campaign, ad set or ad id from ads.campaigns.list) so clicks are attributed at that level.ads_tracking_links_delete— Delete a Cordex tracking link (id from ads.tracking_links.list). The link stops working (its URL answers 'not found'), but the clicks and contacts already attributed to it are kept.ads_tracking_links_list— List the Cordex tracking links of the organization with their URL, short code, destination, click count, how many contacts came through them and the time of the last click. Archived links are hidden unless includeArchived is true.ads_validate— Check an ad draft without creating anything: returns ok and the issues blocking ads.create (each with the form path, a code and the wizard step). withPlatform also asks the ad network to check the ad without creating it, only where the network supports that; it counts against the network rate limit, so use it once before ads.create.
Activity · 1 read · 0 write
activity_list— List this organization's activity log newest first: every data-changing operation and the message.received, conversation.created, contact.created and comment.received events, with the exact payload automations receive as trigger.*. Filter by event name; page with before (createdAt of the last item). Kept for 90 days.
Example requests
- Which WhatsApp conversations have gone unanswered for more than 2 hours?
- Create the contact Maria Souza, phone +55 11 99999-0000, tagged "hot lead".
- Move the Padaria Central deal to the Proposal sent stage.
- How many conversations did each agent handle last week?
- List the campaigns scheduled for this month with their number of recipients.
Security and privacy
The assistant acts as you, only in the company you picked and within the approved scopes. Cordex does not receive your chat history with the assistant. Changes are recorded in the company's activity log. To disconnect, revoke the app in Settings › API and MCP.
REST API
The same operations are available in the REST API v1, with OpenAPI documentation at https://app.cordex.ai/api/v1/docs.