SDK & API
Everything you need to integrate TicketForge into your application.
Quick Start
Install the SDK and create your first ticket in under 2 minutes.
Installation
The official TypeScript SDK — zero dependencies, native fetch, ESM-first.
bun add @ticketforge/sdk npm install @ticketforge/sdk Initialize the Client
import { TicketForgeClient } from '@ticketforge/sdk';
const tf = new TicketForgeClient({
apiKey: 'tf_your_api_key',
baseUrl: '',
}); Examples
Common operations with the SDK.
const ticket = await tf.createTicket({
subject: 'Cannot access billing portal',
body: 'Getting a 403 error when clicking "Manage Subscription"...',
senderEmail: 'jane@acme.com',
senderName: 'Jane Smith',
priority: 'p2_high',
});
console.log(ticket.id); // "tkt_abc123"
console.log(ticket.status); // "open" const ticket = await tf.getTicket('tkt_abc123');
console.log(ticket.subject);
console.log(ticket.status);
console.log(ticket.messages); await tf.addMessage('tkt_abc123', {
body: 'We\'ve identified the issue and deployed a fix.',
isInternal: false,
}); const results = await tf.searchArticles('billing portal');
for (const article of results) {
console.log(article.title, article.slug);
} Authentication
All API requests require a Bearer token in the Authorization header.
Base URL:
Endpoints
| Method | Path | Description |
|---|---|---|
| POST | /v1/tickets | Create a new support ticket |
| GET | /v1/tickets/:id | Get ticket details and messages |
| POST | /v1/tickets/:id/messages | Add a message to a ticket |
| GET | /v1/articles/search?q=... | Search knowledge base articles |
| GET | /v1/search?q=... | Unified search across tickets, articles, contacts |
Create Ticket — Request Body
POST /v1/tickets
| Field | Type | Required | Description |
|---|---|---|---|
| subject | string | Required | Ticket subject line |
| body | string | Required | Full ticket description (Markdown supported) |
| sender_email | string | Optional | Submitter's email address |
| sender_name | string | Optional | Submitter's display name |
| priority | string | Optional | p1_critical, p2_high, p3_medium, p4_low |
| source | string | Optional | api, widget, email, form — defaults to api |
| tags | string[] | Optional | Array of tag names to apply |
| metadata | object | Optional | Arbitrary JSON metadata |
cURL Examples
curl -X POST /v1/tickets \
-H "Authorization: Bearer tf_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"subject": "Cannot access billing portal",
"body": "Getting a 403 error...",
"sender_email": "jane@acme.com",
"priority": "p2_high"
}' curl /v1/tickets/tkt_abc123 \
-H "Authorization: Bearer tf_your_api_key" curl "/v1/articles/search?q=billing" \
-H "Authorization: Bearer tf_your_api_key" curl "/v1/search?q=authentication&types=tickets,articles&limit=5" \
-H "Authorization: Bearer tf_your_api_key" Embeddable Widget
Drop-in support form for any website. Shadow DOM isolated, ~7KB gzipped.
<!-- Add before closing </body> tag -->
<script>
window.TicketForgeConfig = {
projectKey: 'tf_your_api_key',
baseUrl: '',
color: '#0284c7',
position: 'bottom-right',
greeting: 'How can we help?',
};
</script>
<script src="/widget/ticketforge-widget.js"></script> Configuration Options
All available window.TicketForgeConfig properties.
| Property | Type | Default | Description |
|---|---|---|---|
| projectKey | string | — | Your project API key (required) |
| baseUrl | string | — | Ingestion service URL (required) |
| color | string | #0284c7 | Brand color for button and header |
| position | string | bottom-right | bottom-right or bottom-left |
| greeting | string | How can we help? | Header greeting text |
| fields.name | boolean | true | Show name input |
| fields.email | boolean | true | Show email input |
| fields.priority | boolean | false | Show priority selector |
Outbound Webhooks
Receive HTTP callbacks when events occur. HMAC-SHA256 signed, with automatic retries.
Available Events
| Event | Description |
|---|---|
| ticket_created | Fired when a new ticket is created |
| ticket_replied | Fired when a message is added to a ticket |
| ticket_resolved | Fired when a ticket is marked resolved |
| ticket_status_changed | Fired when ticket status changes |
| ticket_assigned | Fired when a ticket is assigned to an agent |
Payload Format
All webhook payloads follow this structure. The data object varies by event type.
{
"event": "ticket_created",
"timestamp": "2026-03-18T12:00:00Z",
"data": {
"id": "tkt_abc123",
"subject": "Cannot access billing portal",
"status": "open",
"priority": "p2_high",
"sender_email": "jane@acme.com",
"project_id": "proj_xyz",
"created_at": "2026-03-18T12:00:00Z"
}
} Headers sent:
Content-Type: application/json
X-TicketForge-Event: ticket_created
X-TicketForge-Signature: sha256=<hmac>
X-TicketForge-Delivery: <uuid>
Verifying Signatures
Verify the HMAC-SHA256 signature to ensure payloads are authentic.
import crypto from 'crypto';
function verifyWebhook(payload: string, signature: string, secret: string) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected),
);
}
// In your webhook handler:
const isValid = verifyWebhook(
rawBody,
req.headers['x-ticketforge-signature'],
process.env.WEBHOOK_SECRET,
);