Skip to main content

Endpoint

POST /api/sdk/tickets/create
Create a support ticket with proper user association. Designed for third-party integrations like form builders, CRMs, bug reporters, and webhook handlers that need to submit structured data to your Halo inbox. Unlike sending a raw email (which may lose user identity when the sender is a notification service like [email protected]), this endpoint lets you explicitly specify who the ticket is from.

Authentication

Requires your publishable widget key in the Authorization header:
Authorization: Bearer ab_live_xxxxxxxxxxxxxxxx
The org_id is derived from the widget key.
Use your widget key from Setup > Install. It is publishable (safe in browser code). Enable Identity Verification when scoping requests by user_id.

Request Body

User Identification

At least one of user_id or email is required. If the user doesn’t exist yet, they are created automatically.
user_id
string
Your system’s unique identifier for this user. If provided, Halo looks up the user by external_id first.
email
string
The user’s email address. Used as a fallback lookup if user_id doesn’t match, or as the primary identifier if user_id is omitted. Also used for email notifications and AI agent replies.
name
string
The user’s display name. Used when creating a new user record, or to enrich context if the user already exists.

Ticket Content

subject
string
required
The ticket subject line. This appears as the ticket title in your inbox. Max 1,000 characters.
message
string
The full ticket body / description. If omitted, the subject is used as the initial message. Max 50,000 characters.
metadata
object
Arbitrary key-value data attached to the ticket. Visible to your team in the dashboard and accessible to the AI agent. Max 50,000 bytes. Use this for structured form data, severity levels, categories, etc.

Options

source
string
default:"api"
A label identifying where the ticket came from (e.g., "contact_form", "bug_report", "webhook"). Max 50 characters.
priority
string
default:"normal"
Set to "priority" to mark the ticket as high priority. Otherwise defaults to "normal" (open status).
ai_enabled
boolean
default:"false"
When true, the AI agent is triggered to respond to this ticket automatically (using your configured email AI agent). Requires AI email auto-reply to be enabled in your settings. The AI will reply to the user’s email if one is provided.

Example

curl -X POST https://api.haloagents.ai/api/sdk/tickets/create \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ab_live_xxxxxxxxxxxxxxxx" \
  -d '{
    "email": "[email protected]",
    "name": "Jane Doe",
    "subject": "Bug: SEO settings missing from Share page",
    "message": "The SEO settings were previously available on the Share page in the Form Editor but are now missing. I was initially able to edit SEO settings, but the option has disappeared.",
    "metadata": {
      "severity": "major",
      "area": "Form Editor",
      "browser": "Chrome 122",
      "plan": "pro"
    },
    "source": "bug_report",
    "priority": "priority"
  }'
Response (201 Created):
{
  "ticket": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "status": "priority",
    "subject": "Bug: SEO settings missing from Share page",
    "created_at": "2026-03-17T10:30:00.000Z"
  },
  "user": {
    "id": "f1e2d3c4-b5a6-7890-abcd-ef0987654321",
    "email": "[email protected]",
    "name": "Jane Doe"
  }
}

User Resolution Logic

The endpoint resolves users in this order:
  1. By user_id — looks up end_users.external_id matching your user_id
  2. By email — falls back to end_users.email lookup
  3. Auto-create — if no match is found, creates a new end user with the provided email, name, and user_id
This means you can use the same endpoint whether the user already exists in Halo or not. If you’ve previously called identify, the ticket is linked to that same user record.

What Happens After Creation

  1. The ticket appears in your Halo inbox immediately
  2. Your team is notified via Slack and email (if configured)
  3. If ai_enabled is true and your AI email agent is configured, the AI processes the ticket and sends a reply to the user’s email
  4. The user record is created or linked, so the AI has full context for future interactions

When to Use This vs Email

ScenarioUse Tickets APIUse Email
Form builder (Typeform, OrbitForms, etc.)Yes — preserves user identityNotification emails lose the sender
CRM webhook (HubSpot, Salesforce)Yes — structured dataEmail loses structure
Bug report toolYes — include metadataSubject line only
Customer emails you directlyNoYes — native email threading
Internal forwarding from Gmail/OutlookNoYes — use email forwarding

Error Responses

StatusErrorCause
400subject is requiredMissing or empty subject field
400At least one of user_id or email is requiredNo user identification provided
401Missing API keyNo Authorization header
401Invalid or revoked API keyBad or revoked API key
500Failed to create ticketServer error during creation