API Reference

Back to Dashboard

Omni Support REST API

The Omni Support API allows you to programmatically create and manage support tickets, add comments and attachments, and retrieve diagnostic information. It is designed for use by frontend support widgets, backend SDKs, and automated error-reporting systems.

API Version: v1  ·  Content-Type: application/json  ·  Specification: OpenAPI 3.0

Base URL

https://your-instance.com/api/v1

Authentication

All API requests require an API key passed via the X-IMS-OMNI-API-KEY header. Keys are generated from the Omni Support dashboard under App Settings.

Security note: API keys are stored as SHA-256 hashes. The raw key is shown only once at creation time. Save it immediately.
curl -H "X-IMS-OMNI-API-KEY: your-raw-api-key" \
  https://your-instance.com/api/v1/tickets

How it works: The system first checks for a per-environment installation key (tied to a specific environment like production or staging). If no installation matches, it falls back to the app-level master key. Installation keys are created automatically when your SDK first connects.

HeaderRequiredDescription
X-IMS-OMNI-API-KEYRequiredYour raw API key (app-level or installation-level)

Errors

The API uses standard HTTP status codes and returns JSON error responses:

StatusMeaning
201Resource created successfully
200Request succeeded
400Bad request — malformed syntax
401Missing or invalid API key
404Resource not found
422Validation failure — check the errors field
500Server error
// Validation error (422)
{
  "errors": {
    "user_email": ["The user email field is required."],
    "user_name": ["The user name field is required."]
  }
}

// Authentication error (401)
{
  "message": "API Key is missing."
}

Create a Ticket

POST /tickets

Submit a new support ticket. This is the primary endpoint used by frontend widgets, SDKs, and external applications to report issues.

Request Body

ParameterTypeRequiredDescription
subjectstringOptional*Ticket subject (max 500 chars). Either subject or title is required.
titlestringOptional*Preferred title (maps to subject if provided)
descriptionstringRequiredDetailed description of the issue
prioritystringOptionallow, medium, high, or critical (default: medium)
categorystringOptionalCategory slug or name (must exist for your app)
user_identifierstringRequiredUnique ID for the end user in your system
user_emailstringRequiredEnd user's email address
user_namestringRequiredEnd user's display name
tenant_identifierstringOptionalMulti-tenant identifier for the user's organization
contextobjectOptionalArbitrary key-value metadata (environments, request data, etc.)
exception_traceobjectOptionalStructured exception/stack trace data
current_urlstringOptionalURL where the issue occurred
browserstringOptionalBrowser name (max 100 chars)
operating_systemstringOptionalOS name (max 100 chars)
devicestringOptionalDevice name (max 100 chars)
app_versionstringOptionalYour application's version
sdk_versionstringOptionalOmni Support SDK version used
attachmentsarrayOptionalBase64-encoded file attachments (see below)

Attachment Object

FieldTypeDescription
file_namestringFile name with extension, e.g. screenshot.png
contentstringBase64-encoded file content
mime_typestringMIME type, e.g. image/png, text/plain

Example Request

curl -X POST "https://your-instance.com/api/v1/tickets" \
  -H "X-IMS-OMNI-API-KEY: your-raw-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "subject": "Database connection timeout",
    "description": "Users are experiencing timeout errors when accessing the dashboard.",
    "priority": "high",
    "category": "database",
    "user_identifier": "usr_8a7b3c",
    "user_email": "john@example.com",
    "user_name": "John Smith",
    "tenant_identifier": "tenant_acme",
    "context": {
      "environment": "production",
      "system": { "hostname": "web-01.example.com" },
      "request": {
        "method": "GET",
        "url": "/api/users",
        "ip": "203.0.113.42"
      }
    },
    "exception_trace": {
      "class": "PDOException",
      "message": "SQLSTATE[HY000] [2002] Connection refused",
      "file": "/var/www/app/Providers/AppServiceProvider.php",
      "line": 45
    }
  }'

Success Response (201)

{
  "message": "Ticket created successfully.",
  "ticket": {
    "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "ticket_number": "TKT-ACME-2026-000042",
    "title": "Database connection timeout",
    "subject": "Database connection timeout",
    "description": "Users are experiencing timeout errors...",
    "status": "open",
    "priority": "high",
    "user_identifier": "usr_8a7b3c",
    "user_email": "john@example.com",
    "user_name": "John Smith",
    "tenant_identifier": "tenant_acme",
    "current_url": null,
    "browser": null,
    "operating_system": null,
    "device": null,
    "app_version": null,
    "sdk_version": null,
    "context": { ... },
    "exception_trace": { ... },
    "resolved_at": null,
    "closed_at": null,
    "created_at": "2026-07-08T14:30:00.000000Z",
    "updated_at": "2026-07-08T14:30:00.000000Z",
    "category": { "id": "...", "name": "Database", "slug": "database" },
    "reporter": { "id": "...", "external_id": "usr_8a7b3c", "name": "John Smith", "email": "john@example.com" },
    "installation": { "id": "...", "environment": "production" },
    "attachments": []
  }
}

