> ## Documentation Index
> Fetch the complete documentation index at: https://developer.qminder.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Creating a Location

> Create a new location in your Qminder account.

To create a location, send a POST request to `/locations`:

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.qminder.com/locations \
    -H "X-Qminder-REST-API-Key: YOUR_API_KEY" \
    -H "X-Qminder-API-Version: 2020-09-01" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "SF City Hall",
      "latitude": 37.7792792,
      "longitude": -122.4214304,
      "address": "1 Dr Carlton B Goodlett Pl, San Francisco, CA 94102, United States",
      "country": "US",
      "languages": ["en", "et", "fr-CA"]
    }'
  ```
</CodeGroup>

**Required fields:**

* `name` - Location name (max 30 characters)
* `latitude` - Geographical latitude (-90 to 90)
* `longitude` - Geographical longitude (-180 to 180)
* `address` - Postal address (max 300 characters)
* `country` - ISO 3166-1 alpha-2 country code (e.g. "US", "CA")

**Optional fields:**

* `languages` - Languages available at this location (see below). Defaults to `["en"]` if omitted.
* `inputFields` - Custom input fields for the location (see below). If omitted, three default fields are created (first name, last name, phone number).
* `lines` - Custom lines (queues) for the location (see below). If omitted, two default lines are created ("Main Service" and "Information").
* `openingHours` - Opening hours configuration (see below). If omitted, the location defaults to 24/7 (00:00-23:59 every day).

**Response (201 Created):**

```json theme={null}
{
  "id": "12345"
}
```

### Languages

You can configure which languages are available at a location by providing an array of ISO 639 / BCP 47 language codes:

```json theme={null}
{
  "languages": ["en", "et", "fr-CA"]
}
```

* The list must include `"en"` (English)
* No duplicate codes allowed
* All codes must be supported (e.g. `en`, `et`, `fr`, `de`, `zh`, `zh-TW`, `fr-CA`, `pt-PT`)
* Order is preserved — the first language is the primary display language
* If omitted, defaults to `["en"]`

### Input Fields

You can specify custom input fields to create with the location by providing an `inputFields` array. If omitted, three default fields are created: first name, last name, and phone number.

Each field uses the same schema as the standalone [Creating an Input Field](/reference/input-fields/creating-an-input-field) endpoint, with these differences:

* `location` — must not be provided (automatically set to the created location)
* `visibleForLines` — must be omitted or empty (lines don't exist yet at creation time)
* `id` — required (client-generated UUID)

**Constraints:**

* Must include at least one `FIRST_NAME` and one `LAST_NAME` field
* Maximum 50 fields
* `FIRST_NAME`, `LAST_NAME`, `EMAIL`, and `PHONE_NUMBER` are singleton types (only one of each allowed)
* `FIRST_NAME` and `LAST_NAME` cannot have `isMandatoryBeforeAdded` or `isMandatoryBeforeServed` set to `true`
* All field and option IDs must be unique within the request and globally
* If fields include translations, the referenced language codes must be declared in the `languages` field

**Example — creating a location with custom input fields:**

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.qminder.com/locations \
    -H "X-Qminder-REST-API-Key: YOUR_API_KEY" \
    -H "X-Qminder-API-Version: 2020-09-01" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Downtown Office",
      "latitude": 37.7749,
      "longitude": -122.4194,
      "address": "123 Main St, San Francisco, CA 94105, United States",
      "country": "US",
      "languages": ["en", "es"],
      "inputFields": [
        {
          "id": "550e8400-e29b-41d4-a716-446655440001",
          "type": "FIRST_NAME",
          "isMandatoryBeforeAdded": false,
          "isMandatoryBeforeServed": false,
          "isMandatoryInRemoteSignIn": false,
          "isVisibleInWaitingDrawer": true,
          "isVisibleInServingDrawer": true,
          "showInRemoteSignIn": true
        },
        {
          "id": "550e8400-e29b-41d4-a716-446655440002",
          "type": "LAST_NAME",
          "isMandatoryBeforeAdded": false,
          "isMandatoryBeforeServed": false,
          "isMandatoryInRemoteSignIn": false,
          "isVisibleInWaitingDrawer": true,
          "isVisibleInServingDrawer": true,
          "showInRemoteSignIn": true
        },
        {
          "id": "550e8400-e29b-41d4-a716-446655440003",
          "type": "TEXT",
          "title": "Reason for visit",
          "visitorFacingTitle": "Why are you here today?",
          "isMandatoryBeforeAdded": true,
          "isMandatoryBeforeServed": false,
          "isMandatoryInRemoteSignIn": false,
          "isVisibleInWaitingDrawer": true,
          "isVisibleInServingDrawer": true,
          "showInRemoteSignIn": true,
          "translations": [
            { "languageCode": "es", "title": "Motivo de la visita", "visitorFacingTitle": "¿Por qué está aquí hoy?" }
          ]
        }
      ]
    }'
  ```
