mobieusKnow mobieusCore API — mobieusHelp History #461
Author
Patrick Bass
Submitted
Jul 28, 2026 3:38pm
Reviewed
Jul 28, 2026 3:38pm
Summary
API reconciliation to 1.23.0 — full surface coverage, corrected plan gate, X-API-Version

mobieusCore API — mobieusHelp

Anchor change in this revision — one heading was renamed because it named a version the API left behind eight releases ago, and stated something untrue:

old new
#whats-not-in-130 #whats-not-in-the-api-yet

The Help surface of the public REST API. Read + write tickets, queues, agents, canned responses, tags, help topics, notification preferences, audit log. Plus 8 AI hooks for reply suggestions, summary, sentiment, categorization, resolution prediction, knowledge-gap detection, audit Q&A, and canned-response generation.

The ticket + queue + agent + reply endpoints landed in API 1.2.0; canned responses, tags, help topics, notification prefs, audit, and AI hooks were added in 1.3.0 (2026-06-02).

Scopes

Scope Grants
helpdesk:read List + read tickets, queues, agents, canned responses, tags, help topics, notification prefs, ticket messages. Also read-only AI hooks (summary, sentiment, resolution-predict).
helpdesk:write Create + update tickets, reply, change status, manage canned responses + tags. Write-side AI hooks (reply-suggest, categorize, canned-generate).
helpdesk:admin Notification-prefs set, audit log, admin-only AI hooks (knowledge-gaps, audit-qa).

Quick start

# Create a tag
curl -X POST https://YOUR-TENANT.mobieus.io/api/v1/helpdesk/tags \
  -H 'Authorization: Bearer mc_live_...' -H 'Content-Type: application/json' \
  -d '{"slug":"refund","name":"Refund","color":"#dc2626"}'

# Have AI summarize an open ticket
curl -X POST https://YOUR-TENANT.mobieus.io/api/v1/helpdesk/ai/summary \
  -H 'Authorization: Bearer mc_live_...' -H 'Content-Type: application/json' \
  -d '{"ticket_id":1234}'

Tickets, queues, agents (1.2.0, unchanged)

See the existing ticket / queue / agent / reply endpoints in api-overview. Nothing about those endpoints changed in 1.3.0 — they're already comprehensive.

Canned responses (1.3.0)

Method Path Scope
GET /api/v1/helpdesk/canned-responses helpdesk:read
GET /api/v1/helpdesk/canned-responses/{id} helpdesk:read
POST /api/v1/helpdesk/canned-responses helpdesk:write
POST /api/v1/helpdesk/canned-responses/{id} helpdesk:write
POST /api/v1/helpdesk/canned-responses/{id}/delete helpdesk:write

Bulk ticket actions

One action applied across up to 200 tickets. Each ticket routes through the same service a single-ticket call uses, so audit entries, SLA clocks and notifications fire per change.

Method Path Scope
POST /api/v1/helpdesk/tickets/bulk helpdesk:write
{ "ticket_ids": [1042, 1043, 1044], "action": "resolve" }

action is one of close, resolve, reopen, assign, unassign, move_queue. Use agent_id with assign, and queue_id with move_queue.

Partial success is the contract. A ticket that is missing, or whose transition is not legal from its current state, is counted in skipped and the batch carries on:

{ "data": { "action": "resolve", "requested": 3, "updated": 2, "skipped": 1 },
  "request_id": "req_…" }

Reconcile against requested / updated / skipped rather than assuming success. Ids beyond the first 200 are dropped silently, so page your own batches.

Body for create:

{
  "slug": "refund-policy",
  "title": "Refund policy",
  "body_md": "Hi {{requester.first_name}},

Our refund policy is 14 days. {{ticket.reference}} is within that window.

— Support",
  "queue_id": null,
  "is_active": true,
  "sort_order": 100
}

Placeholders are Mustache-style; the agent reply composer substitutes at insert time.

Tags (1.3.0)

| GET | /api/v1/helpdesk/tags | helpdesk:read | List. | | GET | /api/v1/helpdesk/tags/{id} | helpdesk:read | Get. | | POST | /api/v1/helpdesk/tags | helpdesk:write | Create. | | POST | /api/v1/helpdesk/tags/{id} | helpdesk:write | Update. | | POST | /api/v1/helpdesk/tags/{id}/delete | helpdesk:write | Delete (also removes from every ticket). |

Help topics (read-only, 1.3.0)

| GET | /api/v1/helpdesk/help-topics | helpdesk:read | List active topics with name, slug, queue_id. |

