# Cancel an appointment Source: https://developer.qminder.com/api-reference/appointments/cancel-an-appointment /api-reference/openapi.json post /v1/appointments/{ticketId}/cancel Cancels a scheduled appointment. # Check in an appointment Source: https://developer.qminder.com/api-reference/appointments/check-in-an-appointment /api-reference/openapi.json post /v1/appointments/{ticketId}/checkin Checks in a visitor for their scheduled appointment, moving them to the queue. # Create an appointment Source: https://developer.qminder.com/api-reference/appointments/create-an-appointment /api-reference/openapi.json post /v1/appointments Creates a scheduled appointment for a visitor. Appointments have a specific time slot and are assigned to a user. # Create an auto-assigning appointment Source: https://developer.qminder.com/api-reference/appointments/create-an-auto-assigning-appointment /api-reference/openapi.json post /v1/appointments/auto-assign Creates a scheduled appointment that will be automatically assigned to an available user based on their availability. # Edit an appointment Source: https://developer.qminder.com/api-reference/appointments/edit-an-appointment /api-reference/openapi.json patch /v1/appointments/{ticketId} Updates an appointment's time slot or assignee. Only include fields you want to change. # Mark appointment as no-show Source: https://developer.qminder.com/api-reference/appointments/mark-appointment-as-no-show /api-reference/openapi.json post /v1/appointments/{ticketId}/marknoshow Marks a scheduled appointment as no-show when the visitor doesn't arrive. # Create an input field Source: https://developer.qminder.com/api-reference/input-fields/create-an-input-field /api-reference/openapi.json post /input-fields Creates a new input field for a location. The client must generate a UUID for the input field ID. EMAIL and PHONE_NUMBER types are singletons — only one of each is allowed per location. # Edit an input field Source: https://developer.qminder.com/api-reference/input-fields/edit-an-input-field /api-reference/openapi.json patch /input-fields/{inputFieldId} Updates an existing input field. Only include fields you want to change — omitted fields remain unchanged. Set `visitorFacingTitle` to `null` to clear it. # Archiving a line Source: https://developer.qminder.com/api-reference/lines/archiving-a-line /api-reference/openapi.json post /v1/lines/{id}/archive # Create a line Source: https://developer.qminder.com/api-reference/lines/create-a-line /api-reference/openapi.json post /v1/locations/{id}/lines Creates a new line (queue) within a location. # Deletion of a line Source: https://developer.qminder.com/api-reference/lines/deletion-of-a-line /api-reference/openapi.json delete /v1/lines/{id} # Disabling a line Source: https://developer.qminder.com/api-reference/lines/disabling-a-line /api-reference/openapi.json post /v1/lines/{id}/disable # Editing a line Source: https://developer.qminder.com/api-reference/lines/editing-a-line /api-reference/openapi.json post /v1/lines/{id} # Enabling a line Source: https://developer.qminder.com/api-reference/lines/enabling-a-line /api-reference/openapi.json post /v1/lines/{id}/enable # Get details of a line Source: https://developer.qminder.com/api-reference/lines/get-details-of-a-line /api-reference/openapi.json get /v1/lines/{id} # Get list of lines Source: https://developer.qminder.com/api-reference/lines/get-list-of-lines /api-reference/openapi.json get /v1/locations/{id}/lines # Unarchiving a line Source: https://developer.qminder.com/api-reference/lines/unarchiving-a-line /api-reference/openapi.json post /v1/lines/{id}/unarchive # Create a location Source: https://developer.qminder.com/api-reference/locations/create-a-location /api-reference/openapi.json post /locations Creates a new location in the account. # Get desks of a Location Source: https://developer.qminder.com/api-reference/locations/get-desks-of-a-location /api-reference/openapi.json get /v1/locations/{id}/desks # Get details of a location Source: https://developer.qminder.com/api-reference/locations/get-details-of-a-location /api-reference/openapi.json get /v1/locations/{id} # Get the list of locations Source: https://developer.qminder.com/api-reference/locations/get-the-list-of-locations /api-reference/openapi.json get /v1/locations # Adding a label Source: https://developer.qminder.com/api-reference/tickets/adding-a-label /api-reference/openapi.json post /v1/tickets/{id}/labels/add # Assigning a ticket to a user Source: https://developer.qminder.com/api-reference/tickets/assigning-a-ticket-to-a-user /api-reference/openapi.json post /v1/tickets/{id}/assign # Calling a ticket Source: https://developer.qminder.com/api-reference/tickets/calling-a-ticket /api-reference/openapi.json post /v1/tickets/{id}/call # Counting tickets Source: https://developer.qminder.com/api-reference/tickets/counting-tickets /api-reference/openapi.json post /v1/tickets/count # Create a ticket Source: https://developer.qminder.com/api-reference/tickets/create-a-ticket /api-reference/openapi.json post /tickets Creates a new ticket in the specified line. # Editing a ticket Source: https://developer.qminder.com/api-reference/tickets/editing-a-ticket /api-reference/openapi.json patch /tickets/{ticketId} Updates ticket fields such as visitor name, contact information, line assignment, and language preference. Only include fields you want to change - omitted fields remain unchanged. Set a field to `null` to clear its value. # Forwarding a ticket Source: https://developer.qminder.com/api-reference/tickets/forwarding-a-ticket /api-reference/openapi.json post /v1/tickets/{id}/forward # Get details of a ticket Source: https://developer.qminder.com/api-reference/tickets/get-details-of-a-ticket /api-reference/openapi.json get /v1/tickets/{id} # Get messages of a ticket Source: https://developer.qminder.com/api-reference/tickets/get-messages-of-a-ticket /api-reference/openapi.json get /v1/tickets/{id}/messages # Marking a ticket as no-show Source: https://developer.qminder.com/api-reference/tickets/marking-a-ticket-as-no-show /api-reference/openapi.json post /v1/tickets/{id}/marknoshow # Marking a ticket as served Source: https://developer.qminder.com/api-reference/tickets/marking-a-ticket-as-served /api-reference/openapi.json post /v1/tickets/{id}/markserved # Re-calling a ticket Source: https://developer.qminder.com/api-reference/tickets/re-calling-a-ticket /api-reference/openapi.json post /v1/tickets/{id}/recall # Remove ticket input field value Source: https://developer.qminder.com/api-reference/tickets/remove-ticket-input-field-value /api-reference/openapi.json delete /v1/tickets/{ticketId}/fields/{inputFieldId} Removes a custom input field value from a ticket. Cannot remove mandatory input fields. # Removing a label Source: https://developer.qminder.com/api-reference/tickets/removing-a-label /api-reference/openapi.json post /v1/tickets/{id}/labels/remove # Removing a ticket from the queue Source: https://developer.qminder.com/api-reference/tickets/removing-a-ticket-from-the-queue /api-reference/openapi.json post /v1/tickets/{id}/cancel # Reordering a ticket Source: https://developer.qminder.com/api-reference/tickets/reordering-a-ticket /api-reference/openapi.json post /v1/tickets/{id}/reorder # Returning a ticket to the queue Source: https://developer.qminder.com/api-reference/tickets/returning-a-ticket-to-the-queue /api-reference/openapi.json post /v1/tickets/{id}/returntoqueue # Save ticket input field value Source: https://developer.qminder.com/api-reference/tickets/save-ticket-input-field-value /api-reference/openapi.json post /v1/tickets/{ticketId}/fields/{inputFieldId} Saves or updates a custom input field value on a ticket. Use `value` for text fields or `optionIds` for select-type fields. # Searching tickets Source: https://developer.qminder.com/api-reference/tickets/searching-tickets /api-reference/openapi.json get /v1/tickets/search # Sending an SMS message Source: https://developer.qminder.com/api-reference/tickets/sending-an-sms-message /api-reference/openapi.json post /v1/tickets/{id}/messages # Un-assigning a ticket Source: https://developer.qminder.com/api-reference/tickets/un-assigning-a-ticket /api-reference/openapi.json post /v1/tickets/{id}/unassign # Changing the user's selected desk Source: https://developer.qminder.com/api-reference/users/changing-the-users-selected-desk /api-reference/openapi.json post /v1/users/{id}/desk # Clearing the user's selected desk Source: https://developer.qminder.com/api-reference/users/clearing-the-users-selected-desk /api-reference/openapi.json delete /v1/users/{id}/desk # Creating a user Source: https://developer.qminder.com/api-reference/users/creating-a-user /api-reference/openapi.json post /v1/users # Getting a list of users Source: https://developer.qminder.com/api-reference/users/getting-a-list-of-users /api-reference/openapi.json get /v1/locations/{id}/users # Getting details of a User Source: https://developer.qminder.com/api-reference/users/getting-details-of-a-user /api-reference/openapi.json get /v1/users/{id} # Getting the user's selected lines Source: https://developer.qminder.com/api-reference/users/getting-the-users-selected-lines /api-reference/openapi.json get /v1/users/{id}/lines # Getting user's selected desk id Source: https://developer.qminder.com/api-reference/users/getting-users-selected-desk-id /api-reference/openapi.json get /v1/users/{id}/desk # Selecting lines Source: https://developer.qminder.com/api-reference/users/selecting-lines /api-reference/openapi.json post /v1/users/{id}/lines # Adding a webhook Source: https://developer.qminder.com/api-reference/webhooks/adding-a-webhook /api-reference/openapi.json post /v1/webhooks # Removing a webhook Source: https://developer.qminder.com/api-reference/webhooks/removing-a-webhook /api-reference/openapi.json delete /v1/webhooks/{id} # Appointments Source: https://developer.qminder.com/reference/appointments Appointments represent scheduled visits with a specific time slot. Appointments are scheduled visits where visitors book a specific time slot in advance. Unlike regular tickets that join a queue immediately, appointments have a defined start and end time and are assigned to a specific user. All appointments belong to a Line and are created with a time slot and assignee. ### Creating an Appointment To create an appointment, send a POST request to `/v1/appointments`: ```bash theme={null} curl -X POST https://api.qminder.com/v1/appointments \ -H "X-Qminder-REST-API-Key: YOUR_API_KEY" \ -H "X-Qminder-API-Version: 2020-09-01" \ -H "Content-Type: application/json" \ -d '{ "lineId": 12345, "firstName": "John", "lastName": "Doe", "startTime": "2024-12-15T10:00:00Z", "endTime": "2024-12-15T10:30:00Z", "assigneeId": 789 }' ``` **Required fields:** * `lineId` - ID of the line to create the appointment in * `firstName` - Visitor's first name (2-50 characters) * `startTime` - Appointment start time in ISO 8601 format * `endTime` - Appointment end time in ISO 8601 format * `assigneeId` - ID of the user to assign the appointment to **Optional fields:** * `lastName` - Visitor's last name (max 50 characters) * `phoneNumber` - Phone number with optional + prefix (5-20 digits) * `email` - Visitor's email address * `languageCode` - Language code (default: "en") * `fields` - Array of custom input fields with `inputFieldId` (UUID) and `value` or `optionIds` * `labels` - Array of labels with `value` **Response:** ```json theme={null} { "id": "226859", "publicId": "A-42" } ``` ### Input Fields To use the `fields` parameter, you first need to discover the available input field IDs for the location. See the [Input Fields query](/reference/queries/input-fields) for details. ### Auto-Assigning Appointments For appointments that should be automatically assigned to an available user, use the `/v1/appointments/auto-assign` endpoint. This endpoint does not require an `assigneeId` - the system will automatically find an available user based on their availability. ```bash theme={null} curl -X POST https://api.qminder.com/v1/appointments/auto-assign \ -H "X-Qminder-REST-API-Key: YOUR_API_KEY" \ -H "X-Qminder-API-Version: 2020-09-01" \ -H "Content-Type: application/json" \ -d '{ "lineId": 12345, "firstName": "John", "startTime": "2024-12-15T10:00:00Z", "endTime": "2024-12-15T10:30:00Z" }' ``` ### Appointment Lifecycle Appointments go through the following states: 1. **Scheduled** - The appointment is created and waiting for the visitor 2. **Checked-in** - The visitor has arrived and checked in (moves to queue) 3. **Served** - The appointment has been completed 4. **Cancelled** - The appointment was cancelled 5. **No-show** - The visitor did not arrive ### Managing Appointments #### Check-in When a visitor arrives for their appointment: ```bash theme={null} curl -X POST https://api.qminder.com/v1/appointments/14848/checkin \ -H "X-Qminder-REST-API-Key: YOUR_API_KEY" \ -H "X-Qminder-API-Version: 2020-09-01" ``` #### Cancel To cancel an appointment: ```bash theme={null} curl -X POST https://api.qminder.com/v1/appointments/14848/cancel \ -H "X-Qminder-REST-API-Key: YOUR_API_KEY" \ -H "X-Qminder-API-Version: 2020-09-01" ``` #### Mark as No-Show When a visitor doesn't arrive: ```bash theme={null} curl -X POST https://api.qminder.com/v1/appointments/14848/marknoshow \ -H "X-Qminder-REST-API-Key: YOUR_API_KEY" \ -H "X-Qminder-API-Version: 2020-09-01" ``` ### Editing an Appointment To update an appointment's time slot or assignee: ```bash theme={null} curl -X PATCH https://api.qminder.com/v1/appointments/14848 \ -H "X-Qminder-REST-API-Key: YOUR_API_KEY" \ -H "X-Qminder-API-Version: 2020-09-01" \ -H "Content-Type: application/json" \ -d '{ "startTime": "2024-12-15T11:00:00Z", "endTime": "2024-12-15T11:30:00Z" }' ``` All fields are optional - only include the fields you want to change. # CRM Integration Template Source: https://developer.qminder.com/reference/crm-integration-template A template for integrating Qminder with your CRM to identify VIP customers at check-in. This template connects Qminder to your CRM and automatically labels VIP customers when they check in. ## What It Does The template listens for visitor check-ins across all Qminder locations. When someone checks in, it queries your CRM to check if they're a VIP. If they are, it applies a "VIP" label to their ticket. ## Prerequisites Before getting started, you'll need: * **Qminder API key** - Create one in [Qminder Dashboard](https://dashboard.qminder.com) under Organization Settings → Developer Tools. See [Authentication](/reference/overview#authentication) for details. * **Docker** (recommended) OR **Node.js 20+** with Yarn * **CRM access** - Credentials for your CRM system (Salesforce, HubSpot, or custom) ## Quick Start ### Clone the Repository ```bash theme={null} git clone https://github.com/Qminder/crm-integration-template.git cd crm-integration-template ``` ### Option 1: Run with Docker (Recommended) ```bash theme={null} docker build -t crm-integration . docker run -e API_KEY=your_qminder_api_key crm-integration ``` ### Option 2: Run with Node.js ```bash theme={null} yarn install API_KEY=your_qminder_api_key yarn start ``` Once running, the template logs that it's listening for visitor events. ## How It Works The template uses Qminder's [GraphQL API](/reference/graphql-api) to subscribe to real-time events: 1. **Connects to Qminder** - Establishes a WebSocket connection using your API key 2. **Subscribes to check-ins** - Listens for the [`createdTickets`](/reference/graphql/subscriptions/created-tickets) subscription across all locations 3. **Extracts visitor info** - When a ticket is created, extracts the visitor's name, phone number, and email 4. **Queries your CRM** - Calls your custom `checkVip()` function to look up the customer 5. **Applies the label** - If the customer is a VIP, adds a "VIP" label to their Qminder ticket ## Customization Edit `src/crm.ts` to connect to your CRM. This file contains the `checkVip()` function. ### The Interface ```typescript theme={null} export async function checkVip(visitor: Visitor): Promise { // Your CRM lookup logic here // Return true if VIP, false otherwise } ``` The `Visitor` object contains: * `firstName` - Visitor's first name * `lastName` - Visitor's last name * `phoneNumber` - Phone number (if provided) * `email` - Email address (if provided) ### Example: Salesforce Integration ```typescript theme={null} import jsforce from 'jsforce'; const conn = new jsforce.Connection({ loginUrl: 'https://login.salesforce.com' }); await conn.login(process.env.SF_USERNAME, process.env.SF_PASSWORD); export async function checkVip(visitor: Visitor): Promise { const result = await conn.query( `SELECT Id, VIP__c FROM Contact WHERE Name = '${visitor.firstName} ${visitor.lastName}' LIMIT 1` ); if (result.records.length > 0) { return result.records[0].VIP__c === true; } return false; } ``` ### Example: HubSpot Integration ```typescript theme={null} import { Client } from '@hubspot/api-client'; const hubspot = new Client({ accessToken: process.env.HUBSPOT_TOKEN }); export async function checkVip(visitor: Visitor): Promise { const response = await hubspot.crm.contacts.searchApi.doSearch({ filterGroups: [{ filters: [{ propertyName: 'firstname', operator: 'EQ', value: visitor.firstName }, { propertyName: 'lastname', operator: 'EQ', value: visitor.lastName }] }], properties: ['vip_status'] }); if (response.results.length > 0) { return response.results[0].properties.vip_status === 'true'; } return false; } ``` ### Example: Custom Database ```typescript theme={null} import { Pool } from 'pg'; const pool = new Pool({ connectionString: process.env.DATABASE_URL }); export async function checkVip(visitor: Visitor): Promise { const result = await pool.query( 'SELECT is_vip FROM customers WHERE phone = $1 OR email = $2', [visitor.phoneNumber, visitor.email] ); return result.rows[0]?.is_vip === true; } ``` ## Project Structure ``` src/ ├── app.ts # Main entry point - sets up the Qminder listener ├── crm.ts # Your CRM integration logic (customize this file) └── model/ticket.ts # TypeScript type definitions for visitor data ``` ## Configuration | Environment Variable | Required | Description | | -------------------- | -------- | ------------------------- | | `API_KEY` | Yes | Your Qminder REST API key | Add any CRM-specific environment variables your integration needs (e.g., `SF_USERNAME`, `HUBSPOT_TOKEN`, `DATABASE_URL`). ## Deployment ### Docker (Production) ```bash theme={null} docker build -t crm-integration . docker run -d \ -e API_KEY=your_qminder_api_key \ -e HUBSPOT_TOKEN=your_hubspot_token \ --restart unless-stopped \ crm-integration ``` ### Cloud Platforms The Docker image can be deployed to any container platform: * **AWS** - ECS, Fargate, or App Runner * **Google Cloud** - Cloud Run or GKE * **Azure** - Container Instances or AKS * **Heroku** - Container Registry ### Process Managers If running directly on a VM without Docker, use a process manager like PM2: ```bash theme={null} npm install -g pm2 API_KEY=your_key pm2 start yarn --name crm-integration -- start ``` ## Troubleshooting ### Template not receiving events * Verify your API key is valid and has access to locations * Check that the WebSocket connection is established (look for connection logs) * Ensure your firewall allows outbound WebSocket connections ### VIP labels not appearing * Confirm your `checkVip()` function returns `true` for test customers * Check the template logs for any CRM query errors * Verify the "VIP" label exists in your Qminder location settings ### CRM connection issues * Double-check your CRM credentials in environment variables * Ensure your CRM API rate limits aren't being exceeded * Test your CRM queries independently before integrating ## Source Code The full source code is available on GitHub: [Qminder/crm-integration-template](https://github.com/Qminder/crm-integration-template) ## Getting Help Contact Qminder support for assistance. Enterprise plan customers have access to premium API support. # Overview Source: https://developer.qminder.com/reference/graphql-api ## Endpoint Qminder's GraphQL endpoint is: ``` https://api.qminder.com/graphql ``` It supports introspection so you can query the whole schema. ## Authentication To authenticate your requests, you need to pass the API key with header: `X-Qminder-REST-API-Key: ` ## Schema The GraphQL schema is available as an SDL file for use with code generators, IDE plugins, and other tooling: * [query.graphqls on GitHub](https://github.com/Qminder/javascript-api/blob/master/query.graphqls) * [Download raw file](https://raw.githubusercontent.com/Qminder/javascript-api/master/query.graphqls) You can also query the schema via [introspection](https://graphql.org/learn/introspection/) at the GraphQL endpoint. ```bash bash theme={null} curl \ -X POST \ -H "Content-Type: application/json" \ -H "X-Qminder-REST-API-Key: " \ --data '{ "query": "query ListOfLocations { account { locations { name} } }" }' \ https://api.qminder.com/graphql ``` # Direction Source: https://developer.qminder.com/reference/graphql/enums/direction No description ```graphql theme={null} enum Direction { ASCENDING DESCENDING } ``` ### Values #### [Direction.ASCENDING](#) #### [Direction.DESCENDING](#) ### Member Of [`Order`](/reference/graphql/inputs/order) input # InputFieldType Source: https://developer.qminder.com/reference/graphql/enums/input-field-type No description ```graphql theme={null} enum InputFieldType { PHONE_NUMBER URL SELECT TEXT EMAIL DATE FIRST_NAME LAST_NAME NUMERIC } ``` ### Values #### [InputFieldType.PHONE\_NUMBER](#) #### [InputFieldType.URL](#) #### [InputFieldType.SELECT](#) #### [InputFieldType.TEXT](#) #### [InputFieldType.EMAIL](#) #### [InputFieldType.DATE](#) #### [InputFieldType.FIRST\_NAME](#) #### [InputFieldType.LAST\_NAME](#) #### [InputFieldType.NUMERIC](#) ### Member Of [`InputField`](/reference/graphql/objects/input-field) object # MessageType Source: https://developer.qminder.com/reference/graphql/enums/message-type No description ```graphql theme={null} enum MessageType { OUTGOING OUTGOING_AUTOMATED INCOMING } ``` ### Values #### [MessageType.OUTGOING](#) #### [MessageType.OUTGOING\_AUTOMATED](#) #### [MessageType.INCOMING](#) ### Member Of [`TicketMessage`](/reference/graphql/objects/ticket-message) object # OrderableField Source: https://developer.qminder.com/reference/graphql/enums/orderable-field No description ```graphql theme={null} enum OrderableField { ID CREATED END_TIME } ``` ### Values #### [OrderableField.ID](#) #### [OrderableField.CREATED](#) #### [OrderableField.END\_TIME](#) ### Member Of [`Order`](/reference/graphql/inputs/order) input # PaymentInterval Source: https://developer.qminder.com/reference/graphql/enums/payment-interval No description ```graphql theme={null} enum PaymentInterval { YEAR MONTH WEEK DAY } ``` ### Values #### [PaymentInterval.YEAR](#) #### [PaymentInterval.MONTH](#) #### [PaymentInterval.WEEK](#) #### [PaymentInterval.DAY](#) ### Member Of [`AccountSubscription`](/reference/graphql/objects/account-subscription) object # PaymentMethod Source: https://developer.qminder.com/reference/graphql/enums/payment-method No description ```graphql theme={null} enum PaymentMethod { STRIPE INVOICE } ``` ### Values #### [PaymentMethod.STRIPE](#) #### [PaymentMethod.INVOICE](#) ### Member Of [`Account`](/reference/graphql/objects/account) object # Sentiment Source: https://developer.qminder.com/reference/graphql/enums/sentiment No description ```graphql theme={null} enum Sentiment { POSITIVE NEGATIVE NEUTRAL MIXED UNKNOWN } ``` ### Values #### [Sentiment.POSITIVE](#) #### [Sentiment.NEGATIVE](#) #### [Sentiment.NEUTRAL](#) #### [Sentiment.MIXED](#) #### [Sentiment.UNKNOWN](#) ### Member Of [`TicketMessage`](/reference/graphql/objects/ticket-message) object # TicketStatus Source: https://developer.qminder.com/reference/graphql/enums/ticket-status No description ```graphql theme={null} enum TicketStatus { SCHEDULED SCHEDULING_CANCELLED SCHEDULING_CANCELLED_BY_VISITOR SCHEDULING_NOSHOW NEW CANCELLED CANCELLED_BY_CLERK CALLED SERVED NOSHOW } ``` ### Values #### [TicketStatus.SCHEDULED](#) #### [TicketStatus.SCHEDULING\_CANCELLED](#) #### [TicketStatus.SCHEDULING\_CANCELLED\_BY\_VISITOR](#) #### [TicketStatus.SCHEDULING\_NOSHOW](#) #### [TicketStatus.NEW](#) #### [TicketStatus.CANCELLED](#) #### [TicketStatus.CANCELLED\_BY\_CLERK](#) #### [TicketStatus.CALLED](#) #### [TicketStatus.SERVED](#) #### [TicketStatus.NOSHOW](#) ### Member Of [`Ticket`](/reference/graphql/objects/ticket) object ● [`ticketSearch`](/reference/graphql/queries/ticket-search) query # AppointmentFilter Source: https://developer.qminder.com/reference/graphql/inputs/appointment-filter No description ```graphql theme={null} input AppointmentFilter { start: Date! end: Date! assignee: [ID!] } ``` ### Fields #### [AppointmentFilter.start](#) ● [Date!](/reference/graphql/scalars/date) non-null scalar #### [AppointmentFilter.end](#) ● [Date!](/reference/graphql/scalars/date) non-null scalar #### [AppointmentFilter.assignee](#) ● [\[ID!\]](/reference/graphql/scalars/id) list scalar ### Member Of [`ticketSearch`](/reference/graphql/queries/ticket-search) query # InteractionsFilter Source: https://developer.qminder.com/reference/graphql/inputs/interactions-filter No description ```graphql theme={null} input InteractionsFilter { onlyLastService: Boolean! } ``` ### Fields #### [InteractionsFilter.onlyLastService](#) ● [Boolean!](/reference/graphql/scalars/boolean) non-null scalar Indicates whether to include interactions created only during the last service until the ticket was marked as served or no-show. # Order Source: https://developer.qminder.com/reference/graphql/inputs/order No description ```graphql theme={null} input Order { field: OrderableField! direction: Direction! } ``` ### Fields #### [Order.field](#) ● [OrderableField!](/reference/graphql/enums/orderable-field) non-null enum #### [Order.direction](#) ● [Direction!](/reference/graphql/enums/direction) non-null enum ### Member Of [`ticketSearch`](/reference/graphql/queries/ticket-search) query # Account Source: https://developer.qminder.com/reference/graphql/objects/account No description ```graphql theme={null} type Account { id: ID! name: String segment: String created: Date! locations: [Location!]! paymentMethod: PaymentMethod hipaa: Boolean! features: [String!] billing: Billing! trialEnds: Date } ``` ### Fields #### [Account.id](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar #### [Account.name](#) ● [String](/reference/graphql/scalars/string) scalar #### [Account.segment](#) ● [String](/reference/graphql/scalars/string) scalar #### [Account.created](#) ● [Date!](/reference/graphql/scalars/date) non-null scalar #### [Account.locations](#) ● [\[Location!\]!](/reference/graphql/objects/location) non-null object #### [Account.paymentMethod](#) ● [PaymentMethod](/reference/graphql/enums/payment-method) enum #### [Account.hipaa](#) ● [Boolean!](/reference/graphql/scalars/boolean) non-null scalar #### [Account.features](#) ● [\[String!\]](/reference/graphql/scalars/string) list scalar #### [Account.billing](#) ● [Billing!](/reference/graphql/objects/billing) non-null object #### [Account.trialEnds](#) ● [Date](/reference/graphql/scalars/date) scalar ### Returned By [`account`](/reference/graphql/queries/account) query # Appointment Source: https://developer.qminder.com/reference/graphql/objects/appointment No description ```graphql theme={null} type Appointment { startTime: Date! endTime: Date! assignee: User! } ``` ### Fields #### [Appointment.startTime](#) ● [Date!](/reference/graphql/scalars/date) non-null scalar #### [Appointment.endTime](#) ● [Date!](/reference/graphql/scalars/date) non-null scalar #### [Appointment.assignee](#) ● [User!](/reference/graphql/objects/user) non-null object ### Returned By [`appointmentChanged`](/reference/graphql/subscriptions/appointment-changed) subscription ### Member Of [`Ticket`](/reference/graphql/objects/ticket) object # Desk Source: https://developer.qminder.com/reference/graphql/objects/desk No description ```graphql theme={null} type Desk { id: ID! name: String! user: User } ``` ### Fields #### [Desk.id](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar #### [Desk.name](#) ● [String!](/reference/graphql/scalars/string) non-null scalar #### [Desk.user](#) ● [User](/reference/graphql/objects/user) object ### Returned By [`changedDesks`](/reference/graphql/subscriptions/changed-desks) subscription ● [`changedDeskSelection`](/reference/graphql/subscriptions/changed-desk-selection) subscription ### Member Of [`Interaction`](/reference/graphql/objects/interaction) object ● [`Location`](/reference/graphql/objects/location) object ● [`User`](/reference/graphql/objects/user) object # InputField Source: https://developer.qminder.com/reference/graphql/objects/input-field No description ```graphql theme={null} type InputField { id: String! location: Location! type: InputFieldType! mandatory: Boolean! @deprecated isMandatoryBeforeAdded: Boolean! isMandatoryBeforeServed: Boolean! isVisibleInWaitingDrawer: Boolean! isVisibleInServingDrawer: Boolean! showInRemoteSignIn: Boolean! visibleForLines: [Line!]! title: String visitorFacingTitle: String multiSelect: Boolean! options: [SelectOption!]! constraints: InputFieldConstraints translations: [InputFieldTranslation!]! isRequiredInAppointments: Boolean! deleted: Boolean! } ``` ### Fields #### [InputField.id](#) ● [String!](/reference/graphql/scalars/string) non-null scalar #### [InputField.location](#) ● [Location!](/reference/graphql/objects/location) non-null object #### [InputField.type](#) ● [InputFieldType!](/reference/graphql/enums/input-field-type) non-null enum #### [InputField.isMandatoryBeforeAdded](#) ● [Boolean!](/reference/graphql/scalars/boolean) non-null scalar #### [InputField.isMandatoryBeforeServed](#) ● [Boolean!](/reference/graphql/scalars/boolean) non-null scalar #### [InputField.isVisibleInWaitingDrawer](#) ● [Boolean!](/reference/graphql/scalars/boolean) non-null scalar #### [InputField.isVisibleInServingDrawer](#) ● [Boolean!](/reference/graphql/scalars/boolean) non-null scalar #### [InputField.showInRemoteSignIn](#) ● [Boolean!](/reference/graphql/scalars/boolean) non-null scalar #### [InputField.visibleForLines](#) ● [\[Line!\]!](/reference/graphql/objects/line) non-null object #### [InputField.title](#) ● [String](/reference/graphql/scalars/string) scalar #### [InputField.visitorFacingTitle](#) ● [String](/reference/graphql/scalars/string) scalar #### [InputField.multiSelect](#) ● [Boolean!](/reference/graphql/scalars/boolean) non-null scalar #### [InputField.options](#) ● [\[SelectOption!\]!](/reference/graphql/objects/select-option) non-null object #### [InputField.constraints](#) ● [InputFieldConstraints](/reference/graphql/interfaces/input-field-constraints) interface #### [InputField.translations](#) ● [\[InputFieldTranslation!\]!](/reference/graphql/objects/input-field-translation) non-null object #### [InputField.isRequiredInAppointments](#) ● [Boolean!](/reference/graphql/scalars/boolean) non-null scalar #### [InputField.deleted](#) ● [Boolean!](/reference/graphql/scalars/boolean) non-null scalar
DEPRECATED
#### [InputField.mandatory](#) ● [Boolean!](/reference/graphql/scalars/boolean) deprecated non-null scalar
⚠️ DEPRECATED Use isMandatoryBeforeAdded instead
undefined ### Returned By [`changedInputFields`](/reference/graphql/subscriptions/changed-input-fields) subscription ● [`inputField`](/reference/graphql/queries/input-field) query ### Member Of [`Location`](/reference/graphql/objects/location) object ● [`TicketFieldV2`](/reference/graphql/objects/ticket-field-v2) object # Interaction Source: https://developer.qminder.com/reference/graphql/objects/interaction No description ```graphql theme={null} type Interaction { id: ID! start: Date! end: Date line: Line! desk: Desk user: User waitTime: Duration! serviceTime: Duration } ``` ### Fields #### [Interaction.id](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar #### [Interaction.start](#) ● [Date!](/reference/graphql/scalars/date) non-null scalar #### [Interaction.end](#) ● [Date](/reference/graphql/scalars/date) scalar #### [Interaction.line](#) ● [Line!](/reference/graphql/objects/line) non-null object #### [Interaction.desk](#) ● [Desk](/reference/graphql/objects/desk) object #### [Interaction.user](#) ● [User](/reference/graphql/objects/user) object #### [Interaction.waitTime](#) ● [Duration!](/reference/graphql/scalars/duration) non-null scalar #### [Interaction.serviceTime](#) ● [Duration](/reference/graphql/scalars/duration) scalar ### Member Of [`Ticket`](/reference/graphql/objects/ticket) object # Ipad Source: https://developer.qminder.com/reference/graphql/objects/ipad No description ```graphql theme={null} type Ipad { id: ID! name: String! online: Boolean! charging: Boolean batteryLevel: Int } ``` ### Fields #### [Ipad.id](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar #### [Ipad.name](#) ● [String!](/reference/graphql/scalars/string) non-null scalar #### [Ipad.online](#) ● [Boolean!](/reference/graphql/scalars/boolean) non-null scalar #### [Ipad.charging](#) ● [Boolean](/reference/graphql/scalars/boolean) scalar #### [Ipad.batteryLevel](#) ● [Int](/reference/graphql/scalars/int) scalar ### Returned By [`changedIpads`](/reference/graphql/subscriptions/changed-ipads) subscription ● [`deletedIpads`](/reference/graphql/subscriptions/deleted-ipads) subscription ● [`iPad`](/reference/graphql/queries/i-pad) query ### Member Of [`Location`](/reference/graphql/objects/location) object # Line Source: https://developer.qminder.com/reference/graphql/objects/line No description ```graphql theme={null} type Line { id: ID! name: String! color: String! disabled: Boolean! archived: Boolean! location: Location! hasActiveTickets: Boolean! hasScheduledTickets: Boolean! translations: [LineTranslation!]! appointmentSettings: LineAppointmentSettings } ``` ### Fields #### [Line.id](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar #### [Line.name](#) ● [String!](/reference/graphql/scalars/string) non-null scalar #### [Line.color](#) ● [String!](/reference/graphql/scalars/string) non-null scalar #### [Line.disabled](#) ● [Boolean!](/reference/graphql/scalars/boolean) non-null scalar #### [Line.archived](#) ● [Boolean!](/reference/graphql/scalars/boolean) non-null scalar #### [Line.location](#) ● [Location!](/reference/graphql/objects/location) non-null object #### [Line.hasActiveTickets](#) ● [Boolean!](/reference/graphql/scalars/boolean) non-null scalar #### [Line.hasScheduledTickets](#) ● [Boolean!](/reference/graphql/scalars/boolean) non-null scalar #### [Line.translations](#) ● [\[LineTranslation!\]!](/reference/graphql/objects/line-translation) non-null object #### [Line.appointmentSettings](#) ● [LineAppointmentSettings](/reference/graphql/objects/line-appointment-settings) object ### Returned By [`changedLines`](/reference/graphql/subscriptions/changed-lines) subscription ● [`line`](/reference/graphql/queries/line) query ### Member Of [`InputField`](/reference/graphql/objects/input-field) object ● [`Interaction`](/reference/graphql/objects/interaction) object ● [`Location`](/reference/graphql/objects/location) object ● [`Ticket`](/reference/graphql/objects/ticket) object ● [`TicketChange`](/reference/graphql/objects/ticket-change) object ● [`TV`](/reference/graphql/objects/tv) object ● [`User`](/reference/graphql/objects/user) object ● [`UserAppointmentsAvailability`](/reference/graphql/objects/user-appointments-availability) object # Location Source: https://developer.qminder.com/reference/graphql/objects/location No description ```graphql theme={null} type Location { id: ID! name: String! address: String! countryCode: String! country: String! timezone: String! created: Date! latitude: Float! longitude: Float! lines( archived: Boolean ): [Line!]! users: [User!]! ipads: [Ipad!] tvs: [TV!] desks: [Desk!] languages: [Language!] selectingDeskMandatory: Boolean smsEnabled: Boolean dynamicLabels: Boolean inputFields( includeDeleted: Boolean ): [InputField] openingHours: JSON @deprecated openingHours2: OpeningHours openingHoursExceptions: JSON @deprecated openingHoursExceptions2: [OpeningHoursException!]! visitPlanner: VisitPlanner labels: [LabelType!]! settings: LocationSettings! isDemo: Boolean! appointmentSettings: LocationAppointmentSettings isServiceViewLastUsedLineMemorised: Boolean! } ``` ### Fields #### [Location.id](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar #### [Location.name](#) ● [String!](/reference/graphql/scalars/string) non-null scalar #### [Location.address](#) ● [String!](/reference/graphql/scalars/string) non-null scalar #### [Location.countryCode](#) ● [String!](/reference/graphql/scalars/string) non-null scalar #### [Location.country](#) ● [String!](/reference/graphql/scalars/string) non-null scalar #### [Location.timezone](#) ● [String!](/reference/graphql/scalars/string) non-null scalar #### [Location.created](#) ● [Date!](/reference/graphql/scalars/date) non-null scalar #### [Location.latitude](#) ● [Float!](/reference/graphql/scalars/float) non-null scalar #### [Location.longitude](#) ● [Float!](/reference/graphql/scalars/float) non-null scalar #### [Location.lines](#) ● [\[Line!\]!](/reference/graphql/objects/line) non-null object ##### [Location.lines.archived](#) ● [Boolean](/reference/graphql/scalars/boolean) scalar #### [Location.users](#) ● [\[User!\]!](/reference/graphql/objects/user) non-null object #### [Location.ipads](#) ● [\[Ipad!\]](/reference/graphql/objects/ipad) list object #### [Location.tvs](#) ● [\[TV!\]](/reference/graphql/objects/tv) list object #### [Location.desks](#) ● [\[Desk!\]](/reference/graphql/objects/desk) list object #### [Location.languages](#) ● [\[Language!\]](/reference/graphql/objects/language) list object #### [Location.selectingDeskMandatory](#) ● [Boolean](/reference/graphql/scalars/boolean) scalar #### [Location.smsEnabled](#) ● [Boolean](/reference/graphql/scalars/boolean) scalar #### [Location.dynamicLabels](#) ● [Boolean](/reference/graphql/scalars/boolean) scalar #### [Location.inputFields](#) ● [\[InputField\]](/reference/graphql/objects/input-field) list object ##### [Location.inputFields.includeDeleted](#) ● [Boolean](/reference/graphql/scalars/boolean) scalar If omitted or false returns non-deleted input fields in location. If true, returns both deleted and non-deleted input fields in location. #### [Location.openingHours2](#) ● [OpeningHours](/reference/graphql/objects/opening-hours) object #### [Location.openingHoursExceptions2](#) ● [\[OpeningHoursException!\]!](/reference/graphql/objects/opening-hours-exception) non-null object #### [Location.visitPlanner](#) ● [VisitPlanner](/reference/graphql/objects/visit-planner) object #### [Location.labels](#) ● [\[LabelType!\]!](/reference/graphql/objects/label-type) non-null object #### [Location.settings](#) ● [LocationSettings!](/reference/graphql/objects/location-settings) non-null object #### [Location.isDemo](#) ● [Boolean!](/reference/graphql/scalars/boolean) non-null scalar #### [Location.appointmentSettings](#) ● [LocationAppointmentSettings](/reference/graphql/objects/location-appointment-settings) object #### [Location.isServiceViewLastUsedLineMemorised](#) ● [Boolean!](/reference/graphql/scalars/boolean) non-null scalar
DEPRECATED
#### [Location.openingHours](#) ● [JSON](/reference/graphql/scalars/json) deprecated scalar
⚠️ DEPRECATED Use openingHours2 instead
#### [Location.openingHoursExceptions](#) ● [JSON](/reference/graphql/scalars/json) deprecated scalar
⚠️ DEPRECATED Use openingHoursExceptions2 instead
undefined ### Returned By [`changedLocation`](/reference/graphql/subscriptions/changed-location) subscription ● [`changedLocationLine`](/reference/graphql/subscriptions/changed-location-line) subscription ● [`location`](/reference/graphql/queries/location) query ● [`locations`](/reference/graphql/queries/locations) query ### Member Of [`Account`](/reference/graphql/objects/account) object ● [`InputField`](/reference/graphql/objects/input-field) object ● [`Line`](/reference/graphql/objects/line) object ● [`Role`](/reference/graphql/objects/role) object ● [`User`](/reference/graphql/objects/user) object ● [`UserAppointmentsAvailability`](/reference/graphql/objects/user-appointments-availability) object # Ticket Source: https://developer.qminder.com/reference/graphql/objects/ticket No description ```graphql theme={null} type Ticket { id: ID! status: TicketStatus! statusSetAt: Date! statusSetBy: User line: Line! firstName: String lastName: String phoneNumber: Long email: String created: TicketCreated! waitStartedAt: Date cancelled: TicketCancelled assignee: User caller: User fields2: [TicketFieldV2!]! labels: [TicketLabel!]! interactions( filter: InteractionsFilter ): [Interaction!]! messages: [TicketMessage!]! connectedTickets: [Ticket!] audits: [TicketAudit!]! external: [TicketExternalData!]! language: Language! appointment: Appointment } ``` ### Fields #### [Ticket.id](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar #### [Ticket.status](#) ● [TicketStatus!](/reference/graphql/enums/ticket-status) non-null enum #### [Ticket.statusSetAt](#) ● [Date!](/reference/graphql/scalars/date) non-null scalar #### [Ticket.statusSetBy](#) ● [User](/reference/graphql/objects/user) object #### [Ticket.line](#) ● [Line!](/reference/graphql/objects/line) non-null object #### [Ticket.firstName](#) ● [String](/reference/graphql/scalars/string) scalar #### [Ticket.lastName](#) ● [String](/reference/graphql/scalars/string) scalar #### [Ticket.phoneNumber](#) ● [Long](/reference/graphql/scalars/long) scalar #### [Ticket.email](#) ● [String](/reference/graphql/scalars/string) scalar #### [Ticket.created](#) ● [TicketCreated!](/reference/graphql/objects/ticket-created) non-null object #### [Ticket.waitStartedAt](#) ● [Date](/reference/graphql/scalars/date) scalar #### [Ticket.cancelled](#) ● [TicketCancelled](/reference/graphql/objects/ticket-cancelled) object #### [Ticket.assignee](#) ● [User](/reference/graphql/objects/user) object #### [Ticket.caller](#) ● [User](/reference/graphql/objects/user) object #### [Ticket.fields2](#) ● [\[TicketFieldV2!\]!](/reference/graphql/objects/ticket-field-v2) non-null object #### [Ticket.labels](#) ● [\[TicketLabel!\]!](/reference/graphql/objects/ticket-label) non-null object #### [Ticket.interactions](#) ● [\[Interaction!\]!](/reference/graphql/objects/interaction) non-null object ##### [Ticket.interactions.filter](#) ● [InteractionsFilter](/reference/graphql/inputs/interactions-filter) input #### [Ticket.messages](#) ● [\[TicketMessage!\]!](/reference/graphql/objects/ticket-message) non-null object #### [Ticket.connectedTickets](#) ● [\[Ticket!\]](/reference/graphql/objects/ticket) list object #### [Ticket.audits](#) ● [\[TicketAudit!\]!](/reference/graphql/objects/ticket-audit) non-null object #### [Ticket.external](#) ● [\[TicketExternalData!\]!](/reference/graphql/objects/ticket-external-data) non-null object #### [Ticket.language](#) ● [Language!](/reference/graphql/objects/language) non-null object #### [Ticket.appointment](#) ● [Appointment](/reference/graphql/objects/appointment) object ### Returned By [`calledTickets`](/reference/graphql/subscriptions/called-tickets) subscription ● [`cancelledTickets`](/reference/graphql/subscriptions/cancelled-tickets) subscription ● [`changedTickets`](/reference/graphql/subscriptions/changed-tickets) subscription ● [`createdTickets`](/reference/graphql/subscriptions/created-tickets) subscription ● [`markedAllTicketMessagesAsRead`](/reference/graphql/subscriptions/marked-all-ticket-messages-as-read) subscription ● [`myCalledTickets`](/reference/graphql/queries/my-called-tickets) query ● [`recalledTickets`](/reference/graphql/subscriptions/recalled-tickets) subscription ● [`reorderedTickets`](/reference/graphql/deprecated/subscriptions/reordered-tickets) subscription ● [`reorderedTicketsList`](/reference/graphql/subscriptions/reordered-tickets-list) subscription ● [`servedTickets`](/reference/graphql/subscriptions/served-tickets) subscription ● [`ticket`](/reference/graphql/queries/ticket) query ● [`ticketSearch`](/reference/graphql/queries/ticket-search) query ● [`ticketStateChanged`](/reference/graphql/subscriptions/ticket-state-changed) subscription ● [`tvTickets`](/reference/graphql/subscriptions/tv-tickets) subscription ### Member Of [`ChangedMultiTicketField`](/reference/graphql/objects/changed-multi-ticket-field) object ● [`ChangedTicketField`](/reference/graphql/interfaces/changed-ticket-field) interface ● [`ChangedTicketLabel`](/reference/graphql/objects/changed-ticket-label) object ● [`ChangedUniTicketField`](/reference/graphql/objects/changed-uni-ticket-field) object ● [`Ticket`](/reference/graphql/objects/ticket) object # TicketMessage Source: https://developer.qminder.com/reference/graphql/objects/ticket-message No description ```graphql theme={null} type TicketMessage { id: ID! created: Date! type: MessageType! status: String! statusSetAt: Date! body: String! user: User attachments: [String]! readAt: Date sentiment: Sentiment! } ``` ### Fields #### [TicketMessage.id](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar #### [TicketMessage.created](#) ● [Date!](/reference/graphql/scalars/date) non-null scalar #### [TicketMessage.type](#) ● [MessageType!](/reference/graphql/enums/message-type) non-null enum #### [TicketMessage.status](#) ● [String!](/reference/graphql/scalars/string) non-null scalar #### [TicketMessage.statusSetAt](#) ● [Date!](/reference/graphql/scalars/date) non-null scalar #### [TicketMessage.body](#) ● [String!](/reference/graphql/scalars/string) non-null scalar #### [TicketMessage.user](#) ● [User](/reference/graphql/objects/user) object #### [TicketMessage.attachments](#) ● [\[String\]!](/reference/graphql/scalars/string) non-null scalar #### [TicketMessage.readAt](#) ● [Date](/reference/graphql/scalars/date) scalar #### [TicketMessage.sentiment](#) ● [Sentiment!](/reference/graphql/enums/sentiment) non-null enum ### Member Of [`Ticket`](/reference/graphql/objects/ticket) object # TV Source: https://developer.qminder.com/reference/graphql/objects/tv No description ```graphql theme={null} type TV { id: ID! name: String! theme: String! layout: String! online: Boolean! settings: String @deprecated lines: [Line!] clearTickets: String notificationViewLineVisible: Boolean listViewLineVisible: Boolean! } ``` ### Fields #### [TV.id](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar #### [TV.name](#) ● [String!](/reference/graphql/scalars/string) non-null scalar #### [TV.theme](#) ● [String!](/reference/graphql/scalars/string) non-null scalar #### [TV.layout](#) ● [String!](/reference/graphql/scalars/string) non-null scalar #### [TV.online](#) ● [Boolean!](/reference/graphql/scalars/boolean) non-null scalar #### [TV.lines](#) ● [\[Line!\]](/reference/graphql/objects/line) list object Visitors in selected lines are visible on TV #### [TV.clearTickets](#) ● [String](/reference/graphql/scalars/string) scalar A time when visitor names are cleared from the TV screen. Possible values: afterCalling, afterServing #### [TV.notificationViewLineVisible](#) ● [Boolean](/reference/graphql/scalars/boolean) scalar The name of the line is displayed on TV when the next visitor is called #### [TV.listViewLineVisible](#) ● [Boolean!](/reference/graphql/scalars/boolean) non-null scalar In the waiting list the service names are visible for visitors who are waiting
DEPRECATED
#### [TV.settings](#) ● [String](/reference/graphql/scalars/string) deprecated scalar
⚠️ DEPRECATED use lines, clearTickets, and notificationViewLineVisible instead
TV's settings in JSON format. Contains lines, clearTickets, and notificationViewLineVisible fields undefined ### Returned By [`changedTV`](/reference/graphql/subscriptions/changed-tv) subscription ● [`deletedTV`](/reference/graphql/subscriptions/deleted-tv) subscription ● [`TV`](/reference/graphql/queries/tv) query ### Member Of [`Location`](/reference/graphql/objects/location) object # User Source: https://developer.qminder.com/reference/graphql/objects/user No description ```graphql theme={null} type User { id: ID! email: String firstName: String! lastName: String! created: Date! profilePicture: ProfilePicture picture: String @deprecated selectedLocation: Location selectedDesk: Desk selectedLines: [Line!] roles: [Role!] lastLoggedIn: Date lastInvited: Date serviceSettings: ServiceSettings deleted: Boolean! deletedAt: Date } ``` ### Fields #### [User.id](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar #### [User.email](#) ● [String](/reference/graphql/scalars/string) scalar #### [User.firstName](#) ● [String!](/reference/graphql/scalars/string) non-null scalar #### [User.lastName](#) ● [String!](/reference/graphql/scalars/string) non-null scalar #### [User.created](#) ● [Date!](/reference/graphql/scalars/date) non-null scalar #### [User.profilePicture](#) ● [ProfilePicture](/reference/graphql/objects/profile-picture) object #### [User.selectedLocation](#) ● [Location](/reference/graphql/objects/location) object #### [User.selectedDesk](#) ● [Desk](/reference/graphql/objects/desk) object #### [User.selectedLines](#) ● [\[Line!\]](/reference/graphql/objects/line) list object #### [User.roles](#) ● [\[Role!\]](/reference/graphql/objects/role) list object #### [User.lastLoggedIn](#) ● [Date](/reference/graphql/scalars/date) scalar #### [User.lastInvited](#) ● [Date](/reference/graphql/scalars/date) scalar #### [User.serviceSettings](#) ● [ServiceSettings](/reference/graphql/objects/service-settings) object #### [User.deleted](#) ● [Boolean!](/reference/graphql/scalars/boolean) non-null scalar #### [User.deletedAt](#) ● [Date](/reference/graphql/scalars/date) scalar
DEPRECATED
#### [User.picture](#) ● [String](/reference/graphql/scalars/string) deprecated scalar
⚠️ DEPRECATED Use profilePicture
undefined ### Returned By [`allUsers`](/reference/graphql/queries/all-users) query ● [`me`](/reference/graphql/queries/me) query ● [`user`](/reference/graphql/queries/user) query ● [`users`](/reference/graphql/queries/users) query ### Member Of [`Appointment`](/reference/graphql/objects/appointment) object ● [`Desk`](/reference/graphql/objects/desk) object ● [`Interaction`](/reference/graphql/objects/interaction) object ● [`Location`](/reference/graphql/objects/location) object ● [`Ticket`](/reference/graphql/objects/ticket) object ● [`TicketAudit`](/reference/graphql/objects/ticket-audit) object ● [`TicketCancelled`](/reference/graphql/objects/ticket-cancelled) object ● [`TicketChange`](/reference/graphql/objects/ticket-change) object ● [`TicketCreated`](/reference/graphql/objects/ticket-created) object ● [`TicketMessage`](/reference/graphql/objects/ticket-message) object ● [`UserAppointmentsAvailability`](/reference/graphql/objects/user-appointments-availability) object # account Source: https://developer.qminder.com/reference/graphql/queries/account No description ```graphql theme={null} account: Account ``` ### Type #### [Account](/reference/graphql/objects/account) object # allUsers Source: https://developer.qminder.com/reference/graphql/queries/all-users No description ```graphql theme={null} allUsers( includeDeletedFrom: Date ): [User!]! ``` ### Arguments #### [allUsers.includeDeletedFrom](#) ● [Date](/reference/graphql/scalars/date) scalar If omitted returns active users in account. If provided, returns active users and users deleted after provided date. ### Type #### [User](/reference/graphql/objects/user) object # iPad Source: https://developer.qminder.com/reference/graphql/queries/i-pad No description ```graphql theme={null} iPad( id: ID! ): Ipad ``` ### Arguments #### [iPad.id](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [Ipad](/reference/graphql/objects/ipad) object # inputField Source: https://developer.qminder.com/reference/graphql/queries/input-field No description ```graphql theme={null} inputField( id: ID! ): InputField ``` ### Arguments #### [inputField.id](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [InputField](/reference/graphql/objects/input-field) object # line Source: https://developer.qminder.com/reference/graphql/queries/line No description ```graphql theme={null} line( id: ID! ): Line ``` ### Arguments #### [line.id](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [Line](/reference/graphql/objects/line) object # location Source: https://developer.qminder.com/reference/graphql/queries/location No description ```graphql theme={null} location( id: ID! ): Location ``` ### Arguments #### [location.id](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [Location](/reference/graphql/objects/location) object # locations Source: https://developer.qminder.com/reference/graphql/queries/locations No description ```graphql theme={null} locations: [Location!]! ``` ### Type #### [Location](/reference/graphql/objects/location) object # mcpClient Source: https://developer.qminder.com/reference/graphql/queries/mcp-client No description ```graphql theme={null} mcpClient( id: String! ): MCPClient ``` ### Arguments #### [mcpClient.id](#) ● [String!](/reference/graphql/scalars/string) non-null scalar ### Type #### [MCPClient](/reference/graphql/objects/mcpclient) object # me Source: https://developer.qminder.com/reference/graphql/queries/me No description ```graphql theme={null} me: User ``` ### Type #### [User](/reference/graphql/objects/user) object # myCalledTickets Source: https://developer.qminder.com/reference/graphql/queries/my-called-tickets No description ```graphql theme={null} myCalledTickets: [Ticket!]! ``` ### Type #### [Ticket](/reference/graphql/objects/ticket) object # productChanges Source: https://developer.qminder.com/reference/graphql/queries/product-changes No description ```graphql theme={null} productChanges( read: Boolean ): [ProductChange!]! ``` ### Arguments #### [productChanges.read](#) ● [Boolean](/reference/graphql/scalars/boolean) scalar ### Type #### [ProductChange](/reference/graphql/objects/product-change) object # ticket Source: https://developer.qminder.com/reference/graphql/queries/ticket No description ```graphql theme={null} ticket( id: ID! ): Ticket ``` ### Arguments #### [ticket.id](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [Ticket](/reference/graphql/objects/ticket) object # ticketSearch Source: https://developer.qminder.com/reference/graphql/queries/ticket-search No description ```graphql theme={null} ticketSearch( locationId: ID! line: [ID!] status: [TicketStatus!] creator: [ID!] minCreated: Date maxCreated: Date limit: Int offset: Int order: Order appointment: AppointmentFilter minWaitStartedAt: Date ): [Ticket!]! ``` ### Arguments #### [ticketSearch.locationId](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar #### [ticketSearch.line](#) ● [\[ID!\]](/reference/graphql/scalars/id) list scalar #### [ticketSearch.status](#) ● [\[TicketStatus!\]](/reference/graphql/enums/ticket-status) list enum #### [ticketSearch.creator](#) ● [\[ID!\]](/reference/graphql/scalars/id) list scalar #### [ticketSearch.minCreated](#) ● [Date](/reference/graphql/scalars/date) scalar #### [ticketSearch.maxCreated](#) ● [Date](/reference/graphql/scalars/date) scalar #### [ticketSearch.limit](#) ● [Int](/reference/graphql/scalars/int) scalar #### [ticketSearch.offset](#) ● [Int](/reference/graphql/scalars/int) scalar #### [ticketSearch.order](#) ● [Order](/reference/graphql/inputs/order) input #### [ticketSearch.appointment](#) ● [AppointmentFilter](/reference/graphql/inputs/appointment-filter) input #### [ticketSearch.minWaitStartedAt](#) ● [Date](/reference/graphql/scalars/date) scalar ### Type #### [Ticket](/reference/graphql/objects/ticket) object # TV Source: https://developer.qminder.com/reference/graphql/queries/tv No description ```graphql theme={null} TV( id: ID! ): TV ``` ### Arguments #### [TV.id](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [TV](/reference/graphql/objects/tv) object # user Source: https://developer.qminder.com/reference/graphql/queries/user No description ```graphql theme={null} user( id: ID! ): User ``` ### Arguments #### [user.id](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [User](/reference/graphql/objects/user) object # userAppointmentsAvailability Source: https://developer.qminder.com/reference/graphql/queries/user-appointments-availability No description ```graphql theme={null} userAppointmentsAvailability( userId: ID! locationId: ID! ): UserAppointmentsAvailability ``` ### Arguments #### [userAppointmentsAvailability.userId](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar #### [userAppointmentsAvailability.locationId](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [UserAppointmentsAvailability](/reference/graphql/objects/user-appointments-availability) object # users Source: https://developer.qminder.com/reference/graphql/queries/users No description ```graphql theme={null} users( ids: [ID!] ): [User] ``` ### Arguments #### [users.ids](#) ● [\[ID!\]](/reference/graphql/scalars/id) list scalar ### Type #### [User](/reference/graphql/objects/user) object # BigDecimal Source: https://developer.qminder.com/reference/graphql/scalars/big-decimal No description ```graphql theme={null} scalar BigDecimal ``` ### Member Of [`NumericFieldConstraints`](/reference/graphql/objects/numeric-field-constraints) object # Date Source: https://developer.qminder.com/reference/graphql/scalars/date ISO 8601 date-time with timezone A date-time scalar representing a point in time with timezone information. ## Format * **Input**: Flexible ISO 8601 parsing (e.g., `2024-01-15T10:30:00.000Z`) * **Output**: `yyyy-MM-dd'T'HH:mm:ss.SSS'Z'` (always UTC) ## Examples ```graphql theme={null} # Query with Date argument ticketSearch(locationId: "123", minCreated: "2024-01-01T00:00:00.000Z") { id created { date } } ``` ```json theme={null} // Response { "created": { "date": "2024-01-15T14:30:45.123Z" } } ``` ```graphql theme={null} scalar Date ``` ### Member Of [`Account`](/reference/graphql/objects/account) object ● [`allUsers`](/reference/graphql/queries/all-users) query ● [`Appointment`](/reference/graphql/objects/appointment) object ● [`AppointmentFilter`](/reference/graphql/inputs/appointment-filter) input ● [`Interaction`](/reference/graphql/objects/interaction) object ● [`LabelType`](/reference/graphql/objects/label-type) object ● [`Location`](/reference/graphql/objects/location) object ● [`ProductChange`](/reference/graphql/objects/product-change) object ● [`Ticket`](/reference/graphql/objects/ticket) object ● [`TicketAudit`](/reference/graphql/objects/ticket-audit) object ● [`TicketCancelled`](/reference/graphql/objects/ticket-cancelled) object ● [`TicketCreated`](/reference/graphql/objects/ticket-created) object ● [`TicketExternalData`](/reference/graphql/objects/ticket-external-data) object ● [`TicketMessage`](/reference/graphql/objects/ticket-message) object ● [`ticketSearch`](/reference/graphql/queries/ticket-search) query ● [`User`](/reference/graphql/objects/user) object # Duration Source: https://developer.qminder.com/reference/graphql/scalars/duration Time duration in ISO 8601 format A duration scalar representing a length of time. ## Format * **Input/Output**: ISO 8601 duration format (e.g., `PT1H30M` for 1 hour 30 minutes) ## Common Patterns | Duration | Meaning | | --------- | ----------------- | | `PT30S` | 30 seconds | | `PT5M` | 5 minutes | | `PT1H` | 1 hour | | `PT1H30M` | 1 hour 30 minutes | | `P1D` | 1 day | ## Examples ```graphql theme={null} # Query ticket interactions with wait/service times query { ticket(id: "123") { interactions { waitTime # Returns Duration serviceTime # Returns Duration } } } ``` ```json theme={null} // Response { "interactions": [ { "waitTime": "PT12M45S", "serviceTime": "PT8M30S" } ] } ``` ```graphql theme={null} scalar Duration ``` ### Member Of [`Interaction`](/reference/graphql/objects/interaction) object # JSON Source: https://developer.qminder.com/reference/graphql/scalars/json Arbitrary JSON data A scalar representing arbitrary JSON data. Used for flexible, unstructured data fields. ## Format * **Input/Output**: Any valid JSON value (object, array, string, number, boolean, null) ## Examples ```graphql theme={null} # Query ticket external data query { ticket(id: "123") { external { provider data # Returns JSON - structure varies by provider } } } ``` ```json theme={null} // Response - data structure depends on the external provider { "external": [ { "provider": "salesforce", "data": { "contactId": "003xx000004TmiP", "accountName": "Acme Corp", "customFields": { "priority": "high" } } } ] } ``` > **Note**: The `JSON` scalar is used sparingly for truly dynamic data. Most fields use strongly-typed GraphQL types. ```graphql theme={null} scalar JSON ``` ### Returned By [`changedOpeningHours`](/reference/graphql/deprecated/subscriptions/changed-opening-hours) subscription ### Member Of [`Location`](/reference/graphql/objects/location) object ● [`TicketExternalData`](/reference/graphql/objects/ticket-external-data) object # LocalDate Source: https://developer.qminder.com/reference/graphql/scalars/local-date Date without time component A date scalar representing a calendar date without time or timezone information. ## Format * **Input/Output**: `yyyy-MM-dd` ## Examples ```graphql theme={null} # Query opening hours exceptions query { location(id: "123") { openingHoursExceptions2 { date # Returns LocalDate closed } } } ``` ```json theme={null} // Response { "openingHoursExceptions2": [ { "date": "2024-12-25", "closed": true } ] } ``` ```graphql theme={null} scalar LocalDate ``` ### Member Of [`OpeningHoursException`](/reference/graphql/objects/opening-hours-exception) object ● [`UserAppointmentsScheduleOverride`](/reference/graphql/objects/user-appointments-schedule-override) object # LocalTime Source: https://developer.qminder.com/reference/graphql/scalars/local-time Time without date component A time scalar representing a time of day without date or timezone information. ## Format * **Input/Output**: `HH:mm:ss` or `HH:mm` (when using `@formatTime` directive) ## Examples ```graphql theme={null} # Query user availability time slots query { userAppointmentsAvailability(userId: "123", locationId: "456") { weeklySchedule { monday { dailySchedule { availableFrom # Returns LocalTime formatted as "HH:mm" availableTo } } } } } ``` ```json theme={null} // Response { "weeklySchedule": { "monday": { "dailySchedule": [ { "availableFrom": "09:00", "availableTo": "17:00" } ] } } } ``` ```graphql theme={null} scalar LocalTime ``` ### Member Of [`UserAppointmentsAvailabilityTimeInterval`](/reference/graphql/objects/user-appointments-availability-time-interval) object # Long Source: https://developer.qminder.com/reference/graphql/scalars/long No description ```graphql theme={null} scalar Long ``` ### Member Of [`AccountSubscription`](/reference/graphql/objects/account-subscription) object ● [`Ticket`](/reference/graphql/objects/ticket) object ● [`VisitPlanner`](/reference/graphql/objects/visit-planner) object # Short Source: https://developer.qminder.com/reference/graphql/scalars/short No description ```graphql theme={null} scalar Short ``` ### Member Of [`NumericFieldConstraints`](/reference/graphql/objects/numeric-field-constraints) object # appointmentChanged Source: https://developer.qminder.com/reference/graphql/subscriptions/appointment-changed Notifies whenever a specified ticket appointment changes. ```graphql theme={null} appointmentChanged( ticketId: ID! ): Appointment ``` ### Arguments #### [appointmentChanged.ticketId](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [Appointment](/reference/graphql/objects/appointment) object # calledTickets Source: https://developer.qminder.com/reference/graphql/subscriptions/called-tickets No description ```graphql theme={null} calledTickets( locationId: ID! ): Ticket! ``` ### Arguments #### [calledTickets.locationId](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [Ticket](/reference/graphql/objects/ticket) object # cancelledTickets Source: https://developer.qminder.com/reference/graphql/subscriptions/cancelled-tickets No description ```graphql theme={null} cancelledTickets( locationId: ID! ): Ticket! ``` ### Arguments #### [cancelledTickets.locationId](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [Ticket](/reference/graphql/objects/ticket) object # changedDeskSelection Source: https://developer.qminder.com/reference/graphql/subscriptions/changed-desk-selection No description ```graphql theme={null} changedDeskSelection( locationId: ID! ): Desk! ``` ### Arguments #### [changedDeskSelection.locationId](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [Desk](/reference/graphql/objects/desk) object # changedDesks Source: https://developer.qminder.com/reference/graphql/subscriptions/changed-desks Notifies when a desk in the given location is updated or a user changes their desk selection. Returns the updated list of desks for the specified location. ```graphql theme={null} changedDesks( locationId: ID! ): [Desk]! ``` ### Arguments #### [changedDesks.locationId](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [Desk](/reference/graphql/objects/desk) object # changedInputFields Source: https://developer.qminder.com/reference/graphql/subscriptions/changed-input-fields No description ```graphql theme={null} changedInputFields( locationId: ID! ): [InputField] ``` ### Arguments #### [changedInputFields.locationId](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [InputField](/reference/graphql/objects/input-field) object # changedIpads Source: https://developer.qminder.com/reference/graphql/subscriptions/changed-ipads No description ```graphql theme={null} changedIpads( locationId: ID! ): Ipad! ``` ### Arguments #### [changedIpads.locationId](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [Ipad](/reference/graphql/objects/ipad) object # changedLines Source: https://developer.qminder.com/reference/graphql/subscriptions/changed-lines No description ```graphql theme={null} changedLines( locationId: ID! ): Line! ``` ### Arguments #### [changedLines.locationId](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [Line](/reference/graphql/objects/line) object # changedLocation Source: https://developer.qminder.com/reference/graphql/subscriptions/changed-location No description ```graphql theme={null} changedLocation( locationId: ID! ): Location! ``` ### Arguments #### [changedLocation.locationId](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [Location](/reference/graphql/objects/location) object # changedLocationLine Source: https://developer.qminder.com/reference/graphql/subscriptions/changed-location-line Notifies a subscribing client whenever a line from the specified location is: * created * updated * enabled * disabled * archived * deleted Returns the updated location associated with the changed line. ```graphql theme={null} changedLocationLine( locationId: ID! ): Location! ``` ### Arguments #### [changedLocationLine.locationId](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [Location](/reference/graphql/objects/location) object # changedOpeningHours2 Source: https://developer.qminder.com/reference/graphql/subscriptions/changed-opening-hours-2 No description ```graphql theme={null} changedOpeningHours2( locationId: ID! ): OpeningHours! ``` ### Arguments #### [changedOpeningHours2.locationId](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [OpeningHours](/reference/graphql/objects/opening-hours) object # changedTicketFields Source: https://developer.qminder.com/reference/graphql/subscriptions/changed-ticket-fields No description ```graphql theme={null} changedTicketFields( locationId: ID! ): ChangedTicketField! ``` ### Arguments #### [changedTicketFields.locationId](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [ChangedTicketField](/reference/graphql/interfaces/changed-ticket-field) interface # changedTicketLabels Source: https://developer.qminder.com/reference/graphql/subscriptions/changed-ticket-labels No description ```graphql theme={null} changedTicketLabels( locationId: ID! ): ChangedTicketLabel! ``` ### Arguments #### [changedTicketLabels.locationId](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [ChangedTicketLabel](/reference/graphql/objects/changed-ticket-label) object # changedTickets Source: https://developer.qminder.com/reference/graphql/subscriptions/changed-tickets No description ```graphql theme={null} changedTickets( locationId: ID! ): Ticket! ``` ### Arguments #### [changedTickets.locationId](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [Ticket](/reference/graphql/objects/ticket) object # changedTV Source: https://developer.qminder.com/reference/graphql/subscriptions/changed-tv No description ```graphql theme={null} changedTV( tvId: ID! ): TV ``` ### Arguments #### [changedTV.tvId](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [TV](/reference/graphql/objects/tv) object # createdTickets Source: https://developer.qminder.com/reference/graphql/subscriptions/created-tickets Notifies when a ticket is created. If `locationId` is provided, the subscription fires only when tickets are created in that specific location. If `locationId` is omitted, it fires for all locations the user has access to. **Note:** Device principals (iPad/TV) must always provide a `locationId`. ```graphql theme={null} createdTickets( locationId: ID ): Ticket! ``` ### Arguments #### [createdTickets.locationId](#) ● [ID](/reference/graphql/scalars/id) nullable scalar If provided, restricts the subscription to tickets created in the specified location. If omitted, the subscription fires for all locations the user has access to. ### Type #### [Ticket](/reference/graphql/objects/ticket) object # deletedIpads Source: https://developer.qminder.com/reference/graphql/subscriptions/deleted-ipads No description ```graphql theme={null} deletedIpads( locationId: ID! ): Ipad! ``` ### Arguments #### [deletedIpads.locationId](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [Ipad](/reference/graphql/objects/ipad) object # deletedTV Source: https://developer.qminder.com/reference/graphql/subscriptions/deleted-tv No description ```graphql theme={null} deletedTV( tvId: ID! ): TV! ``` ### Arguments #### [deletedTV.tvId](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [TV](/reference/graphql/objects/tv) object # markedAllTicketMessagesAsRead Source: https://developer.qminder.com/reference/graphql/subscriptions/marked-all-ticket-messages-as-read Notifies whenever all ticket messages are marked as read in a given location. Returns the ticket that had messages marked as read. ```graphql theme={null} markedAllTicketMessagesAsRead( locationId: ID! ): Ticket! ``` ### Arguments #### [markedAllTicketMessagesAsRead.locationId](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [Ticket](/reference/graphql/objects/ticket) object # recalledTickets Source: https://developer.qminder.com/reference/graphql/subscriptions/recalled-tickets No description ```graphql theme={null} recalledTickets( locationId: ID! ): Ticket! ``` ### Arguments #### [recalledTickets.locationId](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [Ticket](/reference/graphql/objects/ticket) object # reorderedTicketsList Source: https://developer.qminder.com/reference/graphql/subscriptions/reordered-tickets-list No description ```graphql theme={null} reorderedTicketsList( locationId: ID! ): [Ticket!]! ``` ### Arguments #### [reorderedTicketsList.locationId](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [Ticket](/reference/graphql/objects/ticket) object # servedTickets Source: https://developer.qminder.com/reference/graphql/subscriptions/served-tickets No description ```graphql theme={null} servedTickets( locationId: ID! ): Ticket! ``` ### Arguments #### [servedTickets.locationId](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [Ticket](/reference/graphql/objects/ticket) object # ticketStateChanged Source: https://developer.qminder.com/reference/graphql/subscriptions/ticket-state-changed Notifies whenever a specified ticket state changes (e.g. ticket status, label, field, etc. changes) ```graphql theme={null} ticketStateChanged( ticketId: ID! ): Ticket! ``` ### Arguments #### [ticketStateChanged.ticketId](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [Ticket](/reference/graphql/objects/ticket) object # tvTickets Source: https://developer.qminder.com/reference/graphql/subscriptions/tv-tickets Notifies subscribed TV clients whenever a ticket in a specified location changes status or ticket details changes. ```graphql theme={null} tvTickets( locationId: ID! ): [Ticket!]! ``` ### Arguments #### [tvTickets.locationId](#) ● [ID!](/reference/graphql/scalars/id) non-null scalar ### Type #### [Ticket](/reference/graphql/objects/ticket) object # Overview Source: https://developer.qminder.com/reference/input-fields Input fields are custom data fields attached to locations that collect information from visitors. Input fields define what data is collected from visitors when they join a queue. Each location can have its own set of input fields, allowing different locations to collect different information. There are 9 field types available: | Type | Description | | ----------------- | -------------------------------------------------------------- | | **FIRST\_NAME** | Visitor's first name (built-in, one per location) | | **LAST\_NAME** | Visitor's last name (built-in, one per location) | | **EMAIL** | Visitor's email address (one per location) | | **PHONE\_NUMBER** | Visitor's phone number (one per location) | | **TEXT** | Free-form text input | | **SELECT** | Dropdown selection with custom options (supports multi-select) | | **URL** | URL input | | **DATE** | Date input | | **NUMERIC** | Numeric input with optional min/max constraints | Input fields can be configured with visibility and mandatory settings to control when and where they appear — such as before a ticket is added, before it is served, or in remote sign-in. Each input field can be scoped to specific lines within a location using the `visibleForLines` property. If no lines are specified, the field applies to all lines. # Creating an Input Field Source: https://developer.qminder.com/reference/input-fields/creating-an-input-field Create a new input field for a location. To create an input field, send a POST request to `/input-fields`. The `id` field must be a client-generated UUID. ```bash curl theme={null} curl -X POST https://api.qminder.com/input-fields \ -H "X-Qminder-REST-API-Key: YOUR_API_KEY" \ -H "X-Qminder-API-Version: 2020-09-01" \ -H "Content-Type: application/json" \ -d '{ "id": "550e8400-e29b-41d4-a716-446655440000", "location": { "id": 12345 }, "type": "TEXT", "title": "Reason for visit", "isMandatoryBeforeAdded": true, "isMandatoryBeforeServed": false, "isMandatoryInRemoteSignIn": false, "isVisibleInWaitingDrawer": true, "isVisibleInServingDrawer": true, "showInRemoteSignIn": true, "visibleForLines": [] }' ``` ```typescript TypeScript theme={null} import { Qminder } from 'qminder-api'; Qminder.setKey('YOUR_API_KEY'); await Qminder.Location.createInputField({ id: '550e8400-e29b-41d4-a716-446655440000', location: { id: 12345 }, type: 'TEXT', title: 'Reason for visit', isMandatoryBeforeAdded: true, isMandatoryBeforeServed: false, isMandatoryInRemoteSignIn: false, isVisibleInWaitingDrawer: true, isVisibleInServingDrawer: true, showInRemoteSignIn: true, visibleForLines: [], }); ``` **Response:** `201 Created` with an empty body. ## Common Fields These fields are required for all input field types: | Field | Type | Description | | --------------------------- | ------------- | ---------------------------------------------------------------------------- | | `id` | string (UUID) | Client-generated UUID for the input field | | `location` | object | Location reference: `{"id": number}` | | `type` | string | Field type (see [Field Types](#field-types) below) | | `isMandatoryBeforeAdded` | boolean | Must be filled before ticket is added | | `isMandatoryBeforeServed` | boolean | Must be filled before ticket is served | | `isMandatoryInRemoteSignIn` | boolean | Must be filled in remote sign-in | | `isVisibleInWaitingDrawer` | boolean | Shown in the waiting drawer | | `isVisibleInServingDrawer` | boolean | Shown in the serving drawer | | `showInRemoteSignIn` | boolean | Show in remote sign-in | | `visibleForLines` | array | Lines this field applies to: `[{"id": number}]`. Empty array means all lines | ## Field Types The `type` field determines which additional properties are available. ### Built-in Types **FIRST\_NAME** and **LAST\_NAME** are built-in field types with fixed titles. They have no additional required properties beyond the common fields. Optional field: * `isRequiredInAppointments` (boolean) — Whether the field is required when booking appointments. Only available for `LAST_NAME` and `EMAIL` types. **EMAIL** and **PHONE\_NUMBER** are singleton types — only one of each can exist per location. Attempting to create a second will return a `409` error. Optional field for `EMAIL`: * `isRequiredInAppointments` (boolean) — Whether the field is required when booking appointments ### TEXT A free-form text input field. | Field | Type | Required | Description | | -------------------- | ------ | -------- | ------------------------------------------------ | | `title` | string | Yes | Display title | | `visitorFacingTitle` | string | No | Title shown to visitors | | `translations` | array | No | Translations (see [Translations](#translations)) | ### SELECT A dropdown selection field with custom options. | Field | Type | Required | Description | | -------------------- | ------- | -------- | ------------------------------------------------ | | `title` | string | Yes | Display title | | `multiSelect` | boolean | Yes | Allow multiple selections | | `options` | array | Yes | Array of select options (see below) | | `visitorFacingTitle` | string | No | Title shown to visitors | | `translations` | array | No | Translations (see [Translations](#translations)) | Each option in the `options` array: | Field | Type | Required | Description | | ------- | ------------- | -------- | ------------------------------------ | | `id` | string (UUID) | Yes | Client-generated UUID for the option | | `title` | string | Yes | Option display title | | `color` | string | No | Option color | **Example — creating a SELECT field:** ```bash curl theme={null} curl -X POST https://api.qminder.com/input-fields \ -H "X-Qminder-REST-API-Key: YOUR_API_KEY" \ -H "X-Qminder-API-Version: 2020-09-01" \ -H "Content-Type: application/json" \ -d '{ "id": "660e8400-e29b-41d4-a716-446655440001", "location": { "id": 12345 }, "type": "SELECT", "title": "Service type", "multiSelect": false, "options": [ { "id": "770e8400-e29b-41d4-a716-446655440001", "title": "General inquiry" }, { "id": "770e8400-e29b-41d4-a716-446655440002", "title": "Returns" }, { "id": "770e8400-e29b-41d4-a716-446655440003", "title": "Pickup" } ], "isMandatoryBeforeAdded": true, "isMandatoryBeforeServed": false, "isMandatoryInRemoteSignIn": false, "isVisibleInWaitingDrawer": true, "isVisibleInServingDrawer": true, "showInRemoteSignIn": true, "visibleForLines": [] }' ``` ```typescript TypeScript theme={null} import { Qminder } from 'qminder-api'; Qminder.setKey('YOUR_API_KEY'); await Qminder.Location.createInputField({ id: '660e8400-e29b-41d4-a716-446655440001', location: { id: 12345 }, type: 'SELECT', title: 'Service type', multiSelect: false, options: [ { id: '770e8400-e29b-41d4-a716-446655440001', title: 'General inquiry' }, { id: '770e8400-e29b-41d4-a716-446655440002', title: 'Returns' }, { id: '770e8400-e29b-41d4-a716-446655440003', title: 'Pickup' }, ], isMandatoryBeforeAdded: true, isMandatoryBeforeServed: false, isMandatoryInRemoteSignIn: false, isVisibleInWaitingDrawer: true, isVisibleInServingDrawer: true, showInRemoteSignIn: true, visibleForLines: [], }); ``` ### URL A URL input field. | Field | Type | Required | Description | | ------- | ------ | -------- | ------------- | | `title` | string | Yes | Display title | URL fields cannot be shown in remote sign-in — `showInRemoteSignIn` is always treated as `false`. ### DATE A date input field. | Field | Type | Required | Description | | -------------------- | ------ | -------- | ------------------------------------------------ | | `title` | string | Yes | Display title | | `visitorFacingTitle` | string | No | Title shown to visitors | | `translations` | array | No | Translations (see [Translations](#translations)) | ### NUMERIC A numeric input field with optional constraints. | Field | Type | Required | Description | | -------------------- | ------ | -------- | ------------------------------------------------ | | `title` | string | Yes | Display title | | `visitorFacingTitle` | string | No | Title shown to visitors | | `constraints` | object | No | Min/max constraints (see below) | | `translations` | array | No | Translations (see [Translations](#translations)) | The `constraints` object: | Field | Type | Required | Description | | ------- | ------- | -------- | ------------------------ | | `min` | number | No | Minimum allowed value | | `max` | number | No | Maximum allowed value | | `scale` | integer | Yes | Number of decimal places | **Example — creating a NUMERIC field with constraints:** ```bash curl theme={null} curl -X POST https://api.qminder.com/input-fields \ -H "X-Qminder-REST-API-Key: YOUR_API_KEY" \ -H "X-Qminder-API-Version: 2020-09-01" \ -H "Content-Type: application/json" \ -d '{ "id": "880e8400-e29b-41d4-a716-446655440001", "location": { "id": 12345 }, "type": "NUMERIC", "title": "Amount", "constraints": { "min": 0, "max": 10000, "scale": 2 }, "isMandatoryBeforeAdded": false, "isMandatoryBeforeServed": true, "isMandatoryInRemoteSignIn": false, "isVisibleInWaitingDrawer": true, "isVisibleInServingDrawer": true, "showInRemoteSignIn": false, "visibleForLines": [] }' ``` ```typescript TypeScript theme={null} import { Qminder } from 'qminder-api'; Qminder.setKey('YOUR_API_KEY'); await Qminder.Location.createInputField({ id: '880e8400-e29b-41d4-a716-446655440001', location: { id: 12345 }, type: 'NUMERIC', title: 'Amount', constraints: { min: 0, max: 10000, scale: 2, }, isMandatoryBeforeAdded: false, isMandatoryBeforeServed: true, isMandatoryInRemoteSignIn: false, isVisibleInWaitingDrawer: true, isVisibleInServingDrawer: true, showInRemoteSignIn: false, visibleForLines: [], }); ``` ## Translations The following field types support translations: `TEXT`, `SELECT`, `URL`, `DATE`, and `NUMERIC`. Each translation object: | Field | Type | Required | Description | | -------------------- | ------ | -------- | ------------------------------------- | | `languageCode` | string | Yes | Language code (e.g. "fr", "es", "de") | | `title` | string | No | Translated field title | | `visitorFacingTitle` | string | No | Translated visitor-facing title | ```json theme={null} { "translations": [ { "languageCode": "fr", "title": "Raison de la visite", "visitorFacingTitle": "Votre raison" }, { "languageCode": "es", "title": "Motivo de la visita" } ] } ``` ## Error Responses | Status | Code | Description | | ------ | ---------------------------- | ------------------------------------------------------------ | | 400 | `duplicate_items_in_request` | SELECT options have duplicate titles | | 400 | `parameter_invalid_blank` | Translation title or visitor-facing title is blank | | 400 | Bad request | Missing `type` field or invalid request body | | 404 | `resource_missing` | Location not found | | 409 | `input_field_duplicate` | Input field with the same ID already exists | | 409 | `input_field_duplicate` | EMAIL or PHONE\_NUMBER field already exists in this location | # Editing an Input Field Source: https://developer.qminder.com/reference/input-fields/editing-an-input-field Update an existing input field's properties. To update an input field, send a PATCH request to `/input-fields/{inputFieldId}`. Only include fields you want to change — omitted fields remain unchanged. ```bash curl theme={null} curl -X PATCH https://api.qminder.com/input-fields/550e8400-e29b-41d4-a716-446655440000 \ -H "X-Qminder-REST-API-Key: YOUR_API_KEY" \ -H "X-Qminder-API-Version: 2020-09-01" \ -H "Content-Type: application/json" \ -d '{ "title": "Visit reason", "isVisibleInWaitingDrawer": false, "isMandatoryBeforeServed": true }' ``` **Response:** `200 OK` with an empty body. ### Editable Fields All fields are optional — only include the fields you want to change. | Field | Type | Description | | --------------------------- | -------------- | ----------------------------------------------------------------------------------------------------------- | | `title` | string | Display title (max 50 characters). Only for TEXT, SELECT, URL, DATE, NUMERIC. | | `visitorFacingTitle` | string \| null | Title shown to visitors (max 200 characters). Set to `null` to clear. Only for TEXT, SELECT, DATE, NUMERIC. | | `isVisibleInWaitingDrawer` | boolean | Shown in the waiting drawer | | `isVisibleInServingDrawer` | boolean | Shown in the serving drawer | | `isMandatoryBeforeAdded` | boolean | Must be filled before ticket is added | | `isMandatoryBeforeServed` | boolean | Must be filled before ticket is served | | `isMandatoryInRemoteSignIn` | boolean | Must be filled in remote sign-in | | `showInRemoteSignIn` | boolean | Show in remote sign-in | | `visibleForLines` | array | Lines this field applies to: `[{"id": number}]`. Empty array means all lines. | | `multiSelect` | boolean | Allow multiple selections. Only for SELECT. | | `options` | array | Select options. Only for SELECT. | | `constraints` | object | Numeric constraints (`min`, `max`, `scale`). Only for NUMERIC. | | `translations` | array | Translations (see below). Only for TEXT, SELECT, URL, DATE, NUMERIC. | ### Type-Specific Restrictions Not all fields can be set on all input field types. Setting a restricted field returns a `400` error: * **`title`** — cannot be set on FIRST\_NAME, LAST\_NAME, EMAIL, PHONE\_NUMBER * **`visitorFacingTitle`** — cannot be set on FIRST\_NAME, LAST\_NAME, EMAIL, PHONE\_NUMBER, URL * **`multiSelect`** and **`options`** — can only be set on SELECT * **`constraints`** — only applies to NUMERIC ### Translations When `translations` is provided, **all existing translations are replaced** with the new set. There is no way to update a single translation — you must send the complete list. ```json theme={null} { "translations": [ { "languageCode": "fr", "title": "Raison de la visite", "visitorFacingTitle": "Votre raison" }, { "languageCode": "es", "title": "Motivo de la visita" } ] } ``` ### SELECT Options When `options` is provided for a SELECT field, options are matched by `id`: * Options with a matching `id` are **updated** * Options with a new `id` are **added** * Existing options not included in the request are **removed** ```json theme={null} { "options": [ { "id": "770e8400-e29b-41d4-a716-446655440001", "title": "Updated title" }, { "id": "990e8400-e29b-41d4-a716-446655440001", "title": "New option" } ] } ``` ### Error Responses | Status | Code | Description | | ------ | ---------------------------- | ------------------------------------------------------------------------ | | 400 | `invalid_arguments` | Type-specific field set on wrong type (e.g., `title` on EMAIL) | | 400 | `duplicate_items_in_request` | SELECT options have duplicate titles | | 400 | `parameter_invalid_blank` | Title, visitor-facing title, or translation title is blank | | 400 | Validation error | Title too long (>50 chars) or visitor-facing title too long (>200 chars) | | 404 | `resource_missing` | Input field not found | # Overview Source: https://developer.qminder.com/reference/lines Lines represent virtual queues in Qminder. One Location can have multiple Lines. It is recommended to have one Line for every different type of service, because this way it is possible to view statistics based on service type. Visitor tickets are assigned to lines. Lines can be enabled or disabled. When a line is disabled, visitors cannot be added to the line. Disabled lines are not selectable on Visit Planner and iPad. ## Fields Lines have the following data fields: | Name | Type | Description | | ------------ | ------- | ----------------------------------------------------------- | | **id** | number | | | **name** | string | User-specified name of the Line | | **location** | number | ID of the location the Line belongs to | | **color** | string | Hex color code of the line, used for coloring charts | | **disabled** | boolean | True if the line is disabled, false if the line is enabled. | ### Code examples This is a Line object as returned by our RESTful API and our official libraries. ```bash bash theme={null} { "id": 49185, "name": "Service Line", "location": 5610, "color": "#f0f0f0", "disabled": false } ``` # Creating a Line Source: https://developer.qminder.com/reference/lines/creating-a-line Create a new line (queue) within a location. To create a line, send a POST request to `/v1/locations/{locationId}/lines`: ```bash curl theme={null} curl -X POST https://api.qminder.com/v1/locations/12345/lines \ -H "X-Qminder-REST-API-Key: YOUR_API_KEY" \ -H "X-Qminder-API-Version: 2020-09-01" \ -H "Content-Type: application/json" \ -d '{ "name": "Customer Support", "color": "TEAL" }' ``` ```typescript TypeScript theme={null} import { Qminder } from 'qminder-api'; Qminder.setKey('YOUR_API_KEY'); const response = await Qminder.Line.create(12345, { name: 'Customer Support', color: 'TEAL', }); console.log(response.id); ``` **Required fields:** * `name` - Line name (max 30 characters) * `color` - Line color. One of: `VIOLET`, `LAVENDER`, `MARSHMALLOW`, `TEAL`, `MINT`, `CORAL`, `YELLOW`, `ROSE`, `INDIGO`, `BLUE` **Optional fields:** * `disabled` - Whether the line starts disabled (default: `false`) * `translations` - Name translations for multi-language support (see below) * `appointmentSettings` - Appointment configuration (see below) **Response (201 Created):** ```json theme={null} { "id": "12345" } ``` ### Translations You can provide name translations for multi-language support: ```json theme={null} { "name": "Customer Support", "color": "TEAL", "translations": [ { "languageCode": "fr", "name": "Service client" }, { "languageCode": "es", "name": "Atención al cliente" } ] } ``` Each translation object has: * `languageCode` (string, required) - Language code (e.g. "fr", "es", "de") * `name` (string, optional) - Translated line name (max 30 characters) ### Appointment Settings You can enable appointments and set a default duration: ```json theme={null} { "name": "Customer Support", "color": "TEAL", "appointmentSettings": { "enabled": true, "duration": 30 } } ``` * `enabled` (boolean, required) - Whether appointments are enabled for this line * `duration` (integer, required) - Default appointment duration in minutes. Allowed values: `15`, `30`, `45`, `60`, `90`, `120`, `180` ### 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 color name | `{"code": "parameter_invalid", "message": "...", "param": "color"}` | | 400 | Invalid appointment duration | `{"code": "parameter_invalid", "message": "...", "param": "appointmentSettings.duration"}` | | 400 | Language code is blank | `{"code": "parameter_invalid_blank", "message": "...", "param": "translations[0].languageCode"}` | | 400 | Translation name is blank | `{"code": "parameter_invalid", "message": "...", "param": "translations[0].name"}` | | 400 | Translation name too long (>30 chars) | `{"code": "parameter_invalid_size", "message": "...", "param": "translations[0].name"}` | | 409 | Line with same name already exists | Conflict error | # Overview Source: https://developer.qminder.com/reference/locations Locations represent physical locations in Qminder, such as buildings, service points or retail store locations. Every business account can have multiple Locations. It is possible to grant access to staff to only one or multiple locations, and manage access levels on a per-location basis. Service settings such as lines or input fields are stored on a per-location basis. ## Fields | Name | Type | Description | | -------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **id** | number | A unique ID for the Location | | **name** | string | The location's name. | | **latitude** | number | The location's geographical latitude. | | **longitude** | number | The location's geographical longitude. | | **country** | string | Which country the location's located in. | | **address** | string | The location's postal address. | | **selectingDeskMandatory** | boolean | True if clerks need to select a desk to start service, false if not. | | **timezoneOffset** | number | The amount of minutes to add to UTC to get local time in this location. For example, if the timezoneOffset is -240, then the time zone for this location is UTC - 4 (EDT). This parameter follows daylight savings time. | ### Code examples This is a Location object as provided by our RESTful API and our official libraries. ```bash bash theme={null} { "id": 28594, "name": "White House", "latitude": 38.8976763, "longitude": -77.0365298, "country": "United States", "address": "1600 Pennsylvania Ave NW, Washington, DC 20500, United States", "selectingDeskMandatory": false, "timezoneOffset": -240 } ``` # Creating a Location Source: https://developer.qminder.com/reference/locations/creating-a-location Create a new location in your Qminder account. To create a location, send a POST request to `/locations`: ```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"] }' ``` **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:** ```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?" } ] } ] }' ``` 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:** ```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" } ] } ] }' ``` ### 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"}` | # Overview Source: https://developer.qminder.com/reference/overview This page will help you get started with Qminder API. Welcome to Qminder's API documentation! Developers can use Qminder's API to integrate applications with Qminder, such as internal backend systems, CRMs and more. In order to make simple integrations between services without writing code, it is possible to [use the Zapier integration](https://support.qminder.com/en/articles/996949-zapier-connect-with-750-apps?_gl=1*1sm3woz*_gcl_au*OTYwNDE0MDM1LjE3MTgyODczNjguMTg0Nzc4ODUzOS4xNzI1MjY5NjA2LjE3MjUyNjk2MDY.*_ga*MTUxMDYzNzIyNy4xNzE4NjA2OTQ5*_ga_TEGQ0K4MXW*MTcyNTM2MTEyMi42My4xLjE3MjUzNjExMjUuMC4wLjIwNjQ3NzcyMDY.). ### Library In order to simplify integration with Qminder's platform, it is possible to use an official [Javascript / TypeScript](https://github.com/Qminder/javascript-api/) software library. Qminder's official library is tested and used by the team every day. ### REST API The Qminder API is a [HTTP REST API](http://en.wikipedia.org/wiki/Representational_state_transfer). It is possible to connect to the Qminder API with any programming environment that supports sending HTTP requests. [Read more about how to connect to REST APIs](https://www.smashingmagazine.com/2018/01/understanding-using-rest-api/). Most Qminder API endpoints are available under `https://api.qminder.com/v1/`. A handful of newer endpoints — creating a location, creating or editing a ticket, and creating or editing an input field — are served directly from `https://api.qminder.com/` without the `/v1/` prefix. The exact URL for each endpoint is shown in the "API Endpoints" tab. Note that the API can only be used with HTTPS (encrypted HTTP). The API cannot be used with regular HTTP (unencrypted) connections. ### What you can do with the API With the Qminder REST API, it is possible to solve these common business problems: * Adding visitors to queue, editing the details (using the Tickets API) * Managing service lines in a location, enabling and disabling lines (using the Lines API) * Managing user access and automatically sending invites to new employees (using the Users API) ### Qminder Webhooks Using webhooks with the Qminder platform, it is possible to integrate your application by registering a webhook listener. This webhook listener will be notified with a HTTP POST request when events occur in the Qminder platform. ### Premium support **Premium API support is available** if your company is on the Enterprise plan of Qminder. Your developers can contact Qminder support and receive help from the people who created Qminder. Contact Qminder support to receive more information on how to get support for your API questions. ### Authentication To authenticate requests to the Qminder API, you need an API key. Create and manage API keys in the Qminder Dashboard under **Organization Settings → Developer Tools**. You can create multiple API keys for the same account — for example, one per integration — so each can be tracked and revoked independently. For security, keys are hidden in the list by default; click **Reveal** to view a key's value. You can revoke a key at any time to immediately disable any integration using it. Here's how to create an API key in the Qminder Dashboard: ### Making a request Qminder API uses two common data exchange formats: JSON and standard URL forms. API calls expect requests to be formatted with the application/x-www-form-urlencoded format, and reply with JSON data, unless specified otherwise in the API method documentation. In order to call the Qminder API, the API key has to be provided. The API key can be provided as a HTTP request header or as a query string parameter. **It is recommended to send the API key as a HTTP request header.** Here's how to use the [cURL](https://curl.haxx.se/docs/manual.html) command line tool to send an API call: `curl https://api.qminder.com/v1/locations/ -H "X-Qminder-REST-API-Key: KEY"` As an alternative, here is how to specify the Qminder API key as a query string parameter: `curl https://api.qminder.com/v1/locations/?rest-api-key=KEY` ### Response The Qminder API responds to HTTP requests with the correct HTTP status codes. When the HTTP request succeeds, the HTTP status code will be between 200 and 299. When the HTTP request fails, the HTTP status code will be between 400 and 599. API calls also return the HTTP status code in the JSON data to make it easier to extract. Here is an example HTTP response (Ticket Details API call) ```bash bash theme={null} { "statusCode": 200, "id": "42367593", "status": "NEW", "source": "MANUAL", "line": 102321, "firstName": "Mari", "lastName": "Müür", "created": { "date": "2018-12-31T13:53:19.243Z" } } ``` If an error occurs, Qminder will send a HTTP status code indicating the error and also include a message. Optionally, a developer friendly message will be included as well. ```bash bash theme={null} { "statusCode": 401, "message": "Please authenticate", "developerMessage": "Set X-Qminder-REST-API-Key HTTP header with API key" } ``` ### API rate limits The Qminder API is rate limited in order to prevent abuse and ensure that every customer can access the Qminder API. Please design your integration to work within the API rate limits. **Rate limit: 5 requests per second per user / API key** Here is how the rate limits work: All API calls count against the rate limit. The algorithm used for rate limiting is the [token bucket algorithm](https://en.wikipedia.org/wiki/Token_bucket). The capacity of the bucket (the burst size) is 40 requests, the replenish rate for the bucket (the average rate) is 10 per second. The Qminder API sends a HTTP response header for the amount of API calls remaining: `X-Ratelimit-Remaining`. This HTTP header can be used to determine how much of the rate limit has been used. Reaching the rate limit will block access to the API (for the given API key) until the rate limit replenishes. When the limit has been reached, the value of the `X-Ratelimit-Remaining` header will be -1 and all responses will return an HTTP response status of 429. It is possible to request a rate limit increase from Qminder by contacting support. # Input Fields Source: https://developer.qminder.com/reference/queries/input-fields You can get the list of input fields configured for a location. This is useful when creating tickets or appointments with custom field values. Input field IDs are UUIDs (e.g., `550e8400-e29b-41d4-a716-446655440000`), not numeric IDs like locations or lines. ```graphql graphql theme={null} query InputFieldsForLocation { location(id: "123") { inputFields { id type title multiSelect visibleForLines { id } options { id title } } } } ``` Example response: ```json theme={null} { "data": { "location": { "inputFields": [ { "id": "550e8400-e29b-41d4-a716-446655440000", "type": "TEXT", "title": "Reason for visit", "multiSelect": false, "visibleForLines": [], "options": [] }, { "id": "550e8400-e29b-41d4-a716-446655440001", "type": "SELECT", "title": "Service Type", "multiSelect": false, "visibleForLines": [{"id": "88100"}], "options": [ {"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "title": "New Account"}, {"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901", "title": "Support"} ] } ] } } } ``` ## Field Types | Type | Value Format | Description | | -------------- | ------------------------------- | --------------------------------- | | `FIRST_NAME` | `value` (string) | Visitor's first name | | `LAST_NAME` | `value` (string) | Visitor's last name | | `EMAIL` | `value` (string) | Email address | | `PHONE_NUMBER` | `value` (string) | Phone number | | `TEXT` | `value` (string, max 500 chars) | Free-form text | | `URL` | `value` (string) | URL | | `DATE` | `value` (ISO 8601 string) | Date value | | `NUMERIC` | `value` (string) | Numeric value | | `SELECT` | `optionIds` (array of UUIDs) | Selection from predefined options | For the complete field type reference, see [InputFieldType](/reference/graphql/enums/input-field-type). ## Using SELECT Fields For `SELECT` type fields, provide option IDs in the `optionIds` array instead of `value`: * Check the `multiSelect` property to determine if multiple options can be selected * If `multiSelect` is `false`, provide exactly one option ID * If `multiSelect` is `true`, you may provide multiple option IDs ## Line Visibility The `visibleForLines` array indicates which lines the input field applies to: * Empty array (`[]`) means the field is visible for all lines * Non-empty array means the field only applies to those specific lines For more details on the InputField object, see the [GraphQL InputField documentation](/reference/graphql/objects/input-field). # Locations Source: https://developer.qminder.com/reference/queries/locations To get list of all locations for the account you can use the `locations` query: ```graphql graphql theme={null} query ListOfLocations { account { locations { id name address } } } ``` # Visitors Source: https://developer.qminder.com/reference/queries/visitors You can get the list of visitors waiting in a location: ```graphql graphql theme={null} query VisitorsWaiting { ticketSearch(locationId: "123", status: [NEW], order: {field: CREATED, direction: DESCENDING}) { id firstName lastName } } ``` # Overview Source: https://developer.qminder.com/reference/tickets Tickets represent a visitor's single visit to a Location. A ticket is created every time a visitor is added to queue by either service personnel or via iPad and Visit Planner Remote Sign-in. All tickets belong to a Line. Tickets are called when service clerks call the visitor, and are served when service clerks mark the visitor as served. Tickets can contain additional free-form data as name / value pairs, that will be shown on the Qminder Service View as custom input fields. Tickets can additionally have one or more Labels, which are useful for tagging visitors or sharing small notes between coworkers. * [Creating a Ticket](/reference/tickets/creating-a-ticket) — add a visitor to a queue line * [Editing a Ticket](/reference/tickets/editing-a-ticket) — update visitor information or move to a different line * [Attaching External Info](/reference/tickets/attaching-external-info) — enrich tickets with data from external systems ### Fields Tickets have the following data fields: | Name | Type | Description | | ---------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **id** | string | The ticket's unique ID. | | **publicId** | string | The ticket's public-facing ID (e.g., "A-42"). | | **status** | string | The ticket's status. "NEW" = The ticket is in the queue. "CALLED" = The ticket is currently being serviced. "SERVED" = The ticket has been marked as served. "CANCELLED\_BY\_CLERK" = The ticket has been removed from queue. "NOSHOW" = The ticket was marked as no-show. | | **source** | string | The ticket's source. "MANUAL" = The ticket has been created by a clerk. "NAME" = The ticket has been created by iPad Sign-in. "MICROSITE" = The ticket has been created by Visit Planner Remote Sign-in. | | **line** | number | The ID of the Line that the ticket has been created into. | | **firstName** | string | The visitor's first name (given name). | | **lastName** | string | The visitor's last name (family name). | | **phoneNumber** | string | The visitor's phone number with optional + prefix. | | **email** | string | The visitor's email address. | | **languageCode** | string | The visitor's preferred language code (e.g., "en", "es"). | | **orderAfter** | ISO 8601 | If the visitor has been reordered before another ticket, then this timestamp should be used to chronologically order the ticket. | | **created.date** | ISO 8601 | The timestamp when the ticket was created. | | **called.date** | ISO 8601 | The timestamp when the ticket was called. **This field is only present on tickets with the "CALLED" status.** | | **called.caller** | number | The ID of the user who called the ticket. **This field is only present on tickets with the "CALLED" status.** | | **called.desk** | number | The ID of the desk where the ticket was called.- \*This field is only present if the ticket was called to a desk. This field is only present on tickets with the "CALLED" status.\*\* | | **served.date** | ISO 8601 | The timestamp when the ticket was marked as served. **This field is only present on tickets with the "SERVED" status.** | | **assigned.assigner** | number | The ID of the user who assigned the ticket to another user. **This field is only present on tickets that have been reassigned.** | | **assigned.assignee** | number | The ID of the user who was assigned to serve the ticket. **This field is only present on tickets that have been reassigned.** | | **extra** | array | An array of additional data fields. This array is empty when no additional data fields are available. | | **extra\[].title** | string | The title of an additional data field. | | **extra\[].value** | string | The value of an additional data field. | | **labels** | array | An array of ticket labels. This array is empty when no labels are available. | | **labels\[].value** | string | The text of the ticket label. | | **labels\[].color** | string | An RGB hex color of the label. | | **interactions** | array | An array of service interactions. One interaction object is added into the array for every time the ticket is called and either returned to queue or serviced. | | **interactions\[].start** | ISO 8601 | A timestamp of when the interaction with the visitor started. | | **interactions\[].end** | ISO 8601 | A timestamp of when the interaction with the visitor ended. | | **interactions\[].line** | number | The ID of the line the visitor was called from, before the interaction started. | | **interactions\[].user** | number | The ID of the user who serviced the visitor during this interaction. | | **messages** | array | An array of SMS messages sent to the visitor or received from the visitor. | | **messages\[].created.date** | ISO 8601 | A timestamp of when the message was sent or received. | | **messages\[].body** | string | The text of the message. | | **messages\[].type** | string | "OUTGOING" if the message was sent from Qminder to the visitor. "INCOMING" if the message was received from the visitor. | | **messages\[].status** | string | "NEW" if the message has been sent, but not yet delivered to the visitor. "DELIVERED" if the message has been delivered to the visitor. | ### Code examples This is a Ticket object as returned by our RESTful API and our official libraries. ```bash bash theme={null} { "id": "51999102", "status": "SERVED", "source": "MANUAL", "line": 88100, "firstName": "Jane", "lastName": "Doe", "orderAfter": "2015-04-29T12:29:40.701Z", "created": { "date": "2016-04-29T12:29:40.701Z" }, "called": { "date": "2016-05-05T14:05:29Z", "caller": 15144, "desk": 3 }, "served": { "date": "2016-05-05T14:05:34Z" }, "assigned": { "assigner": 15100, "assignee": 15144 }, "extra": [ { "title": "Notes", "value": "assistance required" } ], "labels": [ { "value": "VIP", "color": "FF00FF" } ], "interactions": [ { "start": "2016-05-05T14:05:29Z", "end": "2016-05-05T14:05:34Z", "line": 88100, "user": 15144 } ], "messages": [ { "created": { "date": "2017-06-15T18:43:41Z" }, "body": "Hello Jane! You are now in the queue. We will let you know when it's your turn.", "type": "OUTGOING", "status": "DELIVERED" } ] } ``` # Attaching External Info Source: https://developer.qminder.com/reference/tickets/attaching-external-info Enrich tickets with structured data from external systems like CRMs, EHRs, or payment platforms. Integrations can attach structured external information to a ticket, which is then displayed in the Qminder Service View alongside the visitor's details. This is useful for showing contextual data from CRMs, EHRs, payment systems, or any other external platform — giving service clerks the information they need without switching between tools. External data is for **server-side integrations** that display read-only information from external systems. For visitor-provided input fields that are collected during sign-in, see the `extra` fields in the [Tickets overview](/reference/tickets). ## API Endpoint ``` POST /v1/tickets/{ticketId}/external ``` Both `POST` and `PUT` are accepted with identical behavior. ### Parameters Parameters are sent as **form-encoded** fields (not a JSON body). The `data` field contains a JSON string, which must be URL-encoded. | Parameter | Type | Required | Description | | ---------- | ------ | -------- | -------------------------------------------------------------------------------------------- | | `provider` | string | Yes | Unique identifier for your integration (e.g., `"salesforce"`, `"epic"`). Max 100 characters. | | `title` | string | Yes | Display title shown as the section header in the Service View. Max 100 characters. | | `data` | string | Yes | JSON string conforming to the data schema described below. | ### Example Request ```bash curl theme={null} curl -X POST https://api.qminder.com/v1/tickets/12345/external \ -H "X-Qminder-REST-API-Key: YOUR_SECRET_API_KEY" \ -d "provider=my-crm" \ -d "title=Patient Info" \ --data-urlencode 'data={ "fields": [ { "type": "message", "content": "ALLERGY ALERT: Penicillin — Severe", "importance": "warning" }, { "type": "text", "title": "Patient Name", "value": "Maria Schmidt" }, { "type": "email", "title": "Contact Email", "value": "maria.schmidt@example.com" }, { "type": "list", "title": "Recent Visits", "items": [ { "title": "Annual Checkup", "text": "Dr. Patel", "url": "https://portal.example.com/doc/7391", "footer": "Internal Medicine", "timestamp": "2026-01-10" } ] } ] }' ``` ```typescript TypeScript theme={null} import { Qminder } from 'qminder-api'; Qminder.setKey('YOUR_SECRET_API_KEY'); const data = { fields: [ { type: 'message', content: 'ALLERGY ALERT: Penicillin — Severe', importance: 'warning', }, { type: 'text', title: 'Patient Name', value: 'Maria Schmidt' }, { type: 'email', title: 'Contact Email', value: 'maria.schmidt@example.com' }, { type: 'list', title: 'Recent Visits', items: [ { title: 'Annual Checkup', text: 'Dr. Patel', url: 'https://portal.example.com/doc/7391', footer: 'Internal Medicine', timestamp: '2026-01-10', }, ], }, ], }; await Qminder.Ticket.setExternalData('12345', 'my-crm', 'Patient Info', data); ``` **Response (200 OK):** ```json theme={null} {"statusCode": 200} ``` ## Data Structure The `data` parameter must be a JSON string containing an object with a `fields` array: ```json theme={null} { "fields": [] } ``` Three categories of fields are supported: **message**, **textual** (`text`, `email`, `phoneNumber`), and **list**. You can mix and combine them freely within the `fields` array. ### Message Fields Displays a colored alert banner. Use messages to highlight important information that clerks should see immediately. | Property | Type | Required | Description | | ------------ | ------ | -------- | ----------------------------------- | | `type` | string | Yes | Must be `"message"` | | `content` | string | Yes | The message text to display | | `importance` | string | Yes | `"error"`, `"warning"`, or `"info"` | The `importance` level controls the visual styling: **`error`** — red background, for critical alerts: ```json theme={null} { "type": "message", "content": "CRITICAL: Elevated troponin levels detected in Feb 14 labs. Cardiology follow-up overdue by 17 days.", "importance": "error" } ``` Error message banner **`warning`** — orange background, for important notices: ```json theme={null} { "type": "message", "content": "ALLERGY ALERT: Penicillin — Severe (Anaphylaxis). Consult prescriber before any new medications.", "importance": "warning" } ``` Warning message banner **`info`** — gray background, for general information: ```json theme={null} { "type": "message", "content": "Annual flu vaccination completed on 2025-10-05. Next recommended checkup: Apr 2026.", "importance": "info" } ``` Info message banner ### Textual Fields Displays a key-value row. Three subtypes are available: `text` for plain text, `email` for email addresses, and `phoneNumber` for phone numbers. | Property | Type | Required | Description | | -------- | ------ | -------- | --------------------------------------- | | `type` | string | Yes | `"text"`, `"email"`, or `"phoneNumber"` | | `title` | string | Yes | Label displayed on the left side | | `value` | string | Yes | Value displayed on the right side | ```json theme={null} { "type": "text", "title": "Patient Name", "value": "Maria Schmidt" } ``` ```json theme={null} { "type": "email", "title": "Contact Email", "value": "maria.schmidt@example.com" } ``` ```json theme={null} { "type": "phoneNumber", "title": "Emergency Contact", "value": "+15551234567" } ``` Textual fields displayed as key-value rows ### List Fields Displays a titled section with a collection of items. Each item has a required title and optional metadata. | Property | Type | Required | Description | | -------- | ------ | -------- | --------------------------------------- | | `type` | string | Yes | Must be `"list"` | | `title` | string | Yes | Section header (displayed in uppercase) | | `items` | array | Yes | Array of list item objects | **List item properties:** | Property | Type | Required | Description | | ----------- | ------ | -------- | ---------------------------------------------------------- | | `title` | string | Yes | Bold item title | | `text` | string | No | Description text below the title | | `url` | string | No | Clickable link displayed below the title | | `footer` | string | No | Displayed as a tag/badge pill | | `timestamp` | string | No | Date in `YYYY-MM-DD` format, displayed below other content | A list item with all optional properties: ```json theme={null} { "title": "Complete Record", "text": "Comprehensive entry with all optional fields populated", "url": "https://records.example.com/entry/48291", "footer": "Category: Full Review", "timestamp": "2026-03-01" } ``` List item showing all optional properties A complete list field with multiple items demonstrates different combinations: ```json theme={null} { "type": "list", "title": "Detailed Records", "items": [ { "title": "Complete Record", "text": "Comprehensive entry with all optional fields populated", "url": "https://records.example.com/entry/48291", "footer": "Category: Full Review", "timestamp": "2026-03-01" }, { "title": "Entry with Date", "timestamp": "2026-02-15" }, { "title": "Entry with Description", "text": "This item demonstrates the text property showing a description below the title" }, { "title": "Entry with Link", "url": "https://portal.example.com/doc/7391" }, { "title": "Entry with Tag", "footer": "Status: Pending Approval" } ] } ``` Complete list field with multiple varied items A minimal list with just a title and one item: ```json theme={null} { "type": "list", "title": "Pending Tasks", "items": [{ "title": "Schedule follow-up appointment" }] } ``` Minimal list field ## Key Behaviors * **Upsert semantics:** One record per `(ticketId, provider)` pair. Calling the endpoint again with the same provider replaces the previous data entirely. * **Multiple providers:** A single ticket can have external data from many providers (e.g., both `"salesforce"` and `"epic"`). Each appears as a separate section in the Service View. * **Schema validation:** The `data` JSON is validated server-side. Invalid structures or unknown properties return a 400 error. * **Real-time updates:** After storing, the Service View updates immediately — no page refresh needed. ## Reading External Data External data attached to a ticket can be read back via the GraphQL API using the `external` field on the `Ticket` type. The `data` field returns a [`JSON` scalar](/reference/graphql/scalars/json) — a parsed JSON object matching the structure you originally sent: ```graphql theme={null} query { ticket(id: "12345") { external { provider title data created } } } ``` ## Error Responses | Status | Description | Example | | ------ | ------------------------ | ---------------------------------- | | 400 | Invalid JSON | `"Data is not valid JSON object"` | | 400 | Schema validation failed | `"Data does not match the schema"` | | 403 | Non-SECRET API key used | Forbidden | | 404 | Ticket not found | `"Ticket with id 12345 not found"` | # Creating a Ticket Source: https://developer.qminder.com/reference/tickets/creating-a-ticket Create a new ticket by adding a visitor to a queue line. To create a ticket, send a POST request to `/tickets`: ```bash curl theme={null} curl -X POST https://api.qminder.com/tickets \ -H "X-Qminder-REST-API-Key: YOUR_API_KEY" \ -H "X-Qminder-API-Version: 2020-09-01" \ -H "Content-Type: application/json" \ -d '{ "lineId": "12345", "firstName": "John", "lastName": "Doe", "phoneNumber": "+12125551234", "email": "john@example.com" }' ``` ```typescript TypeScript theme={null} import { Qminder } from 'qminder-api'; Qminder.setKey('YOUR_API_KEY'); const ticket = await Qminder.Ticket.create({ lineId: '12345', firstName: 'John', lastName: 'Doe', phoneNumber: '+12125551234', email: 'john@example.com', }); console.log(ticket.id); // "226859" ``` **Required fields:** * `lineId` - ID of the line to create the ticket in * `firstName` - Visitor's first name (2-50 characters) **Optional fields:** * `lastName` - Visitor's last name (max 50 characters) * `phoneNumber` - Phone number with optional + prefix (5-20 digits) * `email` - Visitor's email address (max 100 characters) * `languageCode` - Language code, e.g. "en", "es" (2-5 characters, default: "en") * `source` - MANUAL, NAME, or MICROSITE (default: MANUAL) * `fields` - Array of custom input fields with `inputFieldId` (UUID) and `value` (max 500 characters) or `optionIds` * `labels` - Array of labels with `value` **Response (201 Created):** ```json theme={null} { "id": "226859", "publicId": "A-42" } ``` ### Input Fields To use the `fields` parameter, you first need to discover the available input field IDs for the location. See the [Input Fields query](/reference/queries/input-fields) for details. ### Error Responses | Status | Description | Example | | ------ | ----------------------------------------- | ------------------------------------------------------------------------- | | 400 | Validation failed | `{"statusCode": 400, "message": "First name must not be empty or blank"}` | | 404 | Line, input fields, or language not found | `{"message": "Line with id 123456 not found"}` | | 409 | Target line is disabled or archived | `{"message": "Line with id 789 is disabled"}` | # Editing a Ticket Source: https://developer.qminder.com/reference/tickets/editing-a-ticket Update a ticket's visitor information, line assignment, or language preference. To update a ticket, send a PATCH request to `/tickets/{ticketId}`. Only include fields you want to change — omitted fields remain unchanged. Set a field to `null` to clear its value. ```bash curl theme={null} curl -X PATCH https://api.qminder.com/tickets/14848 \ -H "X-Qminder-REST-API-Key: YOUR_API_KEY" \ -H "X-Qminder-API-Version: 2020-09-01" \ -H "Content-Type: application/json" \ -d '{ "firstName": "John", "lastName": "Smith", "email": "john.smith@example.com", "phoneNumber": "+12125551234" }' ``` ```typescript TypeScript theme={null} import { Qminder } from 'qminder-api'; Qminder.setKey('YOUR_API_KEY'); await Qminder.Ticket.edit(14848, { firstName: 'John', lastName: 'Smith', email: 'john.smith@example.com', phoneNumber: '+12125551234', }); ``` ### Editable Fields All fields are optional — only include the fields you want to change. | Field | Type | Description | | -------------- | -------------- | -------------------------------------------------------------------------------- | | `firstName` | string | Visitor's first name (2-50 characters). Cannot be null or empty. | | `lastName` | string \| null | Visitor's last name (max 50 characters). Set to `null` to clear. | | `email` | string \| null | Visitor's email address (max 100 characters). Set to `null` to clear. | | `phoneNumber` | string \| null | Phone number with optional + prefix (5-20 digits). Set to `null` to clear. | | `line` | string | ID of the line to move the ticket to. Must be a valid line in the same location. | | `languageCode` | string | Visitor's preferred language code, e.g. "en", "es" (2-5 characters). | ### Error Responses | Status | Description | Example | | ------ | ----------------------------------- | ------------------------------------------------------------------------- | | 400 | Validation failed | `{"statusCode": 400, "message": "First name must not be empty or blank"}` | | 404 | Ticket or line not found | `{"message": "Ticket with id 123456 not found"}` | | 409 | Target line is disabled or archived | `{"message": "Line with id 789 is disabled"}` | # Users Source: https://developer.qminder.com/reference/users Every person who can log in to Qminder has a corresponding User object. Users can be granted access to locations on a per-location basis, either with the "MANAGER" or "CLERK" access level. Users can also be granted access to the entire Account, if they are given the "ADMIN" permission. ### Fields Users have the following data fields: | Name | Type | Description | | -------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------ | | **id** | number | A user's unique ID in Qminder | | **email** | string | A user's email address. Users will use this email address to log in to Qminder. | | **firstName** | string | The user's first (given) name. | | **lastName** | string | The user's last (family) name. | | **selectedLocation** | number | The ID of the location that the user has currently selected. | | **roles** | array | An array of all access roles that the user has. | | **roles\[].id** | number | The ID of the access role. | | **roles\[].type** | string | The access level granted by this access role.- \*"CLERK"\*\* = can service visitors and see statistics about themselves. | * \*"MANAGER"\*\* = can manage settings of a single location and see statistics for the whole location, and all clerks in that location. * \*"ADMIN"\*\* = can manage settings of the whole account. Admins have "MANAGER" access to all locations in an Account. * \*"OWNER"\*\* = same as "ADMIN", but this role cannot be granted to others or removed from the Owner of the account. | \| **roles\[].location** | number | The ID of the Location that this access role grants access to. **Only "CLERK" and "MANAGER" role types have a location ID field.** | ### Code examples This is a Line object as returned by our RESTful API and our official libraries. ```bash bash theme={null} { "id": 891, "email": "[email protected]", "firstName": "Test", "lastName": "User", "selectedLocation": 4022, "roles": [ { "type": "ADMIN" } ] } ``` # Webhooks Source: https://developer.qminder.com/reference/webhooks Using this API, Webhook endpoint URLs can be managed programmatically. [Read more on how to utilize webhooks for your API integration.](/reference/webhooks-overview) ### Fields Webhook endpoints have the following data fields: | Name | Type | Description | | ---------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **id** | number | The unique ID of the webhook endpoint registration. | | **url** | string | The URL that will receive webhook HTTP requests. | | **secret** | string | The HMAC-SHA256 shared secret for webhook signature verification. [Read more on how to secure webhooks with signature verification.](/reference/webhooks-overview#webhook-authentication) | ### Code examples This is a webhook endpoint object as returned by our RESTful API and our official libraries. ```bash bash theme={null} { "id": 827, "secret": "wfdfghfhfgdsfderthyndf4356hyfds" } ``` # Lines Source: https://developer.qminder.com/reference/webhooks-lines Qminder's backend sends HTTP requests to registered URLs every time a Line in the account has changed. ### Line changed This HTTP request is sent to the registered URL every time a Line was changed in Qminder. ```bash bash theme={null} POST /webhooks HTTP/1.1 X-Qminder-Signature: SIGNATURE Content-Type: application/json { "type": "line_changed", "data": { "id": 12345, "name": "Registration" } ``` This HTTP request includes the following data fields in its request body: | Field name | Data type | Description | | ------------- | --------------- | -------------------------------------------------------------------------------------------------- | | **type** | "line\_changed" | Always "line\_changed" for the Line Changed event | | **data.id** | number | The ID of the line that has changed | | **data.name** | string | The name of the line that has changed. If the line's name has changed, this value is the new name. | # Locations Source: https://developer.qminder.com/reference/webhooks-locations Qminder's backend sends HTTP requests to registered URLs every time a Location has been created or changed. ### Location created This HTTP request is sent to registered URLs every time a Location was created in Qminder. ```bash bash theme={null} POST /webhooks HTTP/1.1 X-Qminder-Signature: SIGNATURE Content-Type: application/json { "type": "location_created", "data": { "id": 12345, "name": "Service Location" } } ``` This HTTP request includes the following data fields in its request body: | Field name | Data type | Description | | ------------- | ------------------- | --------------------------------------------------------- | | **type** | "location\_created" | Always "location\_created" for the Location Created event | | **data.id** | number | The ID of the newly created location. | | **data.name** | string | The name of the newly created location. | ### Location changed This HTTP request is sent to registered URLs every time a Location was changed in Qminder. ```bash bash theme={null} POST /webhooks HTTP/1.1 X-Qminder-Signature: SIGNATURE Content-Type: application/json { "type": "location_changed", "data": { "id": 12345, "name": "Service Location 2" } } ``` This HTTP request includes the following data fields in its request body: | Field name | Data type | Description | | ------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------- | | **type** | "location\_changed" | Always "location\_changed" for the Location Changed event | | **data.id** | number | The ID of the changed location | | **data.name** | string | The name of the changed location. If the location's name has changed, the new location name is sent with this HTTP request. | # Overview Source: https://developer.qminder.com/reference/webhooks-overview Webhooks let you register an URL that Qminder's servers will send a HTTP request to, anytime the following actions happen in your account: * A location is added to the Qminder account (using the location\_created event) * A location's settings have changed (using the location\_changed event) * A line's settings have changed (using the line\_changed event) * A ticket is added to queue (using the ticket\_created event) * A ticket is called for service (using the ticket\_called event) * A ticket is re-called (using the ticket\_recalled event) * A ticket's data is changed (using the ticket\_changed event) * A ticket is marked as served (using the ticket\_served event) ### Registering an URL In order to receive webhook events on your company's backend servers, the webhook's URL has to be registered in Qminder Dashboard. After registration, events will be sent to the URL. #### Here's how to register an URL: 1. Go to [Qminder Dashboard](https://dashboard.qminder.com/?_gl=1*7qnlkn*_gcl_au*OTYwNDE0MDM1LjE3MTgyODczNjguMTg0Nzc4ODUzOS4xNzI1MjY5NjA2LjE3MjUyNjk2MDY.*_ga*MTUxMDYzNzIyNy4xNzE4NjA2OTQ5*_ga_TEGQ0K4MXW*MTcyNTQ0ODczMS42Ny4xLjE3MjU0NDk5MTUuMC4wLjEyNzUwMTE0Mjg.) 2. Log in as an Administrator or Owner of the account 3. Using the left side-bar, click on the bottom most option (your profile photo), and select **"Organization Settings"**. 4. Select **"Developer Tools"** from the top navigation bar. 5. Click on the **"New endpoint"** button. 6. Enter the URL to be notified 7. Click on "Save" to finish registration. After completing this procedure, events on the account will be sent to the URL. #### The following rules apply for an URL: * Begins with http(s):// * Consists of at least domain and subdomain * Maximum length is 512 characters ### HTTP request example As an example, if the URL "[https://example.com/webhooks"](https://example.com/webhooks%22) has been registered in Qminder as a webhook listener, it will receive this POST request when a ticket is created: ```bash bash theme={null} POST /webhooks HTTP/1.1 X-Qminder-Signature: SIGNATURE Content-Type: application/json { "type": "ticket_created", "data": { "id": "7024061", "status": "NEW", "source": "MANUAL", "line": 12345, "firstName": "Jane", "lastName": "Eyre", "phoneNumber": 12125551234, "email": "[email protected]", "created": { "date": "2020-05-25T00:00:00Z" }, "extra": [ { "title": "Repeat visitor?", "value": "Yes" } ] } } ``` ### Webhook authentication It is possible to authenticate Qminder webhooks using a HMAC (hash-based message authentication code) signature. Qminder's servers will sign every webhook request and pass the HMAC to your backend servers. Qminder uses the HMAC-SHA256 signature algorithm. Here's how to authenticate Qminder webhooks: 1. After adding a webhook in Qminder Dashboard, copy the "Secret" value and give it to your software. 2. Every time a request is received, digest the URL and the POST request body with the secret value. 3. Extract the digest result in hexadecimal, and compare it with the request's X-Qminder-Signature header. Here's how to do it in code: ```bash bash theme={null} // this example is in JavaScript, with Node.js const crypto = require('crypto'); const QMINDER_SECRET = '71dX4IUKcJMDOaMHeA5IACBSHJkS4LzYNXlZPleg'; function getSignature(url, postBody) { const hmac = crypto.createHmac('sha256', QMINDER_SECRET); hmac.update(url); hmac.update(postBody); const signature = hmac.digest('hex'); return signature; } console.log( getSignature( "https://example.com/webhooks", "{ \"statusCode\": 200 }" ) ); ``` # Tickets Source: https://developer.qminder.com/reference/webhooks-tickets Qminder's backend sends HTTP requests to registered URLs every time a Ticket is created, called, served, re-called or changed. ### Ticket created This HTTP request is sent to the registered URL every time a Ticket was created in Qminder. ```bash bash theme={null} POST /webhooks HTTP/1.1 X-Qminder-Signature: SIGNATURE Content-Type: application/json { "type": "ticket_created", "data": { "id": "123456789", "status": "NEW", "source": "MANUAL", "line": 37338, "firstName": "Jane", "lastName": "Eyre", "phoneNumber": 12125551234, "created": { "date": "2020-05-15T00:15:24Z" }, "extra": [ { "title": "First time visitor?", "value": "Yes" } ] } } ``` This HTTP request includes the following data fields in its request body: | Field name | Data type | Description | | ----------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------- | | **type** | "ticket\_created" | Always "ticket\_created" for the Ticket Created event | | **data.id** | string | The ID of the ticket that was created | | ... | Ticket | Other data fields come from the Ticket data model. [Read more about the Ticket data model.](/reference/tickets#fields) | ### Ticket called This HTTP request is sent to the registered URL every time a Ticket was called in Qminder. ```bash bash theme={null} POST /webhooks HTTP/1.1 X-Qminder-Signature: SIGNATURE Content-Type: application/json { "type": "ticket_called", "data": { "id": "123456789", "status": "CALLED", "source": "MANUAL", "line": 37338, "firstName": "Jane", "lastName": "Eyre", "phoneNumber": 12125551234, "created": { "date": "2020-05-15T00:15:24Z" }, "called": { "date": "2016-02-18T10:43:04Z", "caller": 14267, "desk": 3 }, "extra": [ { "title": "First time visitor?", "value": "Yes" } ] } } ``` This HTTP request includes the following data fields in its request body: | Field name | Data type | Description | | ----------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------- | | **type** | "ticket\_called" | Always "ticket\_called" for the Ticket Called event | | **data.id** | string | The ID of the ticket that was created | | ... | Ticket | Other data fields come from the Ticket data model. [Read more about the Ticket data model.](/reference/tickets#fields) | ### Ticket re-called This HTTP request is sent to the registered URL every time a Ticket was called again in Qminder. ```bash bash theme={null} POST /webhooks HTTP/1.1 X-Qminder-Signature: SIGNATURE Content-Type: application/json { "type": "ticket_created", "data": { "id": "123456789", "status": "CALLED", "source": "MANUAL", "line": 37338, "firstName": "Jane", "lastName": "Eyre", "phoneNumber": 12125551234, "created": { "date": "2020-05-15T00:15:24Z" }, "called": { "date": "2016-02-18T10:43:04Z", "caller": 14267, "desk": 3 }, "extra": [ { "title": "First time visitor?", "value": "Yes" } ] } } ``` This HTTP request includes the following data fields in its request body: | Field name | Data type | Description | | ----------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------- | | **type** | "ticket\_recalled" | Always "ticket\_recalled" for the Ticket Re-called event | | **data.id** | string | The ID of the ticket that was created | | ... | Ticket | Other data fields come from the Ticket data model. [Read more about the Ticket data model.](/reference/tickets#fields) | ### Ticket removed from queue This HTTP request is sent to the registered URL every time a Ticket was removed from the queue in Qminder. ```bash bash theme={null} POST /webhooks HTTP/1.1 X-Qminder-Signature: SIGNATURE Content-Type: application/json { "type": "ticket_cancelled", "data": { "id": "123456789", "status": "CANCELLED_BY_CLERK", "source": "MANUAL", "line": 37338, "firstName": "Jane", "lastName": "Eyre", "phoneNumber": 12125551234, "created": { "date": "2020-05-15T00:15:24Z" }, "extra": [ { "title": "First time visitor?", "value": "Yes" } ] } } ``` This HTTP request includes the following data fields in its request body: | Field name | Data type | Description | | ----------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------- | | **type** | "ticket\_cancelled" | Always "ticket\_cancelled" for the Ticket Removed event | | **data.id** | string | The ID of the ticket that was created | | ... | Ticket | Other data fields come from the Ticket data model. [Read more about the Ticket data model.](/reference/tickets#fields) | ### Ticket served This HTTP request is sent to the registered URL every time a Ticket was served in Qminder. ```bash bash theme={null} POST /webhooks HTTP/1.1 X-Qminder-Signature: SIGNATURE Content-Type: application/json { "type": "ticket_served", "data": { "id": "123456789", "status": "SERVED", "source": "MANUAL", "line": 37338, "firstName": "Jane", "lastName": "Eyre", "phoneNumber": 12125551234, "created": { "date": "2020-05-15T00:15:24Z" }, "called": { "date": "2016-02-18T10:43:04Z", "caller": 14267, "desk": 3 }, "served": { "date": "2016-02-18T10:53:19Z" }, "extra": [ { "title": "First time visitor?", "value": "Yes" } ] } } ``` This HTTP request includes the following data fields in its request body: | Field name | Data type | Description | | ----------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------- | | **type** | "ticket\_served" | Always "ticket\_served" for the Ticket Served event | | **data.id** | string | The ID of the ticket that was created | | ... | Ticket | Other data fields come from the Ticket data model. [Read more about the Ticket data model.](/reference/tickets#fields) | ### Ticket changed This HTTP request is sent to the registered URL every time a Ticket's information was changed in Qminder. ```bash bash theme={null} POST /webhooks HTTP/1.1 X-Qminder-Signature: SIGNATURE Content-Type: application/json { "type": "ticket_changed", "data": { "id": "123456789", "status": "NEW", "source": "MANUAL", "line": 37338, "firstName": "Jane", "lastName": "Eyre", "phoneNumber": 12125551234, "created": { "date": "2020-05-15T00:15:24Z" }, "extra": [ { "title": "First time visitor?", "value": "No" } ] } } ``` This HTTP request includes the following data fields in its request body: | Field name | Data type | Description | | ----------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------- | | **type** | "ticket\_changed" | Always "ticket\_changed" for the Ticket Changed event | | **data.id** | string | The ID of the ticket that was created | | ... | Ticket | Other data fields come from the Ticket data model. [Read more about the Ticket data model.](/reference/tickets#fields) |