Zendesk Integration Architecture
This page explains the architecture behind the Flexivity AI Zendesk integration. It is intended for system administrators and technical staff who want to understand exactly how the integration works, verify it aligns with their data governance posture, and confirm it will not interfere with their existing Zendesk operations.
Architecture Overview
The Zendesk integration is fully cloud-to-cloud. Flexivity AI does not run any software inside your network. The integration has four components:
- A Zendesk marketplace app (ZAF) that renders the Flexivity AI panel in the Agent Workspace ticket sidebar. Installing it also installs the webhooks and triggers that send Flexivity your ticket events.
- Inbound webhooks from Zendesk to Flexivity that deliver ticket events (created, commented, solved or closed, deleted) and Help Center article changes in near-real-time.
- Outbound REST calls from Flexivity to Zendesk to read ticket and Help Center data, and to write replies, notes, field values and Help Center draft articles.
- Zendesk messaging (optional), connected through the Sunshine Conversations API, so the AI can answer customers in chat.
┌─────────────────────────────────────────────────────────────────┐
│ Your Zendesk account │
│ │
│ ┌──────────────┐ triggers ┌──────────────────────┐ │
│ │ Ticket Event │──────────────>│ Zendesk webhook │ │
│ │ (created / │ │ subscription │ │
│ │ commented / │ └──────────┬───────────┘ │
│ │ updated) │ │ │
│ └──────────────┘ │ HTTPS POST │
│ │ (HMAC-signed) │
│ v │
│ ┌──────────────────┐ │
│ │ Agent Workspace │ OAuth + REST │
│ │ Flexivity widget│<───────────────────────┐ │
│ └──────────────────┘ │ │
│ │ │
│ ┌──────────────────────┐ │ │
│ │ Help Center articles │<───────────────────┤ │
│ │ (drafts pushed in) │ │ │
│ └──────────────────────┘ │ │
└──────────────────────────────────────────────┼──────────────────┘
│
│
┌────────────────v────────────────┐
│ Flexivity AI Cloud │
│ (api.flexivity.ai, us-east-1) │
│ Ingestion API → AI Pipeline → │
│ LLM service; scrubbed at rest │
└─────────────────────────────────┘The key design principle is that every interaction with Zendesk uses Zendesk’s documented, supported APIs — OAuth 2.0, the Apps framework, REST APIs, webhooks, and the Help Center API. Nothing about the integration depends on private APIs, screen scraping, or polling Zendesk on a hot loop.
What Flexivity Reads from Zendesk
Flexivity reads the following data from your Zendesk account, all via authenticated REST calls under the OAuth grant you established during connect:
- Tickets — subject, description, status, requester, assignee, group, priority, type, organization, tags, all custom field values.
- Comments — both public and internal, with author, timestamp, and channel metadata.
- Audit events — used to link a chat conversation to the ticket Zendesk creates for it.
- Users — name, role, organization, used to label comments by role (agent vs end-user vs system) for AI processing.
- Groups — the name of the ticket’s group, as context for AI processing.
- Organizations — the ticket’s organization id only.
- Custom ticket fields — the fields your mapped attributes read or write, and their drop-down values, refreshed periodically.
- Help Center articles — title, body, section, locale, published state, indexed so the AI can answer from them and so the Knowledge Builder can tell which topics are covered.
Reads happen in two modes:
- Event-driven — when a webhook fires, Flexivity reads the just-affected ticket plus any comments and audit events needed for that event’s AI processing.
- Bulk — during historical sync (a one-time backfill per instance), Flexivity uses Zendesk’s Incremental Export endpoints with sideloads to efficiently retrieve large volumes of tickets and their associated metadata.
- Help Center sync — articles are read with Zendesk’s incremental article export, updated when an article is published or unpublished, and fully re-synced once a day.
For the exact data fields and retention behavior, see Data Disclosures — Zendesk.
What Flexivity Writes to Zendesk
Flexivity writes the following back to your Zendesk account:
| Write Target | When |
|---|---|
| Public replies | Only for tickets whose rule allows the AI to answer the customer (Reply, Clarify or Resolve). The reply says it was written by AI. |
| Ticket status | Only with the AI’s own reply: Pending while it waits for the customer, Solved when the conversation is resolved. Never Closed. |
| Internal notes | A hand-over note for your agents when the AI passes a ticket to a person. |
| Custom ticket fields | For attributes you have set to be written to a Zendesk field, only once writing is switched on and the AI is sure enough. |
| Chat messages | In Zendesk messaging, the AI’s answers, and the hand-over of the conversation to an agent. |
| Help Center draft articles | When an administrator pushes a draft from the Knowledge Builder. Always Draft, never Published. |
| Per-install JWT secret | During connect and on rotation, written to the marketplace app’s installation settings via the Zendesk Apps API. |
Flexivity does NOT:
- Post a public reply on a ticket your rules keep with your agents.
- Close or merge tickets.
- Change requester, assignee, group, or organization.
- Change ticket types, priorities or tags.
- Publish Help Center articles (drafts only — publishing is always a human action inside Zendesk’s article editor).
- Modify users, groups, organizations, or roles.
A single switch in the admin console, Replies to customers, stops every public reply and chat answer at once, whatever the rules allow.
For the exact write surface, see Data Disclosures — Zendesk.
What Flexivity Stores
Flexivity stores the following on its side, in the Flexivity AI cloud. Storage is multi-tenant-isolated by organization_id and instance_id; nothing here lives in your Zendesk account.
| Stored Data | Purpose |
|---|---|
| AI summaries | Generated at handoff and on an agent’s request, shown in the Flexivity panel; the latest is retained. |
| Attribute values | What the AI decided about each ticket, and any correction an agent made. |
| Drafts and conversations | Draft replies, and the state of any conversation the AI is holding with a customer. |
| AI activity | A record of what the AI did on each ticket and why, shown on AI Activity in the admin console. |
| Anonymous feedback | Thumbs-up / thumbs-down ratings on summaries and drafts. No identifier of the rating agent is stored. |
| Scrubbed ticket history | PII-scrubbed ticket content and the vector embeddings derived from it (computed from the scrubbed text), used to find related tickets and for the Knowledge Builder. |
| Help Center index | Your published Help Center articles and their embeddings, the knowledge the AI answers from. |
| Billing units | One record per billed ticket or conversation. |
PII is scrubbed before ticket content is stored or embedded; the LLM service reads it as written — see PII Handling below. Raw ticket text is not retained; only the scrubbed form is.
For retention windows and what gets deleted on instance disconnect, see Data Disclosures — Zendesk.
Webhook Event Capture
Zendesk delivers events to Flexivity through webhooks and triggers that the marketplace app installs with itself, so there is nothing to set up by hand:
- Ticket created, comment added, and ticket solved or closed, each sent by a Flexivity trigger.
- Ticket deleted, so Flexivity removes the ticket’s AI data.
- Help Center article published or unpublished, so the AI answers only from published articles.
Why Webhooks (Not Polling)
- Near-real-time — agents see AI output within seconds of a ticket event, not after a polling interval.
- Efficient — no API quota burned on polling empty queues.
- Reliable — Zendesk handles delivery retries; Flexivity acknowledges with a 2xx after the event is enqueued for processing.
Webhook Signature Verification
Every webhook delivery is HMAC-SHA256 signed by Zendesk. Flexivity verifies the signature and the delivery’s timestamp, and rejects anything that fails verification, or arrives more than five minutes late, with a 401.
Idempotency
Webhook delivery can occasionally be retried by Zendesk (after a 5xx, network error, or apparent timeout). Flexivity records each delivery it has accepted, keyed on the instance and the delivery’s content, and acknowledges a repeat without processing it again.
OAuth Token Management
The OAuth grant established during connect issues two tokens:
- Access token — used on every Zendesk REST call. Expires in approximately 30 minutes in practice.
- Refresh token — used to mint a new access token without re-prompting the user.
Both tokens are stored encrypted in AWS Secrets Manager keyed by instance id. Flexivity refreshes the access token when a REST call gets a 401 from Zendesk, and checks the connection every five minutes, refreshing it then if needed.
If the refresh token itself becomes invalid (Zendesk admin revoked the OAuth grant from Admin Center → Apps and integrations → Connected apps), the instance shows as Degraded in the Flexivity admin console, with a note that a reconnect is required, and re-running connect re-establishes the grant. No automated background re-prompt is sent.
Never Undo Human Work
Flexivity is built so that a person’s action always wins over the AI’s:
- Corrections win. Flexivity never reads a field value it wrote itself as evidence. When a field differs from what Flexivity wrote, that is an agent’s correction: rules use the agent’s value from then on, and the correction is recorded.
- A person joining ends automation. When an agent replies on a ticket the AI is handling, the AI stops replying and the conversation is the agent’s.
- Another AI agent comes first. Flexivity does not reply on a conversation that another AI agent in Zendesk is handling, or whose state it cannot tell.
- Its own comments are recognised. Flexivity records each comment it posts, so the webhook for that comment is never mistaken for the customer writing again.
In-Cloud Processing Pipeline
Once a webhook event arrives at Flexivity:
- Ingestion API (FastAPI) verifies the HMAC signature, enqueues the event in SQS, and returns 2xx to Zendesk.
- The AI pipeline pulls the ticket’s identifier from SQS, fetches the ticket via Zendesk REST (using sideload-style queries to minimize round trips) and masks payment card, government and bank identifiers in it, then:
- Classifies the ticket’s attributes and applies your rules, which decide what happens next.
- For summaries, drafts and replies — calls the LLM service (Amazon Bedrock) with the relevant knowledge, checks the result, and writes back to Zendesk via REST where your rules allow.
- For the Knowledge Builder — embeds solved tickets with pgvector, clusters them on demand, and surfaces gap candidates in the Flexivity admin console.
- Aurora PostgreSQL stores embeddings, the AI’s records for each ticket, job state, audit logs, and feedback events. Multi-tenant isolation is enforced via
organization_idandinstance_idon every query. - Idempotency keys in Redis prevent duplicate AI work on retried events.
The pipeline is identical to the osTicket pipeline downstream of the ingestion API — the difference is the upstream entry point (Zendesk webhook + OAuth REST vs. osTicket agent / plugin REST).
PII Handling
Raw in flight, scrubbed at rest. Ticket and conversation text is fetched from Zendesk when the AI needs it. As it arrives, payment card numbers, US Social Security and taxpayer numbers, and bank account numbers are masked; that masking is best effort, tuned not to mistake order numbers or product codes for them. The LLM service (Amazon Bedrock) then reads the text as written, so a reply can use the customer’s own details, and keeps no prompts or completions.
Before anything is stored, Presidio scrubs personally identifiable information from it: the database, the embedding index (vectors are computed from scrubbed text), and the logs hold only placeholder text. Queues carry ticket and message identifiers, not their text. The Zendesk and osTicket integrations use the same scrubbing, with identical detection and replacement behavior.
Note: There is no on-premise option for Zendesk; masking and scrubbing both run in the Flexivity AI cloud.
For what Flexivity reads and stores, see Data Disclosures — Zendesk.
Messaging (Chat)
If you connect Zendesk messaging, Flexivity receives chat messages through a Sunshine Conversations webhook authenticated with a key unique to your installation, and answers through the Sunshine Conversations API. When the AI hands a conversation over, it passes control of the conversation to your agents in Zendesk. The same rules, knowledge and Replies to customers switch apply as on tickets.
In chat the AI’s replies reach the customer without an agent reviewing them first; every claim must still cite your knowledge base. With Answer verification, a chat reply is checked after it is shown, and the conversation is handed to an agent if a claim is not supported.
Multi-Tenant Isolation
Every Aurora query and every log line in the Flexivity pipeline includes both organization_id and instance_id. Cross-tenant data leakage is prevented at the query layer, not just at the application layer — there is no shared cache or shared in-memory state that could be reused across tenants.
Why These Patterns Are Safe
The integration approach was designed around three principles:
Standards-Compliant
The integration uses only Zendesk’s documented, public APIs:
- OAuth 2.0 (authorization code flow)
- The Apps framework + Marketplace, including the webhooks and triggers an app declares
- Standard REST APIs (Support, Help Center)
- The Sunshine Conversations API, for messaging
- The Apps installations API (for per-install JWT secret rotation)
There are no undocumented API calls, no DOM scraping, and no reliance on Zendesk internal implementation details.
Cloud-to-Cloud Only
There is no on-premise component, no Docker container to maintain, and no inbound firewall rule. Onboarding is faster, ongoing maintenance is zero, and security review for new customers focuses on Zendesk’s own OAuth surface plus Flexivity’s SOC 2 controls.
Reversible
The integration is fully reversible. Disconnecting or deleting the instance in the Flexivity admin console revokes Flexivity’s OAuth grant with Zendesk, deletes the stored credentials, and stops all processing; deleting your Flexivity account does the same for every Zendesk instance. Uninstalling the marketplace app removes the panel, the webhooks and the triggers. After both steps, your Zendesk account returns to its pre-integration state, apart from the replies, notes and field values the AI wrote, which are ordinary ticket data. You can also withdraw the grant yourself at any time under Admin Center → Apps and integrations → Connected apps.
Summary
| Concern | How It Is Addressed |
|---|---|
| Performance impact on Zendesk | Inbound webhooks return 2xx immediately; outbound REST calls are rate-aware and respect Zendesk’s standard quotas |
| Customer-facing replies | Only where your rules allow; disclosed as AI-written; one switch stops them all |
| Data minimization | Reads only the data the AI uses; card, government and bank identifiers masked on arrival; PII scrubbed before storage |
| Help Center governance | Drafts only — no auto-publish; Zendesk’s existing publishing permissions and approval workflows are respected |
| Never undo human work | Agent corrections win; an agent’s reply ends automation; the AI’s own writes are never read back as evidence |
| Authentication | OAuth 2.0 with token refresh; per-install JWT secret for panel-to-Flexivity calls; per-install key for messaging |
| Multi-tenant data isolation | Every database query and log line scoped to organization_id + instance_id |
| Webhook authenticity | HMAC-SHA256 signature verified on every inbound webhook |
| Disconnect cleanliness | OAuth grant revoked and credentials deleted on disconnect or delete; uninstalling the app removes webhooks and triggers |
| No on-premise component | Fully cloud-to-cloud; no Docker, no agent, no inbound firewall rules required |
For specifics on what data is read, written, and retained, see Data Disclosures — Zendesk.