Ticket Providers
Let users create support tickets directly from the chat widget. Kody supports five ticket providers out of the box.
Enable tickets in your site config by setting tickets.enabled to true and adding at least one provider to the tickets.providers array. When multiple providers are configured, tickets are sent to all of them simultaneously.
You can configure which fields are required from the user via tickets.requiredFields. Valid values are: "name", "email", "subject", and "description". Defaults to ["email", "description"].
Jira
Creates issues in your Jira Cloud instance. Uses the Jira REST API v3 with email + API token authentication.
| Field | Type | Default | Description |
|---|---|---|---|
| provider | literal | — | Must be "jira". |
| baseUrl | string (URL) | required | Your Jira instance URL (e.g. https://yourorg.atlassian.net). |
| projectKey | string | required | Jira project key (e.g. SUP, HELP, SUPPORT). Min 1 char. |
| apiToken | string | required | Jira API token for authentication. Min 1 char. |
| string (email) | required | Atlassian account email associated with the API token. | |
| issueType | string | "Task" | Issue type to create (e.g. "Task", "Bug", "Story"). Must match an issue type in your project. |
Getting an API token:
- Go to Atlassian API Tokens
- Click "Create API token" and give it a descriptive label
- Copy the token and use it as the
apiTokenvalue - Use the email address of your Atlassian account as the
emailvalue
{
"provider": "jira",
"baseUrl": "https://yourorg.atlassian.net",
"projectKey": "SUP",
"apiToken": "your-api-token",
"email": "you@example.com",
"issueType": "Task"
}GitHub Issues
Creates issues in a GitHub repository. Uses the GitHub REST API with a personal access token. You can auto-apply labels to organize tickets.
| Field | Type | Default | Description |
|---|---|---|---|
| provider | literal | — | Must be "github". |
| owner | string | required | GitHub organization or user that owns the repository. |
| repo | string | required | Repository name where issues will be created. |
| token | string | required | Personal access token with Issues write permission. |
| labels | string[] | ["kody-ticket"] | Labels to apply to created issues. The labels must exist in the repository. |
Creating a personal access token:
- Go to GitHub Fine-grained tokens
- Click "Generate new token"
- Select the target repository and grant Issues: Read and write permission
- Copy the token and use it as the
tokenvalue
{
"provider": "github",
"owner": "your-org",
"repo": "support",
"token": "ghp_xxxxxxxxxxxx",
"labels": ["kody-ticket", "bug"]
}Linear
Creates issues in a Linear team using the Linear GraphQL API. Issues are assigned to the specified team and can have labels applied automatically.
| Field | Type | Default | Description |
|---|---|---|---|
| provider | literal | — | Must be "linear". |
| apiKey | string | required | Linear API key. Min 1 char. |
| teamId | string | required | Team ID to create issues in. You can find this in your team settings or via the Linear API. |
| labelIds | string[] | [] | Label IDs to apply to created issues. |
Getting an API key:
- Go to Linear Settings → API
- Create a new personal API key
- Copy the key and use it as the
apiKeyvalue
{
"provider": "linear",
"apiKey": "lin_api_xxxxxxxxxxxx",
"teamId": "TEAM-ID",
"labelIds": ["label-id-1"]
}Sends ticket notifications via email using SMTP. The recipient address is required; all SMTP fields are optional to support future hosted email relay.
| Field | Type | Default | Description |
|---|---|---|---|
| provider | literal | — | Must be "email". |
| to | string (email) | required | Recipient email address. Must be a valid email. |
| from | string (email) | — | Sender email address. Must be a valid email. Optional. |
| smtpHost | string | — | SMTP server hostname (e.g. smtp.gmail.com). Optional. |
| smtpPort | integer | — | SMTP server port (e.g. 587 for TLS, 465 for SSL). Optional. |
| smtpUser | string | — | SMTP username for authentication. Optional. |
| smtpPass | string | — | SMTP password for authentication. Stored server-side only. Optional. |
{
"provider": "email",
"to": "support@example.com",
"from": "noreply@example.com",
"smtpHost": "smtp.example.com",
"smtpPort": 587,
"smtpUser": "smtp-user",
"smtpPass": "smtp-password"
}Webhook
Sends ticket data to any HTTP endpoint. This is the most flexible option — use it to integrate with Slack, Discord, Notion, your own API, or any service that accepts webhooks.
| Field | Type | Default | Description |
|---|---|---|---|
| provider | literal | — | Must be "webhook". |
| url | string (URL) | required | Webhook endpoint URL. Must be a valid URL. |
| method | enum | "POST" | HTTP method: "POST" or "PUT". |
| headers | Record<string, string> | {} | Custom headers to include in the request. Useful for authentication tokens or content type overrides. |
| secret | string | — | HMAC-SHA256 secret for signature verification. When set, Kody includes an X-Kody-Signature header. Optional. |
Signature Verification
When a secret is configured, Kody includes an X-Kody-Signature header containing an HMAC-SHA256 hex digest of the request body. Verify this on your server to ensure requests are authentic and have not been tampered with.
{
"provider": "webhook",
"url": "https://example.com/api/tickets",
"method": "POST",
"headers": {
"Authorization": "Bearer your-token"
},
"secret": "your-hmac-secret"
}import crypto from "node:crypto";
function verify(body: string, signature: string, secret: string) {
const expected = crypto
.createHmac("sha256", secret)
.update(body)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected),
);
}Using Multiple Providers
You can configure multiple providers simultaneously. Tickets are sent to all of them when a user submits one. This is useful for keeping multiple systems in sync, e.g. creating a GitHub issue and sending a Slack notification via webhook at the same time:
{
"tickets": {
"enabled": true,
"promptMessage": "Would you like me to create a support ticket?",
"providers": [
{
"provider": "github",
"owner": "your-org",
"repo": "support",
"token": "ghp_...",
"labels": ["kody-ticket"]
},
{
"provider": "webhook",
"url": "https://hooks.slack.com/services/T.../B.../xxx",
"method": "POST"
}
],
"requiredFields": ["name", "email", "description"]
}
}