List Tickets

GET /tickets

Retrieve all tickets for your application, with optional filters.

Query Parameters

ParameterTypeDescription
user_identifierstringFilter by end user's external ID
user_emailstringFilter by end user's email
statusstringFilter by status: open, in_progress, pending, resolved, closed
prioritystringFilter by priority: low, medium, high, critical

Example Request

curl "https://your-instance.com/api/v1/tickets?status=open&priority=high" \
  -H "X-IMS-OMNI-API-KEY: your-raw-api-key"

Response (200)

{
  "tickets": [
    {
      "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
      "ticket_number": "TKT-ACME-2026-000042",
      "title": "Database connection timeout",
      "status": "open",
      "priority": "high",
      "user_name": "John Smith",
      "user_email": "john@example.com",
      "created_at": "2026-07-08T14:30:00.000000Z",
      "category": { "id": "...", "name": "Database", "slug": "database" },
      "assignee": null,
      "reporter": { ... }
    }
  ]
}

Get a Ticket

GET /tickets/{id}

Retrieve a single ticket by its UUID, including comments, attachments, and audit logs.

Path Parameters

ParameterTypeDescription
iduuidThe ticket's UUID

Example Request

curl "https://your-instance.com/api/v1/tickets/f47ac10b-58cc-4372-a567-0e02b2c3d479" \
  -H "X-IMS-OMNI-API-KEY: your-raw-api-key"

Response (200)

{
  "ticket": {
    "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "ticket_number": "TKT-ACME-2026-000042",
    "title": "Database connection timeout",
    "subject": "Database connection timeout",
    "description": "Users are experiencing timeout errors...",
    "status": "open",
    "priority": "high",
    "user_identifier": "usr_8a7b3c",
    "user_email": "john@example.com",
    "user_name": "John Smith",
    "tenant_identifier": "tenant_acme",
    "context": { ... },
    "exception_trace": { ... },
    "resolved_at": null,
    "closed_at": null,
    "created_at": "2026-07-08T14:30:00.000000Z",
    "updated_at": "2026-07-08T14:30:00.000000Z",
    "deleted_at": null,
    "category": { ... },
    "assignee": null,
    "reporter": { ... },
    "installation": { ... },
    "comments": [
      {
        "id": "...",
        "author_type": "support_agent",
        "author_name": "Support Team",
        "content": "We are investigating this issue.",
        "is_internal": false,
        "created_at": "2026-07-08T15:00:00.000000Z",
        "attachments": []
      }
    ],
    "attachments": [],
    "audit_logs": [
      {
        "id": "...",
        "actor_type": "system",
        "action": "ticket_created",
        "created_at": "2026-07-08T14:30:00.000000Z"
      }
    ]
  }
}

Add a Comment

POST /tickets/{id}/comments

Add a comment or reply to a ticket. Comments can be public or internal (support-agent-only notes).

Request Body

ParameterTypeRequiredDescription
contentstringRequiredThe comment text
author_typestringRequiredexternal_user, support_agent, or system
author_idstringRequiredUnique ID for the author in your system
author_namestringRequiredDisplay name of the author
is_internalbooleanOptionalIf true, only support agents can see this note (default: false)
attachmentsarrayOptionalBase64-encoded file attachments (same structure as ticket attachments)

Example Request

curl -X POST "https://your-instance.com/api/v1/tickets/f47ac10b-58cc-4372-a567-0e02b2c3d479/comments" \
  -H "X-IMS-OMNI-API-KEY: your-raw-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "I have attached the error log for reference.",
    "author_type": "external_user",
    "author_id": "usr_8a7b3c",
    "author_name": "John Smith"
  }'

Response (201)

{
  "message": "Comment added successfully.",
  "comment": {
    "id": "b1a2c3d4-...",
    "ticket_id": "f47ac10b-...",
    "author_type": "external_user",
    "author_id": "usr_8a7b3c",
    "author_name": "John Smith",
    "content": "I have attached the error log for reference.",
    "is_internal": false,
    "created_at": "2026-07-08T16:00:00.000000Z",
    "updated_at": "2026-07-08T16:00:00.000000Z",
    "attachments": []
  }
}

Upload Attachment

POST /tickets/{id}/attachments

Upload a file attachment to a ticket using multipart/form-data. Useful when the file is too large for base64 encoding in the JSON endpoints.

Maximum file size: 10 MB (10240 KB).

Request

FieldTypeRequiredDescription
filefileRequiredThe file to upload (multipart/form-data)

Example Request

