Files
freshservice-claude/reference.md
spencerm 61c0b39e06 Improve ticket-filter guidance: agent_id lookup, status OR, workspace_id
list_tickets struggled to express 'assigned to me and not resolved/closed'.
Document that assignee filtering uses the numeric agent_id (resolve from email
via list_agents first) and that open statuses must be enumerated as
(status:2 OR status:3) since there's no negation. Add workspace_id passthrough
for multi-workspace accounts. Mirror the guidance in the skill reference.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 21:28:36 -06:00

87 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Freshservice API v2 reference
Base URL: `https://<domain>.freshservice.com/api/v2`. Auth is HTTP Basic with the
API key as username (handled by `scripts/fs.py`). Full docs: https://api.freshservice.com
## Codes
**Ticket status:** 2 Open · 3 Pending · 4 Resolved · 5 Closed
**Ticket priority:** 1 Low · 2 Medium · 3 High · 4 Urgent
**Ticket source:** 1 Email · 2 Portal · 3 Phone · 4 Chat · 5 Feedback widget ·
6 Yammer · 7 AWS CloudWatch · 8 PagerDuty · 9 Walkup · 10 Slack
Status/priority for changes use their own workflow codes; list a few existing
records to infer them, or read the ticket-fields / change-fields endpoints.
## Endpoints
| Resource | List | Create | View | Update | Delete |
|----------|------|--------|------|--------|--------|
| Tickets | `GET /tickets` | `POST /tickets` | `GET /tickets/{id}` | `PUT /tickets/{id}` | `DELETE /tickets/{id}` |
| Ticket filter | `GET /tickets/filter?query="..."` | — | — | — | — |
| Conversations | `GET /tickets/{id}/conversations` | reply: `POST /tickets/{id}/reply`; note: `POST /tickets/{id}/notes` | — | `PUT /conversations/{id}` | `DELETE /conversations/{id}` |
| Assets | `GET /assets` | `POST /assets` | `GET /assets/{display_id}` | `PUT /assets/{display_id}` | `DELETE /assets/{display_id}` |
| Agents | `GET /agents` | `POST /agents` | `GET /agents/{id}` | `PUT /agents/{id}` | — |
| Requesters | `GET /requesters` | `POST /requesters` | `GET /requesters/{id}` | `PUT /requesters/{id}` | — |
| Groups | `GET /groups` | `POST /groups` | `GET /groups/{id}` | `PUT /groups/{id}` | `DELETE /groups/{id}` |
| Departments | `GET /departments` | `POST /departments` | `GET /departments/{id}` | `PUT /departments/{id}` | `DELETE /departments/{id}` |
| Changes | `GET /changes` (+ `/changes/filter`) | `POST /changes` | `GET /changes/{id}` | `PUT /changes/{id}` | `DELETE /changes/{id}` |
| Problems | `GET /problems` | `POST /problems` | `GET /problems/{id}` | `PUT /problems/{id}` | `DELETE /problems/{id}` |
| Releases | `GET /releases` | `POST /releases` | `GET /releases/{id}` | `PUT /releases/{id}` | `DELETE /releases/{id}` |
| Current agent | `GET /agents/me` | — | — | — | — |
Other useful endpoints reachable the same way: `/solutions/categories`,
`/solutions/folders`, `/solutions/articles`, `/products`, `/vendors`,
`/ticket_fields`, `/tickets/{id}/time_entries`, `/canned_responses`.
## Ticket fields (create/update)
`subject`, `description` (HTML ok), `email` or `requester_id`, `priority`,
`status`, `source`, `group_id`, `responder_id` (assigned agent), `type`
(e.g. "Incident", "Service Request"), `tags` (array), `category`,
`sub_category`, `custom_fields` (object), `due_by`, `fr_due_by`.
Provide **either** `email` **or** `requester_id`. For a public reply the
requester is emailed; a note with `"private": true` is internal-only.
## Filter (query) syntax — /tickets/filter and /changes/filter
- Format: `field:value`, combined with `AND` / `OR`.
- Strings single-quoted: `tag:'vip'`. Numbers/dates bare or quoted.
- Operators on dates/numbers: `>`, `<`, e.g. `created_at:>'2026-01-01'`.
- Filterable ticket fields include: `status`, `priority`, `agent_id`,
`group_id`, `requester_id`, `type`, `source`, `tag`, `created_at`,
`updated_at`, `due_by`, plus custom fields by name.
- The whole expression must be URL-double-quoted; `scripts/fs.py` does this when
you pass `--param query=...` / `--param filter=...`.
Two common gotchas:
- **Assignee is `agent_id` (numeric), not an email.** Resolve an email to an id
first: `GET /agents?email=person@co.com` → read `id`, then filter on it.
- **No "not" operator for status.** "Open / unresolved / not closed" must be
enumerated: `(status:2 OR status:3)`. Parenthesize the OR group when AND-ing it.
Examples:
- `status:2 AND priority:3`
- `agent_id:0 AND status:2` — unassigned open tickets
- `agent_id:21000816864 AND (status:2 OR status:3)` — assigned to an agent, still open
- `type:'Incident' AND created_at:>'2026-06-01'`
Multi-workspace accounts: `/tickets/filter` searches one workspace by default.
Pass `--param workspace_id=<id>` to target another (an agent's `workspace_ids`
lists which ones they're in).
## Listing vs. filtering
- `GET /tickets` supports `filter` presets (`new_and_my_open`, `watching`,
`spam`, `deleted`), `updated_since`, `order_by`, `order_type`, `page`,
`per_page` (max 100), and `include` (`conversations`, `requester`, `stats`).
- `GET /tickets/filter?query="..."` is for ad-hoc field queries (also 100/page).
## Pagination & rate limits
- 30 results/page default, 100 max via `per_page`. `scripts/fs.py` surfaces
`next_page` when a next-page Link header is present.
- Per-plan minute limits (100500/min). Responses include
`rate_limit_remaining`.