</CodeGroup>

For full details on field types, options, translations, and constraints, see [Creating an Input Field](/reference/input-fields/creating-an-input-field).

### Lines

You can specify custom lines (queues) to create with the location by providing a `lines` array. If omitted, two default lines are created: "Main Service" (TEAL) and "Information" (YELLOW).

Each line object uses the same schema as the standalone [Creating a Line](/reference/lines/creating-a-line) endpoint, with the following difference:

* `appointmentSettings` — not supported in location creation

Each line object has:

* `name` (string, required) - Line name (max 30 characters, trimmed)
* `color` (string, required) - Line color. One of: `VIOLET`, `LAVENDER`, `MARSHMALLOW`, `TEAL`, `MINT`, `CORAL`, `YELLOW`, `ROSE`, `INDIGO`, `BLUE`
* `disabled` (boolean, optional) - Whether the line starts disabled (default: `false`)
* `translations` (array, optional) - Name translations for multi-language support

Each translation object has:

* `languageCode` (string, required) - Language code (e.g. "fr", "es")
* `name` (string, optional) - Translated line name (max 30 characters). Can be `null` as a placeholder.

**Constraints:**

* Between 1 and 50 lines
* No duplicate line names (after trimming, case-sensitive)
* If lines include translations, the referenced language codes must be declared in the `languages` field

