Bring your own X developer app, paste its credentials into OpenCX, and answer direct messages and public mentions with AI.
OpenCX connects to X through your own X developer app. You create the app on X, paste four
credentials into OpenCX, and authorize each brand handle you want to support.
Because the app is yours, X bills you directly for API usage and the app’s rate limits are
yours alone. OpenCX never sits between you and X’s billing.
Sign in at console.x.com and complete the developer signup.
Create an app, giving it a name and a description of your support use case.
Open the app’s User authentication settings and set:
App type: Web App / Automated App (a confidential client)
App permissions: Read and write and Direct Messages
Callback URL: the value OpenCX shows you in the connection dialog
Website URL: your company site
Set App permissions before generating any credentials. X bakes permissions into tokens at the
moment they are issued, so credentials created before you enable Direct Messages will not be able
to read or send DMs — you would have to regenerate them.
X’s API is pay-per-use. In the console, add a payment method and buy credits, then set a
spending limit per billing cycle and, optionally, auto-recharge.
If your credits run out or your spending limit is reached, X stops accepting messages. OpenCX
surfaces this as a banner on the channel page and marks the affected replies as failed, but the
fix always happens in your X console.
In OpenCX go to Channels → X (Twitter) → Add app. All four values live on the app’s
Keys & Tokens tab on X, split across two blocks:
OpenCX field
Where to find it on X
API Key
OAuth 1.0 Keys → Consumer Key (reveal with the eye icon)
API Key Secret
Revealed together with the Consumer Key
OAuth 2.0 Client ID
OAuth 2.0 Keys → Client ID
OAuth 2.0 Client Secret
OAuth 2.0 Keys → Client Secret (reveal with the eye icon)
X’s naming is inconsistent: the credential we call API Key / API Key Secret appears in the
console as Consumer Key, filed under a heading that says OAuth 1.0 Keys. Use it anyway —
OpenCX authenticates accounts with OAuth 2.0, but X signs webhooks with the consumer pair, so both
blocks are needed.
You do not need the Bearer Token or either Access Token on that page. OpenCX derives its
own app-only bearer from the Consumer Key pair, and account tokens come from the OAuth redirect in
the next step.If a secret was never saved and the eye icon only reveals the key, press Regenerate on that
block — it shows both values once. Regenerating invalidates the previous pair, so do it before
connecting accounts, not after.OpenCX validates the credentials and registers a webhook on your app before saving. Two failures are
worth knowing about in advance:
“X rejected these API credentials” — the API Key or Secret is wrong, or was regenerated after
you copied it.
“Your X developer account already has a webhook registered” — X allows one webhook per
developer account on pay-per-use. Remove the existing one in the console, or use a separate
developer account for OpenCX. OpenCX will never delete a webhook it did not create.
With the app saved, choose Add account and authorize the brand handle on X. You can connect
several handles to one app.If the authorization comes back missing a permission, OpenCX refuses the connection and names the
missing scope — fix App permissions on X, regenerate, and try again.Direct messages start flowing immediately, and the AI answers according to your
autopilot settings for the X channel.
Replying publicly when someone mentions your handle is off by default. Turning it on opens a
checklist you must confirm, because X places these requirements on the account, not on OpenCX:
The handle has the Automated label enabled (X → Settings → Your account → Account information
→ Automation).
The account bio discloses automation, for example “AI support by @yourcompany”.
You have X’s prior approval to deploy AI-generated replies, requested through the
Policy Support form.
X’s developer guidelines state that deploying AI-generated replies without prior approval is a
violation even when the replies are helpful. Confirm the checklist before enabling mentions.
Once enabled, the AI replies only to posts that explicitly mention the receiving handle and honors
opt-out phrases such as “stop”.Each person mentioning your handle in a tweet thread gets a separate session. Further mentions
from that person in the same thread stay in their existing open session, so agents can reply to
and resolve each person’s request independently. Existing session history is not split or moved.
To use a support handle for public replies to another brand handle, open Channels → X with
permission to manage channel settings. On the receiving account’s card, enable public mentions,
then choose Reply to mentions as:
This account (default): reply from the handle that received the mention.
Another connected account: reply from that handle when the customer’s post also mentions it.
Only accounts connected to the same app are available.
Confirm the automation notice when choosing another handle, then click Save. The setting
applies to both AI and agent replies, including existing sessions. Each account’s choice is
independent: replies use the chosen handle directly, even if that handle has its own different
reply setting.X only accepts a reply from an account the post mentions. When a post mentions the receiving
handle but not the chosen handle, the reply comes from the receiving handle instead. For example, if
your brand account replies as your support handle, a post mentioning both handles gets a reply from
the support handle, and a post mentioning only the brand handle gets a reply from the brand handle.Direct messages always use the account that received them. The AI replies to DMs switch is
independent of the public reply identity. In a public mention session, the inbox shows
Replying as @handle above the composer for the session’s latest customer post.
X’s automation rules require the author to have summoned the automated account. Acknowledging the
notice does not grant permission from X. Confirm that your intended use is permitted before
enabling it.
If the selected reply account disconnects or moves to another app, affected public replies pause.
The account card shows Public replies are paused. Reconnect the same handle to the same app,
or select another reply account and save. While replies are paused, OpenCX doesn’t fall back to the
receiving brand account, even for posts that don’t mention the selected account. Changing the selection to This account explicitly restores that behavior.
X moved direct messages to XChat, which is end-to-end encrypted. Encrypted chat in OpenCX is
opt-in and always starts from your side:
The account holder sets up Chat in the X app on the handle first, choosing a 4-digit PIN.
In OpenCX, on the channel page, enter that PIN for the handle and confirm.
Entering the PIN joins OpenCX to the handle’s existing encrypted-chat identity as an additional
device — X allows any number of devices, so Chat in the X app keeps working exactly as before.
OpenCX never creates, replaces, or resets encryption keys, and it never touches the handle’s
key backup. There is nothing to set up on our side and nothing we do behind your back.You can enable encrypted chat at connect time or at any later point — the PIN entry stays
available on the channel page for every handle that has not enabled it yet.A handle without XChat keeps working on unencrypted direct messages. One caveat: it may not
receive DMs from users who have migrated to XChat — if that starts happening, OpenCX shows a
banner on the channel page (“encrypted messages are arriving that OpenCX can’t read”), and
entering the PIN is the fix.
Each PIN entry is checked once against X’s key backup, and repeated wrong PIN entries can
permanently destroy that backup for the account. Verify the PIN in the X app before entering
it — OpenCX never retries a PIN on its own and blocks further attempts for an hour after three
failures.
Agent and AI replies show a delivery state in the inbox, the same as WhatsApp: a single check when
sent, blue checks when the customer has read it, and a red icon when X rejected the message — hover
it for X’s reason, such as a message flagged as spam or a recipient whose encryption keys changed.
Was this page helpful?
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Open.cx Docs","description":"Documentation for OpenCX, an AI-powered omnichannel customer support platform. Build AI agents for chat, phone, email, WhatsApp, and SMS with knowledge bases, actions, and human handoff.","colors":{"primary":"#0A0A0A","light":"#FAFAFA","dark":"#0A0A0A"},"logo":{"light":"https://mintcdn.com/openchat/ivWwffb57vEmukK4/logo-light.svg?fit=max\u0026auto=format\u0026n=ivWwffb57vEmukK4\u0026q=85\u0026s=f6a5e94f4909a4d8df45757989c11afe","dark":"https://mintcdn.com/openchat/ivWwffb57vEmukK4/logo.svg?fit=max\u0026auto=format\u0026n=ivWwffb57vEmukK4\u0026q=85\u0026s=84cc8ee0de542d166e76b53651f4f4e8"},"favicon":"https://mintcdn.com/openchat/ivWwffb57vEmukK4/favicon.png?fit=max\u0026auto=format\u0026n=ivWwffb57vEmukK4\u0026q=85\u0026s=68fa269328f9c95d4404b9073ac8aa37","api":{"openapi":"https://api.open.cx/api-json","playground":{"display":"interactive"},"mdx":{"server":"https://api.open.cx"}},"appearance":{"default":"dark","strict":false},"background":{"decoration":"gradient","color":{"light":"#FFFFFF","dark":"#0A0A0A"}},"navbar":{"links":[{"href":"https://platform.open.cx","label":"Dashboard"}],"primary":{"type":"button","label":"Get Started","href":"https://open.cx"}},"seo":{"metatags":{"og:type":"website","og:site_name":"OpenCX Docs"},"indexing":"all"},"fonts":{"heading":{"family":"Inter Tight"},"body":{"family":"Inter"}},"styling":{"eyebrows":"section","codeblocks":"dark","latex":true},"contextual":{"options":["copy","view","claude","chatgpt"],"display":"header"},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"openchat","hasAudioNarration":false,"actualSubdomain":"openchat","customDomains":["docs.open.cx"],"gitSource":{"type":"github","owner":"opencx-labs","repo":"opencx","deployBranch":"main","contentDirectory":"docs","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6ae61e2f3aae848cfc970129","collectionId":"4ec92bce-bd67-4ee4-a98c-cb1f1c6813a6","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ae61e2f3aae848cfc970129"},"feedback":{"thumbs":true,"edits":true,"issues":true},"entitlements":{},"buildId":"6ae61e2f3aae848cfc970129","clientVersion":"0.0.4044","searchFilterCounts":[{"language":"default","tag":"API Reference","count":339},{"language":"default","tag":"Integrations","count":113},{"language":"default","tag":"Ticketing Systems","count":100},{"language":"default","tag":"Build Agents","count":65},{"language":"default","tag":"Agent Training","count":53},{"language":"default","tag":"Help Center","count":45},{"language":"default","tag":"Sequences","count":42},{"language":"default","tag":"Channels","count":37},{"language":"default","tag":"Setup Integration","count":32},{"language":"default","tag":"Main Knowledge Sources","count":30}]},"assistantConfig":{},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":true},"customCss":[{"filePath":"style.css","content":"@keyframes orbit{0%{transform:rotate(calc(var(--angle)*1deg)) translateY(calc(var(--orbit-radius)*-1px)) rotate(calc(var(--angle)*-1deg))}to{transform:rotate(calc(var(--angle)*1deg + 360deg)) translateY(calc(var(--orbit-radius)*-1px)) rotate(calc(var(--angle)*-1deg - 360deg))}}@keyframes docs-footer-status-pulse{0%,to{box-shadow:0 0 0 0 rgba(16,185,129,.55)}50%{box-shadow:0 0 0 5px transparent}}:root{--radius:0.375rem;--radius-sm:0.125rem;--radius-md:0.25rem;--radius-lg:0.375rem;--radius-xl:0.75rem;--radius-2xl:1.125rem;--radius-3xl:1.5rem;--radius-full:9999px}.card,.card-group .card,.card-group card,card,card-group card{border-radius:var(--radius-3xl)}#search-bar-entry,#topbar-cta-button>a,#topbar-cta-button>a>span.absolute,.accordion,.accordion-group .accordion,.callout,.zendesk-flow .zendesk-flow-frame,[data-accordion-item],[data-accordion],accordion,accordion-group accordion,callout,div[class*=language-],div[class*=language-] pre,figure.shiki,pre,pre.shiki,pre>code{border-radius:var(--radius-xl)}.integration-orbit a[href]{touch-action:manipulation}.integration-orbit a[href] img{pointer-events:none}:root{--docs-context-bg:#ffffff;--docs-context-bg-hover:#f5f5f5;--docs-context-border:rgba(10, 10, 10, 0.16);--docs-context-border-strong:rgba(10, 10, 10, 0.32);--docs-context-text:#0a0a0a;--docs-context-muted:rgba(10, 10, 10, 0.6);--docs-context-accent:#0a0a0a;--docs-context-trigger-bg:linear-gradient(180deg, rgba(10, 10, 10, 0.04), transparent 48%),\n var(--docs-context-bg);--docs-context-trigger-bg-hover:linear-gradient(180deg, rgba(10, 10, 10, 0.07), transparent 52%),\n var(--docs-context-bg-hover);--docs-context-trigger-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.9),\n 0 1px 2px rgba(15, 23, 42, 0.04);--docs-context-menu-bg:radial-gradient(circle at top right, rgba(10, 10, 10, 0.05), transparent 38%),\n linear-gradient(180deg, #ffffff, #fafafa);--docs-context-menu-border:rgba(10, 10, 10, 0.14);--docs-context-menu-shadow:0 24px 60px rgba(15, 23, 42, 0.16),\n 0 0 0 1px rgba(10, 10, 10, 0.06);--docs-context-hover-text:#0a0a0a;--docs-context-item-hover:rgba(10, 10, 10, 0.06);--docs-context-divider:rgba(10, 10, 10, 0.1)}html.dark{--docs-context-bg:#0a0a0a;--docs-context-bg-hover:#161616;--docs-context-border:rgba(255, 255, 255, 0.2);--docs-context-border-strong:rgba(255, 255, 255, 0.36);--docs-context-text:#fafafa;--docs-context-muted:rgba(250, 250, 250, 0.72);--docs-context-accent:#fafafa;--docs-context-trigger-bg:linear-gradient(180deg, rgba(255, 255, 255, 0.06), transparent 42%),\n var(--docs-context-bg);--docs-context-trigger-bg-hover:linear-gradient(180deg, rgba(255, 255, 255, 0.1), transparent 48%),\n var(--docs-context-bg-hover);--docs-context-trigger-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.05),\n 0 0 0 1px rgba(255, 255, 255, 0.08);--docs-context-menu-bg:radial-gradient(circle at top right, rgba(255, 255, 255, 0.08), transparent 34%),\n linear-gradient(180deg, #121212, #050505);--docs-context-menu-border:rgba(255, 255, 255, 0.14);--docs-context-menu-shadow:0 24px 60px rgba(0, 0, 0, 0.42),\n 0 0 0 1px rgba(255, 255, 255, 0.08);--docs-context-hover-text:#ffffff;--docs-context-item-hover:rgba(255, 255, 255, 0.1);--docs-context-divider:rgba(255, 255, 255, 0.12);--primary:250 250 250;--primary-light:245 245 245;--primary-dark:10 10 10}#page-context-menu button[aria-label='More actions'],#page-context-menu-button{color:var(--docs-context-text)!important;background:var(--docs-context-trigger-bg)!important;border-color:var(--docs-context-border)!important;box-shadow:var(--docs-context-trigger-shadow)}#page-context-menu-button{border-right-color:var(--docs-context-divider)!important}#page-context-menu button[aria-label='More actions'] svg,#page-context-menu-button svg,body [data-radix-popper-content-wrapper] [role=menuitem] svg{color:var(--docs-context-accent)!important}#page-context-menu button[aria-label='More actions']:hover,#page-context-menu button[aria-label='More actions'][data-state=open],#page-context-menu-button:hover{color:var(--docs-context-hover-text)!important;background:var(--docs-context-trigger-bg-hover)!important;border-color:var(--docs-context-border-strong)!important}body [data-radix-popper-content-wrapper] [role=menu]{color:var(--docs-context-text)!important;background:var(--docs-context-menu-bg)!important;border:1px solid var(--docs-context-menu-border)!important;border-radius:var(--radius-xl)!important;box-shadow:var(--docs-context-menu-shadow)!important}body [data-radix-popper-content-wrapper] [role=menuitem]{color:var(--docs-context-text)!important;border-radius:var(--radius-lg)!important}body [data-radix-popper-content-wrapper] [role=menuitem] *{color:var(--docs-context-text)!important}body [data-radix-popper-content-wrapper] [role=menuitem] [class*=text-gray],body [data-radix-popper-content-wrapper] [role=menuitem] [class*=text-slate],body [data-radix-popper-content-wrapper] [role=menuitem] [class*=text-white],body [data-radix-popper-content-wrapper] [role=menuitem] [class*=text-zinc],body [data-radix-popper-content-wrapper] [role=menuitem] p{color:var(--docs-context-muted)!important}body [data-radix-popper-content-wrapper] [role=menuitem]:hover,body [data-radix-popper-content-wrapper] [role=menuitem][data-highlighted]{color:var(--docs-context-hover-text)!important;background:var(--docs-context-item-hover)!important}html:not(.dark) #sidebar{border-right:1px solid #e5e5e5!important}html.dark #sidebar{border-right:1px solid #262626!important}#sidebar,#sidebar *,#sidebar-content,#sidebar-content *{scrollbar-color:rgba(113,113,122,.4) transparent}#sidebar ::-webkit-scrollbar,#sidebar-content ::-webkit-scrollbar{width:8px;background:0 0}#sidebar ::-webkit-scrollbar-corner,#sidebar ::-webkit-scrollbar-track,#sidebar-content ::-webkit-scrollbar-corner,#sidebar-content ::-webkit-scrollbar-track{background:0 0}#sidebar ::-webkit-scrollbar-thumb,#sidebar-content ::-webkit-scrollbar-thumb{background-color:rgba(113,113,122,.4);border-radius:9999px!important;border:2px solid transparent;background-clip:content-box}#sidebar ::-webkit-scrollbar-thumb:hover,#sidebar-content ::-webkit-scrollbar-thumb:hover{background-color:rgba(113,113,122,.7)}html.dark #sidebar,html.dark #sidebar *,html.dark #sidebar-content,html.dark #sidebar-content *{scrollbar-color:rgba(161,161,170,.35) transparent}html.dark #sidebar ::-webkit-scrollbar-thumb,html.dark #sidebar-content ::-webkit-scrollbar-thumb{background-color:rgba(161,161,170,.35)}html.dark #sidebar ::-webkit-scrollbar-thumb:hover,html.dark #sidebar-content ::-webkit-scrollbar-thumb:hover{background-color:rgba(161,161,170,.6)}#sidebar-content>div>div.sticky.top-0.pointer-events-none.bg-gradient-to-b{background-image:none!important}html.dark #sidebar img[src*='/images/mcp/claude.svg'],html.dark #sidebar img[src*='/images/mcp/cursor.svg'],html.dark #sidebar img[src*='/images/mcp/windsurf.svg'],html.dark #sidebar img[src*='/images/mcp/zed.svg']{filter:invert(1) brightness(.92)}#navbar{box-shadow:none!important;row-gap:.25rem!important}html:not(.dark) #navbar{border-bottom:1px solid #e2e8f0!important}html.dark #navbar{border-bottom:1px solid #3f463f!important}#navbar #header,#navbar #navigation-items,#navbar navigation-items{border-bottom:none!important;box-shadow:none!important}#navbar .nav-tabs,#navbar nav-tabs{border-top:none!important;border-top-width:0!important;box-shadow:none!important}#navbar .h-16 .h-full.relative.flex-1.flex.items-center.gap-x-4.min-w-0{border-bottom:none!important;border-bottom-width:0!important;box-shadow:none!important}:not(pre)>code:is(.dark *){color:rgb(var(--primary-light))}:not(pre)>code{color:rgb(var(--primary))}html:not(.dark) #search-bar-entry{background-color:#fff!important;color:#404040}html:not(.dark) #navbar div.backdrop-blur{backdrop-filter:blur(14px) saturate(180%)!important;-webkit-backdrop-filter:blur(14px) saturate(180%)!important;background-color:rgba(255,255,255,.72)!important}html.dark #navbar div.backdrop-blur{backdrop-filter:blur(6px) saturate(125%)!important;-webkit-backdrop-filter:blur(6px) saturate(125%)!important;background-color:rgba(10,10,10,.6)!important}html:not(.dark) #topbar-cta-button>a>span.absolute{background-color:#0a0a0a!important}html:not(.dark) #topbar-cta-button>a .text-white{color:#fafafa!important}html.dark #topbar-cta-button>a>span.absolute{background-color:#fafafa!important}html.dark #topbar-cta-button>a .text-white,html.dark #topbar-cta-button>a svg{color:#0a0a0a!important}.nav-tabs-item>span>svg:first-child,.nav-tabs-item>svg{display:none!important}.toc-item{padding-left:12px!important;border-left:2px solid rgba(148,163,184,.22)!important;transition:border-color .18s ease,color .18s ease}html.dark .toc-item{border-left-color:rgba(148,163,184,.2)!important}.toc-item:hover{border-left-color:rgba(10,10,10,.45)!important}html.dark .toc-item:hover{border-left-color:rgba(250,250,250,.55)!important}.toc-item:has(>a[class*=text-primary]),.toc-item:has(>a[style*=color]){border-left-color:rgb(var(--primary))!important}html.dark .toc-item:has(>a[class*=text-primary]),html.dark .toc-item:has(>a[style*=color]){border-left-color:rgb(var(--primary-light))!important}button[data-state][aria-label],button[data-state][aria-label]>*,span.tooltip{cursor:help!important}#navbar .h-16 img[src*='logo.svg'],#navbar .h-16 img[src*=logo-light]{transform:scale(1.1);transform-origin:left center}#navbar .h-16>div>div:has(#search-bar-entry){justify-content:flex-end!important}#navbar .h-16>div>div.ml-auto.justify-end{flex:0 0 auto!important}.integration-orbit-grid-fade{background-image:linear-gradient(to right,rgb(0 0 0/.07) 1px,transparent 1px),linear-gradient(to bottom,rgb(0 0 0/.07) 1px,transparent 1px);background-size:16px 16px;background-position:center center;-webkit-mask-image:radial-gradient(72% 72% at 50% 50%,#000 0,#000 38%,transparent 82%);mask-image:radial-gradient(72% 72% at 50% 50%,#000 0,#000 38%,transparent 82%)}html.dark .integration-orbit-grid-fade{background-image:linear-gradient(to right,rgb(255 255 255/.08) 1px,transparent 1px),linear-gradient(to bottom,rgb(255 255 255/.08) 1px,transparent 1px)}.animate-orbit{animation:orbit var(--duration) linear infinite}.zendesk-flow-frame{background-image:radial-gradient(ellipse 80% 50% at 50% 50%,rgb(34 197 94/.04),transparent 70%)}html.dark .zendesk-flow-frame{background-image:radial-gradient(ellipse 80% 50% at 50% 50%,rgb(34 197 94/.06),transparent 70%)}.zendesk-flow-grid{background-image:linear-gradient(to right,rgb(0 0 0/.05) 1px,transparent 1px),linear-gradient(to bottom,rgb(0 0 0/.05) 1px,transparent 1px);background-size:24px 24px;background-position:center center;-webkit-mask-image:radial-gradient(80% 70% at 50% 50%,#000 0,#000 45%,transparent 90%);mask-image:radial-gradient(80% 70% at 50% 50%,#000 0,#000 45%,transparent 90%)}html.dark .zendesk-flow-grid{background-image:linear-gradient(to right,rgb(255 255 255/.05) 1px,transparent 1px),linear-gradient(to bottom,rgb(255 255 255/.05) 1px,transparent 1px)}#footer,.chat-assistant-floating-input,[class*=chat-assistant-floating]{display:none!important}.docs-footer{margin-top:5rem;padding-top:3rem;padding-bottom:1.5rem;border-top:1px solid rgba(228,228,231,.7);font-size:.875rem;color:rgb(82 82 91);line-height:1.5}html.dark .docs-footer{border-top-color:rgba(63,63,70,.35);color:rgb(161 161 170)}.docs-footer__top{display:flex;flex-direction:column;gap:2.5rem;padding-bottom:2.5rem;border-bottom:1px solid rgba(228,228,231,.55)}html.dark .docs-footer__top{border-bottom-color:rgba(63,63,70,.25)}@media (min-width:768px){.docs-footer__top{flex-direction:row;gap:3rem}}.docs-footer__brand{display:flex;flex-direction:column;gap:.75rem;max-width:16rem;flex-shrink:0}@media (min-width:768px){.docs-footer__brand{width:16rem}}.docs-footer__logo-link{display:inline-flex;width:fit-content}.docs-footer__logo{height:1.75rem;width:auto}.docs-footer__logo--dark,html.dark .docs-footer__logo--light{display:none}html.dark .docs-footer__logo--dark{display:inline-block}.docs-footer__desc{margin:.25rem 0 0;font-size:.8125rem;line-height:1.55;color:rgb(63 63 70)}html.dark .docs-footer__desc{color:rgb(212 212 216)}.docs-footer__label{margin:.75rem 0 .25rem;font-size:.6875rem;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:rgb(82 82 91)}html.dark .docs-footer__label{color:rgb(161 161 170)}.docs-footer__socials{display:inline-flex;gap:.875rem;align-items:center}.docs-footer__socials a{display:inline-flex;align-items:center;justify-content:center;color:rgb(24 24 27);transition:opacity .15s ease}.docs-footer__socials a:hover{opacity:.65}html.dark .docs-footer__col-header,html.dark .docs-footer__socials a{color:rgb(244 244 245)}html.dark .docs-footer__socials a:hover{opacity:.7}.docs-footer__columns{flex:1;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:2rem}@media (min-width:640px){.docs-footer__columns{grid-template-columns:repeat(3,minmax(0,1fr))}}.docs-footer__col{display:flex;flex-direction:column;gap:.5rem}.docs-footer__col-header{margin:0 0 .5rem;font-size:.8125rem;font-weight:700!important;color:rgb(24 24 27)}.docs-footer__col a{font-size:.8125rem;color:rgb(63 63 70);text-decoration:none;transition:color .15s ease}.docs-footer__col a:hover,.docs-footer__status:hover{color:rgb(24 24 27)}html.dark .docs-footer__col a{color:rgb(212 212 216)}html.dark .docs-footer__col a:hover,html.dark .docs-footer__status:hover{color:rgb(244 244 245)}.docs-footer__bottom{display:flex;flex-direction:column;align-items:flex-start;gap:.75rem;padding-top:1.25rem}@media (min-width:640px){.docs-footer__bottom{flex-direction:row;align-items:center;justify-content:space-between}}.docs-footer__copy{font-size:.75rem;color:rgb(82 82 91)}html.dark .docs-footer__copy,html.dark .docs-footer__status{color:rgb(161 161 170)}.docs-footer__status{display:inline-flex;align-items:center;gap:.5rem;font-size:.6875rem;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:rgb(82 82 91);text-decoration:none;transition:color .15s ease}.docs-footer__status-dot{display:inline-block;flex-shrink:0;width:.5rem;height:.5rem;background-color:#10b981;border-radius:var(--radius-full);box-shadow:0 0 0 0 rgba(16,185,129,.55);animation:docs-footer-status-pulse 2.4s ease-in-out infinite}@media (prefers-reduced-motion:reduce){.docs-footer__status-dot{animation:none;box-shadow:0 0 0 3px rgba(16,185,129,.25)}}#pagination{margin-top:3rem;padding-top:2rem;border-top:1px solid rgba(228,228,231,.8)}html.dark #pagination,html.dark #table-of-contents-layout .feedback-toolbar{border-top-color:rgba(63,63,70,.6)}#table-of-contents-layout{flex-direction:column}#table-of-contents-layout .feedback-toolbar{width:100%;margin-top:1.5rem;padding-top:1.5rem;padding-bottom:0;border-top:1px solid rgba(228,228,231,.8)}#table-of-contents-layout .feedback-toolbar>div{flex-direction:column;align-items:flex-start;gap:.75rem}#table-of-contents-layout .feedback-toolbar p{white-space:normal}"}],"page":{"pagePath":"twitter/connect-twitter","slug":"/twitter/connect-twitter","pageMetadata":{"title":"Connect X (Twitter)","description":"Bring your own X developer app, paste its credentials into OpenCX, and answer direct messages and public mentions with AI.","icon":"plug","keywords":["connect X","connect Twitter","X API credentials","X developer app","XChat","direct messages","mentions"],"href":"/twitter/connect-twitter"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Bring your own X developer app, paste its credentials into OpenCX, and answer direct messages and public mentions with AI.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,em:`em`,li:`li`,ol:`ol`,p:`p`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,..._provideComponents(),...props.components},{Heading,Note,Table,Warning}=_components;if(!Heading)_missingMdxReference(`Heading`,true);if(!Note)_missingMdxReference(`Note`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[`OpenCX connects to X through `,_jsx(_components.strong,{children:`your own X developer app`}),`. You create the app on X, paste four\ncredentials into OpenCX, and authorize each brand handle you want to support.`]}),`\n`,_jsx(Note,{children:_jsxs(_components.p,{children:[`Because the app is yours, `,_jsx(_components.strong,{children:`X bills you directly`}),` for API usage and the app’s rate limits are\nyours alone. OpenCX never sits between you and X’s billing.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`before-you-start`,children:`Before you start`}),`\n`,_jsx(_components.p,{children:`You need an X account with a verified email and phone number — that account will own the developer\napp permanently.`}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`Use a `,_jsx(_components.strong,{children:`company-owned X account`}),`, not a personal one. Apps cannot be transferred between accounts\nlater.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`1-create-the-app-on-x`,children:`1. Create the app on X`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Sign in at `,_jsx(_components.a,{href:`https://console.x.com`,children:`console.x.com`}),` and complete the developer signup.`]}),`\n`,_jsx(_components.li,{children:`Create an app, giving it a name and a description of your support use case.`}),`\n`,_jsxs(_components.li,{children:[`Open the app’s `,_jsx(_components.strong,{children:`User authentication settings`}),` and set:`,`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`App type:`}),` Web App / Automated App (a confidential client)`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`App permissions:`}),` Read and write `,_jsx(_components.strong,{children:`and`}),` Direct Messages`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Callback URL:`}),` the value OpenCX shows you in the connection dialog`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Website URL:`}),` your company site`]}),`\n`]}),`\n`]}),`\n`]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`Set `,_jsx(_components.strong,{children:`App permissions before generating any credentials`}),`. X bakes permissions into tokens at the\nmoment they are issued, so credentials created before you enable Direct Messages will not be able\nto read or send DMs — you would have to regenerate them.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`2-add-credit-and-a-spending-limit`,children:`2. Add credit and a spending limit`}),`\n`,_jsxs(_components.p,{children:[`X’s API is pay-per-use. In the console, add a payment method and buy credits, then set a\n`,_jsx(_components.strong,{children:`spending limit per billing cycle`}),` and, optionally, auto-recharge.`]}),`\n`,_jsx(Note,{children:_jsx(_components.p,{children:`If your credits run out or your spending limit is reached, X stops accepting messages. OpenCX\nsurfaces this as a banner on the channel page and marks the affected replies as failed, but the\nfix always happens in your X console.`})}),`\n`,_jsx(Heading,{level:`2`,id:`3-paste-the-credentials-into-opencx`,children:`3. Paste the credentials into OpenCX`}),`\n`,_jsxs(_components.p,{children:[`In OpenCX go to `,_jsx(_components.strong,{children:`Channels → X (Twitter) → Add app`}),`. All four values live on the app’s\n`,_jsx(_components.strong,{children:`Keys \u0026 Tokens`}),` tab on X, split across two blocks:`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`OpenCX field`}),_jsx(_components.th,{children:`Where to find it on X`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`API Key`}),_jsxs(_components.td,{children:[_jsx(_components.strong,{children:`OAuth 1.0 Keys → Consumer Key`}),` (reveal with the eye icon)`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`API Key Secret`}),_jsx(_components.td,{children:`Revealed together with the Consumer Key`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`OAuth 2.0 Client ID`}),_jsx(_components.td,{children:_jsx(_components.strong,{children:`OAuth 2.0 Keys → Client ID`})})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`OAuth 2.0 Client Secret`}),_jsxs(_components.td,{children:[_jsx(_components.strong,{children:`OAuth 2.0 Keys → Client Secret`}),` (reveal with the eye icon)`]})]})]})]}),`\n`,_jsx(Note,{children:_jsxs(_components.p,{children:[`X’s naming is inconsistent: the credential we call `,_jsx(_components.strong,{children:`API Key / API Key Secret`}),` appears in the\nconsole as `,_jsx(_components.strong,{children:`Consumer Key`}),`, filed under a heading that says `,_jsx(_components.strong,{children:`OAuth 1.0 Keys`}),`. Use it anyway —\nOpenCX authenticates accounts with OAuth 2.0, but X signs webhooks with the consumer pair, so both\nblocks are needed.`]})}),`\n`,_jsxs(_components.p,{children:[`You do `,_jsx(_components.strong,{children:`not`}),` need the `,_jsx(_components.strong,{children:`Bearer Token`}),` or either `,_jsx(_components.strong,{children:`Access Token`}),` on that page. OpenCX derives its\nown app-only bearer from the Consumer Key pair, and account tokens come from the OAuth redirect in\nthe next step.`]}),`\n`,_jsxs(_components.p,{children:[`If a secret was never saved and the eye icon only reveals the key, press `,_jsx(_components.strong,{children:`Regenerate`}),` on that\nblock — it shows both values once. Regenerating invalidates the previous pair, so do it before\nconnecting accounts, not after.`]}),`\n`,_jsx(_components.p,{children:`OpenCX validates the credentials and registers a webhook on your app before saving. Two failures are\nworth knowing about in advance:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`“X rejected these API credentials”`}),` — the API Key or Secret is wrong, or was regenerated after\nyou copied it.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`“Your X developer account already has a webhook registered”`}),` — X allows one webhook per\ndeveloper account on pay-per-use. Remove the existing one in the console, or use a separate\ndeveloper account for OpenCX. OpenCX will never delete a webhook it did not create.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`4-connect-your-handles`,children:`4. Connect your handles`}),`\n`,_jsxs(_components.p,{children:[`With the app saved, choose `,_jsx(_components.strong,{children:`Add account`}),` and authorize the brand handle on X. You can connect\nseveral handles to one app.`]}),`\n`,_jsxs(_components.p,{children:[`If the authorization comes back missing a permission, OpenCX refuses the connection and names the\nmissing scope — fix `,_jsx(_components.strong,{children:`App permissions`}),` on X, regenerate, and try again.`]}),`\n`,_jsxs(_components.p,{children:[`Direct messages start flowing immediately, and the AI answers according to your\n`,_jsx(_components.a,{href:`/dashboard/introduction`,children:`autopilot settings`}),` for the X channel.`]}),`\n`,_jsx(Heading,{level:`2`,id:`5-public-mentions-optional`,children:`5. Public mentions (optional)`}),`\n`,_jsxs(_components.p,{children:[`Replying publicly when someone mentions your handle is `,_jsx(_components.strong,{children:`off by default`}),`. Turning it on opens a\nchecklist you must confirm, because X places these requirements on the account, not on OpenCX:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`The handle has the `,_jsx(_components.strong,{children:`Automated`}),` label enabled (X → Settings → Your account → Account information\n→ Automation).`]}),`\n`,_jsxs(_components.li,{children:[`The account bio discloses automation, for example `,_jsx(_components.em,{children:`“AI support by @yourcompany”`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`You have `,_jsx(_components.strong,{children:`X’s prior approval to deploy AI-generated replies`}),`, requested through the\n`,_jsx(_components.a,{href:`https://help.x.com/forms/platform`,children:`Policy Support form`}),`.`]}),`\n`]}),`\n`,_jsx(Warning,{children:_jsx(_components.p,{children:`X’s developer guidelines state that deploying AI-generated replies without prior approval is a\nviolation even when the replies are helpful. Confirm the checklist before enabling mentions.`})}),`\n`,_jsx(_components.p,{children:`Once enabled, the AI replies only to posts that explicitly mention the receiving handle and honors\nopt-out phrases such as “stop”.`}),`\n`,_jsx(_components.p,{children:`Each person mentioning your handle in a tweet thread gets a separate session. Further mentions\nfrom that person in the same thread stay in their existing open session, so agents can reply to\nand resolve each person’s request independently. Existing session history is not split or moved.`}),`\n`,_jsx(Heading,{level:`3`,id:`reply-to-mentions-as`,children:`Reply to mentions as`}),`\n`,_jsxs(_components.p,{children:[`To use a support handle for public replies to another brand handle, open `,_jsx(_components.strong,{children:`Channels → X`}),` with\npermission to manage channel settings. On the receiving account’s card, enable public mentions,\nthen choose `,_jsx(_components.strong,{children:`Reply to mentions as`}),`:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`This account`}),` (default): reply from the handle that received the mention.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Another connected account`}),`: reply from that handle when the customer’s post also mentions it.\nOnly accounts connected to the same app are available.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Confirm the automation notice when choosing another handle, then click `,_jsx(_components.strong,{children:`Save`}),`. The setting\napplies to both AI and agent replies, including existing sessions. Each account’s choice is\nindependent: replies use the chosen handle directly, even if that handle has its own different\nreply setting.`]}),`\n`,_jsx(_components.p,{children:`X only accepts a reply from an account the post mentions. When a post mentions the receiving\nhandle but not the chosen handle, the reply comes from the receiving handle instead. For example, if\nyour brand account replies as your support handle, a post mentioning both handles gets a reply from\nthe support handle, and a post mentioning only the brand handle gets a reply from the brand handle.`}),`\n`,_jsxs(_components.p,{children:[`Direct messages always use the account that received them. The `,_jsx(_components.strong,{children:`AI replies to DMs`}),` switch is\nindependent of the public reply identity. In a public mention session, the inbox shows\n`,_jsx(_components.strong,{children:`Replying as @handle`}),` above the composer for the session’s latest customer post.`]}),`\n`,_jsx(Warning,{children:_jsx(_components.p,{children:`X’s automation rules require the author to have summoned the automated account. Acknowledging the\nnotice does not grant permission from X. Confirm that your intended use is permitted before\nenabling it.`})}),`\n`,_jsxs(_components.p,{children:[`If the selected reply account disconnects or moves to another app, affected public replies pause.\nThe account card shows `,_jsx(_components.strong,{children:`Public replies are paused`}),`. Reconnect the same handle to the same app,\nor select another reply account and save. While replies are paused, OpenCX doesn’t fall back to the\nreceiving brand account, even for posts that don’t mention the selected account. Changing the selection to `,_jsx(_components.strong,{children:`This account`}),` explicitly restores that behavior.`]}),`\n`,_jsx(Heading,{level:`2`,id:`encrypted-messages`,children:`Encrypted messages`}),`\n`,_jsxs(_components.p,{children:[`X moved direct messages to XChat, which is end-to-end encrypted. Encrypted chat in OpenCX is\n`,_jsx(_components.strong,{children:`opt-in and always starts from your side`}),`:`]}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`The account holder sets up `,_jsx(_components.strong,{children:`Chat in the X app`}),` on the handle first, choosing a 4-digit PIN.`]}),`\n`,_jsx(_components.li,{children:`In OpenCX, on the channel page, enter that PIN for the handle and confirm.`}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Entering the PIN joins OpenCX to the handle’s existing encrypted-chat identity `,_jsx(_components.strong,{children:`as an additional\ndevice`}),` — X allows any number of devices, so Chat in the X app keeps working exactly as before.\nOpenCX `,_jsx(_components.strong,{children:`never creates, replaces, or resets encryption keys`}),`, and it never touches the handle’s\nkey backup. There is nothing to set up on our side and nothing we do behind your back.`]}),`\n`,_jsx(_components.p,{children:`You can enable encrypted chat at connect time or at any later point — the PIN entry stays\navailable on the channel page for every handle that has not enabled it yet.`}),`\n`,_jsxs(_components.p,{children:[`A handle `,_jsx(_components.strong,{children:`without`}),` XChat keeps working on unencrypted direct messages. One caveat: it `,_jsx(_components.strong,{children:`may not\nreceive DMs from users who have migrated to XChat`}),` — if that starts happening, OpenCX shows a\nbanner on the channel page (“encrypted messages are arriving that OpenCX can’t read”), and\nentering the PIN is the fix.`]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`Each PIN entry is checked once against X’s key backup, and `,_jsx(_components.strong,{children:`repeated wrong PIN entries can\npermanently destroy that backup`}),` for the account. Verify the PIN in the X app before entering\nit — OpenCX never retries a PIN on its own and blocks further attempts for an hour after three\nfailures.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`delivery-status`,children:`Delivery status`}),`\n`,_jsx(_components.p,{children:`Agent and AI replies show a delivery state in the inbox, the same as WhatsApp: a single check when\nsent, blue checks when the customer has read it, and a red icon when X rejected the message — hover\nit for X’s reason, such as a message flagged as spam or a recipient whose encryption keys changed.`})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"codeStyling":"dark","config":{},"pageMetadata":{"title":"Connect X (Twitter)","description":"Bring your own X developer app, paste its credentials into OpenCX, and answer direct messages and public mentions with AI.","icon":"plug","keywords":["connect X","connect Twitter","X API credentials","X developer app","XChat","direct messages","mentions"],"href":"/twitter/connect-twitter"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Before you start","slug":"before-you-start","depth":2,"children":[]},{"title":"1. Create the app on X","slug":"1-create-the-app-on-x","depth":2,"children":[]},{"title":"2. Add credit and a spending limit","slug":"2-add-credit-and-a-spending-limit","depth":2,"children":[]},{"title":"3. Paste the credentials into OpenCX","slug":"3-paste-the-credentials-into-opencx","depth":2,"children":[]},{"title":"4. Connect your handles","slug":"4-connect-your-handles","depth":2,"children":[]},{"title":"5. Public mentions (optional)","slug":"5-public-mentions-optional","depth":2,"children":[{"title":"Reply to mentions as","slug":"reply-to-mentions-as","depth":3,"children":[]}]},{"title":"Encrypted messages","slug":"encrypted-messages","depth":2,"children":[]},{"title":"Delivery status","slug":"delivery-status","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":["/_mintlify/custom/openchat/671ce9e295bc0bed/docs-footer.js","/_mintlify/custom/openchat/5e08dc26b4af039b/opencx-widget.js","/_mintlify/custom/openchat/b138b1492ac22a58/docs-feedback.js"],"subdomain":"openchat","siteName":"Open.cx Docs","title":"Connect X (Twitter) - Open.cx Docs","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-28T00:30:34.955Z","originalFileLocation":"twitter/connect-twitter.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"dark\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Bring your own X developer app, paste its credentials into OpenCX, and answer direct messages and public mentions with AI.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Open.cx Docs\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/openchat/RMvbDkK3gsg3p3OQ/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/openchat/RMvbDkK3gsg3p3OQ/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/openchat/RMvbDkK3gsg3p3OQ/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/openchat/RMvbDkK3gsg3p3OQ/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/openchat/RMvbDkK3gsg3p3OQ/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/openchat/RMvbDkK3gsg3p3OQ/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/openchat/RMvbDkK3gsg3p3OQ/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/openchat/RMvbDkK3gsg3p3OQ/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/openchat/RMvbDkK3gsg3p3OQ/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Connect X (Twitter) - Open.cx Docs\">\u003cmeta data-mint-head property=\"og:description\" content=\"Bring your own X developer app, paste its credentials into OpenCX, and answer direct messages and public mentions with AI.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"OpenCX Docs\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.open.cx/twitter/connect-twitter\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://openchat.mintlify.app/_mintlify/api/og/v2?division=AI+X+%28Twitter%29+Support\u0026amp;title=Connect+X+%28Twitter%29\u0026amp;description=Bring+your+own+X+developer+app%2C+paste+its+credentials+into+OpenCX%2C+and+answer+direct+messages+and+public+mentions+with+AI.\u0026amp;theme=ce95aec8479b2437aa73f5f5\u0026amp;signature=f33b5a02a4f515353c1c59eca715d7eb0164081b5081c2674aa9430515089aec\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Connect X (Twitter) - Open.cx Docs\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Bring your own X developer app, paste its credentials into OpenCX, and answer direct messages and public mentions with AI.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://openchat.mintlify.app/_mintlify/api/og/v2?division=AI+X+%28Twitter%29+Support\u0026amp;title=Connect+X+%28Twitter%29\u0026amp;description=Bring+your+own+X+developer+app%2C+paste+its+credentials+into+OpenCX%2C+and+answer+direct+messages+and+public+mentions+with+AI.\u0026amp;theme=ce95aec8479b2437aa73f5f5\u0026amp;signature=f33b5a02a4f515353c1c59eca715d7eb0164081b5081c2674aa9430515089aec\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/openchat/RMvbDkK3gsg3p3OQ/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Open.cx Docs\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#0A0A0A\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.open.cx/twitter/connect-twitter\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/twitter/connect-twitter.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.open.cx/#organization\",\"name\":\"Open.cx Docs\",\"url\":\"https://docs.open.cx\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/openchat/ivWwffb57vEmukK4/logo-light.svg?fit=max\u0026auto=format\u0026n=ivWwffb57vEmukK4\u0026q=85\u0026s=f6a5e94f4909a4d8df45757989c11afe\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.open.cx#website\",\"name\":\"Open.cx Docs\",\"url\":\"https://docs.open.cx\",\"publisher\":{\"@id\":\"https://docs.open.cx/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.open.cx/twitter/connect-twitter#webpage\",\"url\":\"https://docs.open.cx/twitter/connect-twitter\",\"name\":\"Connect X (Twitter)\",\"description\":\"Bring your own X developer app, paste its credentials into OpenCX, and answer direct messages and public mentions with AI.\",\"dateModified\":\"2026-10-28T00:30:34.955Z\",\"isPartOf\":{\"@id\":\"https://docs.open.cx#website\"},\"breadcrumb\":{\"@id\":\"https://docs.open.cx/twitter/connect-twitter#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.open.cx/twitter/connect-twitter#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Open.cx Docs\",\"item\":\"https://docs.open.cx\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Connect X (Twitter)\",\"item\":\"https://docs.open.cx/twitter/connect-twitter\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.open.cx/twitter/connect-twitter#article\",\"headline\":\"Connect X (Twitter)\",\"name\":\"Connect X (Twitter)\",\"description\":\"Bring your own X developer app, paste its credentials into OpenCX, and answer direct messages and public mentions with AI.\",\"url\":\"https://docs.open.cx/twitter/connect-twitter\",\"mainEntityOfPage\":{\"@id\":\"https://docs.open.cx/twitter/connect-twitter#webpage\"},\"dateModified\":\"2026-10-28T00:30:34.955Z\",\"keywords\":\"connect X, connect Twitter, X API credentials, X developer app, XChat, direct messages, mentions\",\"publisher\":{\"@id\":\"https://docs.open.cx/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.open.cx#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Open.cx Docs\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Open.cx Docs","nav":{"global":null,"tabs":[{"tab":"Get Started","icon":"book-open","pages":[{"title":"Get Started","href":"/welcome"}]},{"tab":"Build Agents","icon":"robot","groups":[{"group":"Overview","pages":[{"title":"Build Agents get started","sidebarTitle":"Get Started","icon":"rocket","href":"/build-agents/get-started"}]},{"group":"AI Chat Widget","pages":[{"title":"Widget overview","sidebarTitle":"Overview","icon":"messages","href":"/widget/introduction"},{"title":"Playground","icon":"play","mode":"wide","href":"/widget/playground"},{"group":"Setup Channel","icon":"gear","pages":[{"title":"Install Widget","icon":"plug","href":"/widget/install-widget"},{"title":"Widget v5 Companion mode","sidebarTitle":"Companion mode","icon":"sparkles","href":"/widget/companion-mode"},{"title":"OpenCX widget AI coding skills","sidebarTitle":"AI coding skills","icon":"terminal","href":"/widget/agent-skills"},{"title":"Migrate the widget from v4 to v5","sidebarTitle":"Migrate to v5","icon":"arrow-up","href":"/widget/migrate-to-v5"},{"title":"Mobile Support","icon":"phone","href":"/widget/native-mobile"},{"title":"Widget configuration","sidebarTitle":"Configuration","icon":"gear","href":"/widget/configuration"},{"title":"Authentication","icon":"shield-check","href":"/widget/authentication"},{"title":"Widget connections and approvals","sidebarTitle":"Connections","icon":"plug","href":"/widget/connections"},{"title":"Widget sessions and unread replies","sidebarTitle":"Sessions","icon":"route","href":"/widget/conversation-sessions"},{"title":"Configuration reference","sidebarTitle":"Reference","icon":"code","href":"/widget/configuration-reference"}]},{"group":"Components","icon":"cubes","pages":[{"title":"Widget overview","sidebarTitle":"Overview","icon":"paintbrush","href":"/widget/custom-components"},{"title":"Widget React components and launcher","sidebarTitle":"React components","icon":"react","href":"/widget/custom-components-react"},{"title":"Headless widget setup and hooks","sidebarTitle":"Headless","icon":"code","href":"/widget/custom-components-headless"}]},{"title":"Widget troubleshooting","sidebarTitle":"Troubleshooting","description":"Fix common AI Chat Widget issues such as a missing embed, repeated identity prompts, missing history, and custom component failures.","icon":"wrench","href":"/widget/troubleshooting"}]},{"group":"AI X (Twitter) Support","pages":[{"title":"Connect X (Twitter)","icon":"plug","href":"/twitter/connect-twitter"}]},{"group":"AI App Review Support","pages":[{"title":"Connect App Store and Google Play reviews","sidebarTitle":"Connect app reviews","description":"Connect App Store and Google Play so every new app review opens a session your AI or team can answer. Use when setting up app review replies.","icon":"star","href":"/app-reviews/connect-app-reviews"}]},{"group":"AI WhatsApp Support","pages":[{"title":"Whatsapp overview","sidebarTitle":"Overview","icon":"comment-dots","href":"/whatsapp/introduction"},{"group":"Setup Channel","icon":"gear","pages":[{"title":"Create WhatsApp Agent","icon":"plug","href":"/whatsapp/connect-whatsapp"},{"title":"WhatsApp Flow","icon":"route","href":"/whatsapp/messaging-rules"},{"title":"Messaging Rules","icon":"scale-balanced","href":"/whatsapp/whatsapp-rules"}]},{"title":"Whatsapp troubleshooting","sidebarTitle":"Troubleshooting","icon":"wrench","href":"/whatsapp/troubleshooting"}]},{"group":"AI SMS Support","pages":[{"title":"Sms overview","sidebarTitle":"Overview","icon":"comment-sms","href":"/sms/introduction"},{"group":"Setup Channel","icon":"gear","pages":[{"title":"Connect SMS","icon":"plug","href":"/sms/connect-sms"},{"title":"SMS Flow","icon":"route","href":"/sms/message-routing"},{"title":"US Number Compliance","icon":"flag","href":"/sms/compliance"}]},{"title":"Sms troubleshooting","sidebarTitle":"Troubleshooting","icon":"wrench","href":"/sms/troubleshooting"}]},{"group":"Phone \u0026 Telephony","pages":[{"title":"Phone and telephony overview","sidebarTitle":"Overview","icon":"phone","href":"/phone/introduction"},{"group":"Setup","icon":"gear","pages":[{"title":"Phone numbers and routing","sidebarTitle":"Numbers and routing","icon":"phone","href":"/phone/numbers-and-routing"},{"title":"Create Phone Agent","icon":"plus","href":"/phone/create-agent"},{"title":"Agent Configuration","icon":"sliders","href":"/phone/agent-config"},{"title":"Classical IVR","href":"/phone/call-flows"},{"title":"SIP Integration","icon":"server","href":"/phone/sip-integration"}]},{"group":"Calling","icon":"phone","pages":[{"title":"Inbound Calls","icon":"phone-arrow-down-left","href":"/phone/inbound-calls"},{"title":"Call answering and ringing settings","sidebarTitle":"Call answering","icon":"phone-volume","href":"/phone/call-answering"},{"title":"Phone answer-time SLA","sidebarTitle":"Answer-time SLA","icon":"stopwatch","href":"/phone/answer-time-sla"},{"title":"Outbound Calls","icon":"phone-arrow-up-right","href":"/phone/outbound-calls"},{"title":"Human phone calling and transfers","sidebarTitle":"Human calling","icon":"phone","href":"/phone/human-calling"},{"title":"Live interpretation for team phone calls","sidebarTitle":"Live interpretation","icon":"language","href":"/phone/live-interpretation"},{"title":"Voice SDK integration","sidebarTitle":"App voice SDK","icon":"microphone","href":"/phone/voice-sdk"},{"title":"Phone Desk agent workspace","sidebarTitle":"Phone Desk","icon":"headset","href":"/phone/phone-desk"},{"title":"Phone recordings, transcripts, and summaries","sidebarTitle":"Recordings and transcripts","icon":"phone","href":"/phone/recordings-and-transcripts"}]},{"group":"Automation","icon":"bolt","pages":[{"title":"Phone call lifecycle and outcomes","sidebarTitle":"Call outcomes","icon":"phone","href":"/phone/call-outcomes"},{"title":"Phone follow-up workflows and callbacks","sidebarTitle":"Follow-up workflows","icon":"phone","href":"/phone/follow-up-workflows"}]},{"title":"Phone calling troubleshooting","sidebarTitle":"Troubleshooting","icon":"phone","href":"/phone/troubleshooting"}]},{"group":"AI Email Support","pages":[{"title":"Email overview","sidebarTitle":"Overview","icon":"envelope","href":"/email/introduction"},{"group":"Setup Channel","icon":"gear","pages":[{"title":"Sending Domains \u0026 DNS","icon":"globe","href":"/email/sending-domains"},{"title":"Sequence email sender settings","sidebarTitle":"Sequence senders","icon":"paper-plane","href":"/email/sequence-senders"},{"title":"Connect Email","icon":"paper-plane","href":"/email/forwarding"},{"title":"Email Flow","icon":"diagram-project","href":"/email/forwarding-rules"},{"title":"Reply Templates","icon":"signature","href":"/email/reply-templates"}]},{"title":"Email troubleshooting","sidebarTitle":"Troubleshooting","icon":"wrench","href":"/email/troubleshooting"}]},{"group":"AI Actions","pages":[{"title":"AI Actions","sidebarTitle":"Overview","icon":"bolt","href":"/actions/introduction"},{"title":"Build An Action","sidebarTitle":"Build an action","icon":"plug","href":"/actions/build-an-action"},{"title":"OpenAPI Import","sidebarTitle":"OpenAPI import","icon":"file-import","href":"/actions/openapi-import"},{"title":"MCP Servers","sidebarTitle":"MCP servers","icon":"plug-circle-bolt","href":"/actions/mcp-servers"},{"title":"Authentication","sidebarTitle":"Authentication","icon":"shield-halved","href":"/actions/authentication"},{"title":"Execution","sidebarTitle":"Execution","icon":"diagram-project","href":"/actions/execution"},{"title":"Actions troubleshooting","sidebarTitle":"Troubleshooting","icon":"wrench","href":"/actions/troubleshooting"}]},{"group":"Resources","pages":[{"title":"Manage Contacts","icon":"user","href":"/contacts/manage-contacts"},{"title":"Guaranteed Message Delivery","icon":"paper-plane","href":"/resources/guaranteed-delivery"},{"title":"Increase Automation","sidebarTitle":"Increase automation","icon":"chart-line","href":"/resources/increase-automation"},{"title":"Collect Customer Satisfaction","sidebarTitle":"CSAT","icon":"star","href":"/resources/csat"}]}]},{"tab":"Ticketing","icon":"ticket","pages":[{"title":"Ticketing","href":"/ticketing/structured-fields"}]},{"tab":"Connect","icon":"arrows-left-right","pages":[{"title":"Connect","href":"/connect/introduction"}]},{"tab":"Integrations","icon":"plug","pages":[{"title":"Integrations","href":"/dashboard/introduction"}]},{"tab":"MCP","icon":"network-wired","pages":[{"title":"MCP","href":"/mcp/introduction"}]},{"tab":"Agent Training","icon":"book","pages":[{"title":"Agent Training","href":"/knowledge/introduction"}]},{"tab":"AI Safety","icon":"shield","pages":[{"title":"AI Safety","href":"/safety/introduction"}]},{"tab":"API Reference","icon":"code","pages":[{"title":"API Reference","href":"/api-reference/authentication"}]},{"tab":"Partners","icon":"handshake","pages":[{"title":"Partners","href":"/partners/introduction"}]}]},"basePath":"","title":"Connect X (Twitter) - Open.cx Docs","buildId":"dpl_DeHjVRGfFnhYQwHnfC2pjeXXv8h9","deploymentId":"dpl_DeHjVRGfFnhYQwHnfC2pjeXXv8h9","dynamics":[],"chunks":[]}