# Create a customer

`POST /accounting/customers`

Group: Accounting › Customers · Operation ID: `createCustomer`

Creates one customer under the given legal entity and returns only its id (a UUID) — the identifier every other customer route is keyed by. Read the created record back with GET accounting/customers/:id.

`name`, `entityId` are required; `entityId` names an existing legal entity and is not itself updatable afterwards — create a new customer under the right entity instead of moving one. `customerType` defaults to 'default' when omitted; the combination of (name, entityId, customerType) must be unique, and a collision fails the call with DUPLICATE_CUSTOMER, naming the existing customer's id.

customerType 'endCustomer' is not supported by this endpoint today: linking the required partner business record has no equivalent field anywhere in this API's read contract, so a request naming it fails with END_CUSTOMER_NOT_SUPPORTED rather than guessing at that shape.

`addresses` carries the customer's addresses, each naming its own type ('billTo', 'soldTo'); mark at most one entry per type with `isDefault`, and when a type has none marked its first entry becomes that type's default. `externalIdentifiers` accepts the customer's initial set, each fieldName matching an active CustomerExternalIdentifierConfiguration (call enumValues/list-style discovery, or POST accounting/customers/search's externalIdentifier filter, to see one already in use).

The call runs in a transaction: a failure writes nothing.

[Open in the interactive reference](https://docs.api.lensing.ai/?op=createCustomer)

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `Api-Version` | header | `"v1"` | yes | The API version this request targets, named by its public identifier. Required on every request; omitting it, or naming a version this company does not have, is answered with 400. This document describes version `v1`. |
| `Idempotency-Key` | header | string | no | An opaque caller-chosen string (1-255 characters) that makes this request safe to retry. Repeating the same key with an identical request body replays the original response instead of re-executing - but only once that original request succeeded; a failed attempt re-executes on retry. Repeating the key with a different body is answered with 422. A key still in flight is answered with 409 - as is a key whose original request was interrupted before it finished, for a few minutes afterwards, until that attempt is presumed dead. A completed response stays replayable for 24 hours. The key is scoped to the caller, not to the action: reusing it for a different action is answered with 409 or 422 rather than treated independently. On read actions this header is ignored. On write actions that cannot offer the guarantee it is answered with `400 IDEMPOTENCY_NOT_SUPPORTED` rather than silently ignored. |

## Request body

Required, `application/json`: createCustomerInput.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes | Customer display name, as it will appear on invoices and official documents. |
| `entityId` | string | yes | Id of the legal entity that owns this customer (a UUID). Not updatable afterwards. |
| `customerType` | string | no | Customer type. One of 'default', 'partner', 'endCustomer'. Defaults to 'default' when omitted. 'endCustomer' is not yet supported by this endpoint (see END_CUSTOMER_NOT_SUPPORTED). |
| `partnerType` | string | no | Partner type, relevant when customerType is 'partner'. One of 'reseller', 'thirdPartyPayer'. |
| `businessType` | string | no | Whether the customer is a registered company or an individual. One of 'company', 'individual'. Defaults to 'company' when omitted. |
| `invoiceEmail` | string | no | Email address that receives invoices and billing statements. |
| `mainEmail` | string | no | Primary business contact email for general correspondence. |
| `taxExempt` | boolean | no | Whether the customer is exempt from tax on all transactions. Defaults to false when omitted. |
| `defaultCurrency` | string | no | Default transaction currency as a 3-letter ISO 4217 code (e.g. USD, EUR, GBP). Defaults to the owning legal entity's own currency when omitted. |
| `segment` | string | no | Market segment classification. One of 'SMB', 'MidMarket', 'Enterprise'. Ignored when businessType is 'individual'. |
| `exemptionNumber` | string | no | Government-issued tax-exemption certificate number. Only storable when taxExempt is true; supplying one otherwise fails with EXEMPTION_NUMBER_REQUIRES_TAX_EXEMPT (taxExempt defaults to false). |
| `paymentTermCode` | string | no | Payment-term code applied to this customer's invoices. Fails with UNKNOWN_REFERENCE when no such payment term exists. |
| `parentId` | string | no | Customer UUID of this customer's parent in the business-partner hierarchy. Fails with UNKNOWN_REFERENCE when no such customer exists. |
| `partnerId` | string | no | Customer UUID of the partner this customer buys through. Fails with UNKNOWN_REFERENCE when no such customer exists. |
| `salesChannel` | string | no | Channel the customer was won through. A SalesChannel member. |
| `additionalContactEmail` | string | no | Further contact addresses, beyond the invoice and main contacts. |
| `mainContactName` | string | no | Name of the customer's main contact person. |
| `preferredLanguage` | string | no | Language the customer prefers correspondence in. A PreferredLanguage member. |
| `crmCustomerId` | string | no | The customer's identifier in the CRM system it was sourced from. |
| `businessIdentificationNumber` | string | no | Government-issued business registration number. |
| `invoiceConsolidation` | string | no | How invoices are consolidated for this customer. An InvoiceConsolidation member. |
| `invoiceDeliveryMode` | string | no | How invoices reach the customer. An InvoiceDeliveryMode member. |
| `isExemptFromCreditCardFee` | boolean | no | Whether the customer is exempt from credit-card surcharges. |
| `billableTravelExpenseInvoiceDetail` | string | no | Whether billable travel and expense items appear itemised or consolidated. An InvoiceDetail member. |
| `status` | string | no | Lifecycle status of the customer record. A CustomerStatus member. |
| `taxExemptCode` | string | no | Code behind the tax exemption, as the authority categorises it. Only meaningful when taxExempt is true. |
| `taxRegistrations` | array of object | no | Tax registrations to record for this customer. Upserted by (country, type): an entry matching an existing registration updates it, anything else is added; registrations left out are untouched. |
| `taxRegistrations[].country` | string | yes | ISO 3166-1 country code the registration applies in. |
| `taxRegistrations[].taxNumber` | string | yes | Official tax identification number issued by the tax authority. |
| `taxRegistrations[].type` | string | yes | Kind of tax identification number. One of 'tax', 'salesTax', 'VAT', 'GST', 'EIN', 'TIN'. |
| `taxRegistrations[].effectiveDate` | string (date) | no | Date the registration becomes valid for tax calculations (YYYY-MM-DD). |
| `taxRegistrations[].isActive` | boolean | no | Whether the registration is used for tax calculations. Defaults to true. |
| `payment` | object | no | Payment-provider link for this customer. `externalPaymentMethodId` requires an `externalCustomerId`, either in the same request or already stored. |
| `payment.provider` | string | no | Payment provider name, e.g. 'Stripe'. Required when any other payment field is supplied. |
| `payment.externalCustomerId` | string | no | The customer's identifier in the payment provider's system, e.g. a Stripe customer id. |
| `payment.externalPaymentMethodId` | string | no | The customer's default payment-method identifier in the provider's system, e.g. a Stripe payment method id. |
| `addresses` | array of object | no | The customer's addresses, each naming its own type. Mark at most one entry per type with isDefault; when a type has none marked, its first entry becomes that type's default. |
| `addresses[].type` | string | yes | Which address this is. One of 'billTo', 'soldTo'. |
| `addresses[].attention` | string | no | Person or department correspondence at this address is directed to. |
| `addresses[].isDefault` | boolean | no | Marks this entry as its type's default. At most one per type; when a type has none marked, its first entry becomes the default. |
| `addresses[].line1` | string | yes | Street address line 1: number, street name, or PO box. |
| `addresses[].line2` | string | no | Apartment, suite, unit, building, floor, etc. |
| `addresses[].city` | string | yes | City or locality. |
| `addresses[].stateProvince` | string | no | State, province, or region. |
| `addresses[].country` | string | yes | Country, as a name or ISO 3166-1 code. |
| `addresses[].zipCode` | string | yes | Postal or ZIP code. |
| `externalIdentifiers` | array of object | no | External identifiers owned by other systems. At most one entry per fieldName; each fieldName must match an active CustomerExternalIdentifierConfiguration or the call fails with UNKNOWN_EXTERNAL_IDENTIFIER. |
| `externalIdentifiers[].fieldName` | string | yes | Configured key of the external identifier, e.g. 'netsuiteSoNumber'. |
| `externalIdentifiers[].value` | string | yes | The identifier as the source system holds it. |
| `externalIdentifiers[].externalUrl` | string | no | Absolute http(s) link to the object in the originating system. |

Example:

```json
{
  "name": "Example Robotics Inc",
  "entityId": "3b7d5e9c-1a24-4f80-9c6d-2e8f70b13a45",
  "customerType": "default",
  "partnerType": "<partnerType>",
  "businessType": "company",
  "invoiceEmail": "billing@example-robotics.com",
  "mainEmail": "<mainEmail>",
  "taxExempt": true,
  "defaultCurrency": "USD",
  "segment": "<segment>",
  "exemptionNumber": "<exemptionNumber>",
  "paymentTermCode": "<paymentTermCode>",
  "parentId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "partnerId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "salesChannel": "<salesChannel>",
  "additionalContactEmail": "<additionalContactEmail>",
  "mainContactName": "<mainContactName>",
  "preferredLanguage": "<preferredLanguage>",
  "crmCustomerId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "businessIdentificationNumber": "<businessIdentificationNumber>",
  "invoiceConsolidation": "<invoiceConsolidation>",
  "invoiceDeliveryMode": "<invoiceDeliveryMode>",
  "isExemptFromCreditCardFee": true,
  "billableTravelExpenseInvoiceDetail": "<billableTravelExpenseInvoiceDetail>",
  "status": "<status>",
  "taxExemptCode": "<taxExemptCode>",
  "taxRegistrations": [
    {
      "country": "<country>",
      "taxNumber": "<taxNumber>",
      "type": "<type>",
      "effectiveDate": "2026-01-15",
      "isActive": true
    }
  ],
  "payment": {
    "provider": "<provider>",
    "externalCustomerId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "externalPaymentMethodId": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
  },
  "addresses": [
    {
      "type": "billTo",
      "line1": "500 Market St",
      "city": "San Francisco",
      "stateProvince": "CA",
      "country": "US",
      "zipCode": "94105",
      "isDefault": true
    }
  ],
  "externalIdentifiers": [
    {
      "fieldName": "<fieldName>",
      "value": "<value>",
      "externalUrl": "<externalUrl>"
    }
  ]
}
```

## Response

`200` Success

Under `data` (createCustomerOutput):

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes | Platform id (a UUID) assigned to the newly created customer. Read the full record with GET accounting/customers/:id. |

## Response headers

- `Idempotency-Replayed` — Present and `true` only when this response replays a previously stored one for the same Idempotency-Key, rather than reflecting a live execution. Absent on a live response - never sent as `false`.

## Errors

| Code | Status |
| --- | --- |
| `INVALID_ENTITY` | 400 |
| `INVALID_FIELD_VALUE` | 400 |
| `MULTIPLE_DEFAULT_ADDRESSES` | 400 |
| `DUPLICATE_CUSTOMER` | 400 |
| `END_CUSTOMER_NOT_SUPPORTED` | 400 |
| `UNKNOWN_EXTERNAL_IDENTIFIER` | 400 |
| `DUPLICATE_EXTERNAL_IDENTIFIER` | 400 |
| `UNKNOWN_REFERENCE` | 400 |
| `UNKNOWN_PAYMENT_PROVIDER` | 400 |
| `PAYMENT_METHOD_REQUIRES_CUSTOMER_ID` | 400 |
| `EXEMPTION_NUMBER_REQUIRES_TAX_EXEMPT` | 400 |
| `IDEMPOTENCY_KEY_CONFLICT` | 409 |
| `IDEMPOTENCY_PAYLOAD_MISMATCH` | 422 |

## Statuses

- `400` — Invalid request or business failure. Codes: INVALID_ENTITY, INVALID_FIELD_VALUE, MULTIPLE_DEFAULT_ADDRESSES, DUPLICATE_CUSTOMER, END_CUSTOMER_NOT_SUPPORTED, UNKNOWN_EXTERNAL_IDENTIFIER, DUPLICATE_EXTERNAL_IDENTIFIER, UNKNOWN_REFERENCE, UNKNOWN_PAYMENT_PROVIDER, PAYMENT_METHOD_REQUIRES_CUSTOMER_ID, EXEMPTION_NUMBER_REQUIRES_TAX_EXEMPT
- `401` — Missing or invalid access token
- `403` — Not authorized
- `404` — Not found
- `409` — The Idempotency-Key is still being processed by another request.
- `422` — The Idempotency-Key was already used with a different request payload.
- `429` — Too many requests
- `500` — Internal server error