CRUD for help topics lives in the admin UI — topics carry custom- field definitions that don't translate cleanly to a simple REST body.

Notification preferences (1.3.0)

| GET | /api/v1/helpdesk/notification-prefs?scope=tenant_default&scope_id=0 | helpdesk:read | | POST | /api/v1/helpdesk/notification-prefs | helpdesk:admin |

Scopes: tenant_default / agent / requester. Body for set:

{
  "scope": "tenant_default",
  "scope_id": 0,
  "event_key": "ticket.created",
  "channel": "email",
  "enabled": true
}

Audit log (1.3.0)

| GET | /api/v1/helpdesk/audit?event_key=&actor_kind=&cursor=&limit= | helpdesk:admin |

Returns up to 200 events per page (default 50). event_key filters by event type; actor_kind is agent / requester / system / api.

AI hooks (1.3.0, BYOK Anthropic)

All 8 hooks route through your tenant's mobieusAI configuration — the same Anthropic key your tenant already configured for Community Manager. If no key is set, every hook returns {"ok": false, "error": "gate_blocked"} (HTTP 200, JSON envelope, no 500).

Operator-facing hooks

Method Path Scope Returns
POST /api/v1/helpdesk/ai/reply-suggest helpdesk:write ok + suggestions[] (3 reply drafts)
POST /api/v1/helpdesk/ai/summary helpdesk:read ok + text (Problem / Tried / Done / Next-step)
POST /api/v1/helpdesk/ai/categorize helpdesk:write ok + data { help_topic_id, queue_id, confidence, reasoning }
POST /api/v1/helpdesk/ai/sentiment helpdesk:read ok + data { overall, confidence, signals[] }
POST /api/v1/helpdesk/ai/resolution-predict helpdesk:read ok + data { eta_hours, risk, next_action, blockers[] }
POST /api/v1/helpdesk/ai/canned-generate helpdesk:write ok + text (a canned-response template from a one-line intent)

All take {"ticket_id": ID} body except canned-generate which takes {"intent": "explain refund policy"}.

Admin-only hooks

| GET | /api/v1/helpdesk/ai/knowledge-gaps?days=30 | helpdesk:admin | ok + data.gaps[] — clusters of repeated unresolved questions across the last N days of tickets (mobieusKnow article candidates). | | POST | /api/v1/helpdesk/ai/audit-qa | helpdesk:admin | ok + text — answers a question about the last 200 audit events with event-id citations. Body: {"question": "..."}. |

Sentiment example

curl -X POST https://YOUR-TENANT.mobieus.io/api/v1/helpdesk/ai/sentiment \
  -H 'Authorization: Bearer mc_live_...' -H 'Content-Type: application/json' \
  -d '{"ticket_id":1234}'
{
  "ok": true,
  "data": {
    "overall": "frustrated",
    "confidence": 0.82,
    "signals": ["second follow-up", "wait time mentioned", "all-caps emphasis"]
  },
  "usage": { "prompt_tokens": 412, "completion_tokens": 87, "model": "claude-haiku-4-5-20251001" }
}

The usage block feeds your admin AI usage dashboard at Admin → AI.

Errors

The AI hooks never throw 500 on a failed AI call — they always return JSON with ok: false and an error code:

Error When
no_key Tenant hasn't configured an Anthropic key.
gate_blocked The call was blocked by your plan, feature toggle, spend cap, or rate limit.
ticket_not_found The ticket_id doesn't exist.
no_requester_text Sentiment hook ran on a ticket with no requester messages yet.
malformed_json The model returned non-JSON for a structured hook. Rare; retry.

What's not in the API yet

Still admin-UI only — each of these has no /api/v1 route today:

  • Rules engine CRUD.
  • SLA-plan + business-hours calendar CRUD.
  • Custom-field schema CRUD.

Bulk ticket operations are available — see POST /api/v1/helpdesk/tickets/bulk above. This section previously listed them as missing, which was wrong.

# mobieusCore API — mobieusHelp

> **Anchor change in this revision** — one heading was renamed because it named a version
> the API left behind eight releases ago, and stated something untrue:
>
> | old | new |
> |---|---|
> | `#whats-not-in-130` | `#whats-not-in-the-api-yet` |


The Help surface of the public REST API. Read + write tickets,
queues, agents, canned responses, tags, help topics, notification
preferences, audit log. Plus 8 AI hooks for reply suggestions,
summary, sentiment, categorization, resolution prediction,
knowledge-gap detection, audit Q&A, and canned-response generation.

