Freshdesk Integration for Open Ticket AI: On-Premise AI Classification via REST API
Integrate self-hosted Open Ticket AI with Freshdesk using custom plugins. Automate ticket routing, priority assignment, and queue classification via REST API.
Freshdesk Integration for Open Ticket AI
Open Ticket AI (OTAI) runs fully on-premise and classifies support tickets into queues, priorities and custom categories. To integrate OTAI with Freshdesk, you create a small plugin that provides a FreshdeskTicketsystemService. OTAI loads this service automatically and uses it to read and update tickets through the Freshdesk REST API.
Architecture
A ticket system integration in OTAI always follows the same pattern:
- separate plugin package (
otai_freshdesk) - a
FreshdeskTicketsystemService(Injectable) - a
FreshdeskPluginregistering the service - configuration in
config.yml - OTAI calls the service at the end of the pipeline and writes AI results back to Freshdesk
This is identical to how otai_zammad works.
Plugin Structure (otai_freshdesk)
otai_freshdesk/src/otai_freshdesk/freshdesk_ticket_system_service.pyplugin.pypyproject.tomlfreshdesk_ticket_system_service.py
from typing import Anyimport aiohttp
from open_ticket_ai import Injectablefrom open_ticket_ai.core.ticket_system_services import TicketSystemService
class FreshdeskTicketsystemService(TicketSystemService): async def _request(self, method: str, path: str, **kwargs) -> Any: base = f"https://{self.params.domain}.freshdesk.com/api/v2" auth = aiohttp.BasicAuth(self.params.api_key, "X") url = f"{base}{path}" async with aiohttp.ClientSession(auth=auth) as session: async with session.request(method, url, **kwargs) as resp: return await resp.json()
async def find_tickets(self, query: dict) -> list[dict]: return await self._request("GET", "/tickets", params=query)
async def find_first_ticket(self, query: dict) -> dict | None: tickets = await self.find_tickets(query) return tickets[0] if tickets else None
async def update_ticket(self, ticket_id: str, data: dict) -> dict: return await self._request("PUT", f"/tickets/{ticket_id}", json=data)plugin.py
from open_ticket_ai import Plugin, Injectable
from otai_freshdesk.freshdesk_ticket_system_service import FreshdeskTicketsystemService
class FreshdeskPlugin(Plugin): def _get_all_injectables(self) -> list[type[Injectable]]: return [ FreshdeskTicketsystemService, ]Configuration
Add this to your OTAI config.yml:
ticket_systems: freshdesk: use: otai_freshdesk:FreshdeskTicketsystemService params: domain: yourcompany api_key: YOUR_FRESHDESK_API_KEYOTAI discovers your plugin automatically through your pyproject.toml:
[project.entry-points."otai.plugins"]otai_freshdesk = "otai_freshdesk.plugin:FreshdeskPlugin"How the Integration Works
- OTAI fetches tickets from Freshdesk (
find_tickets) - AI assigns queue, priority, or custom labels
- OTAI calls
update_ticket(...) - Freshdesk updates the ticket instantly through its API
Everything runs on-premise. Freshdesk authentication uses basic auth with your API key.
Benefits
- full data control (OTAI remains local)
- seamless use of Freshdesk UI and workflows
- AI-driven routing without Freshdesk’s proprietary AI
- clean plugin architecture identical to Zammad / OTOBO / Znuny
