Integration Approach
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 three components:
- A Zendesk marketplace app (ZAF widget) that renders the Flexivity AI widget in the Agent Workspace ticket sidebar.
- Inbound webhooks from Zendesk to Flexivity that deliver ticket events (
ticket.created,ticket.comment_added, etc.) in near-real-time. - Outbound REST calls from Flexivity to Zendesk to read ticket and Help Center data, write classification results, and write Help Center draft articles.
┌─────────────────────────────────────────────────────────────────┐
│ 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 → PII scrub → │
│ Celery workers → Bedrock LLM │
└─────────────────────────────────┘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 detect human edits to fields Flexivity might otherwise overwrite (see “Never undo human work” below).
- Users — name, role, organization, used to label comments by role (agent vs end-user vs system) for AI processing.
- Groups — used by AI Classification when routing decisions are scoped to a group.
- Organizations — used for organization-scoped analytics.
- Custom ticket fields — the dropdown values for any field your administrator configures as the AI Classification topic field, refreshed periodically to keep the picklist cache current.
- Help Center articles — title, body, section, locale, published state, used to detect coverage for KB Analysis and as RAG context for Recommendations.
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.
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 |
|---|---|
| Topic ticket field (AI Classification) | When AI Classification is enabled and the confidence exceeds the auto-assign threshold, the configured topic field is updated. |
| Help Center draft articles | When an administrator clicks “Push to Help Center” on a draft preview in the Flexivity admin console. Always Draft, never Published. |
| Webhook subscription | One-time, during connect — installs the Flexivity AI Events webhook pointing at https://api.flexivity.ai/v1/zendesk/webhook. |
| 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:
- Send comments on behalf of agents.
- Solve, close, or merge tickets.
- Change requester, assignee, or organization.
- Modify ticket types, priorities, or statuses (except via the topic field in Classification — and only when that field happens to be configured as the source of routing).
- Publish Help Center articles (drafts only — publishing is always a human action inside Zendesk’s article editor).
- Modify users, groups, organizations, or roles.
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 per ticket update and surfaced in the Flexivity widget; the latest summary per ticket is retained. |
| Recommendations | The ranked list of similar past tickets and suggested resolutions surfaced for each ticket the widget rendered against. |
| Anonymous feedback | Thumbs-up / thumbs-down ratings on summaries and recommendations. No identifier of the rating agent is stored. |
| Scrubbed ticket history | PII-scrubbed ticket content and the vector embeddings derived from it — the RAG corpus that powers Recommendations and AI Classification. |
PII is scrubbed before anything reaches the embedding index or the LLM API — see PII Handling below. Raw ticket text is not retained; only the scrubbed form is.
Note: Your Zendesk Help Center articles are not stored or embedded by Flexivity. Zendesk’s built-in Help Center semantic search is the source of KB context for Recommendations and the coverage signal for KB Analysis — Flexivity queries it at runtime rather than maintaining its own copy. This is a deliberate Zendesk-specific design choice (see KB Analysis & Authoring — Why No Customer-Facing AI Search Widget?).
For retention windows and what gets deleted on instance disconnect, see Data Disclosures — Zendesk.
Webhook Event Capture
Zendesk delivers ticket events to Flexivity via a single webhook subscription created during connect. The subscription is filtered to the events Flexivity needs:
zen:event-type:ticket.createdzen:event-type:ticket.updatedzen:event-type:ticket.comment_added(a “thread message” in Flexivity terminology)zen:event-type:ticket.solvedzen:event-type:ticket.closed
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 using a webhook signing secret. Flexivity verifies the signature on every inbound webhook and rejects anything that fails verification with a 401. The signing secret is created during connect (via a separate Zendesk Apps API call — Zendesk does not return it in the webhook creation response) and stored encrypted in AWS Secrets Manager.
Idempotency
Webhook delivery can occasionally be retried by Zendesk (after a 5xx, network error, or apparent timeout). Flexivity computes a deterministic idempotency key for each event (combining Zendesk’s event id, ticket id, and event timestamp) and short-circuits duplicate processing using Redis as the idempotency store.
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 on demand (when a REST call gets a 401 from Zendesk) and proactively on a schedule to avoid 401-triggered request retries.
If the refresh token itself becomes invalid (Zendesk admin revoked the OAuth grant from Admin Center → Apps and integrations → Connected apps), the instance enters Reauthorization required state in the Flexivity admin console and re-running connect re-establishes the grant. No automated background re-prompt is sent.
Never Undo Human Work
When Flexivity writes back to a ticket — for example, applying a classification to the topic field — it first checks the ticket’s audit history to detect whether a human has already edited the target field after Flexivity’s session started.
Specifically, before writing:
- Flexivity fetches
GET /api/v2/tickets/{id}/audits.jsonfor the ticket. - Each audit event is filtered:
- Channel — events with channel
system,rule,trigger, orautomationare excluded as automated. - Timestamp — only events created strictly after the Flexivity session started are considered.
- Field — only events of type
Changeon the specific target field (e.g.,group_idfor routing, or the configured topic field id for classification) are considered.
- Channel — events with channel
- If at least one human edit is detected, Flexivity skips the writeback for that field. Your edit wins.
This guards against the worst-case scenario of an automated system overwriting an agent’s manual correction.
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.
- Celery workers (Fargate) pull from SQS, fetch any missing ticket data via Zendesk REST (using sideload-style queries to minimize round trips), scrub PII via Presidio, then:
- For Summaries / Recommendations / Classification — call AWS Bedrock with the configured model and prompt, then write back to Zendesk via REST.
- For KB Analysis — embed solved tickets into Aurora with pgvector, run clustering offline on a schedule, and surface gap candidates in the Flexivity admin console.
- Aurora PostgreSQL stores embeddings, 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
Presidio runs in the Flexivity AI cloud to scrub personally identifiable information from ticket content before it is sent to LLM APIs or stored long-term in embeddings. The Zendesk integration uses the same fai-scrubber package as the osTicket integration, with identical PII detection and replacement behavior.
Note: For the osTicket self-hosted agent mode, PII is scrubbed inside the customer’s network before any data leaves their environment. For Zendesk, PII scrubbing happens in the Flexivity AI cloud — there is no on-premise component. Customers who require on-prem PII scrubbing should use the osTicket integration.
For specifics on what PII categories Flexivity detects and how detected PII is replaced before reaching LLM APIs or embeddings, see Data Disclosures — Zendesk.
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 with PKCE)
- The Apps framework + Marketplace
- Standard REST APIs (Support, Help Center)
- Webhook subscriptions
- 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 at every level. Disconnecting from the Flexivity admin console removes the webhook subscription and revokes the OAuth grant; uninstalling the marketplace app removes the widget. After both actions, your Zendesk account returns to its pre-integration state.
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 |
| Data minimization | Reads only the data needed for active features; PII scrubbed before LLM and long-term storage |
| Help Center governance | Drafts only — no auto-publish; Zendesk’s existing publishing permissions and approval workflows are respected |
| Never undo human work | Audit-event check before every writeback; manual edits always win |
| Authentication | OAuth 2.0 with refresh token rotation; per-install JWT secret for widget-to-Flexivity calls |
| 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, webhook subscription removed, marketplace app independently uninstallable |
| 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.