> For the complete Lynkow documentation index in agent-friendly format, see [llms.txt](/llms.txt).

# SDK Types: Customer

**Publié le** : 2026-08-20
**Catégorie** : Types

# SDK Types: Customer

## `Customer`

*Interface*

The authenticated buyer, as returned by `activation.confirm`, `login`, and `me`.
Serialized through the storefront's anonymous-branch serializer: it carries the
buyer's own contact and account state and NOTHING internal (no tenant id, no
password material, no token internals).

| Property | Type | Optional | Description |
| --- | --- | --- | --- |
| `companyName` | `string \| null` | No | Company name for a business (B2B) buyer. `null` for a personal account, and withheld (`null`) until `emailVerified` is `true`, even if a value is on file. |
| `createdAt` | `string` | No | ISO 8601 datetime the customer record was first created (guest booking or registration). |
| `email` | `string` | No | Account email, normalized (trimmed, lower-cased). The login identifier. Max 320 chars. |
| `emailVerified` | `boolean` | No | `true` once the buyer has confirmed ownership of `email`. Guest bookings placed<br>with the same email before registration appear in `me().bookings` only after<br>this becomes `true`. |
| `firstName` | `string \| null` | No | Buyer first name in the requested profile. `null` when never provided, and withheld (`null`) until `emailVerified` is `true`, even if a value is on file. |
| `hasAccount` | `boolean` | No | `true` once the account is fully established, which is the moment the buyer proves<br>they control `email`: completing `activation.confirm`, verifying their address, or<br>confirming a password reset. A guest row created by a booking, and never claimed<br>through the inbox, reads `false`. |
| `id` | `string` | No | Opaque customer identifier (`'cust_...'`). Stable across sessions. Safe to store client-side. |
| `lastName` | `string \| null` | No | Buyer last name. `null` when never provided, and withheld (`null`) until `emailVerified` is `true`, even if a value is on file. |
| `phone` | `string \| null` | No | Buyer phone number in free form. `null` when never provided, 3 to 40 chars when set, and withheld (`null`) until `emailVerified` is `true`, even if a value is on file. |
| `termsAcceptedAt` | `string \| null` | No | ISO 8601 datetime (e.g. `'2026-07-13T10:30:00.000Z'`) when the buyer accepted the<br>shop's terms. Stamped at `activation.confirm`, from the acceptance made on that<br>page (terms acceptance is always required there). `null` for a guest row that has<br>never been activated. |


---

## `CustomerActivationConfirmInput`

*Interface*

Fields for CustomersService.activation`.confirm`: the token from the emailed
activation link, plus every value CustomerRegisterInput no longer accepts.
This is the only place a buyer's credential, terms acceptance, profile and marketing
consent enter the system, because it is the only point where the caller has proven
they control the address.

| Property | Type | Optional | Description |
| --- | --- | --- | --- |
| `acceptsTerms` | `true` | No | Terms/CGV acceptance. MUST be `true`: the server rejects activation when it is<br>`false` or missing, and the account is not activated. Independent of<br>`marketingOptIn`. Collect it on the activation page itself, from the person<br>completing it; do not carry it over from the form that called `register`. |
| `firstName` | `string` | Yes | Optional buyer first name. Applied only when the account has none on file. |
| `lastName` | `string` | Yes | Optional buyer last name. Applied only when the account has none on file. |
| `marketingOptIn` | `boolean` | Yes | Optional marketing opt-in, unchecked by default. When `true`, the buyer is opted<br>in on every channel in MarketingChannel that carries no consent record yet.<br>A channel where a preference was already expressed, opt-in or opt-out, is left<br>untouched: activation never overrides an existing choice, and such a channel is<br>only changed from the signed-in account. When omitted or `false`, no consent is<br>recorded and the account is still activated. Never blocks activation. |
| `password` | `string` | No | Chosen password. Between 8 and 100 characters. Never stored or logged by the SDK. |
| `phone` | `string` | Yes | Optional buyer phone number. 3 to 40 chars when set. Applied only when the account has none on file. |
| `token` | `string` | No | The single-use, short-lived activation token the buyer received by email. |


