Skip to main content
Create tickets programmatically from CRMs, order systems, custom backends, or automation tools (Zapier, Make, webhooks). Requires the tickets:write scope. Rate limit: 30 requests / minute (see Rate limits).
Do not use legacy POST https://api.armin.cx/public/tickets for new integrations. Prefer v1 and see Migrating from legacy for the sunset date (2026-10-31).

Prerequisites

  1. API key with tickets:read and tickets:write — create or update under Settings → API.
  2. Connected channel — the channel value you send must match a channel type connected in your workspace (for example email or widget). If the organization has multiple channels of the same type, use channel_identifier to target a specific inbox address or identifier.
  3. HTTP clientcurl, Postman, or any server that can send POST with JSON.

Request

Send only the fields listed below. Extra fields in the JSON body return an error.

Request body

Required

Optional — ticket

Optional — contact

Optional — messages

Instead of (or in addition to) note, you can send up to 10 initial messages in messages[]:
For most integrations, note + contact + metadata is enough. Use messages when you need a visible customer message in the thread when the ticket is created.

Attachments

Attach a file to a message in three calls: request an upload URL, upload the file, then confirm it before referencing it on ticket creation.
  1. POST /public/v1/attachments/upload-url with the file’s name, MIME type, and size. Returns id and a presigned upload_url (valid for 30 minutes).
  2. PUT the raw file bytes to upload_url — directly to storage, not through this API.
  3. POST /public/v1/attachments/{id}/confirm. This checks the upload against the size limit and the file’s actual content, not just the MIME type you declared in step 1.
  4. Pass the confirmed id in messages[].attachment_ids when you create the ticket.

Minimal example

Internal note only — no contact required:

Full example

Contact, tags, and external reference in metadata:
Replace metadata keys with whatever your system uses — the API stores them as opaque integration fields.

Automation and webhooks

Many teams call this endpoint from HTTP request actions in automation platforms (custom scripts, Zapier, Make, n8n, ecommerce workflows, etc.):
  1. Trigger when your business rule fires (tag added, field missing, status change).
  2. POST to https://api.armin.cx/public/v1/tickets with your platform’s variable syntax in subject, note, contact, and metadata.
  3. Map your external order or case ID into metadata so agents can trace the source.
Design triggers so they fire only when the condition becomes true, not on every unrelated update.
Every successful request creates a new ticket. Run your automation only when the event should open a ticket (for example when a tag is added), not on every update to the same record.

Response

201 Created — standard v1 success envelope:
Store data.id (UUID) or data.ticket_number (numeric inbox number) to correlate with later GET requests.

Errors

See Errors for the full catalog and request_id usage.

Try it first

  1. In Settings → API, create a key with tickets:write.
  2. Send a test request using the examples above. Use a test subject or tag (for example api-test) so your team can spot it in the inbox.
  3. Confirm the ticket appears with the expected channel, contact, tags, and metadata.
Revoke the test key when you are finished.

OpenAPI reference

Interactive schema and Try it for POST /tickets.

Authentication

Scopes, key rotation, and least privilege.

Rate limits

Write tier (30/min) and backoff on 429.

Migrating from legacy

Map legacy POST /public/tickets to v1.