**Example — creating a location with custom lines:**

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://api.qminder.com/locations \
    -H "X-Qminder-REST-API-Key: YOUR_API_KEY" \
    -H "X-Qminder-API-Version: 2020-09-01" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Downtown Office",
      "latitude": 37.7749,
      "longitude": -122.4194,
      "address": "123 Main St, San Francisco, CA 94105, United States",
      "country": "US",
      "languages": ["en", "es"],
      "lines": [
        {
          "name": "Customer Support",
          "color": "TEAL"
        },
        {
          "name": "Returns",
          "color": "CORAL",
          "translations": [
            { "languageCode": "es", "name": "Devoluciones" }
          ]
        }
      ]
    }'
  ```
</CodeGroup>

### Opening Hours

You can set regular weekly hours and date-specific exceptions:

```json theme={null}
{
  "openingHours": {
    "regular": {
      "mon": { "businessHours": [{ "opens": { "hours": 9, "minutes": 0 }, "closes": { "hours": 17, "minutes": 0 } }] },
      "tue": { "businessHours": [{ "opens": { "hours": 9, "minutes": 0 }, "closes": { "hours": 17, "minutes": 0 } }] },
      "wed": { "businessHours": [{ "opens": { "hours": 9, "minutes": 0 }, "closes": { "hours": 17, "minutes": 0 } }] },
      "thu": { "businessHours": [{ "opens": { "hours": 9, "minutes": 0 }, "closes": { "hours": 17, "minutes": 0 } }] },
      "fri": { "businessHours": [{ "opens": { "hours": 9, "minutes": 0 }, "closes": { "hours": 17, "minutes": 0 } }] },
      "sat": { "closed": true },
      "sun": { "closed": true }
    },
    "exceptions": [
      { "date": "2026-05-01", "closed": true, "closedReason": "Holiday" },
      { "date": "2026-05-02", "businessHours": [{ "opens": { "hours": 10, "minutes": 0 }, "closes": { "hours": 15, "minutes": 0 } }] }
    ]
  }
}
```

Each day in `regular` can have either:

* `businessHours` - An array of time ranges with `opens` and `closes` (each with `hours` 0-23 and `minutes` 0-59)
* `closed: true` - The location is closed that day

Each entry in `exceptions` requires a `date` (ISO 8601 format) and can include:

* `closed` and optional `closedReason` - Mark the date as closed
* `businessHours` - Custom hours for that specific date

### Error Responses

| Status | Description                                  | Example                                                                                                                                    |
| ------ | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| 400    | Name is blank                                | `{"code": "parameter_invalid_blank", "message": "...", "param": "name"}`                                                                   |
| 400    | Name too long (>30 chars)                    | `{"code": "parameter_invalid_size", "message": "...", "param": "name"}`                                                                    |
| 400    | Invalid coordinates                          | `{"code": "parameter_too_large", "message": "...", "param": "latitude"}`                                                                   |
| 400    | Invalid country code                         | `{"code": "parameter_invalid_country_code", "message": "...", "param": "country"}`                                                         |
| 400    | Invalid opening hours                        | `{"code": "parameter_invalid", "message": "...", "param": "openingHours"}`                                                                 |
| 400    | Languages missing "en"                       | `{"code": "parameter_invalid", "message": "languages must include 'en'", "param": "languages"}`                                            |
| 400    | Duplicate language codes                     | `{"code": "parameter_invalid", "message": "languages must not contain duplicates", "param": "languages"}`                                  |
| 400    | Unsupported language code                    | `{"code": "language_code_not_supported", "message": "Language with the code 'xx' is not supported."}`                                      |
| 400    | Invalid input field                          | `{"code": "parameter_invalid", "message": "...", "param": "inputFields"}`                                                                  |
| 400    | Missing FIRST\_NAME or LAST\_NAME            | `{"code": "parameter_invalid", "message": "...", "param": "inputFields"}`                                                                  |
| 400    | More than 50 input fields                    | `{"code": "parameter_invalid", "message": "...", "param": "inputFields"}`                                                                  |
| 400    | Duplicate field or option IDs                | `{"code": "duplicate_items_in_request", "message": "..."}`                                                                                 |
| 400    | Duplicate singleton type                     | `{"code": "input_field_duplicate", "message": "..."}`                                                                                      |
| 400    | Translation language not in `languages`      | `{"code": "parameter_invalid", "message": "...", "param": "inputFields"}`                                                                  |
| 409    | Field or option ID already exists            | `{"code": "input_field_duplicate", "message": "..."}`                                                                                      |
| 400    | Lines array empty or exceeds 50              | `{"code": "parameter_invalid_size", "message": "size must be between 1 and 50", "param": "lines"}`                                         |
| 400    | Line name is blank                           | `{"code": "parameter_invalid_blank", "message": "must not be blank", "param": "lines[0].name"}`                                            |
| 400    | Line name too long (>30 chars)               | `{"code": "parameter_invalid_size", "message": "size must be between 0 and 30", "param": "lines[0].name"}`                                 |
| 400    | Line color missing                           | `{"code": "parameter_invalid_null", "message": "must not be null", "param": "lines[0].color"}`                                             |
| 400    | Invalid line color name                      | `{"code": "parameter_invalid", "message": "Invalid color name", "param": "lines[0].color"}`                                                |
| 400    | Duplicate line names                         | `{"code": "duplicate_items_in_request", "message": "Duplicate line names in request"}`                                                     |
| 400    | Line translation language not in `languages` | `{"code": "parameter_invalid", "message": "Line translations reference languages not included in 'languages': ...", "param": "languages"}` |
