Back to Support Ticket Triage & Routing

Integration and API Spec

The reference during the build: every tool connection, auth scope, field mapping, and error-handling rule.

4 pagesPDF · Technical
FS-DOC-05Technical

Integration and API Spec

Support Ticket Triage and Routing

[YourCompany.com] · Customer Support Department · Prepared by FullSpec · [Today's Date]

This document specifies every integration point, credential requirement, field mapping, and error behaviour needed to build and operate the Support Ticket Triage and Routing automation. It is written for the FullSpec build team and covers Zendesk, HubSpot, Slack, Gmail, Notion, and the orchestration layer. Each section provides exact scope strings, payload structures, rate-limit calculations, and defined failure responses so that no integration decision is left ambiguous during build.

01Tool inventory

Tool
Role in automation
Auth method
Min plan required
Used by agent(s)
Zendesk
Helpdesk: ticket trigger source, field write target, assignee update, internal note creation
OAuth 2.0 / API token
Suite Team ($55/mo)
Agent 1 (Ticket Classification), Agent 2 (Routing and Notification)
HubSpot
CRM: customer record lookup by email, returns plan tier, account status, recent ticket history
OAuth 2.0 (Private App token)
Free CRM (contacts API included)
Agent 1 (Ticket Classification)
Slack
Messaging: sends direct message to assigned agent with ticket details and link
OAuth 2.0 (Bot token)
Free tier sufficient
Agent 2 (Routing and Notification)
Gmail
Email: sends personalised acknowledgement to customer on ticket receipt
OAuth 2.0 (service account or user delegation)
Google Workspace (any tier)
Agent 2 (Routing and Notification)
Notion
Documentation: routing rules database read at runtime to resolve category-to-agent mappings
Notion Internal Integration token
Free tier sufficient
Agent 2 (Routing and Notification)
Orchestration layer
Workflow automation platform: hosts both agent workflows, manages credential store, handles retries and error routing
Platform-managed (internal)
Paid plan with webhook support
All agents
Before you connect anything: all integrations must be validated against sandbox or staging environments before production credentials are loaded. Create a Zendesk sandbox, a HubSpot developer account, a Slack test workspace, and a Gmail test account. Test every connection end-to-end in that environment and confirm data writes are correct before switching to production credentials. This prevents live tickets from being modified or mis-assigned during build.

02Per-tool integration detail

Zendesk

Primary data source and write target. The workflow triggers on new ticket creation via Zendesk webhook. The automation reads ticket subject, body, requester email, and channel, then writes category tag, priority, assignee, and internal note back to the ticket record. All field writes use the Zendesk Tickets API v2.

Auth method
OAuth 2.0 using an API token scoped to a dedicated service account. Store token in credential store as ZENDESK_API_TOKEN. Base URL format: https://{subdomain}.zendesk.com/api/v2/. Store subdomain as ZENDESK_SUBDOMAIN.
Required scopes
tickets:read, tickets:write, users:read, webhooks:write, triggers:write, tags:read, tags:write
Webhook / trigger setup
Create a Zendesk Trigger: Condition = ticket is created AND status is new. Action = notify active webhook. Webhook endpoint = orchestration layer inbound URL. Payload must include: ticket.id, ticket.subject, ticket.description, ticket.requester.email, ticket.channel, ticket.created_at. Enable HMAC-SHA256 signature validation on the webhook. Store the signing secret as ZENDESK_WEBHOOK_SECRET. The orchestration layer must verify the X-Zendesk-Webhook-Signature header on every inbound request before processing.
Required configuration
Custom ticket fields must be created in Zendesk Admin before build: 'triage_category' (dropdown, values: billing, technical, account_access, general_enquiry, other), 'triage_priority_override' (text), 'classification_confidence' (decimal). Field IDs must be stored as ZENDESK_FIELD_ID_CATEGORY, ZENDESK_FIELD_ID_CONFIDENCE in the credential store. Do not hardcode field IDs.
Rate limits
Zendesk Suite Team: 700 requests/minute per account. At ~180 tickets/month (approximately 6 tickets/day, peak estimate 20/day), the automation generates at most 5 API calls per ticket (read + 3 writes + tag update) = 100 calls/day peak. This is well within limits. No throttling logic required at current volume, but implement a 429 retry with exponential backoff as a precaution.
Constraints
Webhook payload does not include ticket comments added after creation. If a requester submits a follow-up within seconds of creation, the classification agent sees only the initial body. The internal note write (POST /tickets/{id}.json with comment.public: false) counts against the same rate limit. Assignee field accepts agent numeric ID only; map agent names to IDs at runtime using the AGENT_ROUTING_MAP stored in the credential store.
// Inbound webhook payload (abbreviated)
{
  "ticket": {
    "id": 98231,
    "subject": "Cannot log into my account",
    "description": "I have been locked out since yesterday...",
    "requester": { "email": "customer@example.com" },
    "channel": "email",
    "created_at": "2024-05-13T09:14:22Z"
  }
}

// Write-back PATCH /api/v2/tickets/{id}.json
{
  "ticket": {
    "priority": "high",
    "assignee_id": 4420193,
    "custom_fields": [
      { "id": "{{ZENDESK_FIELD_ID_CATEGORY}}", "value": "account_access" },
      { "id": "{{ZENDESK_FIELD_ID_CONFIDENCE}}", "value": 0.91 }
    ],
    "comment": { "body": "[Auto-note] Category: account_access | Priority: high | Plan: Pro | Open tickets: 2", "public": false }
  }
}
HubSpot

CRM lookup used by the Ticket Classification Agent to enrich each ticket with customer plan tier, account status, and recent ticket count before classification runs. Read-only access required. No writes to HubSpot.

Auth method
HubSpot Private App token. Create a Private App in HubSpot Settings > Integrations > Private Apps. Store token as HUBSPOT_PRIVATE_APP_TOKEN. Do not use legacy API keys (deprecated).
Required scopes
crm.objects.contacts.read, crm.objects.companies.read, tickets.read (read-only; no write scopes needed)
Webhook / trigger setup
No inbound webhook from HubSpot. The orchestration layer issues a GET request to the Contacts API after receiving the Zendesk webhook. Lookup key is the requester email address.
Required configuration
The HubSpot contact property names for plan tier and account status must be confirmed against the live HubSpot property schema before build. Store the exact internal property names as HUBSPOT_PROP_PLAN_TIER and HUBSPOT_PROP_ACCOUNT_STATUS in the credential store. Do not hardcode. If no matching contact is found, the agent must proceed with a 'unknown' account context value rather than halting.
Rate limits
HubSpot Free CRM: 100 requests/10 seconds, 250,000 requests/day. At peak volume the automation issues 1 contact lookup per ticket. 20 tickets/day = 20 requests/day. No throttling required. Burst protection is not needed at this volume.
Constraints
Lookup by email is case-sensitive in some HubSpot configurations. Normalise the requester email to lowercase before the API call. If the contact has multiple records with the same email, the API returns the most recently updated record. Document this behaviour in the runbook so the team lead is aware.
// GET /crm/v3/objects/contacts/search
{
  "filterGroups": [{
    "filters": [{
      "propertyName": "email",
      "operator": "EQ",
      "value": "customer@example.com"
    }]
  }],
  "properties": ["firstname", "lastname", "email", "{{HUBSPOT_PROP_PLAN_TIER}}", "{{HUBSPOT_PROP_ACCOUNT_STATUS}}", "hs_ticket_count"]
}

// Response (relevant fields extracted)
{
  "results": [{
    "id": "551839204",
    "properties": {
      "email": "customer@example.com",
      "plan_tier": "pro",
      "account_status": "active",
      "hs_ticket_count": "2"
    }
  }]
}
Slack

Used by the Routing and Notification Agent to send a direct message to the assigned support agent immediately after the ticket is assigned in Zendesk. The message includes ticket number, category, priority, and a direct deep-link to the ticket.

Auth method
OAuth 2.0 Bot token. Install a Slack app to the workspace with bot scopes. Store the bot token as SLACK_BOT_TOKEN. Store the Slack workspace ID as SLACK_WORKSPACE_ID.
Required scopes
chat:write, users:read, users:read.email (required to resolve agent Zendesk email to Slack user ID at runtime)
Webhook / trigger setup
No inbound webhook from Slack. The orchestration layer calls the Slack Web API (chat.postMessage) after the Zendesk assignee field is confirmed written. Agent email-to-Slack-user-ID resolution uses users.lookupByEmail called once per run. Cache the result within the run to avoid a second API call.
Required configuration
Store the support team's Slack user IDs mapped to their Zendesk agent IDs in the AGENT_SLACK_MAP credential (JSON object). This avoids a live users.lookupByEmail call for every ticket if email resolution is unreliable. The Slack app must be added to any private channel the team uses for alerts. The deep-link URL format for Zendesk tickets is: https://{subdomain}.zendesk.com/agent/tickets/{ticket_id}.
Rate limits
Slack Web API Tier 3: 50 requests/minute for chat.postMessage. At peak 20 tickets/day the automation sends at most 20 messages/day. No throttling required. Implement a 429 retry with 60-second wait.
Constraints
Slack DMs can only be sent to users who have installed or accepted the app. Ensure all support agents have accepted the app before go-live. If a user ID cannot be resolved, the automation must log the failure and fall back to posting to the SLACK_FALLBACK_CHANNEL stored in the credential store rather than failing silently.
// POST https://slack.com/api/chat.postMessage
{
  "channel": "U04AGENTSLACKID",
  "text": "New ticket assigned to you",
  "blocks": [
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": "*Ticket #98231 assigned*\nCategory: account_access | Priority: high\nCustomer: customer@example.com (Pro plan)\n<https://{subdomain}.zendesk.com/agent/tickets/98231|Open ticket>"
      }
    }
  ]
}
Gmail

