# POST /v1/customers

**Service:** Customers  
**Operation:** `CustomerService_CreateCustomer`

Adds a new customer — company details, addresses, and contacts — to your company. Company name and email are required; a tax identifier is optional (in v1 that means an ABN). The company name must be unique within your company (matched case-insensitively); a duplicate is rejected with HTTP 400 (validation_failure). To make a retry safe, send an idempotency key in `requestId`; a repeat with the same key can never create a second customer — it is rejected with HTTP 409 carrying the original customer's id. Reference the created customer by its id when creating an order or quote.

## Request body

`CreateCustomerRequest` (application/json)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `companyName` | string | yes | The customer's company name. Required, and must be unique within your company (matched case-insensitively); a duplicate is rejected. |
| `taxIdentifier` | TaxIdentifier | no | The customer's tax identifier. Optional. In v1 the only accepted scheme is ABN (Australian Business Number); supplying any other scheme is rejected. |
| `taxIdentifier.value` | string | no | The identifier value, e.g. an 11-digit ABN. Its format depends on `type` and is NOT validated in v1: an ABN is accepted as any non-empty string of up to 15 characters. The length cap may widen when more schemes are supported. |
| `taxIdentifier.type` | TaxIdentifierType | no | Which tax / business registration scheme `value` belongs to. Must be a specified scheme when a TaxIdentifier is present. v1 accepts only ABN. The tax / business registration scheme a TaxIdentifier belongs to. v1 accepts only ABN; the remaining values are reserved for future non-AU support.   - TAX_IDENTIFIER_TYPE_UNSPECIFIED: Default, unset value. Not a valid scheme when a TaxIdentifier is supplied.  - TAX_IDENTIFIER_TYPE_ABN: Australian Business Number. The only scheme accepted in v1.  - TAX_IDENTIFIER_TYPE_EU_VAT: EU VAT number. Does not cover the United Kingdom — a UK VAT registration is TAX_IDENTIFIER_TYPE_GB_VAT. Reserved — not accepted in v1.  - TAX_IDENTIFIER_TYPE_US_EIN: US Employer Identification Number. Reserved — not accepted in v1.  - TAX_IDENTIFIER_TYPE_US_TIN: US Taxpayer Identification Number. Reserved — not accepted in v1.  - TAX_IDENTIFIER_TYPE_US_SSN: US Social Security Number (used by sole traders). Reserved — not accepted in v1.  - TAX_IDENTIFIER_TYPE_GB_VAT: United Kingdom VAT registration number. Reserved — not accepted in v1.  - TAX_IDENTIFIER_TYPE_NZ_GST: New Zealand GST number (the IRD number of a GST-registered business). Reserved — not accepted in v1. One of: TAX_IDENTIFIER_TYPE_UNSPECIFIED, TAX_IDENTIFIER_TYPE_ABN, TAX_IDENTIFIER_TYPE_EU_VAT, TAX_IDENTIFIER_TYPE_US_EIN, TAX_IDENTIFIER_TYPE_US_TIN, TAX_IDENTIFIER_TYPE_US_SSN, TAX_IDENTIFIER_TYPE_GB_VAT, TAX_IDENTIFIER_TYPE_NZ_GST. |
| `email` | string | yes | The customer's email address. Required; must be a valid email address. |
| `phone` | string | no | The customer's phone number. |
| `billingAddress` | Address | no | The customer's billing address. |
| `billingAddress.address1` | string | no | First address line (street number and name). |
| `billingAddress.address2` | string | no | Second address line (unit, suite, or similar). |
| `billingAddress.city` | string | no | City or suburb. |
| `billingAddress.state` | string | no | State, province, or region. |
| `billingAddress.postalCode` | string | no | Postal code (ZIP code, postcode). |
| `billingAddress.countryCode` | string | no | Country, as an uppercase ISO 3166-1 alpha-2 code (e.g. "AU"). Optional; when supplied, any other form is rejected. |
| `deliveryAddresses` | Address[] | no | The customer's delivery addresses. |
| `deliveryAddresses.address1` | string | no | First address line (street number and name). |
| `deliveryAddresses.address2` | string | no | Second address line (unit, suite, or similar). |
| `deliveryAddresses.city` | string | no | City or suburb. |
| `deliveryAddresses.state` | string | no | State, province, or region. |
| `deliveryAddresses.postalCode` | string | no | Postal code (ZIP code, postcode). |
| `deliveryAddresses.countryCode` | string | no | Country, as an uppercase ISO 3166-1 alpha-2 code (e.g. "AU"). Optional; when supplied, any other form is rejected. |
| `contacts` | CustomerContact[] | no | The customer's contacts, at most 50 on a create. Each contact's name is required; its id is assigned by the server, so omit it on create. |
| `contacts.contactId` | string | no | The contact's unique id. |
| `contacts.name` | string | no | The contact's name. |
| `contacts.email` | string | no | The contact's email address. |
| `contacts.phone` | string | no | The contact's phone number. |
| `contacts.mobile` | string | no | The contact's mobile number. |
| `requestId` | string | no | Optional idempotency key for this request: an opaque, client-generated UUID, scoped to the API key that sends it. Requests carrying the same key are executed at most once, so a retry can never create a second copy. Any repeat is rejected with HTTP 409: if the original request completed, the body's `resourceId` carries the id it created; if its outcome is still unknown, or the key is reused with a materially different body, verify with a read before retrying with a fresh key. Keys are retained for at least 24 hours. If the idempotency store is unavailable, requests carrying a key are rejected with HTTP 503 (requests without a key are unaffected). Omit the key for no idempotency guarantee. |
| `fields` | string | no | Comma-separated response fields to include, using camelCase JSON names (e.g. `orderId,total.amountMicros`). Dot paths reach into nested objects and map transparently across arrays. Paths are relative to the resource, not the response envelope; envelope keys are always preserved. Only 2xx JSON responses are filtered; error bodies pass through unmodified. Unknown names are silently ignored. Takes precedence over `excludeFields` when both are provided. |
| `excludeFields` | string | no | Comma-separated response fields to exclude, using camelCase JSON names. Dot paths and array-transparency work the same as `fields`. Paths are relative to the resource, not the response envelope. Only 2xx JSON responses are filtered; error bodies pass through unmodified. Ignored when `fields` is also provided. |