curl -X POST "https://your-instance.com/api/v1/tickets/f47ac10b-58cc-4372-a567-0e02b2c3d479/attachments" \
  -H "X-IMS-OMNI-API-KEY: your-raw-api-key" \
  -F "file=@screenshot.png"

Response (201)

{
  "message": "Attachment uploaded.",
  "attachment": {
    "id": "c4d5e6f7-...",
    "file_name": "screenshot.png",
    "file_size": 245760,
    "mime_type": "image/png",
    "created_at": "2026-07-08T16:30:00.000000Z"
  }
}

List Categories

GET /categories

Retrieve all categories configured for your application. Use the returned slug or name when creating tickets to assign a category.

Example Request

curl "https://your-instance.com/api/v1/categories" \
  -H "X-IMS-OMNI-API-KEY: your-raw-api-key"

Response (200)

{
  "categories": [
    {
      "id": "e5f6a7b8-...",
      "name": "Billing",
      "slug": "billing",
      "description": "Payment, credit cards and subscription issues."
    },
    {
      "id": "f6a7b8c9-...",
      "name": "Database",
      "slug": "database",
      "description": "Connection issues, query problems, migrations."
    }
  ]
}

Webhooks

When a ticket is created, Omni Support can send a webhook POST request to a URL you configure in your app settings. The webhook is dispatched asynchronously via a queue job.

To enable webhooks, set settings.webhook_url on your app via the dashboard. Webhook requests have a 10-second timeout. Failed deliveries are logged and retried by the queue worker.

Payload

{
  "event": "ticket.created",
  "timestamp": "2026-07-08T14:30:00.000000Z",
  "ticket": {
    "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "ticket_number": "TKT-ACME-2026-000042",
    "subject": "Database connection timeout",
    "description": "Users are experiencing timeout errors...",
    "status": "open",
    "priority": "high",
    "user_email": "john@example.com",
    "user_name": "John Smith"
  }
}

Rate Limiting

The API does not currently enforce rate limiting. However, we recommend keeping requests to a reasonable volume. Excessive traffic may result in rate limiting being applied in future releases.


SDK Integration

The Omni Support API is designed to work with both PHP and JavaScript SDKs. The system tracks which SDK version submitted each ticket through the sdk_version field.

PHP SDK Example

$client = new GuzzleHttp\Client([
    'base_uri' => 'https://your-instance.com/api/v1/',
    'headers'  => [
        'X-IMS-OMNI-API-KEY' => 'your-raw-api-key',
        'Content-Type'       => 'application/json',
    ],
]);

$response = $client->post('tickets', [
    'json' => [
        'subject'          => 'API timeout error',
        'description'      => 'Request to /users endpoint timed out after 30s.',
        'priority'         => 'high',
        'user_identifier'  => 'usr_12345',
        'user_email'       => 'user@example.com',
        'user_name'        => 'Jane Doe',
        'context'          => [
            'environment' => 'staging',
            'request'     => [
                'method' => 'GET',
                'url'    => '/api/users',
            ],
        ],
    ],
]);

$ticket = json_decode($response->getBody(), true);
echo $ticket['ticket']['ticket_number'];

JavaScript (Fetch) Example

const response = await fetch('https://your-instance.com/api/v1/tickets', {
  method: 'POST',
  headers: {
    'X-IMS-OMNI-API-KEY': 'your-raw-api-key',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    subject: 'Login page not loading',
    description: 'Users report the login page shows a blank screen.',
    priority: 'critical',
    user_identifier: 'usr_67890',
    user_email: 'support@example.com',
    user_name: 'Alice Johnson',
    browser: 'Chrome 120',
    operating_system: 'macOS 14.2',
    current_url: 'https://app.example.com/login',
  }),
});

const data = await response.json();
console.log(data.ticket.ticket_number);

cURL (Exception Trace)

curl -X POST "https://your-instance.com/api/v1/tickets" \
  -H "X-IMS-OMNI-API-KEY: your-raw-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "subject": "Unhandled exception in OrderController",
    "description": "Call to a member function getPrice() on null",
    "priority": "critical",
    "user_identifier": "sys_bot",
    "user_email": "devops@example.com",
    "user_name": "Error Bot",
    "category": "backend",
    "exception_trace": {
      "class": "ErrorException",
      "message": "Call to a member function getPrice() on null",
      "file": "/var/www/app/Http/Controllers/OrderController.php",
      "line": 142,
      "trace": [
        "#0 /var/www/app/Http/Controllers/OrderController.php(142): calculateTotal()",
        "#1 /var/www/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(45): OrderController->show()"
      ]
    },
    "context": {
      "environment": "production",
      "system": { "hostname": "web-02.example.com" },
      "request": {
        "method": "GET",
        "url": "/orders/123",
        "ip": "10.0.1.42",
        "user_agent": "Mozilla/5.0..."
      }
    }
  }'