# Create a customer

`POST https://app.booksbyinstant.com/api/integrator/v1/customers`

A new customer and its first member, who owns it and is an admin. The member's first chat turn starts the company's setup conversation. Approvals need a second member: nobody approves their own submission, and every new customer has the default bill approval workflow, so a bill the only member posts waits until a second member approves it; the answer does not say so. A country without a setup of its own gets the general company setup.

operationId `createCustomer`; tag Customers.

## Example request

cURL:

```bash
curl -X POST 'https://app.booksbyinstant.com/api/integrator/v1/customers' \
  -H "Authorization: Bearer $INTEGRATOR_CREDENTIAL" \
  -H "Content-Type: application/json" \
  -d '{
  "reference": "string",
  "country": "AD",
  "member": {
    "reference": "string",
    "name": "string",
    "language": "en",
    "timezone": "Europe/Copenhagen"
  }
}'
```

JavaScript:

```javascript
// Node 18 or later, in an ES module (.mjs), which allows the top-level await.
const res = await fetch("https://app.booksbyinstant.com/api/integrator/v1/customers", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.INTEGRATOR_CREDENTIAL}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "reference": "string",
    "country": "AD",
    "member": {
      "reference": "string",
      "name": "string",
      "language": "en",
      "timezone": "Europe/Copenhagen"
    }
  }),
});
const data = await res.json();
```

Python:

```python
import os
import requests

res = requests.post(
    "https://app.booksbyinstant.com/api/integrator/v1/customers",
    headers={
        "Authorization": f"Bearer {os.environ['INTEGRATOR_CREDENTIAL']}",
    },
    json={
        "reference": "string",
        "country": "AD",
        "member": {
            "reference": "string",
            "name": "string",
            "language": "en",
            "timezone": "Europe/Copenhagen",
        },
    },
)
data = res.json()
```

## Authorization

- Bearer token `live_<100 hex>`: `Authorization: Bearer <secret>`. A 401 answers `WWW-Authenticate: Bearer realm="instant-integrator-api"`.

## Request body

At most 4096 bytes.

`application/json`, required: object; no other fields