---

## `CustomerAddress`

*Interface*

A saved postal address in the authenticated buyer's address book. Optional
address fields are returned as `null`, never omitted.

| Property | Type | Optional | Description |
| --- | --- | --- | --- |
| `address1` | `string` | No | Street line 1 (number and street). Always set. Max 255 characters. |
| `address2` | `string \| null` | No | Street line 2 (apartment, floor, building). `null` when not needed. Max 255 characters. |
| `addressName` | `string \| null` | No | Buyer-chosen label such as `Home` or `Office`. `null` when the buyer did not name it. |
| `city` | `string` | No | City or town. Always set. Max 120 characters. |
| `company` | `string \| null` | No | Company name for a business delivery. `null` for a personal address. Max 180 characters. |
| `countryCode` | `string` | No | ISO 3166-1 alpha-2 country code in uppercase (for example `FR`). |
| `createdAt` | `string` | No | ISO 8601 creation datetime (for example `2026-07-20T10:30:00.000Z`). |
| `firstName` | `string` | No | Recipient first name. Always set. Max 120 characters. |
| `id` | `string` | No | Prefixed wire identifier (for example `addr_01h9kz...`). Stable for the life of the address. |
| `isDefaultBilling` | `boolean` | No | `true` for the buyer's at-most-one default billing address. |
| `isDefaultShipping` | `boolean` | No | `true` for the buyer's at-most-one default shipping address. |
| `lastName` | `string` | No | Recipient last name. Always set. Max 120 characters. |
| `phone` | `string \| null` | No | Contact phone for the delivery. `null` when not provided. Max 32 characters. |
| `postalCode` | `string` | No | Postal or ZIP code as unvalidated free-form text. Always set. Max 32 characters. |
| `province` | `string \| null` | No | Province, state, or region. `null` in countries that do not use one. Max 120 characters. |
| `updatedAt` | `string` | No | ISO 8601 datetime of the last edit. Equal to `createdAt` until the address is edited. |


---

## `CustomerAddressInput`

*Interface*

Fields accepted when saving a new buyer address.

| Property | Type | Optional | Description |
| --- | --- | --- | --- |
| `address1` | `string` | No | Street line 1. Required. Max 255 characters. |
| `address2` | `string \| null` | Yes | Street line 2 (apartment, floor). Pass `null` to clear it. Max 255 characters. |
| `addressName` | `string \| null` | Yes | Optional label such as `Home`. Pass `null` to leave the address unlabeled. Max 120 characters. |
| `city` | `string` | No | City or town. Required. Max 120 characters. |
| `company` | `string \| null` | Yes | Company name for a business delivery. Pass `null` to clear it. Max 180 characters. |
| `countryCode` | `string` | No | ISO 3166-1 alpha-2 country code. The API normalizes it to uppercase. |
| `firstName` | `string` | No | Recipient first name. Required. Max 120 characters. |
| `isDefaultBilling` | `boolean` | Yes | Mark this address as the default billing address, atomically unsetting the previous one. |
| `isDefaultShipping` | `boolean` | Yes | Mark this address as the default shipping address, atomically unsetting the previous one. |
| `lastName` | `string` | No | Recipient last name. Required. Max 120 characters. |
| `metadata` | `Record<string, unknown>` | Yes | Optional buyer-supplied extension data stored with the address but not returned by storefront reads. |
| `phone` | `string \| null` | Yes | Contact phone for the delivery. Pass `null` to clear it. Max 32 characters. |
| `postalCode` | `string` | No | Postal or ZIP code. Required. Max 32 characters. |
| `province` | `string \| null` | Yes | Province, state, or region. Pass `null` to clear it. Max 120 characters. |


---

## `CustomerAddressUpdateInput`

*TypeAlias*

Partial address edit. At least one field must be present or the API returns HTTP 422.

```typescript
type CustomerAddressUpdateInput = AtLeastOne<CustomerAddressInput>
```

---

## `CustomerAuthResult`

*Interface*

