> This page is for API Reference.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.navipartner.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.navipartner.com/_mcp/server.

# Confirm Reservation

POST https://api.npretail.app/{tenant}/{environment}/{company}/ticket/reservation/{token}/confirm
Content-Type: application/json

Finalizes a provisional reservation, turning it into a confirmed booking. This endpoint requires the reservation token and may include additional customer information such as ticket holder details and payment reference. Upon successful confirmation, the reservation status is updated, and ticket numbers are assigned.

Reference: https://docs.navipartner.com/apis/api-reference/ticketing/service-reservations/confirm-reservation

## Authentication

- `x-np-api-key` header (required) — API Key authentication via header

## Request

### Path parameters

- `tenant` (string, required) — Your Entra Tenant ID. [More details.](/paths#1-tenant)
- `environment` (string, required) — Your Business Central Environment. [More details.](/paths#2-environment)
- `company` (string, required) — Your Business Central Company. [More details.](/paths#3-company)
- `token` (string, required) — A unique token that identifies a ticket reservation

### Body (application/json)

This endpoint expects a ConfirmReservationRequest.

- `ticketHolder` (string, optional) — The name of the person holding the ticket(s)
- `ticketHolderLanguage` (string, optional) — The language code the ticket holder wants to receive notifications in.
- `notificationAddress` (string, optional) — The email address or mobile phone number to send tickets and notifications to
- `paymentReference` (string, optional) — A reference to the payment transaction. Unless provided, the reservation is not considered paid. A confirmed unpaid reservation must be paid on site before the tickets are valid for usage.

## Response

### 200

- `token` (string, required) — A unique token that identifies a ticket reservation
- `reservationStatus` (enum, required) — The status of the reservation
  - Allowed values: `registered`, `confirmed`, `alreadyConfirmed`, `canceled`, `expired`, `reserved`, `optional`
- `expiresAt` (datetime, optional) — The date and time when the token expires and reservation is no longer valid
- `reservations` (list of ReservationItemDetails, optional)

## Types

### ReservationItemDetails

Contains detailed information about a specific item in a reservation. Includes the itemNumber, quantity reserved, associated ticket details, and a list of content items specifying admissions or other components included with the ticket.

- `itemNumber` (string, required) — An item or product number defined in the ticketing system
- `quantity` (integer, required) — The number of tickets to reserved
- `lineId` (UUID, required) — Stable identifier for this reservation line. Store and echo it back when reconciling sales documents or tickets with the originating reservation.
- `ticket` (ReservationTicketDetails, required) — A ticket within a reservation: validity period, issue date, blocked state and pricing. `ticketNumbers`, `pinCode` and `ticketHolder` are returned once the reservation is confirmed. Until then the tickets are provisional — updating the reservation re-issues them — and they cannot be used at admission. Once confirmed, the reservation can no longer be updated, so the values are final. To get the provisional ticket numbers before confirmation, pass `includeTicketNumbers=true`. `pinCode` and `ticketHolder` are still held back.
- `content` (list of TicketContentDetails, required)

### ReservationTicketDetails

A ticket within a reservation: validity period, issue date, blocked state and pricing. `ticketNumbers`, `pinCode` and `ticketHolder` are returned once the reservation is confirmed. Until then the tickets are provisional — updating the reservation re-issues them — and they cannot be used at admission. Once confirmed, the reservation can no longer be updated, so the values are final. To get the provisional ticket numbers before confirmation, pass `includeTicketNumbers=true`. `pinCode` and `ticketHolder` are still held back.

- `ticketKind` (enum, required) — The kind of ticket, either individual or group admission.
  - Allowed values: `individualAdmission`, `groupAdmission`
- `validFrom` (datetime, required)
- `validUntil` (datetime, required)
- `issuedAt` (datetime, required) — The date and time when the ticket was issued
- `blocked` (boolean, required)
- `unitPrice` (double, required)
- `unitPriceInclVat` (double, required)
- `currencyCode` (string, required)
- `ticketNumbers` (list of TicketNumbers, optional)
- `pinCode` (string, optional) — A pin code for the ticket, used to authorize rescheduling or revoking a confirmed ticket. Returned only for confirmed reservations. The format is configured per tenant, so do not validate it against a fixed length or pattern.
- `ticketHolder` (string, optional) — The name of the person holding the ticket(s)
- `admissionEntitlements` (list of AdmissionEntitlement, optional)

### TicketContentDetails

Provides details about the admissions or content associated with a reserved ticket item. Contains admissionDetails that specify the particular admissions, schedules, and any relevant information for each component of the ticket.

- `admissionDetails` (AdmissionDetails, required) — Details of the admission for a specific reservation
- `scheduleDetails` (ScheduleDetails, required) — Details of the schedule for a specific reservation or ticket.

### TicketNumbers

A list of ticket numbers.

- `ticketId` (UUID, required) — The unique identifier of a ticket
- `ticketNumber` (string, required) — The unique identifier of a ticket

### AdmissionEntitlement

Included for Group Tickets, the admission entitlement objects defines the number of admissions included for the group ticket.

- `code` (string, required) — A unique code that identifies a specific admission.
- `maxGroupSize` (integer, required) — The maximum group size for a group ticket. Calculated as ordered quantity multiplied by a factor defined per admission.

### AdmissionDetails

Details of the admission for a specific reservation

- `capacityControl` (enum, required) — Indicates the type of capacity control that applies. `none` means capacity is not tracked. `sales` means capacity is decremented by ticket sales. `admitted` means capacity is decremented by admitted entries. `full` means capacity tracks both admissions and departures.
  - Allowed values: `none`, `sales`, `admitted`, `full`
- `code` (string, required) — A unique code that identifies a specific admission.
- `default` (boolean, required) — Indicates if this admission is the default admission when there are multiple admission defined.
- `description` (Descriptions, required) — Descriptive information about a ticket item. The source of these fields are configurable.
- `included` (enum, required) — Indicates if the admission is mandatory or optional. `mandatory` implies that the admission can not be deselected. `optionalNotSelected` implies that you must opt-in to include the admission, while `optionalAndSelected` implies that the admission is optional and selected and you can opt-out. You opt-in or opt-out by including or excluding the admission in the reservation request.
  - Allowed values: `mandatory`, `optionalNotSelected`, `optionalAndSelected`
- `scheduleDetails` (ScheduleDetails, optional) — Details of the schedule for a specific reservation or ticket.

### ScheduleDetails

Details of the schedule for a specific reservation or ticket.

- `code` (string, required)
- `duration` (integer, required)
- `endDate` (date, required)
- `endTime` (string, required)
- `externalNumber` (integer, required) — The ID of a specific time slot for a specific admission
- `startDate` (date, required)
- `startTime` (string, required)
- `arrivalFromTime` (string, optional) — The earliest time a customer can arrive for the time slot.
- `arrivalUntilTime` (string, optional) — The latest time a customer can arrive for the time slot.
- `description` (string, optional)
- `type` (enum, optional) — The types of events that can occur for a ticket.
  - Allowed values: `initialEntry`, `reservation`, `admitted`, `departed`, `consumed`, `canceledAdmission`, `payment`, `prePaid`, `postPaid`, `canceledReservation`, `requested`, `unknown`

### Descriptions

Descriptive information about a ticket item. The source of these fields are configurable.

- `title` (string, optional)
- `subtitle` (string, optional)
- `name` (string, optional)
- `description` (string, optional)
- `fullDescription` (string, optional)

## Examples

### Confirm individual admission ticket

**Request**

```json
{
  "ticketHolder": "John Doe",
  "ticketHolderLanguage": "ENU",
  "notificationAddress": "john@acme.com",
  "paymentReference": "PAY123456"
}
```

**Response**

```json
{
  "token": "ABC123456DEF789GHI",
  "reservationStatus": "confirmed",
  "reservations": [
    {
      "itemNumber": "31001",
      "quantity": 2,
      "lineId": "819647d5-9d69-492e-8bb5-87799bfbf179",
      "ticket": {
        "ticketKind": "individualAdmission",
        "validFrom": "2024-10-15T00:00:00Z",
        "validUntil": "2024-10-15T23:59:59Z",
        "issuedAt": "2024-10-15T12:13:00Z",
        "blocked": false,
        "unitPrice": 80,
        "unitPriceInclVat": 100,
        "currencyCode": "DKK",
        "ticketNumbers": [
          {
            "ticketId": "12345678-1234-1234-1234-123456789012",
            "ticketNumber": "TICKET123"
          },
          {
            "ticketId": "ABCDEFAB-1234-1234-1234-123456789013",
            "ticketNumber": "TICKET124"
          }
        ],
        "pinCode": "1234-5678",
        "ticketHolder": "John Doe"
      },
      "content": [
        {
          "admissionDetails": {
            "capacityControl": "sales",
            "code": "CASTLE",
            "default": true,
            "description": {
              "title": "Castle Museum Entrance",
              "subtitle": "Adult Castle Ticket",
              "name": "Explore the Castle",
              "description": "<b>Access</b> to the castle exhibit",
              "fullDescription": "<p>Experience the grandeur of the castle's architecture and marvel at its intricate details.  Walk through beautifully decorated rooms and admire the stunning artwork and furniture on display.</p>"
            },
            "included": "mandatory"
          },
          "scheduleDetails": {
            "code": "MORNING",
            "duration": 10800,
            "endDate": "2024-10-15",
            "endTime": "12:00",
            "externalNumber": 452,
            "startDate": "2024-10-15",
            "startTime": "09:00",
            "arrivalFromTime": "08:30",
            "arrivalUntilTime": "10:00",
            "description": "Morning schedule"
          }
        }
      ]
    }
  ]
}
```

**SDK Code**

```python Confirm individual admission ticket
import requests

url = "https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./ticket/reservation/ABC123456DEF789GHI/confirm"

payload = {
    "ticketHolder": "John Doe",
    "ticketHolderLanguage": "ENU",
    "notificationAddress": "john@acme.com",
    "paymentReference": "PAY123456"
}
headers = {
    "x-np-api-key": "<NaviPartner API Key>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Confirm individual admission ticket
const url = 'https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./ticket/reservation/ABC123456DEF789GHI/confirm';
const options = {
  method: 'POST',
  headers: {'x-np-api-key': '<NaviPartner API Key>', 'Content-Type': 'application/json'},
  body: '{"ticketHolder":"John Doe","ticketHolderLanguage":"ENU","notificationAddress":"john@acme.com","paymentReference":"PAY123456"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Confirm individual admission ticket
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./ticket/reservation/ABC123456DEF789GHI/confirm"

	payload := strings.NewReader("{\n  \"ticketHolder\": \"John Doe\",\n  \"ticketHolderLanguage\": \"ENU\",\n  \"notificationAddress\": \"john@acme.com\",\n  \"paymentReference\": \"PAY123456\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("x-np-api-key", "<NaviPartner API Key>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Confirm individual admission ticket
require 'uri'
require 'net/http'

url = URI("https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./ticket/reservation/ABC123456DEF789GHI/confirm")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["x-np-api-key"] = '<NaviPartner API Key>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"ticketHolder\": \"John Doe\",\n  \"ticketHolderLanguage\": \"ENU\",\n  \"notificationAddress\": \"john@acme.com\",\n  \"paymentReference\": \"PAY123456\"\n}"

response = http.request(request)
puts response.read_body
```

```java Confirm individual admission ticket
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./ticket/reservation/ABC123456DEF789GHI/confirm")
  .header("x-np-api-key", "<NaviPartner API Key>")
  .header("Content-Type", "application/json")
  .body("{\n  \"ticketHolder\": \"John Doe\",\n  \"ticketHolderLanguage\": \"ENU\",\n  \"notificationAddress\": \"john@acme.com\",\n  \"paymentReference\": \"PAY123456\"\n}")
  .asString();
```

```php Confirm individual admission ticket
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./ticket/reservation/ABC123456DEF789GHI/confirm', [
  'body' => '{
  "ticketHolder": "John Doe",
  "ticketHolderLanguage": "ENU",
  "notificationAddress": "john@acme.com",
  "paymentReference": "PAY123456"
}',
  'headers' => [
    'Content-Type' => 'application/json',
    'x-np-api-key' => '<NaviPartner API Key>',
  ],
]);

echo $response->getBody();
```

```csharp Confirm individual admission ticket
using RestSharp;

var client = new RestClient("https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./ticket/reservation/ABC123456DEF789GHI/confirm");
var request = new RestRequest(Method.POST);
request.AddHeader("x-np-api-key", "<NaviPartner API Key>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"ticketHolder\": \"John Doe\",\n  \"ticketHolderLanguage\": \"ENU\",\n  \"notificationAddress\": \"john@acme.com\",\n  \"paymentReference\": \"PAY123456\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Confirm individual admission ticket
import Foundation

let headers = [
  "x-np-api-key": "<NaviPartner API Key>",
  "Content-Type": "application/json"
]
let parameters = [
  "ticketHolder": "John Doe",
  "ticketHolderLanguage": "ENU",
  "notificationAddress": "john@acme.com",
  "paymentReference": "PAY123456"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./ticket/reservation/ABC123456DEF789GHI/confirm")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Confirm group admission ticket

Example of confirming a group ticket reservation. The response includes admissionEntitlements which specify the admission codes and maximum group sizes for the group ticket.

**Request**

```json
{
  "ticketHolder": "John Doe",
  "ticketHolderLanguage": "ENU",
  "notificationAddress": "john@acme.com",
  "paymentReference": "PAY123456"
}
```

**Response**

```json
{
  "token": "ABC123456DEF789GHI",
  "reservationStatus": "confirmed",
  "reservations": [
    {
      "itemNumber": "31001",
      "quantity": 2,
      "lineId": "819647d5-9d69-492e-8bb5-87799bfbf179",
      "ticket": {
        "ticketKind": "groupAdmission",
        "validFrom": "2024-10-15T00:00:00Z",
        "validUntil": "2024-10-15T23:59:59Z",
        "issuedAt": "2024-10-15T12:13:00Z",
        "blocked": false,
        "unitPrice": 80,
        "unitPriceInclVat": 100,
        "currencyCode": "DKK",
        "ticketNumbers": [
          {
            "ticketId": "12345678-1234-1234-1234-123456789012",
            "ticketNumber": "TICKET123"
          }
        ],
        "pinCode": "1234-5678",
        "ticketHolder": "John Doe",
        "admissionEntitlements": [
          {
            "code": "CASTLE",
            "maxGroupSize": 10
          }
        ]
      },
      "content": [
        {
          "admissionDetails": {
            "capacityControl": "sales",
            "code": "CASTLE",
            "default": true,
            "description": {
              "title": "Castle Museum Entrance",
              "subtitle": "Adult Castle Ticket",
              "name": "Explore the Castle",
              "description": "<b>Access</b> to the castle exhibit",
              "fullDescription": "<p>Experience the grandeur of the castle's architecture and marvel at its intricate details.  Walk through beautifully decorated rooms and admire the stunning artwork and furniture on display.</p>"
            },
            "included": "mandatory"
          },
          "scheduleDetails": {
            "code": "MORNING",
            "duration": 10800,
            "endDate": "2024-10-15",
            "endTime": "12:00",
            "externalNumber": 452,
            "startDate": "2024-10-15",
            "startTime": "09:00",
            "arrivalFromTime": "08:30",
            "arrivalUntilTime": "10:00",
            "description": "Morning schedule"
          }
        }
      ]
    }
  ]
}
```

**SDK Code**

```python Confirm group admission ticket
import requests

url = "https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./ticket/reservation/ABC123456DEF789GHI/confirm"

payload = {
    "ticketHolder": "John Doe",
    "ticketHolderLanguage": "ENU",
    "notificationAddress": "john@acme.com",
    "paymentReference": "PAY123456"
}
headers = {
    "x-np-api-key": "<NaviPartner API Key>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Confirm group admission ticket
const url = 'https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./ticket/reservation/ABC123456DEF789GHI/confirm';
const options = {
  method: 'POST',
  headers: {'x-np-api-key': '<NaviPartner API Key>', 'Content-Type': 'application/json'},
  body: '{"ticketHolder":"John Doe","ticketHolderLanguage":"ENU","notificationAddress":"john@acme.com","paymentReference":"PAY123456"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Confirm group admission ticket
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./ticket/reservation/ABC123456DEF789GHI/confirm"

	payload := strings.NewReader("{\n  \"ticketHolder\": \"John Doe\",\n  \"ticketHolderLanguage\": \"ENU\",\n  \"notificationAddress\": \"john@acme.com\",\n  \"paymentReference\": \"PAY123456\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("x-np-api-key", "<NaviPartner API Key>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Confirm group admission ticket
require 'uri'
require 'net/http'

url = URI("https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./ticket/reservation/ABC123456DEF789GHI/confirm")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["x-np-api-key"] = '<NaviPartner API Key>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"ticketHolder\": \"John Doe\",\n  \"ticketHolderLanguage\": \"ENU\",\n  \"notificationAddress\": \"john@acme.com\",\n  \"paymentReference\": \"PAY123456\"\n}"

response = http.request(request)
puts response.read_body
```

```java Confirm group admission ticket
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./ticket/reservation/ABC123456DEF789GHI/confirm")
  .header("x-np-api-key", "<NaviPartner API Key>")
  .header("Content-Type", "application/json")
  .body("{\n  \"ticketHolder\": \"John Doe\",\n  \"ticketHolderLanguage\": \"ENU\",\n  \"notificationAddress\": \"john@acme.com\",\n  \"paymentReference\": \"PAY123456\"\n}")
  .asString();
```

```php Confirm group admission ticket
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./ticket/reservation/ABC123456DEF789GHI/confirm', [
  'body' => '{
  "ticketHolder": "John Doe",
  "ticketHolderLanguage": "ENU",
  "notificationAddress": "john@acme.com",
  "paymentReference": "PAY123456"
}',
  'headers' => [
    'Content-Type' => 'application/json',
    'x-np-api-key' => '<NaviPartner API Key>',
  ],
]);

echo $response->getBody();
```

```csharp Confirm group admission ticket
using RestSharp;

var client = new RestClient("https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./ticket/reservation/ABC123456DEF789GHI/confirm");
var request = new RestRequest(Method.POST);
request.AddHeader("x-np-api-key", "<NaviPartner API Key>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"ticketHolder\": \"John Doe\",\n  \"ticketHolderLanguage\": \"ENU\",\n  \"notificationAddress\": \"john@acme.com\",\n  \"paymentReference\": \"PAY123456\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Confirm group admission ticket
import Foundation

let headers = [
  "x-np-api-key": "<NaviPartner API Key>",
  "Content-Type": "application/json"
]
let parameters = [
  "ticketHolder": "John Doe",
  "ticketHolderLanguage": "ENU",
  "notificationAddress": "john@acme.com",
  "paymentReference": "PAY123456"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.npretail.app/01234567-89ab-cdef-0123-456789abcdef/production/CRONUS%2520International%2520Ltd./ticket/reservation/ABC123456DEF789GHI/confirm")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```