## Responses

| Status | Schema | Description |
| --- | --- | --- |
| 200 | `CreateCustomerResponse` | A successful response. |
| 400 | `Error` | The request was rejected because it failed validation (for example a missing required field or a duplicate company name). The body is a validation-failure envelope: an overall type and message, the echoed `requestId`, and one entry per field-level problem (each with a stable code, a message, and a param pointing at the offending field). |
| 401 | `Error` | The request is missing a valid bearer token, or the token is invalid or expired. |
| 403 | `Error` | The token is valid but does not permit this action, or the resource belongs to a company the token cannot act for. The error type is permission_denied. |
| 409 | `Error` | The idempotency key in `requestId` conflicts with an earlier use: the original request already completed (`resourceId` in the error body carries the id of the customer it created), its outcome is still unknown, or the key was reused with a materially different body. Verify the existing customer with ListCustomers (filter by `companyName` and compare the full name), then send a new `requestId` to create a new customer. |
| 429 | `Error` | The request was throttled (rate_limited) or exceeded a size limit (resource_exhausted). When throttled, the Retry-After header says how many seconds to wait before retrying; a resource_exhausted request will fail the same way if retried unchanged. |
| default | `Error` | Any other error. The body is the same error envelope every error uses: a short stable type identifying the kind of failure (for example "rate_limited" or "internal"), a human-readable message, and the request's idempotency key echoed back when one was supplied. |

## Returns

`CreateCustomerResponse`