The ticket + queue + agent + reply endpoints landed in API 1.2.0;
canned responses, tags, help topics, notification prefs, audit, and
AI hooks were added in **1.3.0** (2026-06-02).

## Scopes

| Scope | Grants |
|---|---|
| `helpdesk:read`  | List + read tickets, queues, agents, canned responses, tags, help topics, notification prefs, ticket messages. Also read-only AI hooks (summary, sentiment, resolution-predict). |
| `helpdesk:write` | Create + update tickets, reply, change status, manage canned responses + tags. Write-side AI hooks (reply-suggest, categorize, canned-generate). |
| `helpdesk:admin` | Notification-prefs set, audit log, admin-only AI hooks (knowledge-gaps, audit-qa). |

## Quick start

```bash
# Create a tag
curl -X POST https://YOUR-TENANT.mobieus.io/api/v1/helpdesk/tags \
  -H 'Authorization: Bearer mc_live_...' -H 'Content-Type: application/json' \
  -d '{"slug":"refund","name":"Refund","color":"#dc2626"}'

# Have AI summarize an open ticket
curl -X POST https://YOUR-TENANT.mobieus.io/api/v1/helpdesk/ai/summary \
  -H 'Authorization: Bearer mc_live_...' -H 'Content-Type: application/json' \
  -d '{"ticket_id":1234}'
```

## Tickets, queues, agents (1.2.0, unchanged)

See the existing ticket / queue / agent / reply endpoints in
[`api-overview`](api-overview). Nothing about those endpoints
changed in 1.3.0 — they're already comprehensive.

## Canned responses (1.3.0)

| Method | Path | Scope |
|---|---|---|
| `GET`  | `/api/v1/helpdesk/canned-responses`             | `helpdesk:read` |
| `GET`  | `/api/v1/helpdesk/canned-responses/{id}`        | `helpdesk:read` |
| `POST` | `/api/v1/helpdesk/canned-responses`             | `helpdesk:write` |
| `POST` | `/api/v1/helpdesk/canned-responses/{id}`        | `helpdesk:write` |
| `POST` | `/api/v1/helpdesk/canned-responses/{id}/delete` | `helpdesk:write` |

### Bulk ticket actions

One action applied across up to 200 tickets. Each ticket routes through the same service a
single-ticket call uses, so audit entries, SLA clocks and notifications fire per change.

| Method | Path | Scope |
|---|---|---|
| `POST` | `/api/v1/helpdesk/tickets/bulk` | `helpdesk:write` |

```json
{ "ticket_ids": [1042, 1043, 1044], "action": "resolve" }
```

`action` is one of `close`, `resolve`, `reopen`, `assign`, `unassign`, `move_queue`. Use
`agent_id` with `assign`, and `queue_id` with `move_queue`.

Partial success is the contract. A ticket that is missing, or whose transition is not legal from
its current state, is counted in `skipped` and the batch carries on:

```json
{ "data": { "action": "resolve", "requested": 3, "updated": 2, "skipped": 1 },
  "request_id": "req_…" }
```

Reconcile against `requested` / `updated` / `skipped` rather than assuming success. Ids beyond the
first 200 are dropped silently, so page your own batches.

Body for create:

```json
{
  "slug": "refund-policy",
  "title": "Refund policy",
  "body_md": "Hi {{requester.first_name}},

Our refund policy is 14 days. {{ticket.reference}} is within that window.

— Support",
  "queue_id": null,
  "is_active": true,
  "sort_order": 100
}
```

Placeholders are Mustache-style; the agent reply composer
substitutes at insert time.

## Tags (1.3.0)

| `GET`  | `/api/v1/helpdesk/tags`               | `helpdesk:read` | List. |
| `GET`  | `/api/v1/helpdesk/tags/{id}`          | `helpdesk:read` | Get. |
| `POST` | `/api/v1/helpdesk/tags`               | `helpdesk:write` | Create. |
| `POST` | `/api/v1/helpdesk/tags/{id}`          | `helpdesk:write` | Update. |
| `POST` | `/api/v1/helpdesk/tags/{id}/delete`   | `helpdesk:write` | Delete (also removes from every ticket). |

## Help topics (read-only, 1.3.0)

| `GET` | `/api/v1/helpdesk/help-topics` | `helpdesk:read` | List active topics with name, slug, queue_id. |

CRUD for help topics lives in the admin UI — topics carry custom-
field definitions that don't translate cleanly to a simple REST body.

