Technical documentation for GrowthSupport — a self-hosted support-ticket system for WordPress. This page covers how the plugin works, its shortcode, roles & capabilities, data model, REST API, AJAX actions, hooks, and the AI / MCP abilities layer.
Version: 1.0.0 | Requires: WordPress 6.0+, PHP 8.0+ | Text domain: growthsupport
1. Overview — how it works
GrowthSupport adds a lightweight help desk to WordPress using two custom database tables (tickets and replies). Logged-in users open tickets from a front-end portal rendered by a shortcode; agents (administrators) manage and reply to every ticket. The plugin exposes three interfaces on top of the same data layer:
- Front end — the
[growthsupport]shortcode + AJAX (for clients and agents in the browser). - REST API — the
growthsupport/v1namespace (for headless / external integrations). - AI abilities — WordPress Abilities API tools, optionally exposed over MCP (for assistants and automation).
All three respect the same capability checks, so permissions behave consistently regardless of how a ticket is accessed.
2. Installation & setup
- Upload and activate the plugin. On activation it creates the database tables and grants capabilities (see below).
- Create a WordPress page and add the shortcode
[growthsupport]. - Publish the page and link to it from your site (e.g. a “Support” menu item). Clients must be logged in to use it.
3. Shortcode
Render the support portal anywhere with:
[growthsupport]Behaviour:
- Visitors who are not logged in see a notice asking them to log in.
- Logged-in users without the
gs_create_ticketscapability see a permission notice. - Users with access see their ticket list; agents (with
gs_manage_tickets) see all tickets.
The portal loads its own assets automatically and talks to the AJAX actions listed in section 7.
4. Roles & capabilities
Two custom capabilities control access. They are granted on activation and removed on deactivation.
| Capability | Grants | Default roles |
|---|---|---|
gs_create_tickets | Open and view own tickets, reply to them, and close them. | Administrator, Editor, Author, Contributor, Subscriber |
gs_manage_tickets | View, reply to, and change the status of all tickets. | Administrator |
To turn any role into an agent, grant it gs_manage_tickets (for example with a role-editor plugin or $role->add_cap()).
5. Data model
Two tables are created (with the site’s table prefix):
Table: {prefix}gs_tickets
| Column | Type | Notes |
|---|---|---|
| id | BIGINT | Primary key |
| user_id | BIGINT | Ticket author (WP user) |
| subject | VARCHAR(255) | |
| description | TEXT | |
| priority | VARCHAR(20) | urgent | high | normal | low |
| status | VARCHAR(20) | open | in_progress | resolved | closed |
| created_at / updated_at | DATETIME | |
| closed_by / closed_at | BIGINT / DATETIME | Set when resolved or closed |
Table: {prefix}gs_ticket_replies
| Column | Type | Notes |
|---|---|---|
| id | BIGINT | Primary key |
| ticket_id | BIGINT | Parent ticket |
| user_id | BIGINT | Reply author |
| content | TEXT | |
| is_client | TINYINT(1) | 1 = client reply, 0 = agent reply |
| created_at | DATETIME |
6. REST API
Namespace: growthsupport/v1 — base URL /wp-json/growthsupport/v1.
Authentication: standard WordPress authentication. For same-site requests, send the logged-in cookie plus the X-WP-Nonce header (nonce from wp_create_nonce('wp_rest')). Every route requires the gs_create_tickets capability; listing/among-all behaviour and status changes additionally check gs_manage_tickets. All responses are wrapped in a { "data": ... } envelope.
| Method | Route | Description |
|---|---|---|
| GET | /tickets?status={all|open|in_progress|resolved|closed} | List tickets. Agents get all tickets; clients get their own. |
| POST | /tickets | Create a ticket. Body: subject, description, optional priority. Returns 201. |
| GET | /tickets/{id} | Get a single ticket including its replies array. |
| PUT / PATCH | /tickets/{id}/status | Change status. Clients may only set their own ticket to closed. |
| POST | /tickets/{id}/replies | Add a reply. Body: content. |
Examples
Create a ticket:
curl -X POST https://example.com/wp-json/growthsupport/v1/tickets \
-H "X-WP-Nonce: <nonce>" \
--cookie "<wp-auth-cookies>" \
-H "Content-Type: application/json" \
-d '{"subject":"Login issue","description":"Cannot reset my password","priority":"high"}'List open tickets:
GET /wp-json/growthsupport/v1/tickets?status=openClose a ticket:
curl -X PATCH https://example.com/wp-json/growthsupport/v1/tickets/42/status \
-H "X-WP-Nonce: <nonce>" --cookie "<wp-auth-cookies>" \
-H "Content-Type: application/json" -d '{"status":"closed"}'7. AJAX actions (front end)
The shortcode UI uses admin-ajax.php. All actions are logged-in only (wp_ajax_*), require the nonce field nonce for action gs_nonce, and check gs_create_tickets.
| Action | Purpose | Key POST fields |
|---|---|---|
gs_get_tickets | List tickets | status |
gs_get_ticket | Single ticket + replies | id |
gs_create_ticket | Create a ticket | subject, description, priority |
gs_reply_ticket | Add a reply | ticket_id, content |
gs_update_ticket_status | Change status | id, status |
8. Hooks (actions & filters)
Extend GrowthSupport — for example to send email notifications on new tickets or replies.
Actions
| Hook | Arguments | Fires when |
|---|---|---|
gs_ticket_created | $ticket_id, $user_id | A ticket is created |
gs_ticket_status_changed | $ticket_id, $status, $user_id | A ticket status changes |
gs_ticket_reply_posted | $reply_id, $ticket_id, $user_id | A reply is posted |
Filters
| Hook | Signature | Purpose |
|---|---|---|
gs_ticket_format | ($ticket_array, $row) | Modify the formatted ticket array before it is returned. |
Example — email the site admin when a ticket is created:
add_action( 'gs_ticket_created', function ( $ticket_id, $user_id ) {
wp_mail(
get_option( 'admin_email' ),
'New support ticket #' . $ticket_id,
'A new ticket was opened by user ' . $user_id
);
}, 10, 2 );9. AI abilities & MCP
GrowthSupport registers tools on the WordPress Abilities API, grouped into two categories:
growthsupport-tickets— create, read, update, and manage tickets and replies.growthsupport-diagnostics— summary statistics across all tickets.
Ticket abilities:
| Ability | Type | Default capability |
|---|---|---|
growthsupport/list-tickets | read-only | gs_manage_tickets |
growthsupport/get-ticket | read-only | gs_manage_tickets |
growthsupport/create-ticket | write | gs_manage_tickets |
growthsupport/update-ticket-status | idempotent | gs_manage_tickets |
growthsupport/add-reply | write | gs_manage_tickets |
growthsupport/delete-ticket | destructive | gs_manage_tickets |
Each ability declares a JSON input/output schema, so assistants receive typed, validated parameters (e.g. priority is limited to urgent|high|normal|low).
Exposing abilities over MCP
Abilities flagged as MCP-public are surfaced as callable MCP tools through the WordPress Abilities MCP adapter, so an AI client can list and manage tickets directly. Two safety defaults apply:
- Every ability is capability-gated — the calling user still needs the required capability.
growthsupport/delete-ticketis not MCP-public by default (destructive), so it is excluded from the MCP surface unless you opt in.
The required capability and MCP visibility of each ability (or a whole category) can be overridden from the plugin’s Abilities settings, which are stored in the gs_abilities_config option (per-ability overrides take precedence over category defaults, which take precedence over the code defaults shown above).
10. FAQ & troubleshooting
The portal says I must log in.
The shortcode requires an authenticated user. Place it on a page behind login, or send visitors to wp-login.php first.
How do I make someone an agent?
Grant their role the gs_manage_tickets capability. Agents then see and manage every ticket in the portal, REST API, and abilities.
How do I add email notifications?
Hook the actions in section 8 (gs_ticket_created, gs_ticket_reply_posted, gs_ticket_status_changed) and call wp_mail().
The REST API returns 401/403.
Ensure you send the logged-in cookie and a valid X-WP-Nonce header, and that the user has gs_create_tickets (and gs_manage_tickets for cross-user or status operations).
Back to GrowthSupport product page.