The result of a successful `activation.confirm` or `login`. The `token` is an opaque
signed session token: the SDK stores it in memory on the client and attaches it as
`Authorization: Bearer <token>` on subsequent authenticated calls. Persist it in
your own storage (for example a cookie) if the session must survive a page reload.

`register` does NOT return this: it is anonymous and hands out no session. A session
is only ever issued to someone who has proven they control the address.

| Property | Type | Optional | Description |
| --- | --- | --- | --- |
| `customer` | `Customer` | No | The authenticated buyer. |
| `token` | `string` | No | Opaque session token. Attach on authenticated requests; store it to keep the buyer signed in. |


---

## `CustomerBooking`

*TypeAlias*

A booking in the `me` history: the buyer-safe subset of the storefront
Booking shape the authenticated buyer sees for their own reservations.
Contact fields (`guestName`, `guestEmail`) and the booked resource are omitted
here (the buyer's own identity lives on Customer). The `reference` and slot
fields reuse the `Booking` formats; `status` is widened to the full
CustomerBookingStatus lifecycle, because the history is NOT filtered to
confirmed bookings the way a fresh create response is.

```typescript
type CustomerBooking = Pick<Booking, "reference" | "startsAt" | "endsAt" | "partySize"> & { status: CustomerBookingStatus }
```

---

## `CustomerBookingStatus`

*TypeAlias*

The lifecycle status of a booking in the buyer's `me` history. A freshly created
booking is always `'confirmed'`, but a historical booking can also be `'cancelled'`
(and the reserved `'pending'`, `'completed'`, `'no_show'` as later lifecycle
transitions ship), so the history status is wider than a create response's fixed
`'confirmed'`.

```typescript
type CustomerBookingStatus = "pending" | "confirmed" | "cancelled" | "completed" | "no_show"
```

---

## `CustomerEmailVerificationResult`

*Interface*

The result of `verifyEmail`: the buyer's email-verification state after consuming the
token. `emailVerified` is `true` on success (an invalid, expired, or already-used token
throws instead), and once it flips, retro-linked guest bookings placed with the same
email before registration become visible in CustomerSession `bookings`.

| Property | Type | Optional | Description |
| --- | --- | --- | --- |
| `emailVerified` | `boolean` | No | `true` once the token confirmed ownership of the buyer's email. Always `true` on a successful call. |


---

## `CustomerLoginInput`

*Interface*

Credentials for `login`.

| Property | Type | Optional | Description |
| --- | --- | --- | --- |
| `email` | `string` | No | Account email. |
| `password` | `string` | No | Account password. |


---

## `CustomerLogoutOptions`

*Interface*

Options for `logout`.

| Property | Type | Optional | Description |
| --- | --- | --- | --- |
| `everywhere` | `boolean` | Yes | When `true`, revokes EVERY session token issued to this buyer server-side (the<br>"log out everywhere" action), then clears the local token. When omitted or<br>`false`, `logout` only discards the token held by this client and performs no<br>network round-trip. |


---

## `CustomerRegisterInput`

*Interface*

The single field `register` accepts: the address to send an activation link to.

Credentials, terms, profile and marketing consent are deliberately NOT here. An
anonymous caller proves nothing about the address they type, so nothing they type may
take effect on it. Everything that used to live on this type moved to
CustomerActivationConfirmInput, collected on the inbox-linked activation page
from whoever actually opens the link.

| Property | Type | Optional | Description |
| --- | --- | --- | --- |
| `email` | `string` | No | Account email. Normalized server-side (trimmed, lower-cased). The login identifier. |


---

## `CustomerSession`

*Interface*

The result of `me`: the current buyer plus their bookings. Bookings are scoped to
this buyer; retro-linked guest bookings are withheld until `customer.emailVerified`
is `true`.

| Property | Type | Optional | Description |
| --- | --- | --- | --- |
| `bookings` | `CustomerBooking[]` | No | Up to the buyer's 100 most recent bookings. A buyer-safe subset of the Booking shape. |
| `customer` | `Customer` | No | The authenticated buyer. |


---

## `CustomerSpamOptions`

*Interface*

Options for customer writes protected by the storefront anti-spam middleware,
including registration, password-reset requests, and address-book mutations.

Extends: `SubmitOptions`, `BaseRequestOptions`

| Property | Type | Optional | Description |
| --- | --- | --- | --- |
| `fetchOptions` | `RequestInit` | Yes | Raw `fetch()` options merged into this specific request.<br>Useful for setting Next.js cache directives (`next: { revalidate: 60 }`)<br>or custom headers on a per-request basis.<br>These options are shallow-merged with the client-level `fetchOptions`. |
| `formStartedAt` | `number` | Yes | Epoch timestamp in milliseconds when the buyer started filling the form. The SDK<br>sends it as `_ts` so the API can reject submissions that are implausibly fast or<br>stale. When omitted, buyer-email requests use the client-creation time and address<br>writes ensure the value is also old enough for the standard minimum window. Both<br>defaults are clamped to at most 55 minutes before the request so a long-lived client<br>does not become permanently expired. Sites with customized timing bounds must pass<br>the real interaction start here because those bounds are not part of the public<br>settings response. Explicit values are sent unchanged. |
| `locale` | `string` | Yes | Locale override for this specific request.<br>When set, overrides the `locale` configured on the client instance.<br>Must be a locale code enabled on the site (e.g. `'en'`, `'fr'`, `'de'`).<br>If omitted, the client's default locale is used; if that is also unset,<br>the site's default locale applies. |
| `recaptchaToken` | `string` | Yes | Google reCAPTCHA v3 token for spam protection.<br>Required when the form/site has reCAPTCHA enabled (check `form.recaptchaEnabled`).<br>Obtained client-side via `grecaptcha.execute(siteKey, { action: 'submit' })`.<br>When reCAPTCHA is not enabled on the form, this field is ignored.<br>The site key for rendering the reCAPTCHA widget is available at `form.recaptchaSiteKey`. |


---

## `MarketingChannel`

*TypeAlias*

A marketing channel the buyer can consent to. Exposed by its generic channel
name only, never an infrastructure vendor. `'whatsapp'` and `'email'` in v1;
the union is additive as new channels ship.

```typescript
type MarketingChannel = "whatsapp" | "email"
```

---

## `MarketingConsentList`

*Interface*

The consent read/write response: one entry per channel in MarketingChannel.

| Property | Type | Optional | Description |
| --- | --- | --- | --- |
| `channels` | `MarketingConsentState[]` | No | Per-channel effective consent, one entry for every known channel. |


---

## `MarketingConsentState`

*Interface*

The effective consent state for one marketing channel.

| Property | Type | Optional | Description |
| --- | --- | --- | --- |
| `channel` | `MarketingChannel` | No | The channel this entry describes. |
| `optedIn` | `boolean` | No | `true` when the buyer is currently opted in on this channel (opt-out always wins<br>over any prior opt-in). A channel with no consent record reads `false`. |


---

## `MarketingConsentUpdateInput`

*Interface*

Input for `marketingConsent.update`.

| Property | Type | Optional | Description |
| --- | --- | --- | --- |
| `channel` | `MarketingChannel \| "all"` | No | The channel to change, or the literal `'all'` to change every channel at once. |
| `optIn` | `boolean` | No | `false` opts the buyer OUT of the target channel(s); `true` re-opts them IN<br>(recorded as a manual opt-in). Opt-out always wins over a prior opt-in. |


---

## `PasswordResetConfirmInput`

*Interface*

Input for `passwordReset.confirm`.

| Property | Type | Optional | Description |
| --- | --- | --- | --- |
| `password` | `string` | No | The new password. Must satisfy the server's minimum length (8). |
| `token` | `string` | No | The single-use, short-lived reset token the buyer received by email. |


---

## `PasswordResetRequestInput`

*Interface*

Input for `passwordReset.request`.

| Property | Type | Optional | Description |
| --- | --- | --- | --- |
| `email` | `string` | No | The account email to send a reset link to. The call always resolves, whether or not it exists. |