## Notification preferences (1.3.0)

| `GET`  | `/api/v1/helpdesk/notification-prefs?scope=tenant_default&scope_id=0` | `helpdesk:read` |
| `POST` | `/api/v1/helpdesk/notification-prefs` | `helpdesk:admin` |

Scopes: `tenant_default` / `agent` / `requester`. Body for set:

```json
{
  "scope": "tenant_default",
  "scope_id": 0,
  "event_key": "ticket.created",
  "channel": "email",
  "enabled": true
}
```

## Audit log (1.3.0)

| `GET` | `/api/v1/helpdesk/audit?event_key=&actor_kind=&cursor=&limit=` | `helpdesk:admin` |

Returns up to 200 events per page (default 50). `event_key` filters by
event type; `actor_kind` is `agent` / `requester` / `system` / `api`.

## AI hooks (1.3.0, BYOK Anthropic)

All 8 hooks route through your tenant's mobieusAI configuration
— the same Anthropic key your tenant already configured for Community
Manager. If no key is set, every hook returns `{"ok": false, "error":
"gate_blocked"}` (HTTP 200, JSON envelope, no 500).

### Operator-facing hooks

| Method | Path | Scope | Returns |
|---|---|---|---|
| `POST` | `/api/v1/helpdesk/ai/reply-suggest`       | `helpdesk:write` | `ok + suggestions[]` (3 reply drafts) |
| `POST` | `/api/v1/helpdesk/ai/summary`             | `helpdesk:read`  | `ok + text` (Problem / Tried / Done / Next-step) |
| `POST` | `/api/v1/helpdesk/ai/categorize`          | `helpdesk:write` | `ok + data { help_topic_id, queue_id, confidence, reasoning }` |
| `POST` | `/api/v1/helpdesk/ai/sentiment`           | `helpdesk:read`  | `ok + data { overall, confidence, signals[] }` |
| `POST` | `/api/v1/helpdesk/ai/resolution-predict`  | `helpdesk:read`  | `ok + data { eta_hours, risk, next_action, blockers[] }` |
| `POST` | `/api/v1/helpdesk/ai/canned-generate`     | `helpdesk:write` | `ok + text` (a canned-response template from a one-line intent) |

All take `{"ticket_id": ID}` body except `canned-generate` which takes
`{"intent": "explain refund policy"}`.

### Admin-only hooks

| `GET`  | `/api/v1/helpdesk/ai/knowledge-gaps?days=30` | `helpdesk:admin` | `ok + data.gaps[]` — clusters of repeated unresolved questions across the last N days of tickets (mobieusKnow article candidates). |
| `POST` | `/api/v1/helpdesk/ai/audit-qa`               | `helpdesk:admin` | `ok + text` — answers a question about the last 200 audit events with event-id citations. Body: `{"question": "..."}`. |

### Sentiment example

```bash
curl -X POST https://YOUR-TENANT.mobieus.io/api/v1/helpdesk/ai/sentiment \
  -H 'Authorization: Bearer mc_live_...' -H 'Content-Type: application/json' \
  -d '{"ticket_id":1234}'
```

```json
{
  "ok": true,
  "data": {
    "overall": "frustrated",
    "confidence": 0.82,
    "signals": ["second follow-up", "wait time mentioned", "all-caps emphasis"]
  },
  "usage": { "prompt_tokens": 412, "completion_tokens": 87, "model": "claude-haiku-4-5-20251001" }
}
```

The `usage` block feeds your admin AI usage dashboard at **Admin → AI**.

## Errors

The AI hooks never throw 500 on a failed AI call — they always
return JSON with `ok: false` and an `error` code:

| Error | When |
|---|---|
| `no_key`         | Tenant hasn't configured an Anthropic key. |
| `gate_blocked`   | The call was blocked by your plan, feature toggle, spend cap, or rate limit. |
| `ticket_not_found` | The `ticket_id` doesn't exist. |
| `no_requester_text` | Sentiment hook ran on a ticket with no requester messages yet. |
| `malformed_json` | The model returned non-JSON for a structured hook. Rare; retry. |

## What's not in the API yet

Still admin-UI only — each of these has no `/api/v1` route today:

- Rules engine CRUD.
- SLA-plan + business-hours calendar CRUD.
- Custom-field schema CRUD.

Bulk ticket operations **are** available — see `POST /api/v1/helpdesk/tickets/bulk` above. This
section previously listed them as missing, which was wrong.