Freshdesk Integration
Keep Freshdesk as your system of record. AscendCore becomes the approval-gated system of action on top: tickets flow in, a human approves in Slack or Teams, the runbook executes, and the decision is written back to the ticket as a private note. No migration.
In one sentence
A Freshdesk Automations rule POSTs new tickets to AscendCore, where the ticket is AI-classified into a runbook, held for explicit human approval, executed against your identity stack, and the outcome lands back on the originating ticket as a private note with an audit-chain reference.
Freshdesk and Freshservice are separate Freshworks products with separate accounts. This guide is for Freshdesk (yourcompany.freshdesk.com). If your service desk runs on Freshservice, use the Freshservice guide instead.
How a ticket flows
- Ingest. Your Automations rule POSTs the ticket number to
POST /api/v1/tickets/ingestwith a scoped API key. AscendCore then reads the ticket's subject, description, and requester from your Freshdesk with the key you connected. One ticket is ingested at most once: retries and rule re-fires return the original run instead of posting a second card. - Classify. AscendCore classifies the ticket text into a runbook intent with a confidence score. Low-confidence or unrecognized tickets are received, audit-logged, and left alone (
no_action). Nothing executes on a guess. - Approve. The matching runbook's approval is staged where your organization's approval routing says: a card in your Slack or Teams admin channel, with the originating ticket number, a link back to it, and the AI's classification and confidence; or the approval queue in the admin portal, with approvers emailed. A human approves or denies. Every runbook is approval-gated. There is no autonomous path.
- Execute. On approval, the runbook runs against your stack (Okta, Entra ID, M365) and the action is recorded on the org's tamper-evident SHA-256 audit chain.
- Write back. The decision (approved or denied, by whom, at what time) is added to the originating ticket as a private note. Your helpdesk keeps the complete story.
Step 1: Connect Freshdesk
In the admin portal under Integrations, open Freshdesk and enter:
- Base URL: your account address,
https://yourcompany.freshdesk.com. Use the freshdesk.com address even if your support portal has a custom domain: the Freshdesk API answers there. - API key: the key of the Freshdesk agent AscendCore acts as, found under Profile settings. Least privilege applies: the agent needs to view tickets and add private notes. A dedicated agent for the integration keeps the notes from appearing under a person's name.
Save & verify stores the key in your organization's encrypted vault and reads one ticket to prove the key works. The key is never shown again, and it is used only for your organization. Adding a note is not tested by Verify, because that would change a ticket.
Step 2: Create a scoped AscendCore API key
In the admin portal under API & Webhooks, create a key with only the ticket:ingest scope. The form ticks audit:read and runbook:read by default, so untick them first. The key is shown once, so have the Freshdesk rule open before you create it. A key with only this scope can submit tickets but cannot execute runbooks directly, read audit rows, or browse the catalog.
You will paste this key into the rule's webhook headers in the next step. It is stored inside the rule, visible only to Freshdesk admins who can edit automations.
Step 3: Add the Automations rule
In Admin, then Workflows, then Automations, open the Ticket Creation tab and create a new rule:
- Conditions: match the tickets you want routed to AscendCore (for example, a group, type, or tag). Freshdesk needs at least one condition before it saves the rule.
- Action: Trigger webhook, with:
- Request type: POST (Freshdesk defaults to GET, so change it)
- URL:
https://ascendcore.ai/api/v1/tickets/ingest - Authentication: leave Requires authentication off, and enter the custom headers as JSON:
{ "Authorization": "Bearer ak_live_..." }. AscendCore only accepts the Bearer form. - Encoding: JSON, with Content set to Advanced, and the body below
{
"source": "freshdesk",
"ticket": {
"ticketId": "{{ticket.id}}"
}
}Only the ticket number is sent. Placeholder values are inserted into the body as they are, so a quote or a line break in a subject or description could make the body invalid JSON. AscendCore reads those fields from your Freshdesk instead, which also means a request can only refer to a ticket that exists in your account. Raise a test ticket to confirm a 200 before relying on the rule.
Payload reference
| Field | Required | Purpose |
|---|---|---|
source | Yes | Must be "freshdesk" for this integration. |
ticket.ticketId | Yes | Ticket number (string or number, #42 is accepted). Idempotency key and write-back target. |
ticket.subject | Only without a connection | Primary classification input. Read from Freshdesk when it is connected. |
ticket.description | No | Appended to the classification input. Read from Freshdesk when it is connected. |
ticket.url | No | Link back to the ticket, shown to the approver. Built from your connected address when Freshdesk is connected. |
ticket.requesterEmail | No | Target-user fallback when the ticket text names nobody else. Read from Freshdesk when it is connected. |
The supported intents are the same as for every ticket source; see the Freshservice guide for the current list. Tickets that classify to anything else are acknowledged with no_action and audit-logged.
What the write-back looks like
When the approval reaches a decision (from Slack, Teams, or the dashboard), AscendCore adds a private note to the originating ticket:
[AscendCore] Runbook decision: APPROVED
Runbook: Account Unlock
Target user: Sarah Chen (sarah.chen@acme.com)
Decision by: teams:approver@acme.com at 2026-10-27T15:42:11.310Z
Completed. The action ran after explicit human approval.
AscendCore run: unlock_1793115731_310000
This decision is recorded on the org's tamper-evident audit chain in AscendCore.Denied requests get a note too, stating that no changes were made. If the run only partly finished, was stopped by a safety check, or failed, the note says so; it never claims an action that did not run. The note is private (visible to agents, not the requester). The write-back is deliberately non-blocking: if Freshdesk is unreachable, the approval flow itself is unaffected and the decision remains on the AscendCore audit chain.
Limits and troubleshooting
- Freshdesk plans. The webhook action in Automations and API access depend on your Freshdesk plan. Check that yours includes Trigger webhook before you build the rule.
- API rate limits. Freshdesk limits API calls per account per minute, shared with your other integrations. When Freshdesk asks AscendCore to slow down for a few seconds, it waits and tries once more; otherwise the note is skipped and the decision stays on the audit chain.
- Repeat deliveries. A ticket AscendCore already took returns the original run, so no second card is posted.
400 invalid_payload: the body was not valid JSON or had no ticket number. Use the body above, with no free-text placeholders.422 ticket_not_found: the connected Freshdesk account has no ticket with that number. Check that the rule and the connection point at the same account.503 itsm_unavailable: Freshdesk could not be reached to read the ticket. Send it again once Freshdesk is reachable.
Security model
- Scoped bearer auth. The integration reuses AscendCore's standard API-key model. Keys are salted-hashed at rest, scope-gated, rate-limited, and revocable from the dashboard.
- Approval-gated, always. Ingested tickets follow the same human-in-the-loop policy as every other trigger. AI classifies; it never executes.
- Audit-chained. Every ingestion (including no-action dispositions) and every decision is recorded on the org's tamper-evident SHA-256 audit chain.
- Sandbox-aware. If your org is in Sandbox Mode, ingested tickets exercise the full approval flow with simulated execution. The note on the ticket is labeled
[AscendCore Sandbox], says nothing was changed in your identity systems, and is written only through the Freshdesk connection your org added itself.
Full API reference
The complete request/response contract for POST /api/v1/tickets/ingest lives in the OpenAPI reference.
