Browse API docs

Customers

Customers are the people who’ve purchased tickets in your account. A customer record is created on the first paid order; subsequent orders attach to the same record (matched by email).

Use this endpoint to sync your buyer list to a CRM, mailing list, or analytics tool.

GET /admin/customers

Returns customers for your account, newest first, with aggregate stats. The list is paginated with a cursor.

curl -H "Authorization: Bearer your-token-here" \
  -H "Accept: application/json" \
  https://app.usetix.io/admin/customers

Query parameters:

Parameter Description
period One of today, week, month, year, all. Filters customers by when the customer record was created. Defaults to all (no time restriction). The period applies only to the current request.
event_slug Only customers who bought at least one ticket to this event.
query Free-text search across email, name, and company.
marketing_only 1 to return only customers who opted into marketing.
limit Customers per page, from 1 to 100. Defaults to 50.
page Opaque cursor from the previous response’s pagination.next_page value. Do not parse or construct it.

Response:

{
  "customers": [
    {
      "id": 17,
      "email": "jane@example.com",
      "salutation": "ms",
      "title": "Dr.",
      "name": "Jane Doe",
      "company": null,
      "phone": "+49 30 1234567",
      "total_spent": { "amount": "126.00", "currency": "EUR" },
      "marketing_consent": true,
      "marketing_consent_at": "2026-04-22T12:34:50Z",
      "created_at": "2026-04-22T12:34:50Z"
    }
  ],
  "stats": {
    "customer_count": 1,
    "total_spent": { "amount": "126.00", "currency": "EUR" }
  },
  "pagination": {
    "total_count": 1,
    "limit": 50,
    "next_page": null
  }
}

stats and pagination.total_count describe the full filtered result, not only the returned page. While another page exists, the response also includes an RFC 8288 Link response header with rel="next"; X-Total-Count contains the total number of matching customers. next_page is null on the final page. To sync every customer, follow next_page (or the Link header) until it is null.

GET /admin/customers/:id

Returns a single customer along with all their paid orders.

curl -H "Authorization: Bearer your-token-here" \
  -H "Accept: application/json" \
  https://app.usetix.io/admin/customers/17

Response:

{
  "id": 17,
  "email": "jane@example.com",
  "salutation": "ms",
  "title": "Dr.",
  "name": "Jane Doe",
  "company": null,
  "phone": "+49 30 1234567",
  "total_spent": { "amount": "126.00", "currency": "EUR" },
  "marketing_consent": true,
  "marketing_consent_at": "2026-04-22T12:34:50Z",
  "created_at": "2026-04-22T12:34:50Z",
  "orders": [
    {
      "public_id": "abcd1234efgh5678",
      "order_code": "7K3Q9D2A",
      "display_number": "7K3Q-9D2A",
      "status": "paid",
      "customer_name": "Jane Doe",
      "customer_email": "jane@example.com",
      "total": { "amount": "42.00", "currency": "EUR" },
      "payment_provider": "stripe",
      "paid_at": "2026-04-22T12:34:50Z",
      "created_at": "2026-04-22T12:34:00Z",
      "item_count": 2,
      "attribution": {}
    }
  ]
}

The orders array uses the same shape as the orders endpoint.

PATCH /admin/customers/:id

Corrects a customer’s details. Requires a write token. Send any of salutation, title, name, company and phone; omitted fields stay unchanged, and an empty string clears a field.

curl -X PATCH \
  -H "Authorization: Bearer your-write-token-here" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  https://app.usetix.io/admin/customers/17 \
  -d '{ "customer": { "salutation": "ms", "title": "Dr.", "name": "Jane Doe", "company": "Acme GmbH" } }'

A successful update returns the customer with 200 OK. An unknown salutation or a title longer than 50 characters returns 422 with errors. The email cannot be changed: it signs the customer in to your shop and matches their orders. A later purchase brings the name, phone and company the buyer enters but never clears a field they leave empty; salutation and title stay as you set them. Co-organizers cannot change customer details (403).

Customer interactions

Use the nested interactions resource to keep a factual CRM timeline for a customer. Reading requires a read token; creating an interaction requires a write token.

GET /admin/customers/:customer_id/contacts

Returns interactions newest first. The endpoint uses cursor pagination with limit (default 50, maximum 100) and the opaque page value returned as pagination.next_page.

{
  "contacts": [
    {
      "id": 91,
      "customer_id": 17,
      "event_slug": "spring-showcase",
      "order_id": "abcd1234efgh5678",
      "kind": "email_sent",
      "note": "Asked for the missing menu choice.",
      "occurred_at": "2026-04-23T09:15:00Z",
      "creator": { "id": 4, "name": "Sam Organizer" },
      "created_at": "2026-04-23T09:15:02Z",
      "updated_at": "2026-04-23T09:15:02Z",
      "editable": true
    }
  ],
  "pagination": {
    "total_count": 1,
    "limit": 50,
    "next_page": null
  }
}

GET /admin/customers/:customer_id/contacts/:id returns one interaction in the same shape.

POST /admin/customers/:customer_id/contacts

Records an interaction that actually happened. kind is one of email_sent, email_received, phone_call_made, phone_call_received, in_person, or note. An internal note is part of the timeline but does not count as contacting the customer.

curl -X POST \
  -H "Authorization: Bearer your-write-token-here" \
  -H "Content-Type: application/json" \
  https://app.usetix.io/admin/customers/17/contacts \
  -d '{
    "event_slug": "spring-showcase",
    "order_public_id": "abcd1234efgh5678",
    "customer_contact": {
      "kind": "email_sent",
      "note": "Asked for the missing menu choice."
    }
  }'

event_slug, order_public_id, and occurred_at are optional. The referenced order must belong to the customer. A successful request returns 201 Created, the interaction JSON, and a Location header.

Customer fields

Field Type Notes
id integer Internal numeric ID. Path parameter.
email string Lowercased, normalized email. Uniquely identifies a customer within an account. Read-only.
salutation string | null How to address the customer: ms, mr, mx, or null. Set by you, never by checkout.
title string | null Title written before the name, such as Dr.. Up to 50 characters. Set by you, never by checkout.
name string | null Buyer’s name as entered at their latest checkout, or as you corrected it.
company string | null Optional company / organization.
phone string | null Phone number from checkout or as you set it.
total_spent.amount string Lifetime spend across paid orders, as a decimal string. Refunded amounts subtract.
total_spent.currency string ISO 4217 code (your account currency).
marketing_consent boolean true if the customer opted into marketing emails at any checkout.
marketing_consent_at string | null ISO 8601 UTC of when consent was given. null if never given.
created_at string ISO 8601 UTC of when this customer record was created (first paid order).

Correct or delete an interaction

PATCH /admin/customers/:customer_id/contacts/:id requires a write token:

{
  "customer_contact": {
    "note": "Corrected call summary",
    "kind": "phone_call_received",
    "occurred_at": "2026-09-08T12:00:00Z"
  }
}

All three fields are optional for updates; omitted fields remain unchanged. The customer, creator, event and order cannot be reassigned. A successful update returns the interaction with 200 OK; invalid values return 422 with errors.

DELETE /admin/customers/:customer_id/contacts/:id requires a write token and permanently removes the interaction, returning 204 No Content.

Interaction responses include updated_at (ISO 8601 UTC) and editable. Automatically recorded announcement deliveries have editable: false; attempts to edit or delete them return 403. Manual email and call logs remain editable. Read-only tokens cannot update or delete entries (401). Records outside the account or specified customer return 404.

Co-organizers must supply an assigned event_slug and the customer’s order_public_id (order code); only contacts attached to that exact event and order are accessible for edits and deletion.