{"info":{"_postman_id":"68b77633-b313-47ba-bb11-6d64095d3956","name":"Natours","description":"<html><head></head><body><p>The Natours API contains endpoints for Tours, Users, and Reviews<br>The <strong>Natours API</strong> is a full-featured RESTful backend for a tour booking application. It covers the complete lifecycle of a tour platform — from browsing and booking tours to writing reviews and managing user accounts — and is organized into six focused resource folders.</p>\n<hr>\n<h3 id=\"tours\">Tours</h3>\n<p>Core CRUD operations for tour resources, plus specialized endpoints for aggregation (statistics, monthly planning, top-5 cheap tours) and geospatial queries (find tours within a radius, calculate distances from a point). Also includes utility requests for testing error handling and HTTP Parameter Pollution (HPP) protection.</p>\n<h3 id=\"reviews\">Reviews</h3>\n<p>Full CRUD lifecycle for user-submitted tour reviews via the top-level <code>/api/v1/reviews</code> route — get, create, update, and delete reviews across all tours.</p>\n<h3 id=\"tours--reviews\">Tours / Reviews</h3>\n<p>Nested review endpoints scoped to a specific tour (<code>/api/v1/tours/:tourId/reviews</code>). Use these to retrieve or create reviews in the context of a parent tour resource.</p>\n<h3 id=\"users\">Users</h3>\n<p>Admin-level user management (list, fetch, update, delete any user) alongside self-service endpoints that let the currently authenticated user view, update, or deactivate their own account.</p>\n<h3 id=\"authentication\">Authentication</h3>\n<p>All identity and account-security flows: sign up, log in, forgot password, reset password (via emailed token), and update password for an already-authenticated user. JWT-based authentication is used throughout the API.</p>\n<h3 id=\"bookings\">Bookings</h3>\n<p>Tour booking management, including initiating a Stripe checkout session for a tour, retrieving all bookings (admin only), and fetching a single booking by ID.</p>\n<hr>\n<p><strong>Base URL:</strong> <code>{{URL}}api/v1</code><br><strong>Auth:</strong> JWT Bearer token — store your token in the <code>{{jwt}}</code> environment variable after logging in.</p>\n</body></html>","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","toc":[],"owner":"45895052","collectionId":"68b77633-b313-47ba-bb11-6d64095d3956","publishedId":"2sB3BBrCag","public":true,"customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"55c57a"},"publishDate":"2026-09-17T19:05:57.000Z"},"item":[{"name":"Tours","item":[{"name":"Get All Tours","id":"927d2fd6-b69b-4b1e-bb5d-71532cd07db4","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"body":{"mode":"raw","raw":""},"url":"{{URL}}api/v1/tours","description":"<p>Retrieves a list of all available tours. Supports advanced filtering, sorting, field limiting, and pagination via query parameters.</p>\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>difficulty</code></td>\n<td>Filter tours by difficulty level. Accepted values: <code>easy</code>, <code>medium</code>, <code>difficult</code>.</td>\n</tr>\n<tr>\n<td><code>duration</code></td>\n<td>Filter by duration (in days). Supports comparison operators: <code>[gte]</code>, <code>[lte]</code>, <code>[gt]</code>, <code>[lt]</code> (e.g. <code>duration[gte]=7</code>).</td>\n</tr>\n<tr>\n<td><code>price</code></td>\n<td>Filter by price. Supports comparison operators: <code>[gte]</code>, <code>[lte]</code>, <code>[gt]</code>, <code>[lt]</code> (e.g. <code>price[lt]=1500</code>).</td>\n</tr>\n<tr>\n<td><code>ratingsAverage</code></td>\n<td>Filter by average rating. Supports comparison operators (e.g. <code>ratingsAverage[gte]=4.7</code>).</td>\n</tr>\n<tr>\n<td><code>sort</code></td>\n<td>Sort results by one or more fields. Prefix a field name with <code>-</code> for descending order. Comma-separate multiple fields (e.g. <code>sort=-ratingsAverage,price</code>).</td>\n</tr>\n<tr>\n<td><code>fields</code></td>\n<td>Limit the fields returned in the response. Comma-separate field names (e.g. <code>fields=name,duration,price</code>). Prefix with <code>-</code> to exclude fields (e.g. <code>fields=-name</code>).</td>\n</tr>\n<tr>\n<td><code>page</code></td>\n<td>Page number for pagination (e.g. <code>page=2</code>).</td>\n</tr>\n<tr>\n<td><code>limit</code></td>\n<td>Number of results per page (e.g. <code>limit=10</code>).</td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"authentication\">Authentication</h2>\n<p>This endpoint does not require authentication. An <code>Authorization</code> header with a Bearer token may be provided to access protected tour data if applicable.</p>\n<h2 id=\"response\">Response</h2>\n<p>Returns a JSON object with a <code>status</code> field and a <code>data</code> object containing an array of tour documents.</p>\n","urlObject":{"path":["v1","tours"],"host":["{{URL}}api"],"query":[{"disabled":true,"key":"difficulty","value":"easy"},{"disabled":true,"key":"sort","value":"1"},{"disabled":true,"key":"duration[gte]","value":"7"},{"disabled":true,"key":"price[lt]","value":"1500"},{"disabled":true,"key":"sort","value":"-price,-ratingsAverage"},{"disabled":true,"key":"fields","value":"name,duration,difficulty,price"},{"disabled":true,"key":"fields","value":"-name,-duration"},{"disabled":true,"key":"page","value":"3"},{"disabled":true,"key":"sort","value":"-ratingsAverage,price"},{"disabled":true,"key":"limit","value":"5"},{"disabled":true,"key":"fields","value":"name,duration"},{"disabled":true,"key":"sort","value":"duration"},{"disabled":true,"key":"sort","value":"price"},{"disabled":true,"description":{"content":"<p>Query for tour duration.Supports gte,lte,gt,It operators.</p>\n","type":"text/plain"},"key":"duration","value":"7"},{"disabled":true,"key":"duration","value":"9"},{"disabled":true,"key":"price[lt]","value":"1000"},{"disabled":true,"key":"ratingsAverage[gte]","value":"4.7"}],"variable":[]}},"response":[],"_postman_id":"927d2fd6-b69b-4b1e-bb5d-71532cd07db4"},{"name":"Get Tour","id":"b3aa2797-3305-462f-b8c7-284c3a9433bb","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"{{URL}}api/v1/tours/5c88fa8cf4afda39709c2961","description":"<p>Retrieves the details of a single tour by its unique ID.</p>\n<h2 id=\"endpoint\">Endpoint</h2>\n<p><code>GET {{URL}}api/v1/tours/:id</code></p>\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>id</code></td>\n<td>string</td>\n<td>Yes</td>\n<td>The unique MongoDB ObjectId of the tour to retrieve.</td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"authentication\">Authentication</h2>\n<p>No authentication is required for this endpoint.</p>\n<h2 id=\"response\">Response</h2>\n<p>Returns a JSON object containing the full details of the requested tour, including fields such as name, duration, difficulty, price, summary, description, and more.</p>\n<h3 id=\"example-response\">Example Response</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": \"success\",\n  \"data\": {\n    \"tour\": {\n      \"_id\": \"5c88fa8cf4afda39709c2961\",\n      \"name\": \"The Forest Hiker\",\n      \"duration\": 5,\n      \"maxGroupSize\": 25,\n      \"difficulty\": \"easy\",\n      \"price\": 397,\n      \"summary\": \"Breathtaking hike through the Canadian Banff National Park\",\n      ...\n    }\n  }\n}\n</code></pre>\n<h2 id=\"error-responses\">Error Responses</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Status Code</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>404</code></td>\n<td>Tour not found for the given ID.</td>\n</tr>\n<tr>\n<td><code>500</code></td>\n<td>Internal server error.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["v1","tours","5c88fa8cf4afda39709c2961"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"b3aa2797-3305-462f-b8c7-284c3a9433bb"},{"name":"Create New Tour","id":"51b8cde7-d473-481f-9785-fea1c95ad9b5","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt}}"}]},"isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\r\n    \"name\": \"New Test Tour\",\r\n    \"duration\":1,\r\n    \"maxGroupSize\": 1,\r\n    \"difficulty\": \"easy\",\r\n    \"price\": 200,\r\n    \"summary\": \"Test tour\",\r\n    \"imageCover\": \"tour-3-cover.jpg\"\r\n  }","options":{"raw":{"language":"json"}}},"url":"{{URL}}api/v1/tours","description":"<h2 id=\"create-new-tour\">Create New Tour</h2>\n<p>Creates a new tour in the Natours database. This endpoint requires authentication with a valid JWT token.</p>\n<hr />\n<h3 id=\"request-body\">Request Body</h3>\n<p>Send a JSON object with the following fields:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>name</code></td>\n<td>String</td>\n<td>Yes</td>\n<td>Unique name of the tour</td>\n</tr>\n<tr>\n<td><code>duration</code></td>\n<td>Number</td>\n<td>Yes</td>\n<td>Duration of the tour in days</td>\n</tr>\n<tr>\n<td><code>maxGroupSize</code></td>\n<td>Number</td>\n<td>Yes</td>\n<td>Maximum number of participants allowed</td>\n</tr>\n<tr>\n<td><code>difficulty</code></td>\n<td>String</td>\n<td>Yes</td>\n<td>Difficulty level: <code>easy</code>, <code>medium</code>, or <code>difficult</code></td>\n</tr>\n<tr>\n<td><code>price</code></td>\n<td>Number</td>\n<td>Yes</td>\n<td>Price of the tour in USD</td>\n</tr>\n<tr>\n<td><code>summary</code></td>\n<td>String</td>\n<td>Yes</td>\n<td>Short summary describing the tour</td>\n</tr>\n<tr>\n<td><code>imageCover</code></td>\n<td>String</td>\n<td>Yes</td>\n<td>Filename of the cover image</td>\n</tr>\n<tr>\n<td><code>ratingsAverage</code></td>\n<td>Number</td>\n<td>No</td>\n<td>Average rating (1.0–5.0). Defaults to <code>4.5</code></td>\n</tr>\n<tr>\n<td><code>ratingsQuantity</code></td>\n<td>Number</td>\n<td>No</td>\n<td>Number of ratings. Defaults to <code>0</code></td>\n</tr>\n<tr>\n<td><code>description</code></td>\n<td>String</td>\n<td>No</td>\n<td>Full description of the tour</td>\n</tr>\n<tr>\n<td><code>images</code></td>\n<td>Array</td>\n<td>No</td>\n<td>Array of image filenames</td>\n</tr>\n<tr>\n<td><code>startDates</code></td>\n<td>Array</td>\n<td>No</td>\n<td>Array of available start dates (ISO 8601)</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"example-request-body\">Example Request Body</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"name\": \"New Test Tour\",\n  \"duration\": 1,\n  \"maxGroupSize\": 1,\n  \"difficulty\": \"easy\",\n  \"price\": 200,\n  \"summary\": \"Test tour\",\n  \"imageCover\": \"tour-3-cover.jpg\"\n}\n</code></pre>\n<hr />\n<h3 id=\"authentication\">Authentication</h3>\n<p>This request uses a Bearer token passed via the <code>Authorization</code> header. The <code>{{jwt}}</code> environment variable must be set with a valid token.</p>\n<hr />\n<h3 id=\"responses\">Responses</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Status</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>201 Created</code></td>\n<td>Tour was successfully created. Returns the new tour object.</td>\n</tr>\n<tr>\n<td><code>400 Bad Request</code></td>\n<td>Validation failed. A required field is missing or invalid.</td>\n</tr>\n<tr>\n<td><code>401 Unauthorized</code></td>\n<td>Missing or invalid JWT token.</td>\n</tr>\n<tr>\n<td><code>500 Internal Server Error</code></td>\n<td>Unexpected server error.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["v1","tours"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"51b8cde7-d473-481f-9785-fea1c95ad9b5"},{"name":"Update Tour","id":"78df7dda-9b8b-45fc-8ae3-15c071ab93cb","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt}}"}]},"isInherited":false},"method":"PATCH","header":[],"body":{"mode":"formdata","formdata":[{"key":"imageCover","type":"file","src":"/D:/.Node JS Items/Node JS Practice Sets/4-natours/dev-data/img/new-tour-1.jpg"},{"key":"images","type":"file","src":"/D:/.Node JS Items/Node JS Practice Sets/4-natours/dev-data/img/new-tour-2.jpg"},{"key":"images","type":"file","src":"/D:/.Node JS Items/Node JS Practice Sets/4-natours/dev-data/img/new-tour-3.jpg"},{"key":"images","type":"file","src":"/D:/.Node JS Items/Node JS Practice Sets/4-natours/dev-data/img/new-tour-4.jpg"},{"key":"price","value":"997","type":"text"}]},"url":"{{URL}}api/v1/tours/68a2c2c8ad34dde50469563e","description":"<h2 id=\"update-tour\">Update Tour</h2>\n<p>Updates an existing tour by its ID using a <code>PATCH</code> request. This endpoint supports partial updates — only the fields provided in the request body will be updated.</p>\n<hr />\n<h3 id=\"authentication\">Authentication</h3>\n<p>This request requires a valid <strong>JWT token</strong>. The token is read from the <code>{{jwt}}</code> variable (set in your active environment). Ensure the <code>jwt</code> variable is populated before sending this request.</p>\n<hr />\n<h3 id=\"url-parameter\">URL Parameter</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Location</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>tourId</code></td>\n<td>Path</td>\n<td>The unique ID of the tour to update. Currently hardcoded in the URL path (e.g. <code>68a2c2c8ad34dde50469563e</code>).</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"request-body\">Request Body</h3>\n<p>The request body uses <strong><code>multipart/form-data</code></strong> encoding.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>imageCover</code></td>\n<td><code>file</code></td>\n<td>No</td>\n<td>The cover image for the tour. Replaces the existing cover image.</td>\n</tr>\n<tr>\n<td><code>images</code></td>\n<td><code>file</code></td>\n<td>No</td>\n<td>Additional tour images. Can be included up to <strong>3 times</strong> to upload multiple images.</td>\n</tr>\n<tr>\n<td><code>price</code></td>\n<td><code>text</code></td>\n<td>No</td>\n<td>The price of the tour in USD (e.g. <code>997</code>).</td>\n</tr>\n</tbody>\n</table>\n</div><blockquote>\n<p><strong>Note:</strong> At least one field should be provided for a meaningful update.</p>\n</blockquote>\n<hr />\n<h3 id=\"response\">Response</h3>\n<p>On success, the endpoint returns a <code>200 OK</code> response containing the <strong>updated tour object</strong> with all current field values reflected.</p>\n","urlObject":{"path":["v1","tours","68a2c2c8ad34dde50469563e"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"78df7dda-9b8b-45fc-8ae3-15c071ab93cb"},{"name":"Delete Tour","id":"e4ea8761-20bb-4fcf-9ce8-577a1e507a1a","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt}}"}]},"isInherited":false},"method":"DELETE","header":[],"url":"{{URL}}api/v1/tours/5c88fa8cf4afda39709c295a","description":"<h2 id=\"delete-tour\">Delete Tour</h2>\n<p>Permanently deletes a specific tour from the database by its unique ID.</p>\n<h3 id=\"endpoint\">Endpoint</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>DELETE {{URL}}api/v1/tours/:id\n</code></pre><p>The tour ID is embedded directly in the URL path. In this request, the tour with ID <code>5c88fa8cf4afda39709c295a</code> will be deleted.</p>\n<h3 id=\"authentication\">Authentication</h3>\n<p>This endpoint requires <strong>JWT authentication</strong>. The <code>jwt</code> variable must be set in the active environment and passed as a Bearer token in the <code>Authorization</code> header. Requests without a valid token will be rejected with a <code>401 Unauthorized</code> response.</p>\n<h3 id=\"success-response\">Success Response</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Status Code</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>204 No Content</code></td>\n<td>The tour was successfully deleted. No response body is returned.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"error-responses\">Error Responses</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Status Code</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>401 Unauthorized</code></td>\n<td>Missing or invalid JWT token.</td>\n</tr>\n<tr>\n<td><code>403 Forbidden</code></td>\n<td>The authenticated user does not have permission to delete tours (admin/lead-guide role required).</td>\n</tr>\n<tr>\n<td><code>404 Not Found</code></td>\n<td>No tour found with the specified ID.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"notes\">Notes</h3>\n<ul>\n<li>This operation is <strong>irreversible</strong> — once a tour is deleted, it cannot be recovered.</li>\n<li>Only users with the appropriate role (e.g., <code>admin</code> or <code>lead-guide</code>) are authorized to perform this action.</li>\n<li>Ensure the <code>URL</code> environment variable is set to the correct base URL (e.g., <code>http://localhost:3000/</code> or the production URL) before sending this request.</li>\n</ul>\n","urlObject":{"path":["v1","tours","5c88fa8cf4afda39709c295a"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"e4ea8761-20bb-4fcf-9ce8-577a1e507a1a"},{"name":"Mutiple Objects Optional","id":"a54b1d0d-7db3-463d-97a8-d98a9876f579","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"{{URL}}api/v1/tours/5/23","description":"<h2 id=\"multiple-objects-optional\">Multiple Objects Optional</h2>\n<p>Demonstrates how the Natours API handles routes with <strong>multiple optional URL path parameters</strong>. This request is used as a learning/testing exercise to explore how Express.js can be configured to accept optional route segments.</p>\n<h3 id=\"method--url\">Method &amp; URL</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>GET {{URL}}api/v1/tours/5/23\n</code></pre><h3 id=\"url-structure\">URL Structure</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Segment</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>{{URL}}</code></td>\n<td><em>(env variable)</em></td>\n<td>Base URL of the Natours API</td>\n</tr>\n<tr>\n<td><code>api/v1/tours</code></td>\n<td><em>(path prefix)</em></td>\n<td>Tours resource base path</td>\n</tr>\n<tr>\n<td><code>5</code></td>\n<td><em>(first param)</em></td>\n<td>First optional path parameter (e.g. tour ID or page)</td>\n</tr>\n<tr>\n<td><code>23</code></td>\n<td><em>(second param)</em></td>\n<td>Second optional path parameter</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"purpose\">Purpose</h3>\n<p>This request illustrates how Express routes can be defined with optional parameters using the <code>?</code> modifier in the route definition. For example:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-js\">router.get('/:id/:x?/:y?', tourController.getTour);\n</code></pre>\n<p>With this pattern:</p>\n<ul>\n<li><code>:id</code> is <strong>required</strong></li>\n<li><code>:x</code> and <code>:y</code> are <strong>optional</strong> — the route will still match even if they are omitted</li>\n</ul>\n<p>This is useful when you want a single route handler to accommodate varying levels of specificity in the URL without defining multiple separate routes.</p>\n<h3 id=\"notes\">Notes</h3>\n<ul>\n<li>This request is primarily for <strong>educational/testing purposes</strong> and may not correspond to a real production endpoint.</li>\n<li>No request body or query parameters are required.</li>\n<li>Authentication is not enforced on this route in its current form.</li>\n</ul>\n","urlObject":{"path":["v1","tours","5","23"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"a54b1d0d-7db3-463d-97a8-d98a9876f579"},{"name":"Get Top 5 Cheap Tours","id":"48767fa2-409a-4bf3-a06c-e3da089e5a26","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"{{URL}}api/v1/tours/top-5-cheap","description":"<h2 id=\"get-top-5-cheap-tours\">Get Top 5 Cheap Tours</h2>\n<p>Retrieves the <strong>top 5 cheapest tours</strong> available in the Natours API. This is a pre-aliased route that automatically applies sorting by price (ascending) and limits the results to 5 tours — no additional query parameters are needed.</p>\n<hr />\n<h3 id=\"endpoint\">Endpoint</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Value</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Method</strong></td>\n<td><code>GET</code></td>\n</tr>\n<tr>\n<td><strong>URL</strong></td>\n<td><code>{{URL}}api/v1/tours/top-5-cheap</code></td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"how-it-works\">How It Works</h3>\n<p>This route is a convenience alias for the following query:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>GET {{URL}}api/v1/tours?sort=price&amp;limit=5\n</code></pre><p>The server pre-configures the query middleware to:</p>\n<ul>\n<li><strong>Sort</strong> results by <code>price</code> in ascending order (cheapest first)</li>\n<li><strong>Limit</strong> the response to <strong>5 tour documents</strong></li>\n</ul>\n<hr />\n<h3 id=\"authentication\">Authentication</h3>\n<p>🔓 <strong>No authentication required.</strong> This endpoint is publicly accessible.</p>\n<hr />\n<h3 id=\"request-parameters\">Request Parameters</h3>\n<p>None. No query parameters, headers, or request body are needed.</p>\n<hr />\n<h3 id=\"expected-response\">Expected Response</h3>\n<p><strong>Status:</strong> <code>200 OK</code></p>\n<p>Returns a JSON object containing a list of up to 5 tour objects, sorted from cheapest to most expensive.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": \"success\",\n  \"results\": 5,\n  \"data\": {\n    \"tours\": [\n      {\n        \"name\": \"The Sea Explorer\",\n        \"duration\": 7,\n        \"maxGroupSize\": 15,\n        \"difficulty\": \"medium\",\n        \"ratingsAverage\": 4.8,\n        \"price\": 497,\n        ...\n      },\n      ...\n    ]\n  }\n}\n</code></pre>\n<p>Each tour object typically includes fields such as <code>name</code>, <code>duration</code>, <code>maxGroupSize</code>, <code>difficulty</code>, <code>ratingsAverage</code>, <code>ratingsQuantity</code>, <code>price</code>, <code>summary</code>, <code>imageCover</code>, and more.</p>\n","urlObject":{"path":["v1","tours","top-5-cheap"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"48767fa2-409a-4bf3-a06c-e3da089e5a26"},{"name":"Get Monthly Plan","id":"1f783cff-2b8d-40f3-8e37-409b563560ad","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{URL}}api/v1/tours/monthly-plan/2021","description":"<h1 id=\"get-monthly-plan\">Get Monthly Plan</h1>\n<p>Retrieves a monthly breakdown/statistics of tours for a given year. For each month that has tours starting in that year, the response includes the number of tours, the tour names, and the month itself — useful for planning and analytics purposes.</p>\n<hr />\n<h2 id=\"endpoint\">Endpoint</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Details</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Method</strong></td>\n<td><code>GET</code></td>\n</tr>\n<tr>\n<td><strong>URL</strong></td>\n<td><code>{{URL}}api/v1/tours/monthly-plan/:year</code></td>\n</tr>\n</tbody>\n</table>\n</div><blockquote>\n<p><strong>Note:</strong> The <code>year</code> path variable is currently hardcoded to <code>2021</code> in the URL.</p>\n</blockquote>\n<hr />\n<h2 id=\"path-variables\">Path Variables</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Variable</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>year</code></td>\n<td><code>integer</code></td>\n<td>The year for which the monthly plan is retrieved (e.g. <code>2021</code>).</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"authentication\">Authentication</h2>\n<p>This request requires a <strong>Bearer Token</strong> for authentication. The token is sourced from the <code>{{jwt}}</code> environment variable.</p>\n<p>Make sure the <code>jwt</code> variable is set in your active environment (e.g. by first sending a <strong>Login</strong> or <strong>Sign Up</strong> request, which typically sets this variable automatically via a test script).</p>\n<hr />\n<h2 id=\"example-request\">Example Request</h2>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>GET {{URL}}api/v1/tours/monthly-plan/2021\nAuthorization: Bearer {{jwt}}\n</code></pre><hr />\n<h2 id=\"example-response\">Example Response</h2>\n<p>A successful response returns a <code>200 OK</code> status with a JSON body containing the monthly plan data:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": \"success\",\n  \"data\": {\n    \"plan\": [\n      {\n        \"numTourStarts\": 3,\n        \"tours\": [\"The Forest Hiker\", \"The Sea Explorer\", \"The Snow Adventurer\"],\n        \"month\": 7\n      },\n      ...\n    ]\n  }\n}\n</code></pre>\n","urlObject":{"path":["v1","tours","monthly-plan","2021"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"1f783cff-2b8d-40f3-8e37-409b563560ad"},{"name":"Get Tour Stats","id":"7f3cc18e-f86f-4c95-a0a1-c4258ec16658","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"{{URL}}api/v1/tours/tour-stats","description":"<h1 id=\"get-tour-stats\">Get Tour Stats</h1>\n<p>Retrieves aggregated statistical data for all tours in the Natours application. This endpoint uses a MongoDB aggregation pipeline to compute meaningful metrics grouped by tour difficulty level.</p>\n<h2 id=\"endpoint\">Endpoint</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Value</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Method</strong></td>\n<td><code>GET</code></td>\n</tr>\n<tr>\n<td><strong>URL</strong></td>\n<td><code>{{URL}}api/v1/tours/tour-stats</code></td>\n</tr>\n<tr>\n<td><strong>Auth Required</strong></td>\n<td>No</td>\n</tr>\n<tr>\n<td><strong>Request Body</strong></td>\n<td>None</td>\n</tr>\n<tr>\n<td><strong>Query Parameters</strong></td>\n<td>None</td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"description\">Description</h2>\n<p>This endpoint processes all tours through an aggregation pipeline that filters, groups, and sorts the data to produce a statistical summary. It is useful for gaining a high-level overview of tour offerings broken down by difficulty.</p>\n<p>Typical metrics returned per difficulty group include:</p>\n<ul>\n<li><strong>Number of tours</strong> in the group</li>\n<li><strong>Number of ratings</strong> across all tours in the group</li>\n<li><strong>Average rating</strong></li>\n<li><strong>Average price</strong></li>\n<li><strong>Minimum price</strong></li>\n<li><strong>Maximum price</strong></li>\n</ul>\n<h2 id=\"example-response\">Example Response</h2>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": \"success\",\n  \"data\": {\n    \"stats\": [\n      {\n        \"_id\": \"EASY\",\n        \"numTours\": 4,\n        \"numRatings\": 34,\n        \"avgRating\": 4.675,\n        \"avgPrice\": 1272,\n        \"minPrice\": 397,\n        \"maxPrice\": 1997\n      },\n      {\n        \"_id\": \"MEDIUM\",\n        \"numTours\": 3,\n        \"numRatings\": 27,\n        \"avgRating\": 4.8,\n        \"avgPrice\": 1663.67,\n        \"minPrice\": 497,\n        \"maxPrice\": 2997\n      },\n      {\n        \"_id\": \"DIFFICULT\",\n        \"numTours\": 2,\n        \"numRatings\": 25,\n        \"avgRating\": 4.35,\n        \"avgPrice\": 1998,\n        \"minPrice\": 999,\n        \"maxPrice\": 2997\n      }\n    ]\n  }\n}\n</code></pre>\n<h2 id=\"usage-notes\">Usage Notes</h2>\n<ul>\n<li>Results are typically sorted by <strong>average price</strong> in ascending order.</li>\n<li>Only tours with a rating of <strong>4.5 or above</strong> may be included depending on the aggregation filter applied on the server side.</li>\n<li>This is a <strong>read-only</strong> endpoint — no data is created or modified.</li>\n<li>Useful for dashboards, analytics views, or admin panels that need a quick summary of tour inventory.</li>\n</ul>\n","urlObject":{"path":["v1","tours","tour-stats"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"7f3cc18e-f86f-4c95-a0a1-c4258ec16658"},{"name":"Error Testing","id":"31b9c4ff-156a-45aa-9195-59aa6cbe0380","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"body":{"mode":"raw","raw":""},"url":"{{URL}}api/tours","description":"<h2 id=\"error-testing\">Error Testing</h2>\n<p>Hits an <strong>intentionally incorrect route</strong> (<code>{{URL}}api/tours</code>) to verify that the application's global error-handling middleware is working correctly.</p>\n<p>The correct base path for the Natours API is <code>/api/v1/...</code>. By omitting the <code>v1</code> segment, this request triggers a route-not-found error, which should be caught and formatted by the global error handler.</p>\n<hr />\n<h3 id=\"method--url\">Method &amp; URL</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>GET {{URL}}api/tours\n</code></pre><hr />\n<h3 id=\"purpose\">Purpose</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Aspect</th>\n<th>Detail</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>What it tests</strong></td>\n<td>Global error-handling middleware</td>\n</tr>\n<tr>\n<td><strong>Why it fails</strong></td>\n<td>The route <code>/api/tours</code> does not exist — the correct prefix is <code>/api/v1/tours</code></td>\n</tr>\n<tr>\n<td><strong>Expected behaviour</strong></td>\n<td>The server returns a structured error response (e.g. <code>404 Not Found</code>) formatted by the global error handler, rather than an unhandled crash or a generic framework error</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"expected-response\">Expected Response</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": \"fail\",\n  \"message\": \"Can't find /api/tours on this server!\"\n}\n</code></pre>\n<hr />\n<h3 id=\"notes\">Notes</h3>\n<ul>\n<li>No authentication is required — the route does not exist, so the request never reaches any auth middleware.</li>\n<li>This request is intentionally broken and is not meant to succeed. A <code>404</code> response confirms the error handler is functioning as expected.</li>\n<li>Do not change the URL to the correct route — the wrong path is the point of this request.</li>\n</ul>\n","urlObject":{"path":["tours"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"31b9c4ff-156a-45aa-9195-59aa6cbe0380"},{"name":"Get Tours Within Radius","id":"17547ef0-c003-4cfa-bd53-e13c5a165771","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"{{URL}}api/v1/tours/tours-within/200/center/34.111745,-118.113491/unit/mi","description":"<h2 id=\"get-tours-within-radius\">Get Tours Within Radius</h2>\n<p>Retrieves all tours that fall within a specified radius from a given geographic center point. This is a geospatial query endpoint that returns tours located within the defined distance from the provided latitude/longitude coordinates.</p>\n<hr />\n<h2 id=\"url-structure\">URL Structure</h2>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>GET {{URL}}api/v1/tours/tours-within/:distance/center/:latlng/unit/:unit\n</code></pre><hr />\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Description</th>\n<th>Example</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>distance</code></td>\n<td>The radius distance within which to search for tours.</td>\n<td><code>200</code></td>\n</tr>\n<tr>\n<td><code>latlng</code></td>\n<td>The geographic center point as a comma-separated <code>latitude,longitude</code> pair.</td>\n<td><code>34.111745,-118.113491</code></td>\n</tr>\n<tr>\n<td><code>unit</code></td>\n<td>The unit of measurement for the distance. Supported values: <code>mi</code> (miles) or <code>km</code> (kilometers).</td>\n<td><code>mi</code></td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"example-request\">Example Request</h2>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>GET {{URL}}api/v1/tours/tours-within/200/center/34.111745,-118.113491/unit/mi\n</code></pre><p>This example fetches all tours within <strong>200 miles</strong> of the coordinates <strong>34.111745°N, 118.113491°W</strong> (Los Angeles area).</p>\n<hr />\n<h2 id=\"notes\">Notes</h2>\n<ul>\n<li><strong>Supported units:</strong> <code>mi</code> for miles, <code>km</code> for kilometers.</li>\n<li>The <code>latlng</code> value must be provided as <code>latitude,longitude</code> with no spaces.</li>\n<li>The center coordinates in the example (<code>34.111745,-118.113491</code>) correspond to a location in the <strong>Los Angeles, California</strong> area.</li>\n<li>Ensure the <code>URL</code> environment variable is set to the correct base URL before sending the request.</li>\n</ul>\n","urlObject":{"path":["v1","tours","tours-within","200","center","34.111745,-118.113491","unit","mi"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"17547ef0-c003-4cfa-bd53-e13c5a165771"},{"name":"Get Distances to Tours from Point mi/km","id":"17cf976d-a629-459a-b8ea-f2ac8d30a12b","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"{{URL}}api/v1/tours/distances/34.111745,-118.113491/unit/mi","description":"<p>Returns the distances from a given geographical point to all available tours, expressed in <strong>miles</strong> or <strong>kilometers</strong>.</p>\n<h3 id=\"url-parameters\">URL Parameters</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>latlng</code></td>\n<td>The coordinates of the origin point in <code>latitude,longitude</code> format (e.g. <code>34.111745,-118.113491</code>).</td>\n</tr>\n<tr>\n<td><code>unit</code></td>\n<td>The unit of distance measurement. Accepted values: <code>mi</code> (miles) or <code>km</code> (kilometers).</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"example-request\">Example Request</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>GET {{URL}}api/v1/tours/distances/34.111745,-118.113491/unit/mi\n</code></pre><h3 id=\"notes\">Notes</h3>\n<ul>\n<li>Coordinates must be provided as a comma-separated <code>latitude,longitude</code> pair.</li>\n<li>The endpoint uses geospatial queries to calculate distances from the provided point to each tour's starting location.</li>\n<li>Results are sorted by distance in ascending order.</li>\n</ul>\n","urlObject":{"path":["v1","tours","distances","34.111745,-118.113491","unit","mi"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"17cf976d-a629-459a-b8ea-f2ac8d30a12b"},{"name":"HPP","id":"bd9a9ecf-8e42-432a-a821-fbb8549d23b7","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{URL}}api/v1/tours?sort=duration&sort=price","description":"<h2 id=\"http-parameter-pollution-hpp\">HTTP Parameter Pollution (HPP)</h2>\n<p>This request demonstrates <strong>HTTP Parameter Pollution (HPP)</strong> — a vulnerability/technique where duplicate query parameters are sent in a single request.</p>\n<h3 id=\"what-is-hpp\">What is HPP?</h3>\n<p>HPP occurs when an attacker (or client) sends multiple values for the same query parameter. Different web frameworks and servers handle this inconsistently:</p>\n<ul>\n<li>Some use the <strong>first</strong> value</li>\n<li>Some use the <strong>last</strong> value</li>\n<li>Some <strong>merge</strong> all values into an array</li>\n</ul>\n<h3 id=\"this-request\">This Request</h3>\n<p>The request sends two <code>sort</code> parameters simultaneously:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Value</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>sort</code></td>\n<td><code>duration</code></td>\n</tr>\n<tr>\n<td><code>sort</code></td>\n<td><code>price</code></td>\n</tr>\n</tbody>\n</table>\n</div><p>Without HPP protection, a naive parser might receive <code>sort=duration&amp;sort=price</code> and only use one of the values, or throw an error. With HPP protection (e.g. using the <a href=\"https://www.npmjs.com/package/hpp\"><code>hpp</code></a> middleware in Express), duplicate parameters are handled gracefully — typically by using the <strong>last</strong> value or by whitelisting parameters that are allowed to have multiple values.</p>\n<h3 id=\"expected-behaviour\">Expected Behaviour</h3>\n<p>With <code>hpp</code> middleware and a whitelist for <code>sort</code>, the API should correctly sort tours by both <code>duration</code> and <code>price</code>, returning results ordered accordingly.</p>\n","urlObject":{"path":["v1","tours"],"host":["{{URL}}api"],"query":[{"key":"sort","value":"duration"},{"key":"sort","value":"price"}],"variable":[]}},"response":[],"_postman_id":"bd9a9ecf-8e42-432a-a821-fbb8549d23b7"}],"id":"f203befd-f112-4acd-bd5d-40ffc27ff88d","description":"<p><strong>You can get all tours, create new ones, and edit and delete tours</strong>. There are also special endpoints for some special requirements.<br />Core endpoints for managing tours in the Natours application. This folder covers the full CRUD lifecycle for tours, along with several specialized aggregation and geospatial query endpoints.</p>\n<p><strong>CRUD Operations</strong></p>\n<ul>\n<li><p><strong>Get All Tours</strong> — Retrieves a list of all tours, with support for filtering, sorting, field limiting, and pagination (<code>GET /api/v1/tours</code>).</p>\n</li>\n<li><p><strong>Get Tour</strong> — Fetches the full details of a single tour by its ID (<code>GET /api/v1/tours/:id</code>).</p>\n</li>\n<li><p><strong>Create New Tour</strong> — Creates a new tour resource (<code>POST /api/v1/tours</code>).</p>\n</li>\n<li><p><strong>Update Tour</strong> — Partially updates an existing tour by its ID (<code>PATCH /api/v1/tours/:id</code>).</p>\n</li>\n<li><p><strong>Delete Tour</strong> — Permanently removes a tour by its ID (<code>DELETE /api/v1/tours/:id</code>).</p>\n</li>\n</ul>\n<p><strong>Aggregation &amp; Statistics</strong></p>\n<ul>\n<li><p><strong>Get Tour Stats</strong> — Returns aggregated statistics (e.g. average rating, price, difficulty) across all tours (<code>GET /api/v1/tours/tour-stats</code>).</p>\n</li>\n<li><p><strong>Get Monthly Plan</strong> — Returns the number of tours starting each month for a given year, useful for business planning (<code>GET /api/v1/tours/monthly-plan/:year</code>).</p>\n</li>\n<li><p><strong>Get Top 5 Cheap Tours</strong> — A pre-aliased query that returns the five cheapest, highest-rated tours (<code>GET /api/v1/tours/top-5-cheap</code>).</p>\n</li>\n</ul>\n<p><strong>Geospatial Queries</strong></p>\n<ul>\n<li><p><strong>Get Tours Within Radius</strong> — Finds all tours that start within a specified distance from a given geographic coordinate (<code>GET /api/v1/tours/tours-within/:distance/center/:latlng/unit/:unit</code>).</p>\n</li>\n<li><p><strong>Get Distances to Tours from Point</strong> — Calculates the distance from a given point to the starting location of every tour (<code>GET /api/v1/tours/distances/:latlng/unit/:unit</code>).</p>\n</li>\n</ul>\n<p><strong>Other</strong></p>\n<ul>\n<li><p><strong>HPP</strong> — Tests HTTP Parameter Pollution protection by sending duplicate query parameters (<code>GET /api/v1/tours?sort=duration&amp;sort=price</code>).</p>\n</li>\n<li><p><strong>Error Testing</strong> — Hits an intentionally incorrect route to verify global error handling behaviour (<code>GET /api/tours</code>).</p>\n</li>\n<li><p><strong>Multiple Objects Optional</strong> — Tests optional URL parameter handling (<code>GET /api/v1/tours/:id/:id2</code>).</p>\n</li>\n</ul>\n","event":[{"listen":"prerequest","script":{"id":"6b233ab3-dd3b-447d-a1e7-f18f8285c458","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"d1d1a186-3e5e-4a46-b232-83380f276adb","type":"text/javascript","exec":[""]}}],"_postman_id":"f203befd-f112-4acd-bd5d-40ffc27ff88d"},{"name":"Reviews","item":[{"name":"Get Review","id":"810df9fd-1c62-43ca-aef5-2eef6a129986","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{URL}}api/v1/reviews/6891a5d069cebe4c42572016","description":"<h2 id=\"get-review\">Get Review</h2>\n<p>Retrieves a single review by its unique ID. This endpoint returns the full details of a specific review resource.</p>\n<hr />\n<h3 id=\"http-method--url\">HTTP Method &amp; URL</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>GET {{URL}}api/v1/reviews/:reviewId\n</code></pre><hr />\n<h3 id=\"path-parameters\">Path Parameters</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>reviewId</code></td>\n<td>String</td>\n<td>✅ Yes</td>\n<td>The unique ID of the review to fetch. Example: <code>6891a5d069cebe4c42572016</code></td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"variables-used\">Variables Used</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Variable</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>{{URL}}</code></td>\n<td>The base URL of the Natours API (e.g., <code>https://your-api-domain.com/</code>). Set in the active environment.</td>\n</tr>\n<tr>\n<td><code>jwt</code></td>\n<td>JSON Web Token used for authentication. Passed as a Bearer token in the <code>Authorization</code> header if the endpoint requires authentication.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"authentication\">Authentication</h3>\n<p>This request uses the <code>jwt</code> environment variable as a Bearer token for authorization:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>Authorization: Bearer {{jwt}}\n</code></pre><hr />\n<h3 id=\"expected-response\">Expected Response</h3>\n<p><strong>Status:</strong> <code>200 OK</code></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": \"success\",\n  \"data\": {\n    \"review\": {\n      \"_id\": \"6891a5d069cebe4c42572016\",\n      \"review\": \"Review text content\",\n      \"rating\": 5,\n      \"createdAt\": \"2024-01-01T00:00:00.000Z\",\n      \"tour\": { ... },\n      \"user\": { ... }\n    }\n  }\n}\n</code></pre>\n<p><strong>Error Responses:</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Status</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>404 Not Found</code></td>\n<td>No review found with the provided ID.</td>\n</tr>\n<tr>\n<td><code>401 Unauthorized</code></td>\n<td>Missing or invalid <code>jwt</code> token.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["v1","reviews","6891a5d069cebe4c42572016"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"810df9fd-1c62-43ca-aef5-2eef6a129986"},{"name":"Get All Reviews","id":"8f18fe05-4612-469f-ad64-a4e6886ea7d5","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{URL}}api/v1/reviews","description":"<h2 id=\"get-all-reviews\">Get All Reviews</h2>\n<p>Retrieves a list of all reviews submitted across all tours in the Natours application.</p>\n<hr />\n<h3 id=\"endpoint\">Endpoint</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Value</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Method</strong></td>\n<td><code>GET</code></td>\n</tr>\n<tr>\n<td><strong>URL</strong></td>\n<td><code>{{URL}}api/v1/reviews</code></td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"authentication\">Authentication</h3>\n<p>This endpoint requires a valid <strong>JWT Bearer token</strong> passed via the <code>{{jwt}}</code> environment variable.</p>\n<hr />\n<h3 id=\"query-parameters\">Query Parameters</h3>\n<p>This endpoint supports the standard Natours API query options:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>rating</code></td>\n<td>Filter reviews by rating value (e.g. <code>rating=4</code>). Disabled by default in this request.</td>\n</tr>\n<tr>\n<td><code>fields</code></td>\n<td>Comma-separated list of fields to include in the response (field limiting).</td>\n</tr>\n<tr>\n<td><code>sort</code></td>\n<td>Field(s) to sort by. Prefix with <code>-</code> for descending order (e.g. <code>sort=-createdAt</code>).</td>\n</tr>\n<tr>\n<td><code>page</code></td>\n<td>Page number for pagination (default: <code>1</code>).</td>\n</tr>\n<tr>\n<td><code>limit</code></td>\n<td>Number of results per page (default: <code>100</code>).</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"request-body\">Request Body</h3>\n<p>None required.</p>\n<hr />\n<h3 id=\"response\">Response</h3>\n<p><strong><code>200 OK</code></strong> — Returns an array of all review documents.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": \"success\",\n  \"results\": 10,\n  \"data\": {\n    \"data\": [\n      {\n        \"_id\": \"6891a5d069cebe4c42572016\",\n        \"review\": \"Amazing experience!\",\n        \"rating\": 5,\n        \"createdAt\": \"2024-01-01T00:00:00.000Z\",\n        \"tour\": { ... },\n        \"user\": { ... }\n      }\n    ]\n  }\n}\n</code></pre>\n<hr />\n<h3 id=\"error-responses\">Error Responses</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Status</th>\n<th>Reason</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>401 Unauthorized</code></td>\n<td>Missing or invalid JWT token.</td>\n</tr>\n<tr>\n<td><code>403 Forbidden</code></td>\n<td>Authenticated user does not have the required role.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"notes\">Notes</h3>\n<ul>\n<li>To retrieve reviews scoped to a specific tour, use the nested route under the <strong>Tours/Reviews</strong> folder: <code>GET /api/v1/tours/:tourId/reviews</code>.</li>\n<li>Creating, updating, or deleting reviews requires authentication. See the <strong>Create New Review</strong>, <strong>Update Review</strong>, and <strong>Delete Review</strong> endpoints in this folder.</li>\n</ul>\n","urlObject":{"path":["v1","reviews"],"host":["{{URL}}api"],"query":[{"disabled":true,"key":"rating","value":"4"}],"variable":[]}},"response":[],"_postman_id":"8f18fe05-4612-469f-ad64-a4e6886ea7d5"},{"name":"Create New Review","id":"a6763fd5-f75f-44e8-8b33-6d4283e30864","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt}}"}]},"isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\r\n    \"review\":\"Loved it\",\r\n    \"rating\":4,\r\n    \"tour\":\"5c88fa8cf4afda39709c2951\",\r\n    \"user\":\"6891057256313983f4c6f39f\"\r\n}","options":{"raw":{"language":"json"}}},"url":"{{URL}}api/v1/reviews","description":"<h2 id=\"create-new-review\">Create New Review</h2>\n<p>Creates a new review for a specific tour. The review is associated with both a tour and a user, and includes a text review along with a numeric rating.</p>\n<hr />\n<h2 id=\"authentication\">Authentication</h2>\n<p>This endpoint requires a valid <strong>JWT Bearer token</strong>. Include the token in the <code>Authorization</code> header using the <code>{{jwt}}</code> variable:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>Authorization: Bearer {{jwt}}\n</code></pre><hr />\n<h2 id=\"request-body\">Request Body</h2>\n<p>The request body must be sent as <strong>raw JSON</strong> with the following fields:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>review</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>The text content of the review (e.g. <code>\"Loved it\"</code>).</td>\n</tr>\n<tr>\n<td><code>rating</code></td>\n<td><code>number</code></td>\n<td>Yes</td>\n<td>Numeric rating for the tour. Typically between <code>1</code>–<code>5</code>.</td>\n</tr>\n<tr>\n<td><code>tour</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>The MongoDB ObjectId of the tour being reviewed.</td>\n</tr>\n<tr>\n<td><code>user</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>The MongoDB ObjectId of the user submitting the review.</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Example:</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"review\": \"Loved it\",\n    \"rating\": 4,\n    \"tour\": \"5c88fa8cf4afda39709c2951\",\n    \"user\": \"6891057256313983f4c6f39f\"\n}\n</code></pre>\n<hr />\n<h2 id=\"response\">Response</h2>\n<p><strong><code>201 Created</code></strong> — Returns the newly created review object.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"status\": \"success\",\n    \"data\": {\n        \"review\": {\n            \"_id\": \"&lt;new_review_id&gt;\",\n            \"review\": \"Loved it\",\n            \"rating\": 4,\n            \"tour\": \"5c88fa8cf4afda39709c2951\",\n            \"user\": \"6891057256313983f4c6f39f\",\n            \"createdAt\": \"&lt;timestamp&gt;\"\n        }\n    }\n}\n</code></pre>\n","urlObject":{"path":["v1","reviews"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"a6763fd5-f75f-44e8-8b33-6d4283e30864"},{"name":"Update Review","id":"30f8fe52-0248-430d-be5d-191388adb26e","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt}}"}]},"isInherited":false},"method":"PATCH","header":[],"body":{"mode":"raw","raw":"{\r\n    \"rating\":5\r\n}","options":{"raw":{"language":"json"}}},"url":"{{URL}}api/v1/reviews/6892688e061d403aab98babf","description":"<p>Updates an existing review by its ID. Only the fields provided in the request body will be updated (partial update).</p>\n<p><strong>Authentication:</strong> Requires a valid JWT token passed via the <code>jwt</code> variable (Bearer token).</p>\n<p><strong>Path Parameters:</strong></p>\n<ul>\n<li><code>id</code> <em>(string)</em> — The unique identifier of the review to update. Currently hardcoded in the URL as <code>6892688e061d403aab98babf</code>.</li>\n</ul>\n<p><strong>Request Body</strong> <em>(application/json)</em>:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"rating\": 5\n}\n</code></pre>\n<p>Any review field can be updated (e.g. <code>rating</code>, <code>review</code>). Only the fields included in the body will be changed.</p>\n<p><strong>Response:</strong> Returns the updated review document.</p>\n<p><strong>Base URL:</strong> Uses the <code>{{URL}}</code> environment variable (currently pointing to the Prod: Natours environment).</p>\n","urlObject":{"path":["v1","reviews","6892688e061d403aab98babf"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"30f8fe52-0248-430d-be5d-191388adb26e"},{"name":"Delete Review","id":"e988543a-5123-4007-8b6b-4326ac20cc94","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt}}"}]},"isInherited":false},"method":"DELETE","header":[],"url":"{{URL}}api/v1/reviews/68926406fe208a94560e1357","description":"<h1 id=\"delete-review\">Delete Review</h1>\n<p>Deletes a specific review from the database by its unique ID. This is a permanent, irreversible operation — the review will be removed entirely.</p>\n<hr />\n<h2 id=\"endpoint\">Endpoint</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Details</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Method</strong></td>\n<td><code>DELETE</code></td>\n</tr>\n<tr>\n<td><strong>URL</strong></td>\n<td><code>{{URL}}api/v1/reviews/68926406fe208a94560e1357</code></td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"authentication\">Authentication</h2>\n<p>This request requires a valid <strong>JWT Bearer token</strong>. The token is supplied via the <code>jwt</code> variable (set in the active environment or collection-level auth).</p>\n<p>The token is sent as a Bearer token in the <code>Authorization</code> header:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>Authorization: Bearer {{jwt}}\n</code></pre><p>Make sure the <code>jwt</code> variable is set in your active environment before sending this request.</p>\n<hr />\n<h2 id=\"url--path-details\">URL / Path Details</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Segment</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>api/v1/reviews/</code></td>\n<td><em>(path prefix)</em></td>\n<td>Base path for the Reviews resource</td>\n</tr>\n<tr>\n<td><code>68926406fe208a94560e1357</code></td>\n<td><em>(hardcoded review ID)</em></td>\n<td>The MongoDB ObjectId of the review to delete</td>\n</tr>\n</tbody>\n</table>\n</div><blockquote>\n<p><strong>Note:</strong> The review ID <code>68926406fe208a94560e1357</code> is hardcoded in the URL. To delete a different review, update this segment with the desired review's ID.</p>\n</blockquote>\n<hr />\n<h2 id=\"request-body--query-parameters\">Request Body &amp; Query Parameters</h2>\n<p>None — this request does not require a body or any query parameters.</p>\n<hr />\n<h2 id=\"expected-response\">Expected Response</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Status Code</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>204 No Content</code></td>\n<td>The review was successfully deleted. No response body is returned.</td>\n</tr>\n<tr>\n<td><code>401 Unauthorized</code></td>\n<td>Missing or invalid JWT token.</td>\n</tr>\n<tr>\n<td><code>403 Forbidden</code></td>\n<td>The authenticated user does not have permission to delete this review.</td>\n</tr>\n<tr>\n<td><code>404 Not Found</code></td>\n<td>No review exists with the provided ID.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"notes\">Notes</h2>\n<ul>\n<li>A <code>204 No Content</code> response with an empty body is the standard REST convention for a successful delete operation.</li>\n<li>Ensure the <code>URL</code> environment variable is set to the correct base URL (e.g., <code>https://your-api-domain.com/</code>) before sending.</li>\n<li>Only authorized users (e.g., admins or the review owner) should be able to delete a review — ensure the <code>jwt</code> token belongs to a user with the appropriate role/permissions.</li>\n</ul>\n","urlObject":{"path":["v1","reviews","68926406fe208a94560e1357"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"e988543a-5123-4007-8b6b-4326ac20cc94"}],"id":"fd4f61d7-02aa-4c7c-a33e-81df901cca09","description":"<p>Endpoints for managing tour reviews in the Natours application. This folder covers the full CRUD lifecycle for reviews, which are written by users about tours they have taken.</p>\n<ul>\n<li><strong>Get All Reviews</strong> — Retrieves a list of all reviews across all tours (<code>GET /api/v1/reviews</code>).</li>\n<li><strong>Get Review</strong> — Fetches the details of a single review by its ID (<code>GET /api/v1/reviews/:id</code>).</li>\n<li><strong>Create New Review</strong> — Allows an authenticated user to submit a new review for a tour (<code>POST /api/v1/reviews</code>).</li>\n<li><strong>Update Review</strong> — Updates the content or rating of an existing review by its ID (<code>PATCH /api/v1/reviews/:id</code>).</li>\n<li><strong>Delete Review</strong> — Permanently removes a review by its ID (<code>DELETE /api/v1/reviews/:id</code>).</li>\n</ul>\n<blockquote>\n<p><strong>Note:</strong> Creating and updating reviews requires authentication. Include a valid JWT in the <code>Authorization</code> header as <code>Bearer {{jwt}}</code>. For reviews scoped to a specific tour, see the <strong>Tours/Reviews</strong> folder.</p>\n</blockquote>\n","_postman_id":"fd4f61d7-02aa-4c7c-a33e-81df901cca09"},{"name":"Tours/Reviews","item":[{"name":"Create New Review on Tour","id":"85480f86-4e76-41c6-a436-58769a4932c8","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt}}"}]},"isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\r\n    \"rating\":5,\r\n    \"review\":\"Amazing\"\r\n}","options":{"raw":{"language":"json"}}},"url":"{{URL}}api/v1/tours/68924bc55ad67b512b95ec3c/reviews","description":"<h1 id=\"create-new-review-on-tour\">Create New Review on Tour</h1>\n<p>Creates a new review for a specific tour. This endpoint allows authenticated users to submit a rating and written review for a tour they have taken.</p>\n<hr />\n<h2 id=\"endpoint\">Endpoint</h2>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>POST {{URL}}api/v1/tours/:tourId/reviews\n</code></pre><p><strong>Example URL:</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>POST {{URL}}api/v1/tours/68924bc55ad67b512b95ec3c/reviews\n</code></pre><hr />\n<h2 id=\"authentication\">Authentication</h2>\n<p>This endpoint <strong>requires authentication</strong>. A valid JWT token must be provided in the request headers.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Header</th>\n<th>Value</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>Authorization</code></td>\n<td><code>Bearer {{jwt}}</code></td>\n</tr>\n</tbody>\n</table>\n</div><p>The <code>{{jwt}}</code> variable should be set in your active environment after logging in.</p>\n<hr />\n<h2 id=\"url-structure\">URL Structure</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Segment</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>{{URL}}</code></td>\n<td>Base URL of the API (set in the active environment)</td>\n</tr>\n<tr>\n<td><code>api/v1/tours</code></td>\n<td>Tours resource path</td>\n</tr>\n<tr>\n<td><code>68924bc55ad67b512b95ec3c</code></td>\n<td>The unique ID of the tour being reviewed</td>\n</tr>\n<tr>\n<td><code>reviews</code></td>\n<td>Reviews sub-resource for the specified tour</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"request-body\">Request Body</h2>\n<p>Send a JSON object with the following fields:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>rating</code></td>\n<td><code>Number</code></td>\n<td>✅ Yes</td>\n<td>Numeric rating for the tour (e.g., <code>1</code> to <code>5</code>)</td>\n</tr>\n<tr>\n<td><code>review</code></td>\n<td><code>String</code></td>\n<td>✅ Yes</td>\n<td>Written review text describing the experience</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Example:</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"rating\": 5,\n    \"review\": \"Amazing\"\n}\n</code></pre>\n<hr />\n<h2 id=\"expected-response\">Expected Response</h2>\n<p>On success, the API returns a <code>201 Created</code> status with the newly created review object.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"status\": \"success\",\n    \"data\": {\n        \"review\": {\n            \"_id\": \"&lt;review_id&gt;\",\n            \"review\": \"Amazing\",\n            \"rating\": 5,\n            \"tour\": \"68924bc55ad67b512b95ec3c\",\n            \"user\": \"&lt;user_id&gt;\",\n            \"createdAt\": \"&lt;timestamp&gt;\"\n        }\n    }\n}\n</code></pre>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Status Code</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>201</code></td>\n<td>Review created successfully</td>\n</tr>\n<tr>\n<td><code>400</code></td>\n<td>Bad request — missing or invalid fields</td>\n</tr>\n<tr>\n<td><code>401</code></td>\n<td>Unauthorized — missing or invalid JWT token</td>\n</tr>\n<tr>\n<td><code>404</code></td>\n<td>Tour not found for the given ID</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["v1","tours","68924bc55ad67b512b95ec3c","reviews"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"85480f86-4e76-41c6-a436-58769a4932c8"},{"name":"Get All Reviews on Tour","id":"228748d7-b5db-4e55-911b-6fd051969e02","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{URL}}api/v1/tours/5c88fa8cf4afda39709c2951/reviews","description":"<h2 id=\"get-all-reviews-on-tour\">Get All Reviews on Tour</h2>\n<p>Retrieves all reviews associated with a specific tour. This endpoint returns a list of review documents that belong to the tour identified by the tour ID in the URL.</p>\n<h3 id=\"http-method\">HTTP Method</h3>\n<p><code>GET</code></p>\n<h3 id=\"url-pattern\">URL Pattern</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>{{URL}}api/v1/tours/:tourId/reviews\n</code></pre><p>The <code>:tourId</code> segment is a <strong>path parameter</strong> identifying the tour whose reviews you want to retrieve. In this request, it is hardcoded as <code>5c88fa8cf4afda39709c2951</code>.</p>\n<h3 id=\"authentication\">Authentication</h3>\n<p>This endpoint may be accessed without authentication for public tour reviews. If the API enforces access control, include a valid JWT token in the <code>Authorization</code> header as a Bearer token:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>Authorization: Bearer {{jwt}}\n</code></pre><h3 id=\"notes\">Notes</h3>\n<ul>\n<li>The response includes all reviews linked to the specified tour.</li>\n<li>This route follows a nested route pattern (<code>/tours/:tourId/reviews</code>), scoping reviews to a particular tour resource.</li>\n</ul>\n","urlObject":{"path":["v1","tours","5c88fa8cf4afda39709c2951","reviews"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"228748d7-b5db-4e55-911b-6fd051969e02"}],"id":"cf67f1ea-69ab-453a-98b7-f559754be8ea","description":"<h2 id=\"tours--reviews\">Tours / Reviews</h2>\n<p>This folder contains endpoints for managing <strong>reviews as a nested sub-resource of tours</strong>. Reviews in the Natours API are scoped to a specific tour, meaning all operations are performed through a nested route under the parent tour resource.</p>\n<h3 id=\"nested-route-pattern\">Nested Route Pattern</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>/api/v1/tours/:tourId/reviews\n</code></pre><p>The <code>:tourId</code> path parameter identifies the tour for which reviews are being retrieved or created.</p>\n<hr />\n<h3 id=\"endpoints\">Endpoints</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Method</th>\n<th>Endpoint</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>GET</code></td>\n<td><code>/api/v1/tours/:tourId/reviews</code></td>\n<td>Retrieve all reviews for a specific tour</td>\n</tr>\n<tr>\n<td><code>POST</code></td>\n<td><code>/api/v1/tours/:tourId/reviews</code></td>\n<td>Create a new review on a specific tour</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"notes\">Notes</h3>\n<ul>\n<li>All requests require a valid <code>tourId</code> in the URL path.</li>\n<li>The <code>POST</code> endpoint requires authentication — include a valid JWT in the <code>Authorization</code> header as <code>Bearer {{jwt}}</code>.</li>\n<li>Reviews are tightly coupled to their parent tour and cannot exist independently through this route.</li>\n</ul>\n","_postman_id":"cf67f1ea-69ab-453a-98b7-f559754be8ea"},{"name":"Users","item":[{"name":"Get All Users","id":"1e882c35-22e2-4344-aba0-9b6762468678","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{URL}}api/v1/users","description":"<h2 id=\"get-all-users\">Get All Users</h2>\n<p>Retrieves a list of all registered users in the Natours application. This is an <strong>admin-only</strong> operation — only users with the <code>admin</code> role are authorised to access this endpoint.</p>\n<hr />\n<h3 id=\"endpoint\">Endpoint</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Value</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Method</strong></td>\n<td><code>GET</code></td>\n</tr>\n<tr>\n<td><strong>URL</strong></td>\n<td><code>{{URL}}api/v1/users</code></td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"authentication\">Authentication</h3>\n<p>Requires a valid <strong>JWT Bearer token</strong> passed via the <code>{{jwt}}</code> environment variable. The authenticated user must have the <code>admin</code> role.</p>\n<blockquote>\n<p>Set the <code>jwt</code> variable in your active environment to an admin token before sending this request.</p>\n</blockquote>\n<hr />\n<h3 id=\"query-parameters\">Query Parameters</h3>\n<p>This endpoint supports the standard Natours API query options:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>fields</code></td>\n<td>Comma-separated list of fields to include in the response (field limiting).</td>\n</tr>\n<tr>\n<td><code>sort</code></td>\n<td>Field(s) to sort by. Prefix with <code>-</code> for descending order (e.g. <code>sort=-createdAt</code>).</td>\n</tr>\n<tr>\n<td><code>page</code></td>\n<td>Page number for pagination (default: <code>1</code>).</td>\n</tr>\n<tr>\n<td><code>limit</code></td>\n<td>Number of results per page (default: <code>100</code>).</td>\n</tr>\n<tr>\n<td><code>role</code></td>\n<td>Filter users by role (e.g. <code>role=user</code>, <code>role=guide</code>).</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"request-body\">Request Body</h3>\n<p>None required.</p>\n<hr />\n<h3 id=\"response\">Response</h3>\n<p><strong><code>200 OK</code></strong> — Returns an array of all user documents.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": \"success\",\n  \"results\": 10,\n  \"data\": {\n    \"data\": [\n      {\n        \"_id\": \"64a1f2c3e4b0a12345678901\",\n        \"name\": \"John Doe\",\n        \"email\": \"john@example.com\",\n        \"role\": \"user\",\n        \"active\": true\n      }\n    ]\n  }\n}\n</code></pre>\n<hr />\n<h3 id=\"error-responses\">Error Responses</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Status</th>\n<th>Reason</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>401 Unauthorized</code></td>\n<td>Missing or invalid JWT token.</td>\n</tr>\n<tr>\n<td><code>403 Forbidden</code></td>\n<td>Authenticated user does not have the <code>admin</code> role.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"notes\">Notes</h3>\n<ul>\n<li>This endpoint is <strong>admin-only</strong>. Non-admin users will receive a <code>403 Forbidden</code> response.</li>\n<li>Inactive users (accounts that have been soft-deleted via <strong>Delete Current User</strong>) are excluded from the results by default.</li>\n<li>For fetching a single user by ID, use the <strong>Get User</strong> endpoint (<code>GET /api/v1/users/:id</code>).</li>\n</ul>\n","urlObject":{"path":["v1","users"],"host":["{{URL}}api"],"query":[{"disabled":true,"key":"role","value":"user"}],"variable":[]}},"response":[],"_postman_id":"1e882c35-22e2-4344-aba0-9b6762468678"},{"name":"Get User","id":"f04cbe52-ee1a-497e-8e10-6f61b1ae63ab","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{URL}}api/v1/users","description":"<p>Fetches the details of a single user by their MongoDB ObjectId. This is an <strong>admin-only</strong> operation and is part of the user management interface in the Natours API.</p>\n<hr />\n<h2 id=\"endpoint\">Endpoint</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Method</th>\n<th>URL</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>GET</code></td>\n<td><code>{{URL}}api/v1/users/:id</code></td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"authentication\">Authentication</h2>\n<p>This request requires a valid <strong>JWT Bearer token</strong> passed via the <code>{{jwt}}</code> environment variable. The authenticated user must have the <strong><code>admin</code></strong> role.</p>\n<blockquote>\n<p>Set the <code>jwt</code> variable in your active environment before sending this request.</p>\n</blockquote>\n<hr />\n<h2 id=\"url-parameters\">URL Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>id</code></td>\n<td><code>string</code> (MongoDB ObjectId)</td>\n<td>✅ Yes</td>\n<td>The unique identifier of the user to retrieve.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"request-body\">Request Body</h2>\n<p>No request body is required for this endpoint.</p>\n<hr />\n<h2 id=\"response\">Response</h2>\n<h3 id=\"200-ok\"><code>200 OK</code></h3>\n<p>Returns the user object matching the provided <code>id</code>.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": \"success\",\n  \"data\": {\n    \"data\": {\n      \"_id\": \"64a1f2c3e4b0a12345678901\",\n      \"name\": \"John Doe\",\n      \"email\": \"john@example.com\",\n      \"role\": \"user\",\n      \"active\": true\n    }\n  }\n}\n</code></pre>\n<hr />\n<h2 id=\"notes\">Notes</h2>\n<ul>\n<li>🔒 <strong>Admin only</strong> — this route is restricted to users with the <code>admin</code> role.</li>\n<li>Returns <code>403 Forbidden</code> if the authenticated user does not have the <code>admin</code> role.</li>\n<li>Returns <code>404 Not Found</code> if no user exists with the given <code>id</code>.</li>\n<li>The <code>id</code> must be a valid MongoDB ObjectId; an invalid format may return a <code>400 Bad Request</code> or <code>500</code> error.</li>\n</ul>\n","urlObject":{"path":["v1","users"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"f04cbe52-ee1a-497e-8e10-6f61b1ae63ab"},{"name":"Update User","id":"39bd8026-4b02-4580-a6f2-bf9308cb6555","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt}}"}]},"isInherited":false},"method":"PATCH","header":[],"body":{"mode":"raw","raw":"{\r\n    \"name\":\"Adminstrator\"\r\n}","options":{"raw":{"language":"json"}}},"url":"{{URL}}api/v1/users/68908f0d31c6fe58b8cb9a36","description":"<h2 id=\"update-user\">Update User</h2>\n<p>Updates the details of any specific user by their ID. This is an <strong>admin-only</strong> operation — it allows an administrator to modify any user's data in the system.</p>\n<hr />\n<h3 id=\"endpoint\">Endpoint</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Value</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Method</strong></td>\n<td><code>PATCH</code></td>\n</tr>\n<tr>\n<td><strong>URL</strong></td>\n<td><code>{{URL}}api/v1/users/68908f0d31c6fe58b8cb9a36</code></td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"authentication\">Authentication</h3>\n<p>This endpoint requires a valid <strong>JWT Bearer token</strong> with <strong>admin</strong> privileges.</p>\n<ul>\n<li>The token is read from the <code>{{jwt}}</code> environment variable.</li>\n<li>It must be sent as a <code>Bearer</code> token in the <code>Authorization</code> header.</li>\n<li>Requests from non-admin users will be rejected with a <code>403 Forbidden</code> error.</li>\n</ul>\n<blockquote>\n<p>Make sure the <code>jwt</code> variable is set to an <strong>admin</strong> token in your active environment before sending this request.</p>\n</blockquote>\n<hr />\n<h3 id=\"url-parameters\">URL Parameters</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>id</code></td>\n<td>String</td>\n<td>Yes</td>\n<td>The MongoDB ObjectId of the user to update (e.g. <code>68908f0d31c6fe58b8cb9a36</code>).</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"request-body\">Request Body</h3>\n<p>Send the body as <strong>raw JSON</strong>. Only include the fields you want to update — this is a partial update (<code>PATCH</code>), so omitted fields remain unchanged.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>name</code></td>\n<td>String</td>\n<td>No</td>\n<td>The user's display name.</td>\n</tr>\n<tr>\n<td><code>email</code></td>\n<td>String</td>\n<td>No</td>\n<td>The user's email address (must be unique).</td>\n</tr>\n<tr>\n<td><code>role</code></td>\n<td>String</td>\n<td>No</td>\n<td>The user's role. Accepted values: <code>user</code>, <code>guide</code>, <code>lead-guide</code>, <code>admin</code>.</td>\n</tr>\n<tr>\n<td><code>photo</code></td>\n<td>String</td>\n<td>No</td>\n<td>Filename or URL of the user's profile photo.</td>\n</tr>\n<tr>\n<td><code>active</code></td>\n<td>Boolean</td>\n<td>No</td>\n<td>Whether the user account is active (<code>true</code>) or deactivated (<code>false</code>).</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Example:</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"name\": \"Jane Doe\",\n    \"email\": \"jane@example.com\",\n    \"role\": \"guide\"\n}\n</code></pre>\n<blockquote>\n<p>⚠️ <strong>Do not include <code>password</code> or <code>passwordConfirm</code> in this request body.</strong> Password updates are not handled here — use the dedicated <strong>Update Password</strong> endpoint instead.</p>\n</blockquote>\n<hr />\n<h3 id=\"expected-response\">Expected Response</h3>\n<p><strong>Success — <code>200 OK</code></strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"status\": \"success\",\n    \"data\": {\n        \"user\": {\n            \"_id\": \"68908f0d31c6fe58b8cb9a36\",\n            \"name\": \"Jane Doe\",\n            \"email\": \"jane@example.com\",\n            \"role\": \"guide\",\n            \"photo\": \"default.jpg\",\n            \"active\": true\n        }\n    }\n}\n</code></pre>\n<p><strong>Error Responses</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Status</th>\n<th>Reason</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>400 Bad Request</code></td>\n<td>Invalid field values or attempting to update password via this endpoint.</td>\n</tr>\n<tr>\n<td><code>401 Unauthorized</code></td>\n<td>Missing or invalid JWT token.</td>\n</tr>\n<tr>\n<td><code>403 Forbidden</code></td>\n<td>Authenticated user does not have admin privileges.</td>\n</tr>\n<tr>\n<td><code>404 Not Found</code></td>\n<td>No user found with the provided ID.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"notes\">Notes</h3>\n<ul>\n<li>This endpoint is intended for <strong>admin use only</strong>. For users updating their own profile, use the <strong>Update Me</strong> endpoint instead.</li>\n<li><strong>Passwords cannot be updated through this endpoint.</strong> Use the dedicated password update route to handle password changes securely.</li>\n<li>The user ID in the URL must be a valid MongoDB ObjectId — an invalid format will result in a <code>400</code> or <code>500</code> error depending on the implementation.</li>\n<li>Only fields explicitly listed in the server's <code>filterObj</code> whitelist will be updated; any other fields sent in the body will be silently ignored.</li>\n</ul>\n","urlObject":{"path":["v1","users","68908f0d31c6fe58b8cb9a36"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"39bd8026-4b02-4580-a6f2-bf9308cb6555"},{"name":"Delete User","id":"04ce77ef-05c4-4d2c-8e7b-092b0dfdd644","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt}}"}]},"isInherited":false},"method":"DELETE","header":[],"url":"{{URL}}api/v1/users/6891b470869c32f6e3aa8df4","description":"<h2 id=\"delete-user\">Delete User</h2>\n<p>Permanently deletes a user account by its ID. This is an <strong>admin-only</strong> operation — only users with the <code>admin</code> role are authorised to call this endpoint.</p>\n<hr />\n<h3 id=\"authentication\">Authentication</h3>\n<p>Requires a valid <strong>JWT Bearer token</strong> passed via the <code>{{jwt}}</code> environment variable. The authenticated user must have the <code>admin</code> role.</p>\n<hr />\n<h3 id=\"method--url\">Method &amp; URL</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>DELETE {{URL}}api/v1/users/:id\n</code></pre><h3 id=\"url-parameters\">URL Parameters</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>id</code></td>\n<td>The MongoDB ObjectId of the user to delete</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"request-body\">Request Body</h3>\n<p>None required.</p>\n<hr />\n<h3 id=\"response\">Response</h3>\n<p>On success, the server returns a <code>204 No Content</code> response with no response body, indicating the user has been permanently removed.</p>\n<hr />\n<h3 id=\"notes\">Notes</h3>\n<ul>\n<li>This operation is <strong>irreversible</strong> — the user document is permanently deleted from the database.</li>\n<li>To deactivate your own account instead of deleting it outright, use the <strong>Delete Current User</strong> endpoint (<code>DELETE /api/v1/users/deleteMe</code>), which sets the account to inactive rather than removing it.</li>\n<li>Non-admin users attempting to access this endpoint will receive a <code>403 Forbidden</code> response.</li>\n</ul>\n","urlObject":{"path":["v1","users","6891b470869c32f6e3aa8df4"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"04ce77ef-05c4-4d2c-8e7b-092b0dfdd644"},{"name":"Get Current User","id":"f5c8f4ba-8f8e-4e1e-8a2e-d9ea8d8e74ef","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{URL}}api/v1/users/me","description":"<h2 id=\"get-current-user\">Get Current User</h2>\n<p>Retrieves the profile data of the currently authenticated user.</p>\n<hr />\n<h3 id=\"endpoint\">Endpoint</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Details</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Method</strong></td>\n<td><code>GET</code></td>\n</tr>\n<tr>\n<td><strong>URL</strong></td>\n<td><code>{{URL}}api/v1/users/me</code></td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"authentication\">Authentication</h3>\n<p>This endpoint requires a valid <strong>JWT token</strong>. The token should be passed as a <strong>Bearer token</strong> in the <code>Authorization</code> header, or via a cookie depending on the server configuration.</p>\n<blockquote>\n<p>The <code>{{jwt}}</code> variable is used to supply the authentication token.</p>\n</blockquote>\n<hr />\n<h3 id=\"request-body\">Request Body</h3>\n<p>No request body is required for this endpoint.</p>\n<hr />\n<h3 id=\"response\">Response</h3>\n<p>Returns the data of the currently logged-in user, including profile information such as name, email, and role.</p>\n<hr />\n<h3 id=\"notes\">Notes</h3>\n<ul>\n<li>The <code>{{URL}}</code> variable should be set to the base URL of the Natours API (e.g., <code>https://your-api-domain.com/</code>).</li>\n<li>Ensure you are authenticated before calling this endpoint — unauthenticated requests will be rejected with a <code>401 Unauthorized</code> response.</li>\n</ul>\n","urlObject":{"path":["v1","users","me"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"f5c8f4ba-8f8e-4e1e-8a2e-d9ea8d8e74ef"},{"name":"Update Current User","id":"e6ce6505-f6e2-412f-8b91-2b727f0f35fa","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt}}"}]},"isInherited":false},"method":"PATCH","header":[],"body":{"mode":"formdata","formdata":[{"key":"name","value":"Leo J. Gillespie","type":"text","disabled":true},{"key":"photo","type":"file","src":"/D:/.Node JS Items/Node JS Practice Sets/4-natours/dev-data/img/aarav.jpg"}]},"url":"{{URL}}api/v1/users/updateMe","description":"<h2 id=\"update-current-user\">Update Current User</h2>\n<p>Allows the <strong>currently authenticated user</strong> to update their own profile information. This endpoint accepts multipart form data, making it suitable for file uploads such as a new profile photo.</p>\n<blockquote>\n<p>⚠️ <strong>Note:</strong> This endpoint does <strong>not</strong> update passwords. To change your password, use the dedicated change-password endpoint.</p>\n</blockquote>\n<hr />\n<h3 id=\"authentication\">Authentication</h3>\n<p>Requires a valid <strong>JWT Bearer token</strong>, provided via the <code>{{jwt}}</code> environment variable.</p>\n<hr />\n<h3 id=\"request\">Request</h3>\n<p><strong>Method:</strong> <code>PATCH</code><br /><strong>URL:</strong> <code>{{URL}}api/v1/users/updateMe</code><br /><strong>Body Type:</strong> <code>multipart/form-data</code></p>\n<h4 id=\"body-fields\">Body Fields</h4>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>name</code></td>\n<td>text</td>\n<td>Optional</td>\n<td>The new display name for the authenticated user.</td>\n</tr>\n<tr>\n<td><code>photo</code></td>\n<td>file</td>\n<td>Optional</td>\n<td>A new profile photo to upload for the user.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"notes\">Notes</h3>\n<ul>\n<li>Only the fields provided in the request body will be updated; omitted fields remain unchanged.</li>\n<li>Attempting to update password-related fields through this endpoint will have no effect — use the appropriate password update endpoint instead.</li>\n</ul>\n","urlObject":{"path":["v1","users","updateMe"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"e6ce6505-f6e2-412f-8b91-2b727f0f35fa"},{"name":"Delete Current User","id":"aba90d8f-498d-4872-a60e-0244fb347dfc","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt}}"}]},"isInherited":false},"method":"DELETE","header":[],"url":"{{URL}}api/v1/users/deleteMe","description":"<h2 id=\"delete-current-user\">Delete Current User</h2>\n<p>Soft-deletes the currently authenticated user by setting their account status to <strong>inactive</strong>. The user's data is retained in the database but the account is no longer accessible.</p>\n<blockquote>\n<p><strong>Note:</strong> This action deactivates the account associated with the JWT provided in the <code>Authorization</code> header. It does <strong>not</strong> permanently remove the user record from the database.</p>\n</blockquote>\n<h3 id=\"authentication\">Authentication</h3>\n<p>This endpoint requires a valid JWT bearer token. Include it in the <code>Authorization</code> header:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>Authorization: Bearer &lt;token&gt;\n</code></pre><p>The <code>jwt</code> variable from the active environment is used automatically.</p>\n<h3 id=\"request\">Request</h3>\n<ul>\n<li><strong>Method:</strong> <code>DELETE</code></li>\n<li><strong>URL:</strong> <code>{{URL}}api/v1/users/deleteMe</code></li>\n<li><strong>Body:</strong> None required</li>\n</ul>\n<h3 id=\"responses\">Responses</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Status</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>204 No Content</code></td>\n<td>User successfully deactivated. No response body is returned.</td>\n</tr>\n<tr>\n<td><code>401 Unauthorized</code></td>\n<td>Missing or invalid JWT token.</td>\n</tr>\n<tr>\n<td><code>500 Internal Server Error</code></td>\n<td>An unexpected server error occurred.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["v1","users","deleteMe"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"aba90d8f-498d-4872-a60e-0244fb347dfc"}],"id":"3fddac02-a8ad-4211-bae4-b198c88df11e","description":"<p>Endpoints for managing user accounts in the Natours application. This folder covers both <strong>admin-level</strong> user management and <strong>self-service</strong> operations for the currently authenticated user.</p>\n<p><strong>Admin Operations</strong></p>\n<ul>\n<li><strong>Get All Users</strong> — Retrieves a list of all registered users (<code>GET /api/v1/users</code>).</li>\n<li><strong>Get User</strong> — Fetches the details of a single user by their ID (<code>GET /api/v1/users/:id</code>).</li>\n<li><strong>Update User</strong> — Updates a user's data (e.g. name, role) by ID (<code>PATCH /api/v1/users/:id</code>).</li>\n<li><strong>Delete User</strong> — Permanently removes a user account by ID (<code>DELETE /api/v1/users/:id</code>).</li>\n</ul>\n<p><strong>Current User (Self-Service)</strong></p>\n<ul>\n<li><strong>Get Current User</strong> — Returns the profile of the currently logged-in user (<code>GET /api/v1/users/me</code>).</li>\n<li><strong>Update Current User</strong> — Allows the authenticated user to update their own name or email (<code>PATCH /api/v1/users/updateMe</code>).</li>\n<li><strong>Delete Current User</strong> — Deactivates the authenticated user's own account (<code>DELETE /api/v1/users/deleteMe</code>).</li>\n</ul>\n","_postman_id":"3fddac02-a8ad-4211-bae4-b198c88df11e"},{"name":"Authentication","item":[{"name":"Update Current User  Password","event":[{"listen":"test","script":{"id":"d3485ab3-3e5c-4b03-85a4-73694cf7de40","exec":["pm.environment.set(\"jwt\", pm.response.json().token);"],"type":"text/javascript"}}],"id":"e91a2724-175b-4d90-a0f8-d7ecda06dd46","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt}}"}]},"isInherited":false},"method":"PATCH","header":[],"body":{"mode":"raw","raw":"{\r\n    \"passwordCurrent\":\"pass1234\",\r\n    \"password\":\"newpassword\",\r\n    \"passwordConfirm\":\"newpassword\"\r\n}","options":{"raw":{"language":"json"}}},"url":"{{URL}}api/v1/users/updateMyPassword","description":"<h2 id=\"update-current-user-password\">Update Current User Password</h2>\n<p>Updates the password of the currently authenticated user. The user must provide their current password along with the new password and a confirmation of the new password.</p>\n<hr />\n<h3 id=\"authentication\">Authentication</h3>\n<p>This endpoint requires a valid <strong>JWT token</strong>. The token is read from the <code>{{jwt}}</code> environment variable and must be sent as a Bearer token in the <code>Authorization</code> header.</p>\n<hr />\n<h3 id=\"request-body\">Request Body</h3>\n<p>The request body must be sent as <strong>raw JSON</strong>.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>passwordCurrent</code></td>\n<td><code>string</code></td>\n<td>✅ Yes</td>\n<td>The user's current (existing) password.</td>\n</tr>\n<tr>\n<td><code>password</code></td>\n<td><code>string</code></td>\n<td>✅ Yes</td>\n<td>The new password to set.</td>\n</tr>\n<tr>\n<td><code>passwordConfirm</code></td>\n<td><code>string</code></td>\n<td>✅ Yes</td>\n<td>Must match <code>password</code> exactly for confirmation.</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Example:</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"passwordCurrent\": \"pass1234\",\n    \"password\": \"newpassword\",\n    \"passwordConfirm\": \"newpassword\"\n}\n</code></pre>\n<hr />\n<h3 id=\"response\">Response</h3>\n<p>On success, the server returns a new JWT token (since the password change invalidates the old one). The test script automatically saves the new token to the <code>{{jwt}}</code> environment variable for use in subsequent requests.</p>\n<p><strong>Example response shape:</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"status\": \"success\",\n    \"token\": \"&lt;new_jwt_token&gt;\",\n    \"data\": {\n        \"user\": { ... }\n    }\n}\n</code></pre>\n<hr />\n<h3 id=\"notes\">Notes</h3>\n<ul>\n<li>The <code>passwordCurrent</code> field is validated server-side — an incorrect value will result in an error response.</li>\n<li><code>password</code> and <code>passwordConfirm</code> must match; a mismatch will result in a validation error.</li>\n<li>After a successful password update, the old JWT token is no longer valid. The new token is automatically stored in the <code>{{jwt}}</code> environment variable by the post-response test script.</li>\n</ul>\n","urlObject":{"path":["v1","users","updateMyPassword"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"e91a2724-175b-4d90-a0f8-d7ecda06dd46"},{"name":"Forget Password","event":[{"listen":"test","script":{"id":"fdbce427-40c3-4d2f-842a-e74577eb23c5","exec":[""],"type":"text/javascript"}}],"id":"6f32670c-978e-480e-932d-a07aa18c8ddb","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\r\n    \"email\":\"test7@natours.io\"\r\n}","options":{"raw":{"language":"json"}}},"url":"{{URL}}api/v1/users/forgetPassword","description":"<h2 id=\"forget-password\">Forget Password</h2>\n<p>Initiates a password reset flow by sending a password reset email to the provided email address.</p>\n<hr />\n<h3 id=\"method--url\">Method &amp; URL</h3>\n<p><strong>POST</strong> <code>{{URL}}api/v1/users/forgetPassword</code></p>\n<hr />\n<h3 id=\"request-body\">Request Body</h3>\n<p>Send a JSON object with the following field:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>email</code></td>\n<td>String</td>\n<td>✅ Yes</td>\n<td>The registered email address of the user</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Example:</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"email\": \"user@example.com\"\n}\n</code></pre>\n<hr />\n<h3 id=\"expected-behavior\">Expected Behavior</h3>\n<p>Upon a successful request, the server generates a password reset token and sends a reset link/token to the provided email address. The user can then use that link or token to set a new password.</p>\n<hr />\n<h3 id=\"notes\">Notes</h3>\n<ul>\n<li>The email address <strong>must belong to a registered user</strong> in the system. If no account is found with the given email, the request will fail.</li>\n<li>The reset token/link is typically time-limited and expires after a short period.</li>\n<li>Check your spam/junk folder if the reset email does not appear in your inbox.</li>\n</ul>\n","urlObject":{"path":["v1","users","forgetPassword"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"6f32670c-978e-480e-932d-a07aa18c8ddb"},{"name":"Login","event":[{"listen":"test","script":{"id":"520df2f3-82d3-45a9-b6cd-387d43e7a302","exec":["pm.environment.set(\"jwt\", pm.response.json().token);"],"type":"text/javascript","packages":{},"requests":{}}}],"id":"c68b9ca7-0419-4640-ad6d-28bd0c0fd974","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt}}"}]},"isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\r\n  \"email\": \"zubair@mailsac.com\",\r\n  \"password\":\"{{password}}\"\r\n}\r\n","options":{"raw":{"language":"json"}}},"url":"{{URL}}api/v1/users/login","description":"<h2 id=\"login\">Login</h2>\n<p>Authenticates an existing user and returns a <strong>JWT token</strong> for use in subsequent authenticated requests.</p>\n<h3 id=\"request-body\">Request Body</h3>\n<p>Send a JSON object with the following required fields:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>email</code></td>\n<td>string</td>\n<td>The registered email address of the user</td>\n</tr>\n<tr>\n<td><code>password</code></td>\n<td>string</td>\n<td>The user's password</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Example:</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"email\": \"zubair@mailsac.com\",\n  \"password\": \"{{password}}\"\n}\n</code></pre>\n<h3 id=\"response\">Response</h3>\n<p>On success, the response contains a JWT token:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"token\": \"&lt;jwt_token&gt;\"\n}\n</code></pre>\n<h3 id=\"test-script\">Test Script</h3>\n<p>The test script automatically saves the returned token to the <strong><code>jwt</code> environment variable</strong>, so it can be used in subsequent requests without manual copying:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-js\">pm.environment.set(\"jwt\", pm.response.json().token);\n</code></pre>\n","urlObject":{"path":["v1","users","login"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"c68b9ca7-0419-4640-ad6d-28bd0c0fd974"},{"name":"Sign Up","event":[{"listen":"test","script":{"id":"1923fd89-086c-4d44-b58f-a53076337429","exec":["pm.environment.set(\"jwt\", pm.response.json().token);"],"type":"text/javascript","packages":{},"requests":{}}}],"id":"209c9bbc-2bf9-4105-b84c-b14efeaf5afb","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\r\n    \"name\":\"Jonas Schmedtmann\",\r\n    \"email\":\"admin@natours.io\",\r\n    \"password\":\"test1234\",\r\n    \"passwordConfirm\":\"test1234\"\r\n}","options":{"raw":{"language":"json"}}},"url":"{{URL}}api/v1/users/signup","description":"<h2 id=\"sign-up\">Sign Up</h2>\n<p>Registers a new user account in the Natours application.</p>\n<hr />\n<h3 id=\"method--url\">Method &amp; URL</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>POST {{URL}}api/v1/users/signup\n</code></pre><hr />\n<h3 id=\"request-body\">Request Body</h3>\n<p>Send a JSON object with the following fields:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>name</code></td>\n<td>String</td>\n<td>The full name of the user.</td>\n</tr>\n<tr>\n<td><code>email</code></td>\n<td>String</td>\n<td>A valid, unique email address for the account.</td>\n</tr>\n<tr>\n<td><code>password</code></td>\n<td>String</td>\n<td>The user's chosen password (min. 8 characters).</td>\n</tr>\n<tr>\n<td><code>passwordConfirm</code></td>\n<td>String</td>\n<td>Must match the <code>password</code> field exactly.</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Example:</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"name\": \"Jonas Schmedtmann\",\n    \"email\": \"admin@natours.io\",\n    \"password\": \"test1234\",\n    \"passwordConfirm\": \"test1234\"\n}\n</code></pre>\n<hr />\n<h3 id=\"response\">Response</h3>\n<p>On success, the API returns a <code>201 Created</code> response containing a JWT token in the <code>token</code> field of the response body.</p>\n<blockquote>\n<p><strong>Note:</strong> The test script automatically saves the returned token to the <code>jwt</code> environment variable, making it available for authenticated requests throughout the collection.</p>\n</blockquote>\n","urlObject":{"path":["v1","users","signup"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"209c9bbc-2bf9-4105-b84c-b14efeaf5afb"},{"name":"Reset Password","event":[{"listen":"test","script":{"id":"e0595783-1767-4be8-b2a4-d68c4b036de4","exec":["pm.environment.set(\"jwt\", pm.response.json().token);"],"type":"text/javascript"}}],"id":"c63e09bb-ae12-47da-991c-b7679ec21264","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"PATCH","header":[],"body":{"mode":"raw","raw":"{\r\n    \"password\":\"newpassword\",\r\n    \"passwordConfirm\":\"newpassword\"\r\n}","options":{"raw":{"language":"json"}}},"url":"{{URL}}api/v1/users/resetPassword/682a10211e1a0ab6a81e91520baa60538ec73f88660cd012e06f5f9421af3d2d","description":"<h2 id=\"reset-password\">Reset Password</h2>\n<p>Resets a user's password using a valid password reset token. This endpoint is typically called after the user has received a reset link via email (from the <strong>Forgot Password</strong> endpoint) and clicked through to the reset form.</p>\n<hr />\n<h3 id=\"method--url\">Method &amp; URL</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>PATCH {{URL}}api/v1/users/resetPassword/:resetToken\n</code></pre><hr />\n<h3 id=\"path-parameters\">Path Parameters</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>resetToken</code></td>\n<td>String</td>\n<td>The password reset token sent to the user's email. It is embedded in the reset link URL and must be valid and unexpired.</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Example token in URL:</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>682a10211e1a0ab6a81e91520baa60538ec73f88660cd012e06f5f9421af3d2d\n</code></pre><hr />\n<h3 id=\"request-body\">Request Body</h3>\n<p>Send a raw JSON body with the following fields:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>password</code></td>\n<td>String</td>\n<td>✅ Yes</td>\n<td>The new password to set for the account.</td>\n</tr>\n<tr>\n<td><code>passwordConfirm</code></td>\n<td>String</td>\n<td>✅ Yes</td>\n<td>Must match <code>password</code> exactly for validation.</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Example:</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"password\": \"newpassword\",\n  \"passwordConfirm\": \"newpassword\"\n}\n</code></pre>\n<hr />\n<h3 id=\"response\">Response</h3>\n<p>On success, the server returns a JSON object containing a JWT token, which is used to authenticate subsequent requests.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>token</code></td>\n<td>String</td>\n<td>A new JWT authentication token for the logged-in user.</td>\n</tr>\n</tbody>\n</table>\n</div><p>The test script automatically saves this token to the active environment:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-javascript\">pm.environment.set(\"jwt\", pm.response.json().token);\n</code></pre>\n<hr />\n<h3 id=\"notes\">Notes</h3>\n<ul>\n<li>The reset token is <strong>single-use</strong> and <strong>time-limited</strong> — it will expire after a set period (typically 10 minutes). Attempting to use an expired or already-used token will result in an error.</li>\n<li>After a successful password reset, the user is considered logged in and the returned <code>jwt</code> token can be used for authenticated requests.</li>\n<li>Ensure <code>password</code> and <code>passwordConfirm</code> match; a mismatch will result in a validation error.</li>\n</ul>\n","urlObject":{"path":["v1","users","resetPassword","682a10211e1a0ab6a81e91520baa60538ec73f88660cd012e06f5f9421af3d2d"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"c63e09bb-ae12-47da-991c-b7679ec21264"}],"id":"c75adf90-7c7e-4fef-9962-10ecced7fde2","description":"<p>Handles all user authentication and account security flows for the Natours API.</p>\n<ul>\n<li><strong>Sign Up</strong> — Registers a new user account (<code>POST /api/v1/users/signup</code>).</li>\n<li><strong>Login</strong> — Authenticates an existing user and returns a JWT (<code>POST /api/v1/users/login</code>).</li>\n<li><strong>Forget Password</strong> — Sends a password reset token to the user's email address (<code>POST /api/v1/users/forgetPassword</code>).</li>\n<li><strong>Reset Password</strong> — Resets the user's password using the token received by email (<code>PATCH /api/v1/users/resetPassword/:token</code>).</li>\n<li><strong>Update Current User Password</strong> — Allows an authenticated user to change their current password (<code>PATCH /api/v1/users/updateMyPassword</code>).</li>\n</ul>\n","_postman_id":"c75adf90-7c7e-4fef-9962-10ecced7fde2"},{"name":"Bookings","item":[{"name":"Get Booking","id":"f5d07792-6267-47a5-9d2e-f07b8adb1766","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{URL}}api/v1/bookings/68a5b59b90d4ebdfb03fe0bc","description":"<h2 id=\"get-booking\">Get Booking</h2>\n<p>Retrieves a single booking by its unique ID. Returns the full booking object associated with the specified booking ID.</p>\n<hr />\n<h3 id=\"authentication\">Authentication</h3>\n<p>This endpoint requires a valid <strong>JWT bearer token</strong>. The token must be included in the request via the <code>{{jwt}}</code> variable, which is resolved from the active environment.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Type</th>\n<th>Value</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Bearer Token</td>\n<td><code>{{jwt}}</code></td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"url-structure\">URL Structure</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>GET {{URL}}api/v1/bookings/68a5b59b90d4ebdfb03fe0bc\n</code></pre><div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Part</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>{{URL}}</code></td>\n<td>Base URL of the API (set in the active environment)</td>\n</tr>\n<tr>\n<td><code>api/v1/bookings/</code></td>\n<td>Bookings resource path</td>\n</tr>\n<tr>\n<td><code>68a5b59b90d4ebdfb03fe0bc</code></td>\n<td>Unique ID of the booking to retrieve</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h3 id=\"request-parameters\">Request Parameters</h3>\n<p>No query parameters or request body required.</p>\n<hr />\n<h3 id=\"expected-response\">Expected Response</h3>\n<p><strong>Status:</strong> <code>200 OK</code></p>\n<p>Returns a booking object containing details such as the tour, user, price, and booking date.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"status\": \"success\",\n  \"data\": {\n    \"booking\": {\n      \"_id\": \"68a5b59b90d4ebdfb03fe0bc\",\n      \"tour\": { ... },\n      \"user\": { ... },\n      \"price\": 997,\n      \"createdAt\": \"2024-01-01T00:00:00.000Z\",\n      \"paid\": true\n    }\n  }\n}\n</code></pre>\n","urlObject":{"path":["v1","bookings","68a5b59b90d4ebdfb03fe0bc"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"f5d07792-6267-47a5-9d2e-f07b8adb1766"},{"name":"Get All Bookings","id":"c0a22534-ab45-4496-8de6-b23b8a3446d9","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{URL}}api/v1/bookings","description":"<h1 id=\"get-all-bookings\">Get All Bookings</h1>\n<p>Retrieves a list of <strong>all bookings</strong> in the Natours system. This is an <strong>admin-only</strong> endpoint — only users with the <code>admin</code> role are authorised to access it.</p>\n<h2 id=\"endpoint\">Endpoint</h2>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>GET {{URL}}api/v1/bookings\n</code></pre><h2 id=\"authentication\">Authentication</h2>\n<p>Requires a valid <strong>JWT Bearer token</strong> passed via the <code>{{jwt}}</code> environment variable. The authenticated user must have the <code>admin</code> role.</p>\n<h2 id=\"request-details\">Request Details</h2>\n<ul>\n<li><strong>Method:</strong> <code>GET</code></li>\n<li><strong>Body:</strong> None</li>\n<li><strong>Query Parameters:</strong> None (standard filtering, sorting, field limiting, and pagination query parameters may be supported)</li>\n</ul>\n<h2 id=\"expected-response\">Expected Response</h2>\n<p>On success, the server returns a JSON object containing:</p>\n<ul>\n<li><code>status</code>: <code>\"success\"</code></li>\n<li><code>results</code>: The total number of bookings returned</li>\n<li><code>data</code>: An object with a <code>bookings</code> array, where each booking document includes details such as the associated tour, user, price, and creation date.</li>\n</ul>\n<h2 id=\"notes\">Notes</h2>\n<ul>\n<li>This endpoint returns all bookings across all users and tours.</li>\n<li>For a single booking, use the <strong>Get Booking</strong> endpoint with a specific booking ID.</li>\n<li>Access is restricted to admins. Authenticated non-admin users will receive a <code>403 Forbidden</code> response.</li>\n</ul>\n","urlObject":{"path":["v1","bookings"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"c0a22534-ab45-4496-8de6-b23b8a3446d9"},{"name":"Session Checkout","id":"bcc25a09-7193-4409-a9c8-1b707b12ed78","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{jwt}}"}]},"isInherited":false},"method":"GET","header":[],"body":{"mode":"formdata","formdata":[]},"url":"{{URL}}api/v1/bookings/checkout-session/5c88fa8cf4afda39709c2955","description":"<h1 id=\"session-checkout\">Session Checkout</h1>\n<p>Initiates a <strong>Stripe checkout session</strong> for a specific tour booking. This endpoint generates a Stripe-hosted payment page URL that the client can redirect the user to in order to complete their booking payment.</p>\n<h2 id=\"endpoint\">Endpoint</h2>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>GET {{URL}}api/v1/bookings/checkout-session/:tourId\n</code></pre><h2 id=\"url-parameters\">URL Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Value</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>tourId</code></td>\n<td><code>5c88fa8cf4afda39709c2955</code></td>\n<td>The unique MongoDB ObjectId of the tour to be booked</td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"authentication\">Authentication</h2>\n<p>Requires a valid <strong>JWT Bearer token</strong> passed via the <code>{{jwt}}</code> variable. The user must be logged in to initiate a checkout session.</p>\n<h2 id=\"request-details\">Request Details</h2>\n<ul>\n<li><strong>Method:</strong> <code>GET</code></li>\n<li><strong>Body:</strong> None</li>\n<li><strong>Query Parameters:</strong> None</li>\n</ul>\n<h2 id=\"expected-response\">Expected Response</h2>\n<p>On success, the server returns a Stripe checkout session object containing:</p>\n<ul>\n<li><code>status</code>: <code>\"success\"</code></li>\n<li><code>session</code>: A Stripe session object that includes the <code>url</code> property — the hosted Stripe payment page the user should be redirected to in order to complete the booking.</li>\n</ul>\n<h2 id=\"notes\">Notes</h2>\n<ul>\n<li>The tour ID in the URL corresponds to an existing tour document in the database.</li>\n<li>Upon successful payment, Stripe will redirect the user back to the application and the booking will be recorded automatically.</li>\n</ul>\n","urlObject":{"path":["v1","bookings","checkout-session","5c88fa8cf4afda39709c2955"],"host":["{{URL}}api"],"query":[],"variable":[]}},"response":[],"_postman_id":"bcc25a09-7193-4409-a9c8-1b707b12ed78"}],"id":"d32f23b3-d996-4237-8a97-b5289ccaa923","description":"<p>Endpoints for managing tour bookings in the Natours application.</p>\n<ul>\n<li><strong>Session Checkout</strong> — Initiates a Stripe checkout session for a given tour, allowing users to complete a booking payment (<code>GET /api/v1/bookings/checkout-session/:tourId</code>).</li>\n<li><strong>Get All Bookings</strong> — Retrieves a list of all bookings in the system. Restricted to admin use (<code>GET /api/v1/bookings</code>).</li>\n<li><strong>Get Booking</strong> — Fetches the details of a single booking by its ID (<code>GET /api/v1/bookings/:id</code>).</li>\n</ul>\n","_postman_id":"d32f23b3-d996-4237-8a97-b5289ccaa923"}],"event":[{"listen":"prerequest","script":{"id":"f61059a2-a40d-41dc-a3db-2e817326545f","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"8a5bcc7e-4a62-416a-829b-484ba2393594","type":"text/javascript","exec":[""]}}]}