- `reference` (string; required; 1 to 1000 characters): The integrator's own reference: 1 to 200 characters after spaces at either end are trimmed. Any other whitespace at an end (a tab, a newline, a no-break space) is refused, never trimmed.
- `country` (string; required; one of `AD`, `AE`, `AF`, `AG`, `AI`, `AL`, `AM`, `AO`, `AQ`, `AR`, `AS`, `AT`, `AU`, `AW`, `AX`, `AZ`, `BA`, `BB`, `BD`, `BE`, `BF`, `BG`, `BH`, `BI`, `BJ`, `BL`, `BM`, `BN`, `BO`, `BQ`, `BR`, `BS`, `BT`, `BV`, `BW`, `BY`, `BZ`, `CA`, `CC`, `CD`, `CF`, `CG`, `CH`, `CI`, `CK`, `CL`, `CM`, `CN`, `CO`, `CR`, `CU`, `CV`, `CW`, `CX`, `CY`, `CZ`, `DE`, `DJ`, `DK`, `DM`, `DO`, `DZ`, `EC`, `EE`, `EG`, `EH`, `ER`, `ES`, `ET`, `FI`, `FJ`, `FK`, `FM`, `FO`, `FR`, `GA`, `GB`, `GD`, `GE`, `GF`, `GG`, `GH`, `GI`, `GL`, `GM`, `GN`, `GP`, `GQ`, `GR`, `GS`, `GT`, `GU`, `GW`, `GY`, `HK`, `HM`, `HN`, `HR`, `HT`, `HU`, `ID`, `IE`, `IL`, `IM`, `IN`, `IO`, `IQ`, `IR`, `IS`, `IT`, `JE`, `JM`, `JO`, `JP`, `KE`, `KG`, `KH`, `KI`, `KM`, `KN`, `KP`, `KR`, `KW`, `KY`, `KZ`, `LA`, `LB`, `LC`, `LI`, `LK`, `LR`, `LS`, `LT`, `LU`, `LV`, `LY`, `MA`, `MC`, `MD`, `ME`, `MF`, `MG`, `MH`, `MK`, `ML`, `MM`, `MN`, `MO`, `MP`, `MQ`, `MR`, `MS`, `MT`, `MU`, `MV`, `MW`, `MX`, `MY`, `MZ`, `NA`, `NC`, `NE`, `NF`, `NG`, `NI`, `NL`, `NO`, `NP`, `NR`, `NU`, `NZ`, `OM`, `PA`, `PE`, `PF`, `PG`, `PH`, `PK`, `PL`, `PM`, `PN`, `PR`, `PS`, `PT`, `PW`, `PY`, `QA`, `RE`, `RO`, `RS`, `RU`, `RW`, `SA`, `SB`, `SC`, `SD`, `SE`, `SG`, `SH`, `SI`, `SJ`, `SK`, `SL`, `SM`, `SN`, `SO`, `SR`, `SS`, `ST`, `SV`, `SX`, `SY`, `SZ`, `TC`, `TD`, `TF`, `TG`, `TH`, `TJ`, `TK`, `TL`, `TM`, `TN`, `TO`, `TR`, `TT`, `TV`, `TW`, `TZ`, `UA`, `UG`, `UM`, `US`, `UY`, `UZ`, `VA`, `VC`, `VE`, `VG`, `VI`, `VN`, `VU`, `WF`, `WS`, `YE`, `YT`, `ZA`, `ZM`, `ZW`): An assigned ISO 3166-1 alpha-2 code in capitals, such as DK (GB, not UK).
- `member` (object; required; no other fields)
  - `reference` (string; required; 1 to 1000 characters): The integrator's own reference: 1 to 200 characters after spaces at either end are trimmed. Any other whitespace at an end (a tab, a newline, a no-break space) is refused, never trimmed.
  - `name` (string; required; at least 1 character): The member's name: 1 to 120 characters after leading and trailing whitespace is removed. With two or more words, the last is the last name.
  - `language` (string; required; one of `en`, `de`, `sv`, `nb`, `da`, `fr`, `es`, `pl`, `pt-BR`, `it`, `hr`, `tr`, `he`, `ar`, `ro`): One of Instant's languages.
  - `timezone` (string; 1 to 100 characters): An IANA time zone.

Example, built from the schema:

```json
{
  "reference": "string",
  "country": "AD",
  "member": {
    "reference": "string",
    "name": "string",
    "language": "en",
    "timezone": "Europe/Copenhagen"
  }
}
```

## Responses

### 201

The customer and its member.

`application/json`: object

- `customer` (object; required): A customer: a company in Instant that the integrator created.
  - `id` (string · uuid; required): The customer's id.
  - `reference` (string; required): The integrator's own reference for the customer.
  - `status` (string; required; one of `active`, `paused`): paused while the integrator has paused the customer.
  - `country` (string or null; required): The customer's ISO 3166-1 alpha-2 country code, in capitals, or null when none is recorded.
  - `createdAt` (string · date-time; required): When the customer was created. ISO 8601 in UTC with milliseconds, such as 2026-11-06T10:00:00.000Z.
  - `pausedAt` (string · date-time or null; required): When the customer was paused, or null while it is active. ISO 8601 in UTC with milliseconds, such as 2026-11-06T10:00:00.000Z.