Used by the Routing and Notification Agent to send a personalised acknowledgement email to the customer confirming ticket receipt, their ticket reference number, and an expected response window based on the assigned priority level.

Auth method
OAuth 2.0. For a shared support inbox, use Google Workspace service account with domain-wide delegation, or OAuth user token for the support@ address. Store credentials as GMAIL_CLIENT_ID, GMAIL_CLIENT_SECRET, GMAIL_REFRESH_TOKEN, GMAIL_SENDER_ADDRESS.
Required scopes
https://www.googleapis.com/auth/gmail.send (send-only; no read access required or granted)
Webhook / trigger setup
No inbound webhook from Gmail. The orchestration layer calls Gmail API (users.messages.send) after the Slack notification step confirms success. Sending is triggered by the automation only.
Required configuration
The acknowledgement email template must be stored as GMAIL_ACK_TEMPLATE in the credential store (or a Notion page ID referenced as NOTION_ACK_TEMPLATE_PAGE_ID). Template placeholders: {{customer_first_name}}, {{ticket_id}}, {{priority_response_window}}. The priority-to-response-window mapping must be defined: urgent=2 hours, high=4 hours, normal=1 business day, low=2 business days. Store this map as PRIORITY_RESPONSE_MAP. Sender display name must be configured on the Gmail account itself, not in the API call.
Rate limits
Gmail API: 250 quota units/user/second; users.messages.send costs 100 units. Effective rate: 2.5 sends/second per user. At 20 tickets/day the automation is well within limits. No throttling needed. Daily sending limit is 2,000 messages for Google Workspace accounts.
Constraints
Email must be sent as plain text with an HTML alternative. Do not attach files. The customer reply-to address must be the Zendesk ticket email address (not the Gmail sender address) so replies route back into Zendesk correctly. Set the Reply-To header to the Zendesk ticket email: {ticket_id}@{subdomain}.zendesk.com.
// Gmail API message body (base64-encoded MIME, shown decoded)
From: Support <support@yourcompany.com>
To: customer@example.com
Reply-To: 98231@yoursubdomain.zendesk.com
Subject: We received your request [Ticket #98231]
Content-Type: text/plain

Hi {{customer_first_name}},

Thanks for reaching out. We have received your request and assigned it
ticket reference #98231. Based on the priority of your issue, you can
expect a response within {{priority_response_window}}.

Best regards,
The Support Team
Notion

Read-only runtime reference for the routing rules database. The Routing and Notification Agent queries a Notion database page to resolve ticket category and priority to the correct Zendesk agent ID. Notion stores the human-maintained routing table so routing rules can be updated by the team lead without a code change.

Auth method
Notion Internal Integration token. Create an integration in Notion Settings > Connections > Develop or manage integrations. Share the routing rules database page with the integration. Store the token as NOTION_INTEGRATION_TOKEN and the database ID as NOTION_ROUTING_RULES_DB_ID.
Required scopes
read_content (read access to the shared database page; no insert, update, or delete permissions granted to the integration)
Webhook / trigger setup
No webhook. The orchestration layer queries the Notion Database API (POST /v1/databases/{database_id}/query) at the start of each Routing and Notification Agent run to retrieve the current routing table. Cache the result for the duration of the run. Do not call Notion per-ticket to avoid unnecessary API calls.
Required configuration
The Notion routing rules database must have the following columns before build: Category (select), Priority (select), Zendesk Agent ID (number), Escalate to Human (checkbox). The team lead is responsible for keeping this table up to date. The database ID must not be hardcoded; store as NOTION_ROUTING_RULES_DB_ID.
Rate limits
Notion API: 3 requests/second average. One database query per workflow run. At 20 runs/day, this is negligible. No throttling required.
Constraints
If the Notion API is unavailable or the query returns no matching row for a category/priority combination, the automation must not assign the ticket. It must route to the human review queue (set Zendesk assignee to ZENDESK_FALLBACK_AGENT_ID) and log the missing rule. The team lead must be notified via SLACK_FALLBACK_CHANNEL.
// POST /v1/databases/{{NOTION_ROUTING_RULES_DB_ID}}/query
{
  "filter": {
    "and": [
      { "property": "Category", "select": { "equals": "account_access" } },
      { "property": "Priority", "select": { "equals": "high" } }
    ]
  }
}

// Response (relevant fields)
{
  "results": [{
    "properties": {
      "Zendesk Agent ID": { "number": 4420193 },
      "Escalate to Human": { "checkbox": false }
    }
  }]
}
Integration and API SpecPage 1 of 3
FS-DOC-05Technical

03Field mappings between tools

The tables below define every field transferred between tools across both agent handoffs. Use the exact field names shown; these are the names the orchestration layer must reference in its mapping configuration. Monospace names reflect API property identifiers, not display labels.

Handoff 1: Zendesk trigger to Ticket Classification Agent (inbound webhook payload to classification logic)

Source tool
Source field
Destination tool
Destination field
Zendesk
`ticket.id`
Classification Agent
`ticket_id`
Zendesk
`ticket.subject`
Classification Agent
`ticket_subject`
Zendesk
`ticket.description`
Classification Agent
`ticket_body`
Zendesk
`ticket.requester.email`
Classification Agent
`requester_email`
Zendesk
`ticket.via.channel`
Classification Agent
`inbound_channel`
Zendesk
`ticket.created_at`
Classification Agent
`ticket_created_at`

Handoff 2: HubSpot lookup response to Ticket Classification Agent (CRM enrichment merged into classification context)

Source tool
Source field
Destination tool
Destination field
HubSpot
`properties.{{HUBSPOT_PROP_PLAN_TIER}}`
Classification Agent
`customer_plan_tier`
HubSpot
`properties.{{HUBSPOT_PROP_ACCOUNT_STATUS}}`
Classification Agent
`customer_account_status`
HubSpot
`properties.hs_ticket_count`
Classification Agent
`customer_open_ticket_count`
HubSpot
`properties.firstname`
Classification Agent
`customer_first_name`
HubSpot
`id`
Classification Agent
`hubspot_contact_id`

Handoff 3: Classification Agent output to Zendesk write-back (ticket field update and internal note)

Source tool
Source field
Destination tool
Destination field
Classification Agent
`classification.category`
Zendesk
`ticket.custom_fields[ZENDESK_FIELD_ID_CATEGORY].value`
Classification Agent
`classification.priority`
Zendesk
`ticket.priority`
Classification Agent
`classification.confidence_score`
Zendesk
`ticket.custom_fields[ZENDESK_FIELD_ID_CONFIDENCE].value`
Classification Agent
`classification.category`
Zendesk
`ticket.tags[]`
Classification Agent
`routing.zendesk_agent_id`
Zendesk
`ticket.assignee_id`
Classification Agent
`internal_note_body`
Zendesk
`ticket.comment.body` (public: false)

Handoff 4: Routing and Notification Agent to Slack (agent DM)

Source tool
Source field
Destination tool
Destination field
Zendesk (confirmed write)
`ticket.id`
Slack
`blocks[].text` (ticket reference)
Classification Agent
`classification.category`
Slack
`blocks[].text` (category label)
Classification Agent
`classification.priority`
Slack
`blocks[].text` (priority label)
HubSpot
`customer_plan_tier`
Slack
`blocks[].text` (plan tier context)
AGENT_SLACK_MAP
`slack_user_id` (resolved from assignee_id)
Slack
`channel`
Zendesk
`ticket.id` + ZENDESK_SUBDOMAIN
Slack
`blocks[].url` (deep-link)

Handoff 5: Routing and Notification Agent to Gmail (customer acknowledgement)

Source tool
Source field
Destination tool
Destination field
Zendesk
`ticket.requester.email`
Gmail
`To` header
Zendesk
`ticket.id`
Gmail
`Subject` header (ticket reference) and `Reply-To` header
HubSpot
`customer_first_name`
Gmail
`{{customer_first_name}}` template placeholder
Zendesk
`ticket.id`
Gmail
`{{ticket_id}}` template placeholder
PRIORITY_RESPONSE_MAP
`classification.priority` resolved to window string
Gmail
`{{priority_response_window}}` template placeholder

04Build stack and orchestration

Orchestration layout
Two discrete workflows, one per agent: 'Ticket Classification Agent' workflow and 'Routing and Notification Agent' workflow. Both workflows share a single credential store. The Classification Agent workflow terminates by publishing a structured payload to an internal queue or variable store that the Routing Agent workflow reads as its trigger input. Neither workflow is monolithic; they are linked sequentially via this handoff payload.
Credential store
All secrets, IDs, and configuration values are stored in the orchestration platform's native encrypted credential store. No credential is hardcoded in any node or workflow step. Environment: production credentials are separate from sandbox credentials and must be swapped explicitly at go-live.
Agent 1 trigger mechanism
Webhook (push). Zendesk posts to the orchestration layer's inbound webhook URL the moment a new ticket is created. The orchestration layer validates the HMAC-SHA256 signature using ZENDESK_WEBHOOK_SECRET before any processing begins. Invalid signatures must return HTTP 401 and halt execution immediately.
Agent 2 trigger mechanism
Internal event (chained). Agent 2 is triggered by the successful completion of Agent 1, receiving the structured classification output as its input payload. There is no external webhook for Agent 2. If Agent 1 fails, Agent 2 must not fire.
Human review path trigger
Poll or conditional branch (internal). If the classification confidence score is below the defined threshold (stored as CLASSIFICATION_CONFIDENCE_THRESHOLD, default 0.80), the workflow routes to a Zendesk update that assigns the ticket to ZENDESK_FALLBACK_AGENT_ID and tags it 'manual_review'. No Slack DM or Gmail send fires on this path until a human confirms the classification.
Notion routing table cache
The Notion routing rules database is queried once per Agent 2 workflow run (not per ticket step). The result is held in a runtime variable for the duration of the run. If a run processes a single ticket (standard case), there is one Notion API call per ticket. If batching is introduced later, cache the table for the batch duration.
Retry configuration
All HTTP calls use a maximum of 3 retry attempts with exponential backoff: 5 seconds, 30 seconds, 120 seconds. After 3 failures the step is marked as failed and the error handler fires. No silent failures permitted anywhere in either workflow.

The following code block defines the complete credential store contents. Every key listed here must be populated before either workflow is activated in production.

Credential store: populate all keys in the orchestration platform's encrypted secrets manager before production go-live
// Credential store: all keys required before production activation

// Zendesk
ZENDESK_API_TOKEN           = "<Zendesk API token for service account>"
ZENDESK_SUBDOMAIN           = "<yourcompany>"
ZENDESK_WEBHOOK_SECRET      = "<HMAC-SHA256 signing secret from Zendesk webhook settings>"
ZENDESK_FIELD_ID_CATEGORY   = "<numeric custom field ID for triage_category>"
ZENDESK_FIELD_ID_CONFIDENCE = "<numeric custom field ID for classification_confidence>"
ZENDESK_FALLBACK_AGENT_ID   = "<numeric Zendesk agent ID for manual review queue owner>"
AGENT_ROUTING_MAP           = "<JSON object: { zendesk_agent_id: name }>"

// HubSpot
HUBSPOT_PRIVATE_APP_TOKEN   = "<HubSpot Private App token>"
HUBSPOT_PROP_PLAN_TIER      = "<internal HubSpot property name for plan tier>"
HUBSPOT_PROP_ACCOUNT_STATUS = "<internal HubSpot property name for account status>"

// Slack
SLACK_BOT_TOKEN             = "<xoxb- Slack bot token>"
SLACK_WORKSPACE_ID          = "<T-prefixed Slack workspace ID>"
SLACK_FALLBACK_CHANNEL      = "<#channel-id for fallback and error alerts>"
AGENT_SLACK_MAP             = "<JSON object: { zendesk_agent_id: slack_user_id }>"

// Gmail
GMAIL_CLIENT_ID             = "<OAuth 2.0 client ID>"
GMAIL_CLIENT_SECRET         = "<OAuth 2.0 client secret>"
GMAIL_REFRESH_TOKEN         = "<OAuth 2.0 refresh token for support@ account>"
GMAIL_SENDER_ADDRESS        = "support@[YourCompany.com]"

// Notion
NOTION_INTEGRATION_TOKEN    = "<secret_xxx Notion internal integration token>"
NOTION_ROUTING_RULES_DB_ID  = "<32-character Notion database ID>"
NOTION_ACK_TEMPLATE_PAGE_ID = "<Notion page ID for acknowledgement email template>"

// Shared configuration
CLASSIFICATION_CONFIDENCE_THRESHOLD = 0.80
PRIORITY_RESPONSE_MAP       = "{ urgent: '2 hours', high: '4 hours', normal: '1 business day', low: '2 business days' }"
Integration and API SpecPage 2 of 3
FS-DOC-05Technical

05Error handling and retry logic

Every integration point has a defined failure behaviour. Unhandled exceptions must never fail silently. Where automation cannot proceed, the ticket must be routed to the human review queue and an alert posted to SLACK_FALLBACK_CHANNEL. The table below covers all failure scenarios across both agent workflows.

Integration
Scenario
Required behaviour
Zendesk webhook inbound
Signature validation fails (HMAC mismatch or missing header)
Return HTTP 401 immediately. Do not process payload. Log the raw headers. Post alert to SLACK_FALLBACK_CHANNEL. Do not retry; this is a security event, not a transient error.
Zendesk webhook inbound
Webhook payload missing required fields (ticket.id, ticket.description, or requester.email absent)
Halt workflow. Log missing fields. Attempt to fetch full ticket via GET /tickets/{id} if ticket.id is present. If ticket.id is also absent, post to SLACK_FALLBACK_CHANNEL and discard run.
HubSpot contact lookup
No contact record found for requester email
Do not halt. Set customer_plan_tier = 'unknown', customer_account_status = 'unknown', customer_open_ticket_count = 0. Proceed with classification using ticket body only. Log the lookup miss for monitoring.
HubSpot contact lookup
HubSpot API returns 429 (rate limit) or 5xx error
Retry up to 3 times with exponential backoff: 5s, 30s, 120s. If all retries fail, proceed with unknown account context (same as no-record path) and log the failure. Do not halt the workflow for a CRM enrichment failure.
Classification Agent
Confidence score below CLASSIFICATION_CONFIDENCE_THRESHOLD (default 0.80)
Do not auto-assign. Write classification attempt to Zendesk internal note with confidence score. Assign ticket to ZENDESK_FALLBACK_AGENT_ID. Tag ticket 'manual_review'. Post to SLACK_FALLBACK_CHANNEL with ticket link. Stop Agent 2 execution for this ticket.
Zendesk ticket field write (PATCH)
Zendesk API returns 422 (invalid field value, e.g. unrecognised category string)
Log the invalid value and the field ID. Post alert to SLACK_FALLBACK_CHANNEL. Assign ticket to ZENDESK_FALLBACK_AGENT_ID for manual field completion. Do not retry with the same value.
Zendesk ticket field write (PATCH)
Zendesk API returns 429 or 5xx
Retry up to 3 times with backoff: 5s, 30s, 120s. If all retries fail, route to ZENDESK_FALLBACK_AGENT_ID, log failure, post to SLACK_FALLBACK_CHANNEL. The ticket must not remain unassigned.
Notion routing rules query
Notion API unavailable or query returns zero matching rows for the category and priority combination
Do not assign the ticket. Route to ZENDESK_FALLBACK_AGENT_ID. Tag ticket 'routing_rule_missing'. Post to SLACK_FALLBACK_CHANNEL identifying the missing rule combination. Log for the team lead to add the rule to the Notion database.
Slack agent notification (chat.postMessage)
Slack user ID cannot be resolved for the assigned agent
Post the notification to SLACK_FALLBACK_CHANNEL instead of the DM, tagging the agent by name if possible. Log the resolution failure. Do not halt or revert the Zendesk assignment. The ticket remains assigned; only the notification path changes.
Slack agent notification (chat.postMessage)
Slack API returns 429 or 5xx
Retry up to 3 times with backoff: 5s, 30s, 120s. If all retries fail, log failure and continue to the Gmail step. The Zendesk assignment is already written. Post a summary failure alert to SLACK_FALLBACK_CHANNEL if the channel itself is reachable.
Gmail acknowledgement send
Gmail OAuth token expired or refresh fails
Attempt token refresh using GMAIL_REFRESH_TOKEN. If refresh fails, log the error and post to SLACK_FALLBACK_CHANNEL. Do not send the acknowledgement without a valid token. Queue the send for retry after 10 minutes (one retry only). If the second attempt fails, flag the ticket in Zendesk with tag 'ack_email_failed' for manual follow-up.
Gmail acknowledgement send
Template placeholder not resolved (e.g. customer_first_name is null)
Substitute empty string for missing first name (salutation becomes 'Hi,' not 'Hi null,'). All other placeholders must resolve; if ticket_id is missing, halt the send and flag the ticket with 'ack_email_failed'. Log the specific missing placeholder.
Global rule: no step in either workflow may fail silently. Every exception, whether a network timeout, a missing field, an API error, or a logic branch with no matching rule, must produce a log entry and either a SLACK_FALLBACK_CHANNEL alert or a Zendesk tag (or both). The FullSpec team will configure centralised error logging in the orchestration platform's execution history, and review error rates during the parallel-run week before go-live. Contact support@gofullspec.com if any error scenario arises that is not covered by the table above.
Integration and API SpecPage 3 of 3

More documents for this process

Every document generated for Support Ticket Triage & Routing.

Launch Plan
Operations · Owner
View
ROI and Business Case
Finance · Owner
View
Process Runbook / SOP
Operations · Owner
View
Developer Handover Pack
Technical · Developer
View
Test and QA Plan
Quality · Developer
View