# Customers

> Manage the contacts you invoice and receive from.

Source: /docs/guides/customers

Customers are contacts of the organization. The same records serve as buyers on outgoing invoices and as suppliers on incoming ones (`type`: `buyer`, `seller`, `both`).

The app shows these types with the organization's own words (default Customer and Supplier; for example Client and Vendor). The words are the `terminology` option of `GET` / `PATCH /settings/options`; the stored and accepted `type` values never change:

```bash
curl -X PATCH "$BASE/settings/options" -H "X-API-KEY: $KEY" -H "Content-Type: application/json" \
  -d '{ "terminology": { "buyer": { "singular": "client", "plural": "clients" }, "seller": { "singular": "vendor", "plural": "vendors" } } }'
```

Words are stored in lower case, up to 30 characters each; a role you leave out keeps its current words, and `"terminology": null` resets everything. The same option also names received supplier documents in the app: `"incoming": { "singular": "bill" }` (one of `incoming invoice`, `bill`, `receipt`, `purchase invoice`).

## Fields

| Field | Notes |
| --- | --- |
| `name`, `nameAr`, `tradingName` | Legal name (BT-44), Arabic name for bilingual PDFs, trading name |
| `type` | `buyer` (default), `seller`, `both` |
| `trn` | 15-digit Tax Registration Number (BT-48); validated |
| `peppolId`, `peppolSchemeId` | Peppol participant id, `0235:<TIN>`, where the TIN is the first 10 digits of the TRN; `peppolId` holds the 10-digit TIN without the prefix and `peppolSchemeId` is `0235` |
| `customerNumber` | Your reference; `generateNumber: true` allocates the next number of the `customer` series |
| `email`, `contactName`, `phone`, `website` | Contact details; `email` is the default recipient when sending; if it is empty, the contact person with `receivesInvoices` (primary first) is used |
| `address` | `street`, `additional`, `city`, `emirate`, `postalCode`, `country` (ISO 3166-1 alpha-2, default `AE`) |
| `paymentTermsDays`, `defaultCurrency`, `notes`, `isActive` | Defaults applied in the editor |
| `isCompany`, `legalForm`, `firstName`, `lastName` | Company (default) with legal form, or natural person |
| `category` | Free-text group, e.g. `wholesale` |
| `defaultPriceListId` | Price list applied to this customer (see [Products](/docs/guides/products)) |
| `peppolVerifiedAt` | Set by `POST /customers/{id}/verify-peppol` when the SML confirms the registration |

## Routes

```bash
curl "$BASE/customers?keyword=buyer&type=buyer&perPage=50" -H "X-API-KEY: $KEY"
curl -X POST "$BASE/customers" -H "X-API-KEY: $KEY" -H "Content-Type: application/json" \
  -d '{ "name": "Buyer LLC", "trn": "100000000000011", "email": "ap@buyer.ae", "address": { "city": "Dubai", "country": "AE" }, "generateNumber": true }'
curl -X PATCH "$BASE/customers/{id}" -H "X-API-KEY: $KEY" -H "Content-Type: application/json" -d '{ "paymentTermsDays": 45 }'
curl -X DELETE "$BASE/customers/{id}" -H "X-API-KEY: $KEY"
```

Changing `trn` or `name` updates the contact's draft and validated invoices; a value set differently on one invoice is kept, and submitted invoices never change.

`DELETE` removes a contact without invoices; a contact that has invoices is deactivated instead (`deactivated: true` in the response) so history stays intact. `GET /customers/next-number` previews the next customer number and `GET /customers/verify-number?value=` checks one.

`POST /customers/import` creates up to 500 contacts in one call and returns a per-element result (`201` when all succeed, `207` otherwise).

## Inline buyers on invoices

When you create an invoice with a `buyer` object instead of `buyer.id`, Alya Books matches an existing contact by TRN, then by exact name, and otherwise creates one from the inline data. The `customer.created` webhook fires in that case as well.

## Contact persons and addresses

```bash
curl -X POST "$BASE/customers/{id}/contact-persons" -H "X-API-KEY: $KEY" -H "Content-Type: application/json" \
  -d '{ "salutation": "Ms", "firstName": "Amal", "lastName": "Hassan", "position": "Finance manager", "email": "amal@buyer.ae", "isPrimary": true }'
curl -X POST "$BASE/customers/{id}/addresses" -H "X-API-KEY: $KEY" -H "Content-Type: application/json" \
  -d '{ "kind": "delivery", "label": "Warehouse", "street": "Al Quoz 3", "city": "Dubai", "emirate": "Dubai", "isDefault": true }'
```

`GET`, `PATCH` and `DELETE` on `/customers/{id}/contact-persons/{personId}` and `/customers/{id}/addresses/{addressId}` complete the set. One person per contact is `isPrimary`; one address per `kind` (`delivery`, `billing`, `other`) is `isDefault`. Recurring invoices reference them by `contactPersonId` (email recipient) and `deliveryAddressId` (BT-70 to BT-80).

## Peppol lookup

`GET /customers/peppol-lookup?participantId=0235:1000000000` (a bare 15-digit TRN is accepted and converted to its TIN) validates the format and, when DNS is available, checks the Peppol SML for the participant. The response carries `valid`, `registered` (`true`, `false`, or `null` when the check could not run), `checked` (`sml`, `smk`, `format-only`) and a message. `POST /customers/{id}/verify-peppol` runs the same check for a customer and stores `peppolVerifiedAt` on success. In `mock` ASP mode every well-formed id is reported as registered.