- `member` (object; required): A person in a customer, with a role and entity access.
  - `id` (string · uuid; required): The member's id.
  - `reference` (string; required): The integrator's own reference for the member, unique across all its customers.
  - `name` (string; required): The member's name.
  - `role` (string; required; one of `admin`, `user`, `auditor`): admin manages the company and sees every entity, user works within their entities, auditor reads.
  - `owner` (boolean; required): True for the one member who owns the customer.
  - `language` (string or null; required): The member's language: one of the language values the requests take, or null when none is set.
  - `timezone` (string or null; required): The member's IANA time zone, or null when none is set.
  - `active` (boolean; required): False while the member is deactivated.
  - `joinedAt` (string · date-time; required): When the member joined the customer. ISO 8601 in UTC with milliseconds, such as 2026-11-06T10:00:00.000Z.
  - `deactivatedAt` (string · date-time or null; required): When the member was deactivated, or null while active. ISO 8601 in UTC with milliseconds, such as 2026-11-06T10:00:00.000Z.
  - `entityAccess` (one of 2 shapes; required): Which of the customer's entities the member works in: all of them, or a selection. An admin always has all. A deactivated member shows the selection that reactivating them restores.
    - either object
      - `mode` (string; required; always `all`)
    - or object
      - `mode` (string; required; always `selected`)
      - `entityIds` (array of string · uuid; required): The entity ids of the selection, sorted.
  - `tokens` (object; required)
    - `active` (integer; required; at least `0`): How many of the member's tokens are active and unexpired, at most 20.

Example, built from the schema:

```json
{
  "customer": {
    "id": "01900000-0000-7000-8000-000000000000",
    "reference": "string",
    "status": "active",
    "country": "string",
    "createdAt": "2026-01-15T09:30:00.000Z",
    "pausedAt": "2026-01-15T09:30:00.000Z"
  },
  "member": {
    "id": "01900000-0000-7000-8000-000000000000",
    "reference": "string",
    "name": "string",
    "role": "admin",
    "owner": true,
    "language": "string",
    "timezone": "string",
    "active": true,
    "joinedAt": "2026-01-15T09:30:00.000Z",
    "deactivatedAt": "2026-01-15T09:30:00.000Z",
    "entityAccess": {
      "mode": "all"
    },
    "tokens": {
      "active": 0
    }
  }
}
```

### 400

The body is not one JSON object, or a field is invalid; `error` says which.

`application/json`: object; `Error`

Every answer that is not a success.

- `error` (string; required): Instant's sentence for people. A 4xx keeps the refusal's own sentence; a 5xx always says "Instant is temporarily unavailable. Please try again shortly."
- `code` (string; required): Stable, and what a caller branches on: VALIDATION_ERROR (400), UNAUTHENTICATED (401), FORBIDDEN (403), NOT_FOUND (404), CONFLICT (409), LIMIT_EXCEEDED (413), UNSUPPORTED_MEDIA_TYPE (415), UNREADABLE_FILE (422), RATE_LIMITED (429) and UNAVAILABLE (5xx). More codes may be added; treat one you do not know by its status.
- `retryAfter` (integer; at least `1`): Seconds to wait before retrying, also sent as the `Retry-After` header. Present only when there is a wait, as on a 429.
- `existingId` (string · uuid): On a 409 that names the object already there, such as a customer with that reference: its id.

Example, built from the schema:

```json
{
  "error": "string",
  "code": "VALIDATION_ERROR",
  "retryAfter": 1,
  "existingId": "01900000-0000-7000-8000-000000000000"
}
```

### 401

The credential is missing, malformed, unknown, revoked or rotated, or its integrator is disabled. All of these answer the same way.

Headers:

- `WWW-Authenticate` (string): Bearer realm="instant-integrator-api"

`application/json`: the `Error` object, as in 400.

### 409

A customer with that reference already exists: the answer carries its `existingId`, so a retry after a lost answer finds what it created. Or a member with that reference already exists, and the answer has no id.

`application/json`: the `Error` object, as in 400.

### 413

The body is over 4096 bytes.

`application/json`: the `Error` object, as in 400.

### 415

The body is not sent as `application/json`.

`application/json`: the `Error` object, as in 400.

### 5XX

Instant is temporarily unavailable. Retry later, with backoff.

`application/json`: the `Error` object, as in 400.

---

Page: https://booksbyinstant.com/docs/create-customer/ · Overview: https://booksbyinstant.com/docs/index.md