| Field | Type | Description |
| --- | --- | --- |
| `customer` | Customer | The created customer. |
| `customer.customerId` | string | The customer's unique id. |
| `customer.companyName` | string | The customer's company name. Unique within your company and matched case-insensitively when resolving. |
| `customer.taxIdentifier` | TaxIdentifier | The customer's tax identifier, if set. Not required to be unique. On read the scheme is ABN for existing (Australian) customers. |
| `customer.taxIdentifier.value` | string | The identifier value, e.g. an 11-digit ABN. Its format depends on `type` and is NOT validated in v1: an ABN is accepted as any non-empty string of up to 15 characters. The length cap may widen when more schemes are supported. |
| `customer.taxIdentifier.type` | TaxIdentifierType | Which tax / business registration scheme `value` belongs to. Must be a specified scheme when a TaxIdentifier is present. v1 accepts only ABN. The tax / business registration scheme a TaxIdentifier belongs to. v1 accepts only ABN; the remaining values are reserved for future non-AU support.   - TAX_IDENTIFIER_TYPE_UNSPECIFIED: Default, unset value. Not a valid scheme when a TaxIdentifier is supplied.  - TAX_IDENTIFIER_TYPE_ABN: Australian Business Number. The only scheme accepted in v1.  - TAX_IDENTIFIER_TYPE_EU_VAT: EU VAT number. Does not cover the United Kingdom — a UK VAT registration is TAX_IDENTIFIER_TYPE_GB_VAT. Reserved — not accepted in v1.  - TAX_IDENTIFIER_TYPE_US_EIN: US Employer Identification Number. Reserved — not accepted in v1.  - TAX_IDENTIFIER_TYPE_US_TIN: US Taxpayer Identification Number. Reserved — not accepted in v1.  - TAX_IDENTIFIER_TYPE_US_SSN: US Social Security Number (used by sole traders). Reserved — not accepted in v1.  - TAX_IDENTIFIER_TYPE_GB_VAT: United Kingdom VAT registration number. Reserved — not accepted in v1.  - TAX_IDENTIFIER_TYPE_NZ_GST: New Zealand GST number (the IRD number of a GST-registered business). Reserved — not accepted in v1. One of: TAX_IDENTIFIER_TYPE_UNSPECIFIED, TAX_IDENTIFIER_TYPE_ABN, TAX_IDENTIFIER_TYPE_EU_VAT, TAX_IDENTIFIER_TYPE_US_EIN, TAX_IDENTIFIER_TYPE_US_TIN, TAX_IDENTIFIER_TYPE_US_SSN, TAX_IDENTIFIER_TYPE_GB_VAT, TAX_IDENTIFIER_TYPE_NZ_GST. |
| `customer.email` | string | The customer's email address, if set. |
| `customer.phone` | string | The customer's phone number. |
| `customer.defaultPriceLevelId` | string | The customer's default price level, by id. Read reference only; line pricing is supplied by the caller on each order line. |
| `customer.defaultPriceLevelName` | string | The name of the customer's default price level. |
| `customer.billingAddress` | Address | The customer's billing address. |
| `customer.billingAddress.address1` | string | First address line (street number and name). |
| `customer.billingAddress.address2` | string | Second address line (unit, suite, or similar). |
| `customer.billingAddress.city` | string | City or suburb. |
| `customer.billingAddress.state` | string | State, province, or region. |
| `customer.billingAddress.postalCode` | string | Postal code (ZIP code, postcode). |
| `customer.billingAddress.countryCode` | string | Country, as an uppercase ISO 3166-1 alpha-2 code (e.g. "AU"). Optional; when supplied, any other form is rejected. |
| `customer.deliveryAddresses` | Address[] | The customer's delivery addresses. |
| `customer.deliveryAddresses.address1` | string | First address line (street number and name). |
| `customer.deliveryAddresses.address2` | string | Second address line (unit, suite, or similar). |
| `customer.deliveryAddresses.city` | string | City or suburb. |
| `customer.deliveryAddresses.state` | string | State, province, or region. |
| `customer.deliveryAddresses.postalCode` | string | Postal code (ZIP code, postcode). |
| `customer.deliveryAddresses.countryCode` | string | Country, as an uppercase ISO 3166-1 alpha-2 code (e.g. "AU"). Optional; when supplied, any other form is rejected. |
| `customer.contacts` | CustomerContact[] | The customer's contacts. |
| `customer.contacts.contactId` | string | The contact's unique id. |
| `customer.contacts.name` | string | The contact's name. |
| `customer.contacts.email` | string | The contact's email address. |
| `customer.contacts.phone` | string | The contact's phone number. |
| `customer.contacts.mobile` | string | The contact's mobile number. |
| `customer.isOnCreditHold` | boolean | Whether the customer is currently on credit hold. |
| `customer.disableTaxByDefault` | boolean | Whether tax is disabled by default for this customer. |
| `customer.lastOrderAt` | string | When the customer most recently placed an order. Populated on ListCustomers entries; not currently returned by GetCustomer. |

---

Source: https://developer.factory.app/reference/customers/create-customer · Factory Sales API v1
