Integrations and credentials
Connect third-party accounts, store encrypted credentials, and use OAuth from Settings.
Integrations are catalog entries per workspace. Most connections store a workspace-scoped credential (encrypted) and mark the integration connected. Secrets you type in Settings → Secrets are the same credential records.
Personal browser connections keep a separate browser profile for each account and website. Use Manage my browser connections to enter the site's login page, account page and identifying account text, then sign in and save. The Web browser blocks verify access, report connection status or read a page using that session. To let your agent browse, enable Allow my agent to read on your connection. For interactive browsing in Codex CLI or Claude Code, attach Playwright MCP · saved browser on the node and authorize its separate control grant. Existing MCP tools and skills remain attached. Shared workspace credentials do not grant access to someone else's browser. See workspace settings.
Settings surfaces
| Section | Path | Purpose |
|---|---|---|
| Integrations | /confluye/{slug}/settings/integrations | Search the catalog, start OAuth, paste a token, toggle connected |
| Secrets | /confluye/{slug}/settings/secrets | Search, create, update, and save workspace credentials |
The app uses tRPC settings.listIntegrations / updateIntegration and settings.listCredentials / createCredential (also session REST /api/integrations and /api/credentials).
Catalog and connection
GET /api/v1/integrations returns { integrations[] } for the API key's workspace: key, name, category, description, status (available or connected), optional credentialId / credentialName / credentialType, credentialConfigured, connectedCredentials[], timestamps.
PATCH with { key, connected } upserts the connection row. Unknown keys return 400 "Unknown integration.".
When connected is true and credentialValue is present, the server creates or updates a workspace credential (type derived from the integration) and returns { integration, credential } with maskedValue (never the plaintext). Multiple named credentials can exist for one key (for example two Gmail accounts).
Supported OAuth keys include github, google-workspace, google-drive, gmail, jira, microsoft-teams, and others in integrationOAuthProviders. Start returns { authorizationUrl, provider, credentialName, expiresAt } and sets an OAuth state cookie, or 200 with missingConnectorSetup / mode: "manual" when client env is incomplete. Callback writes the token into a credential and redirects to returnTo (default Settings → Integrations). returnTo must be a safe internal path.
Gmail and Trash
Gmail connections request gmail.modify, which supports reading, sending, organizing mail and moving it to Trash. The Google Workspace connection uses the same Gmail permission alongside its other service permissions.
Use Move message to Trash or Move thread to Trash in a Gmail block. The thread action moves all messages in that conversation. You can restore mail from Trash in Gmail while it remains there. These actions retain their confirmation requirement.
Existing saved workflows and imported n8n Gmail Delete actions now move mail to Trash too. Their operation IDs remain delete-message and delete-thread. Successful outputs include trashed: true; the older deleted: true field remains for compatibility and means the move succeeded.
Existing connections with full Gmail access remain usable. Requesting a smaller scope does not remove an earlier Google grant. To grant only the currently requested permissions, remove the app's existing access in your Google Account, then reconnect the affected services in Integrations. Removing a shared grant can disconnect other services that use it.
Using your own OAuth Client ID and Client Secret still requires Google consent. Google's unverified-app warning depends on the OAuth application's verification status and requested permissions.
The individual Docs connection requests document access only. Calendar requests calendar discovery, event management and availability permissions; it does not request permission to manage sharing or delete calendars. Existing full Calendar grants remain usable. Older event-only connections must reconnect before using Check availability.
In production, new Google consent is limited to reviewed permissions or a configured verification audience. A 403 with google-oauth-verification-required means the deployment administrator must finish that setup; repeatedly reconnecting or pasting a different client secret will not clear it. The verification audience is checked again when Google redirects back. Saved connections continue to use their recorded grants.
Copy and move Drive files; replace text in Docs
Select a Google Drive or Google Workspace connection for Copy file and Move file. Both use fileId for the source file. Set parentFolderId to the destination folder; it is required for Move file and optional for Copy file. Copy file also accepts an optional name for the new file. Open the result in Drive to check its name and location.
For Google Docs Replace all text, select a Docs or Google Workspace connection, enter documentId, and add replacements entries with search and replace. An empty replace removes the matching text. For example, [{"search":"BEFORE","replace":"AFTER"}] replaces every occurrence of BEFORE. Open the document to verify the change. These actions use the existing Drive and Docs permissions.
Imported workflows can also use the older folderId, fileName, text, and replaceText fields. Non-blank older destination, name, and search values take precedence; if they render as empty or whitespace, the fields above are used. An empty replaceText still removes matching text, even when replace is also present.
Create a Google Sheets tab
In the workflow builder, add Google Sheets: Create sheet to create a tab inside an existing spreadsheet.
- Select your Google Sheets or Google Workspace connection.
- Choose the existing spreadsheet or enter its
spreadsheetIdfrom its Google Sheets URL. - Set
titleto the new tab name, then test the block. - Open the returned
urlto check the new tab. Use the returnedsheetIdin later blocks that need a tab identifier; use the tab title in A1 ranges for reading or writing cells.
The action returns spreadsheetId, sheetId, title, index, and url. Create spreadsheet creates a separate file; Create sheet adds a tab to the selected file. This uses the existing spreadsheets permission and requires no additional OAuth permission.
A duplicate tab name produces a Google error; choose another name. The action does not retry automatically. If a request times out, check the spreadsheet before running it again, because Google may already have created the tab.
WhatsApp Business Cloud
Add WhatsApp: Send message or WhatsApp: Send template in the workflow builder’s Communication catalog.
- Create or select a WhatsApp account. Enter its Access Token and Business Account ID from Meta’s WhatsApp → API Setup in separate fields. The Business Account ID is the WABA ID, not the Phone Number ID. The token needs
whatsapp_business_messagingpermission for sending. The credential type iswhatsAppApi; existing token-only and JSON credentials remain usable for their previous sending flows. - Save and test checks token validity without sending anything. It does not prove that the token can send from a particular phone number.
- Set
phoneNumberIdto the sender’s Phone Number ID from Meta, not its telephone number or Business Account ID. SetrecipientPhoneNumberto the recipient’s international number, including country code, for example+14155552671. - Send message accepts
text(up to 4,096 characters) and optionalpreviewUrl. Free-form messages require an open customer service window, normally 24 hours after the customer’s last message. Outside that window, use Send template. - Send template accepts the exact approved
templateName, itslanguageCode(for examplees_MX), and optional orderedbodyParametersentries such as[{"text":"Ana"},{"text":"123"}]. This operation supports text body parameters; headers, buttons, media and interactive messages are not supported. - Test with an authorized recipient. Meta test numbers require recipients configured in the Meta developer console. The output contains
messageIdandstatus: "accepted"; acceptance is not a delivery receipt.
The connector makes one attempt per execution. Leave the node’s Retry On Fail setting off to avoid duplicate messages. If a send times out or returns no receipt, check Meta before running it again. For rejected requests, check token expiry, sender access, recipient setup and template approval. Sending does not track delivery updates. Operators can disable WhatsApp sending with WORKFLOW_LIVE_WHATSAPP=false.
Receive WhatsApp messages
Add a WhatsApp trigger. From the trigger, choose Add account to open the WhatsApp credential form; its Access Token and Business Account ID fields are both visible and required. Enter the WABA ID from Meta’s WhatsApp → API Setup, not the sender’s Phone Number ID. Existing token-only accounts can be updated by re-entering the token and adding the WABA ID. The token needs whatsapp_business_management permission. The Meta app must already have its Webhooks product and messages field enabled. Publish the workflow to let Confluye subscribe the WABA with a callback override. Meta may reject registration if the app has not completed its initial webhook setup; the publication error names that prerequisite. One WABA callback override receives the account's messages, so use one trigger per WABA. Confluye answers Meta's verification challenge automatically. Optionally enter the App Secret to verify the signature of incoming POST requests; re-enter it when updating that account.
Send Telegram messages
Add a Telegram action from the Communication catalog, or use a block’s + menu and choose Telegram. Choose a workspace Telegram account containing the Bot Token, then configure the action. Send a text message accepts a numeric Chat ID or channel username such as @examplechannel and a Text value; to reply to the incoming chat, use {{input.message.chat.id}}. Text fields accept workflow expressions, for example Thanks {{input.message.text}}. The bot must be allowed to post in the target chat or channel. Delivery is queued durably, and the node returns a queued delivery reference rather than a Telegram delivery receipt. Existing Telegram alert credentials that contain both botToken and chatId still work in their old nodes without editing.
The Telegram action list also includes Send a photo message, Send a video, Send an audio file, Send an animated file, Send a document, Send a sticker, Send a location, and Send a media group message. Media actions accept a Telegram file_id or a URL. Add an optional caption where the action offers one. Location requires latitude and longitude. A media group takes a JSON array of Telegram media entries. These actions use the selected bot account and the same Chat ID field.
For message management, Edit a text message, Delete a chat message, Pin a chat message, and Unpin a chat message use Chat ID and message ID. Send a chat action uses Telegram action values such as typing or upload_photo. When handling an incoming Telegram interaction, Answer Query a callback accepts the callback query ID and optional text, alert choice and cache time; Answer an inline query callback accepts the inline query ID and a JSON results array. Get a file accepts a file ID and returns Telegram file metadata, including file_path when available; it does not download the file contents.
Send message and wait for response sends a message with a response link, then pauses the run until someone submits the linked form or its timeout expires. Choose Approval to let the recipient approve or reject, or Free text to collect a written response. The resumed node output contains responseType and response (the approval outcome or submitted text). Set Wait timeout (seconds) to end the wait after a chosen interval; leave it empty to wait without a timeout. Configure the application with its public HTTPS origin so the link can reach the response form.
The inbound Telegram trigger is documented below.
With a running platform worker, incoming messages and queued replies are picked up by separate loops every second by default. They do not wait for the general scheduler's minute-long cycle. Workflow execution, Telegram requests, retries and messages already queued for the same chat can add time; a queued delivery reference confirms acceptance, not delivery.
Receive Telegram messages
Add a Telegram trigger and select a workspace Telegram account containing the Bot Token, either as a plain token or {"botToken":"…"}. Under Trigger on, choose Messages, Callback queries, or Inline queries; new and existing triggers default to Messages. Publishing calls Telegram setWebhook with the selected update types. The trigger validates Telegram's secret header and starts the workflow when a selected update arrives. Callback query payloads are available as {{input.callback_query}}; inline query payloads as {{input.inline_query}}. A Telegram bot has one active webhook, so publishing another workflow for the same bot replaces its previous callback. A destination chat ID is needed only for sending Telegram messages, not for this trigger.
Existing Telegram and WhatsApp triggers that use a manually registered webhook keep their current URL and continue to work without editing. In one of those nodes, select a workspace account to switch it to automatic registration when you next publish.
After changing a selected trigger account's token, publish the workflow again so the provider receives the current callback verification token.
Publishing Production or a named preview, including switching a stopped deployment back On, registers the managed callback and its secret header. If registration fails, Confluye reports the provider registration error even though the deployment was saved. Retry publication to register the callback again; a retry of the same publication request keeps the existing activation. Avoid manually calling setWebhook for a managed trigger, because a callback registered without Confluye's secret will be rejected with HTTP 403. Use a separate bot for each simultaneously active destination: publishing a preview with the same bot replaces Production's Telegram callback.
The implementation follows the official Cloud API approach used by n8n’s WhatsApp node. Existing encrypted workspace credentials and workflow connection bindings apply.
Jenkins
Add a Jenkins block from the workflow builder’s Developer Tools catalog.
-
Create an API token in Jenkins under your user’s Security settings. Use a dedicated user with only the job permissions the workflow needs. Do not use the account password.
-
Create or select a Jenkins connection. Save JSON with the HTTPS Jenkins URL, including any context path, the user and the token:
{"baseUrl":"https://jenkins.example.com","username":"ci-bot","apiToken":"…"}. The credential type isjenkinsApi, and theapiKeyfield name from n8n is also accepted. -
Save and test signs in as that user without starting a build. It does not prove that the user can build a particular job.
-
Set
jobNameto the job name. For a job inside folders, separate the folders with/, for exampleplatform/api/deploy. -
Trigger build starts a job without parameters. Trigger build with parameters accepts optional
parametersentries such as[{"name":"BRANCH","value":"main"}]. Parameters you omit use the job’s defaults. Both returnstatus: "queued"and, when Jenkins reports it, aqueueId. Trigger build, and Trigger build and wait for result without parameters, call Jenkins’/buildendpoint. When Jenkins answers400because the job declares parameters, they retry once with/buildWithParametersand no values, so the job’s defaults apply. -
Get queue item uses that
queueId. It returnsstate(waiting,startedorcancelled) and, after the build starts,buildNumberandbuildUrl. Jenkins only keeps finished queue items for a few minutes. -
Get build accepts a
buildNumberorlastBuild,lastCompletedBuild,lastSuccessfulBuildorlastFailedBuild. It defaults tolastBuild. The output includesbuilding,result(for exampleSUCCESSorFAILURE, ornullwhile it runs),durationMs,startedAt(nullwhen Jenkins reports no start time) andurl. List builds returns up tolimitrecent builds, newest first. -
Get build details accepts the same
buildNumbervalues as Get build and returns the same build fields, plus:status:running,success,unstable,build_failure,abortedornot_built.stages: each Pipeline stage withname,status(for exampleSUCCESS,FAILEDorNOT_EXECUTED),durationMsand, when Jenkins reports one,errorMessage.failedStage: thenameanderrorMessageof the first stage with statusFAILED, ornullwhen no stage failed.stagesAvailable:falsewhen Jenkins has no stage data for the build, as with freestyle jobs or servers without the Pipeline Stage View plugin.stagesis then empty.logTail: the lastlogLineslines of the console log (default 200, up to 1,000), without Jenkins console annotations and terminal color codes. At most the last 256 KB of the log is read.logTruncated:truewhenlogTaildoes not include the whole log.
To analyze a failure in the same step, turn on
includeDetailsin Trigger build and wait for result instead. Otherwise, connect Get build details to itsbuild_failurebranch, withbuildNumberset to that node’sbuildNumber. Then passfailedStageandlogTailto an agent or AI block to explain the failure. The console log can contain anything the job prints, so the workflow’s later steps receive it as-is.
A trigger makes one attempt per execution. Leave the node’s Retry On Fail setting off to avoid starting duplicate builds. If a trigger times out, check Jenkins before running it again. Once Jenkins accepts the build, a later failure of the node is never retried, even with Retry On Fail on. Reading operations retry once.
Start a workflow when a build finishes
The Jenkins build finished trigger starts the workflow when a build finishes on jobs you name. Jenkins does not call Confluye: the destination polls Jenkins with the connection you choose, so no Jenkins plugin or webhook is needed.
- Add Jenkins build finished from the Triggers catalog and save the workflow.
- In Versions & previews, open the destination and choose Add event source. Select Jenkins finished builds, the saved Jenkins trigger and a Jenkins connection. You need permission to edit that destination.
- Add one row per job. Use the full job name, with folders separated by
/. Jobs are never discovered from folders or the server. - Choose the Build results that start the workflow. All five are selected by default:
SUCCESS,UNSTABLE,FAILURE,ABORTEDandNOT_BUILT. - Set the poll interval in seconds. The default and minimum are 60 seconds. Then choose Configure source.
A source for a trigger that the destination's deployed version does not have yet shows Off and starts polling when you deploy that version, so builds never start the older version. Changes to a source that is already polling apply from its next poll. Configure source is refused when the saved or deployed version launches one of the listed jobs.
The first poll of each job records the latest existing build, finished or still running, as its baseline. That build and older builds never start the workflow; only builds numbered above the baseline do. Adding a job later takes a baseline for that job only. If the connection starts pointing at another Jenkins server, every job takes a new baseline. A job that is deleted and recreated in Jenkins restarts its build numbers, so it also takes a new baseline. Stopping the destination turns its Jenkins sources off. When you deploy or resume it again, each job takes a new baseline, so builds that finished while it was stopped never start the workflow.
Each finished build starts at most one run per destination, even with retries, several workers or restarts. A build that finishes out of order, for example #14 before #13, still starts its own run. Each poll delivers up to 25 builds per job, oldest first. When more than 100 newer builds arrive before an earlier build finishes, that build is skipped and counted.
The run input contains job, buildNumber, result, durationMs, startedAt (null when Jenkins reports no start time) and url, plus trigger: "jenkins" and the triggerId.
The destination shows the source's state, interval and last poll time. For each job it shows Waiting for first poll or Baseline: build #N, then Last build seen: #N, the number of builds skipped and the latest error. A job Jenkins cannot find (404) shows its own error while the other jobs keep polling. Authentication failures (401 or 403), a blocked host and a deleted connection stop the whole source, show the error and retry with increasing delays.
Set up Jenkins from an MCP client
An AI client connected to the Confluye MCP server can do the same setup. It needs a workspace API key with write and execute authority.
catalog.searchwithjenkinsreturns the trigger and the Jenkins blocks, whose credential type isjenkinsApi.credentials.createwithproviderId: "jenkins"stores the connection JSON shown above.credentials.listwithproviderId: "jenkins"lists existing connections as metadata, andcredentials.testruns the same connection test as Settings. No tool returns the API token.workflows.update-targetwith theconfigure-sourceaction, the destination'sexpectedRevisionfromworkflows.targets, and ajenkinssource (targetId, the trigger'snodeId,credentialId,jobs, optionalresultsandintervalSeconds) configures the source with the same limits and loop check as Configure source, as the key's user.workflows.targetsreports each source's state, interval, last poll and per-job status.
Only a workspace API key can create a credential through MCP. OAuth clients such as ChatGPT can list and test connections and configure sources, but create the connection in Settings → Credentials.
Trigger a build and wait for its result
Trigger build and wait for result queues a build and pauses the run until that exact build finishes or the timeout passes. It never follows another build of the same job. While paused, the run holds no worker and uses no compute credits.
jobNameis required.parametersis optional, in the same format as Trigger build with parameters.timeoutMinutesis between 1 and 10,080 (7 days) and defaults to 60.- Connect the node’s outgoing edges with the branch labels
success,unstable,build_failure,aborted,not_built,cancelledandtimeout.cancelledmeans the queue item was cancelled in Jenkins. A status without its own edge follows the unlabeled edge. Errors from the node itself, such as a rejected request, follow theerrorbranch, neverbuild_failure. - The output includes
status,jobName,queueId,buildNumber,url,timedOutand, when Jenkins reports them,queueWhyandreason. Parameter values are not repeated in the node output. - Turn on
includeDetailsto also getstagesAvailable,stages,failedStage,logTailandlogTruncatedwhen the build finishes, as described for Get build details.logLinessets how many final log lines to keep (default 200, up to 1,000). They are read when the wait resumes withsuccess,unstable,build_failure,abortedornot_built, never withcancelledortimeout. If they cannot be read, the output includesdetailsErrorinstead, and the run still continues on the branch for the build result. - After the deadline, a build keeps its real result only if Jenkins’ completion time (its start time plus duration) is at or before the deadline, even if Confluye sees it slightly later. If the timeout passes first, or Jenkins does not report when the build finished, the run continues on
timeoutand the output includes the build URL once the build has started. A queue item cancellation first seen after the deadline also continues ontimeout. - A timeout or a cancelled run does not stop the build or remove it from the Jenkins queue.
- While the run waits, the node inspector and the run query show the job, queue item, build number once it starts, and the deadline. They do not show the Jenkins server address.
- If Jenkins does not return a queue item, the node fails without pausing, and Retry On Fail does not queue the build again. Check Jenkins before retrying.
This operation cannot run inside a loop or parallel group; deployment is blocked until it moves to the main path. A workflow with a Jenkins trigger also cannot deploy if it launches a job its own trigger listens to on the same Jenkins server, or a job whose name is an expression. A job with the same name on another server is allowed only when the destination can read both connections; otherwise it counts as the same job.
Network access and operator switch
The Jenkins server must be reachable over HTTPS from Confluye. The egress guard blocks private and internal addresses unless an operator adds the host to FLUXUS_HTTP_EGRESS_ALLOWLIST. Every Jenkins request, including each redirect, stays on the exact scheme, host and port of the connection URL; a redirect to another host, subdomain, port or to http:// is refused before anything is sent.
Operators set WORKFLOW_LIVE_JENKINS on both the web service and the worker. WORKFLOW_LIVE_JENKINS=false disables the actions, including trigger and wait, and pauses polling and wait tracking. Waiting runs keep their deadline and continue on timeout when it passes. Builds that finish while polling is paused are not delivered: when it is turned back on, each job takes a new baseline and its status counts the skipped builds. A pause does not count as a polling failure, so it does not lengthen the retry delay after polling resumes.
The operations follow the Jenkins remote access API used by n8n’s Jenkins node. Creating, copying and deleting jobs and restarting or pausing Jenkins are not supported.
Credentials and secrets
For workflow Versions & previews, choose compatible connections explicitly for each destination. Each field filters by provider and required permissions. Add credential opens the existing provider dialog without leaving the deployment setup; save and test a workspace credential, then save the destination’s connection choices. OAuth sign-in returns to the same destination, where you can select the connected account. Production and a preview can share an AI connection while using different CRM accounts. A shared account still reaches the same real data; a separate preview URL does not isolate that account. AIMS approval covers the exact destination and connection references. Rotated secret values are resolved when executing, while missing, inaccessible or retired connections block execution. Creating a preview does not copy provider subscriptions, mailbox cursors or pinned test data. External secret-provider references from the former environment catalog are not automatically converted into workflow connections.
Values are encrypted with AES-256-GCM (APP_ENCRYPTION_KEY, or a dev-only default). List/create/update responses expose maskedValue (•••••••• from Prisma mapping). OAuth scope strings may be parsed from JSON secrets into oauthScopes.
Create requires name and type. Optional envVar is not an arbitrary environment variable: it must be a known deployment source (DATABASE_URL, GITHUB_TOKEN, OPENAI_API_KEY, SMTP/Google/Jira/Microsoft/Supabase JSON, etc.) whose type matches the credential. Otherwise the API returns a public error and does not store the secret.
Claude Code / Codex CLI types (claudeCodeOAuth, codexCliSession, or those display names) cannot be created or patched through credentials REST/tRPC. Use the local AI CLI worker login on Settings → Workers.
POST /api/v1/credentials/{id}/test decrypts the secret and runs testCredentialConnection. Unlike list/create/update/delete, the test route does not require workspace-scoped keys — any valid bearer key for that workspace id can test.
Personal credentials: tRPC createCredential accepts scope: "personal" and binds userId. The v1 REST create path always stores scope: "workspace".
Authorization
| Action | Gate |
|---|---|
| Session list/update integrations or credentials | Membership in the workspace |
| v1 integrations | Any valid API key (not limited to workspace scope) |
| v1 credentials list/create/patch/delete | Workspace API key (403 otherwise) |
| Invite members (related) | See Workspace settings |
There is no Admin/Owner check on credential CRUD. Cross-workspace ids return 403/404.
Failure modes
- Invalid type/value format:
400fromvalidateCredentialSecretValue. - Duplicate name for the same scope: create updates the existing row instead of erroring.
- Decrypt failure at test/runtime:
SecretDecryptionError— reconnect the credential. - OAuth start without
key:400. ForeignworkspaceId:403.
