# Customers

A **customer** is the person who holds a ticket. Customers are **email-first**:
you create one with your own `externalId` and an `email` (plus an optional
`name`), and from then on you reference it by its `id` — which is simply the
`externalId` you supplied. That is the entire model you need to know.

> **Tip:** No account or credential is ever requested from a customer or returned
> to you. A customer is just `{ id, email, name, status }` plus the tickets they
> hold.


## Creating a customer

Send your own `externalId` and an email (a `name` is optional). You get back a
customer whose `id` is that same `externalId` — use it everywhere else
(issuance, transfers, lookups).

**curl**

```bash
curl https://api.ticketconnect.example/v1/customers \
  -H "Authorization: Bearer sk_test_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "externalId": "user_42",
    "email": "ada@example.com",
    "name": "Ada Lovelace"
  }'
```

**Response**

```json
{
  "id": "user_42",
  "email": "ada@example.com",
  "name": "Ada Lovelace",
  "status": "active",
  "created_at": "2026-06-05T12:01:00.000Z"
}
```

Requires the `customers:write` scope. This endpoint accepts an
[`Idempotency-Key`](#idempotency) header so retries are safe.

## Provisioning happens transparently

Creating the customer is the only setup step. The moment you `POST
/v1/customers`, the platform quietly does everything needed to make that
customer's future tickets tamper-proof and deliverable behind the scenes:

* It is **idempotent** — creating the same `externalId` again returns the
  existing customer unchanged; nothing is set up twice, and retries are safe.
* It is **invisible** — none of the internal setup is exposed in your request
  or response, and it never asks the customer for anything.
* It is **required before issuance** — a ticket can only be issued to a
  customer that already exists; referencing an unknown `customer_id` at
  issuance returns a `404`.

In short: create the customer first, then issue tickets. The platform handles
the rest.

## The relationship to tickets

Every ticket belongs to exactly one customer at a time. You reference the
customer's `id` as `customer_id` when issuing, and retrieve the customer record
itself at any time:

```bash
curl https://api.ticketconnect.example/v1/customers/user_42 \
  -H "Authorization: Bearer sk_test_your_key_here"
```

When you [transfer a ticket](#transfer-refund-upgrade), it simply
moves from one customer to another — the ticket's identity and tamper-proof
guarantees are unchanged.

## Reference

| Method & path | Scope | Purpose |
| --- | --- | --- |
| `POST /v1/customers` | `customers:write` | Create a customer from `{ externalId, email, name? }`. |
| `GET /v1/customers/:id` | `customers:write` | Retrieve a customer by the `externalId` you supplied. |

See the full [Customers API reference](#api-customers) for field
details.
