Public API
Integrate NextInQue's reservation system directly into your own website or app. Create bookings, check availability, and manage reservations programmatically.
https://nextinque.com/api/v1/publicGetting Access
API access is available on request. Once enabled by the NextInQue team, you can generate API keys from your dashboard.
- Log into your NextInQue dashboard
- Go to Settings → API Access
- Click Request API Access and briefly describe your use case
- Once approved, click Generate Key — copy it immediately, it's shown only once
Authentication
Every request must include your API key in the header:
X-API-Key: your_api_key_hereKeep your API key secret. Do not expose it in client-side JavaScript. Use it only from your server.
Integration Flow
There are 4 steps to complete a booking — exactly the same flow staff use in the dashboard.
GET /servicesFetch available services and their IDs
GET /availabilityGet open time slots for a specific date and service
POST /reservationsBook the selected slot for a customer
GET /reservations/:codeConfirm the booking was created successfully
Step 1 — List Services
/servicesReturns all active services for your account. You need a serviceId to check availability and create reservations.
Request
GET https://nextinque.com/api/v1/public/services
X-API-Key: your_api_key_hereResponse 200
{
"services": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "General Consultation",
"description": "30-minute general consultation",
"durationMinutes": 30
},
{
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"name": "Follow-up Visit",
"description": null,
"durationMinutes": 30
}
]
}id values — you'll need them in the next steps.Step 2 — Check Availability
/availabilityReturns available time slots for a date and service. Only show slots where available > 0 to customers.
Query Parameters
| Parameter | Required | Type | Description |
|---|---|---|---|
| date | Required | YYYY-MM-DD | The date to check |
| serviceId | Recommended | UUID | Service to check — omit only if you have no services configured |
Request
GET https://nextinque.com/api/v1/public/availability?date=2025-12-15&serviceId=a1b2c3d4-e5f6-7890-abcd-ef1234567890
X-API-Key: your_api_key_hereResponse 200
{
"date": "2025-12-15",
"service": {
"id": "a1b2c3d4-...",
"name": "General Consultation",
"durationMinutes": 30
},
"slots": [
{ "time": "09:00", "iso": "2025-12-15T09:00:00.000+05:00", "available": 1, "total": 1 },
{ "time": "09:30", "iso": "2025-12-15T09:30:00.000+05:00", "available": 0, "total": 1 },
{ "time": "10:00", "iso": "2025-12-15T10:00:00.000+05:00", "available": 1, "total": 1 }
]
}Slot Fields
| Parameter | Required | Type | Description |
|---|---|---|---|
| time | — | string | Human-readable time in HH:mm format (tenant timezone) |
| iso | — | ISO 8601 | Full datetime — use this as scheduledAt when creating a reservation |
| available | — | number | Remaining open bookings at this slot (0 = fully booked) |
| total | — | number | Maximum concurrent bookings allowed |
iso value as scheduledAt — it contains the correct timezone offset. Do not construct your own datetime string.Step 3 — Create a Reservation
/reservationsCreates a booking. A confirmation notification is sent automatically to the customer.
Request Body
| Parameter | Required | Type | Description |
|---|---|---|---|
| customerName | Required | string | Full name of the customer (min 2 chars) |
| phone | Required | string | Phone number — used for SMS/WhatsApp notifications |
| Optional | Email address for email notifications | ||
| scheduledAt | Required | ISO 8601 | Use the iso value from /availability exactly |
| serviceId | Required | UUID | Service ID from Step 1 |
| notes | Optional | string | Special requests or notes (max 1000 chars) |
Request
POST https://nextinque.com/api/v1/public/reservations
X-API-Key: your_api_key_here
Content-Type: application/json
{
"customerName": "John Doe",
"phone": "+923001234567",
"email": "john@example.com",
"scheduledAt": "2025-12-15T09:00:00.000+05:00",
"serviceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"notes": "First-time customer"
}Response 201 Created
{
"reservation": {
"id": "c3d4e5f6-...",
"confirmationCode": "A3F1B9C02D4E",
"customerName": "John Doe",
"phone": "+923001234567",
"email": "john@example.com",
"scheduledAt": "2025-12-15T04:00:00.000Z",
"status": "PENDING",
"notes": "First-time customer",
"source": "API",
"createdAt": "2025-12-10T14:32:00.000Z",
"service": { "name": "General Consultation", "durationMinutes": 30 },
"tenant": { "name": "City Service Center" }
}
}confirmationCode — customers use it to view or cancel their booking.Step 4 — Retrieve a Reservation
/reservations/:codeRequest
GET https://nextinque.com/api/v1/public/reservations/A3F1B9C02D4E
X-API-Key: your_api_key_hereReservation Status Values
Optional — Cancel or Confirm
/reservations/:code/cancelCancel a reservation. Works on PENDING or CONFIRMED status.
PATCH https://nextinque.com/api/v1/public/reservations/A3F1B9C02D4E/cancel
X-API-Key: your_api_key_here/reservations/:code/confirmCustomer self-confirms (idempotent — safe to call multiple times).
PATCH https://nextinque.com/api/v1/public/reservations/A3F1B9C02D4E/confirm
X-API-Key: your_api_key_hereError Reference
All errors use the same JSON shape:
{ "message": "Human-readable description of what went wrong" }| Code | Scenario | Message |
|---|---|---|
400 | Invalid request body / params | Describes the invalid field |
400 | Scheduled time is in the past | Scheduled time must be in the future |
401 | Missing or invalid API key | Invalid or missing API key |
404 | Service not found or inactive | Service not found |
404 | Reservation code not found | Reservation not found |
409 | Slot is fully booked | See slot conflict section below |
Slot Conflict (409) — Includes Alternatives
When a slot is fully booked, the response includes the next available times on the same date:
{
"message": "\"General Consultation\" is fully booked at the selected time. Next available slots on 2025-12-15: 10:00, 10:30, 11:00.",
"service_name": "General Consultation",
"available_slots": ["10:00", "10:30", "11:00"],
"date": "2025-12-15"
}Recommended Handling
try {
const res = await createReservation({ scheduledAt: slot.iso, ... });
// success — show confirmation code to customer
} catch (err) {
if (err.response?.status === 409) {
const { message, available_slots } = err.response.data;
showMessage(message);
if (available_slots?.length > 0) {
offerAlternativeSlots(available_slots); // let customer pick another
}
}
}Full Working Example
Complete JavaScript example that walks through all 4 steps:
const API_BASE = "https://nextinque.com/api/v1/public";
const API_KEY = "your_api_key_here"; // store server-side, never in client JS
const headers = {
"Content-Type": "application/json",
"X-API-Key": API_KEY,
};
async function bookReservation() {
// Step 1: Get services
const { services } = await fetch(`${API_BASE}/services`, { headers }).then(r => r.json());
const service = services[0]; // let user pick from a dropdown
console.log("Service:", service.name, " — ID:", service.id);
// Step 2: Check availability
const date = "2025-12-15";
const { slots } = await fetch(
`${API_BASE}/availability?date=${date}&serviceId=${service.id}`,
{ headers }
).then(r => r.json());
const openSlots = slots.filter(s => s.available > 0);
console.log("Open slots:", openSlots.map(s => s.time));
if (openSlots.length === 0) {
console.log("No slots available on this date.");
return;
}
const chosenSlot = openSlots[0]; // user selects from UI
// Step 3: Create reservation
try {
const res = await fetch(`${API_BASE}/reservations`, {
method: "POST",
headers,
body: JSON.stringify({
customerName: "John Doe",
phone: "+923001234567",
email: "john@example.com",
scheduledAt: chosenSlot.iso, // always use .iso, not .time
serviceId: service.id,
notes: "Referred by Dr. Smith",
}),
});
const { reservation } = await res.json();
console.log("Booked! Code:", reservation.confirmationCode);
// Step 4: Verify
const check = await fetch(
`${API_BASE}/reservations/${reservation.confirmationCode}`,
{ headers }
).then(r => r.json());
console.log("Status:", check.reservation.status); // PENDING
} catch (err) {
if (err.response?.status === 409) {
const { message, available_slots } = err.response.data;
console.log(message);
if (available_slots?.length) {
console.log("Try instead:", available_slots);
}
}
}
}
bookReservation();All Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | https://nextinque.com/api/v1/public/services | List active services |
| GET | https://nextinque.com/api/v1/public/availability | Get available time slots for a date |
| POST | https://nextinque.com/api/v1/public/reservations | Create a reservation |
| GET | https://nextinque.com/api/v1/public/reservations/:code | Get reservation by confirmation code |
| PATCH | https://nextinque.com/api/v1/public/reservations/:code/confirm | Customer self-confirms |
| PATCH | https://nextinque.com/api/v1/public/reservations/:code/cancel | Cancel a reservation |
Review Sync — Google Reviews
Brings the reviews from your Google Maps listing into your NextInQue Reviews dashboard, next to your survey feedback, with sentiment tags and analytics. There's no Google sign-in or password — you use your own Google API key (a free-to-create key from your Google Cloud account), so reviews are fetched with your key, for your business only, and any usage is billed to your Google account — never shared with other clients.
Before You Start
Your business needs to appear on Google Maps. Search for its name on Google Maps — if you can see your listing with its reviews, you're ready.
Step 1 — Create Your Google API Key
- In Google Cloud Console, create a project (for example NextInQue Reviews) and enable billing on it — the Places API is a paid API with a generous free monthly allowance; checking your reviews once a day is far below it
- Go to APIs & Services → Library, search for Places API (New) and click Enable
- Go to APIs & Services → Credentials → Create credentials → API key
- Open the key and restrict it: under API restrictions choose Restrict key and select only Places API (New). Do not add website (HTTP referrer) or IP restrictions — requests are made from NextInQue's servers, so they would be blocked
- Optional but recommended: under Quotas set a small daily limit, and add a Budget alert in Billing, so you are never surprised
- Use a key made just for NextInQue — you can revoke or replace it anytime without affecting anything else
Step 2 — Add It and Connect Your Business
- Log into your NextInQue dashboard
- Go to Settings → Reputation → Sync Reviews → Google Reviews
- Paste your key and press Verify & save. NextInQue tests it with Google and tells you exactly what to fix if something is off (billing, API not enabled, wrong restriction). The key is stored encrypted and is never shown again — only its last 4 characters
- Type your business name and city (for example Smash Burger Lahore) and press Find my business
- Pick your business from the list — check the address — and press Connect
- Your Google reviews appear in the Reviews list straight away
Each location (branch) that syncs separately uses its own connection; you can paste the same key for every branch. To change keys later use Replace key — your business and reviews are kept. Disconnect deletes the saved key.
If You Can't Find It — Use the Place ID
Every Google listing has a unique Place ID (it looks like ChIJN1t_tDeuEmsRUsoyG83frY4). If searching doesn't show your business, paste the Place ID into the Or paste your Place ID box instead:
- Open Google's Place ID Finder
- Type your business name in the search box on the map and choose it
- Copy the Place ID shown in the pop-up and paste it into NextInQue, then press Connect
What to Expect
- Only your own business. Google lets anyone read any listing's public reviews, so NextInQue checks that the listing you pick matches the business you registered with — your phone number, business name and address. If it matches, your reviews import immediately. If it doesn't (for example a different name or address on Google), the connection waits for a NextInQue administrator to approve it, and no reviews are imported until then. A listing that belongs to someone else will be declined.
- Google shares only 5 reviews per check. This is a limit of Google's Places API itself — it returns the 5 most relevant reviews of a listing and no way to page through the rest, so a listing with thousands of reviews can never be fully downloaded this way (waiting longer doesn't change it). NextInQue keeps every review it has seen, so the list grows as Google's selection changes. To bring in your full history, use Import Old Reviews (CSV/Excel — thousands of rows in one go). Your overall star rating and total review count shown on the connection card always come from Google and include every review.
- Several branches? Your head office manages Google reviews for every location: add one API key once at the head office (it's used for all branches — branches don't need their own), then pick each location in the list at the top of the Google card and connect its listing. Each branch can use its own Google listing, or several can share one — your choice. Branch logins can see their reviews but can't change the connection. The review list shows every location together and can be filtered by location, searched by reviewer name or review text, and paged.
- Disconnecting is clean. Pressing Disconnect removes every review that was synced from that Google connection (and, for a single-location business, deletes the saved API key; a head office keeps its key so other locations keep syncing) (reviews from surveys, CSV imports or your own website are untouched). Reconnect any time to bring them back.
- Your overall rating is complete. The star average and total review count shown on the connection card come from Google and include every review.
- Checked about once a day, automatically. Sync Now checks immediately, up to once every 10 minutes.
- Replies are posted on Google. Google doesn't allow other apps to post replies, so use Draft with AI in NextInQue to write one, copy it, and paste it into Google Business Profile.
Bringing In Your Full Review History
The API key method shows the latest handful of reviews. To load all your existing Google reviews (for example 10,000+), use one of these:
- Import Old Reviews (available now). Go to Settings → Reputation → Reviews → Import Old Reviews and upload a CSV or Excel file of your reviews (reviewer name, star rating, review text, date). Thousands of rows import in one go, then the daily Google sync keeps new reviews flowing in.
- Getting that file from Google. Google Business Profile has no one-click “download all reviews as CSV” button. The free option is Google Takeout: sign in as the profile owner, choose the Business Profile data, and export. It arrives as JSON, which you convert to CSV (a spreadsheet tool or our support team can do this). Because Google changes Takeout, check what it currently offers for Business Profile. Paid review-management and export tools can also produce a CSV of all your reviews.
Recommended: Sign in with Google (All Reviews + Replies)
When your NextInQue account has Sign in with Google available, this is the best way to connect. You don't need an API key or a Google Cloud account — you just sign in with the Google account that owns or manages your Business Profile.
- Go to Settings → Reputation → Sync Reviews → Google Reviews and press Sign in with Google
- Choose the Google account that owns or manages your listing and allow NextInQue to read (and reply to) your reviews
- Back in NextInQue, pick your location from the list (the best match is marked ★) and press Connect & import reviews
- Every review is imported — the latest appear immediately and the full history (even 10,000+ reviews) fills in over the next few minutes in the background. New reviews then sync automatically every few hours
- Reply to any Google review straight from the review list with Post reply to Google
Several branches? The head office signs in once and then connects each location to its Google listing (the location picker at the top of the card). Branch logins can see their reviews but can't change the connection. Only listings the signed-in Google account manages can be connected, so you can only ever connect your own business. Remove Google sign-in stops syncing without deleting reviews already imported.
For the NextInQue Administrator: One-Time Google Setup
- Have a verified, complete Business Profile on Google for NextInQue itself (with your official website). Google recommends keeping it complete and up to date, and guides commonly mention it should have been active for around 60 days — confirm the current requirement on Google's prerequisites page.
- Use the right Google account: the account you apply from must be an owner or manager of that profile.
- Create a Google Cloud project at console.cloud.google.com (for example NextInQue) and note its Project Number.
- Request Business Profile API access with Google's contact form (“Application for Basic API Access”), entering that project number. Google reviews the request and replies by email. Until you are approved, requests from the project are refused.
- After approval, enable the APIs in the same project (APIs & Services → Library): My Business Account Management API, My Business Business Information API and Google My Business API (reviews are still served by the older v4 API — enable what Google's reference lists).
- Create the sign-in (OAuth): APIs & Services → OAuth consent screen (app name, support email, your domain, a public privacy policy) and add the scope
https://www.googleapis.com/auth/business.manage; then Credentials → Create credentials → OAuth client ID (type: Web application). Add this as an Authorized redirect URI:https://YOUR-API-DOMAIN/api/review-sync/connections/google/oauth/callback. Google may ask to verify the app before it can be used by everyone. - Give the server the three values as GitHub deploy secrets (they are already wired into the deploy workflows):
GOOGLE_REVIEWS_CLIENT_ID,GOOGLE_REVIEWS_CLIENT_SECRETandGOOGLE_REVIEWS_REDIRECT_URI(the same redirect URI as above), then redeploy. The Sign in with Google button appears for clients as soon as they are set. - Keep the client secret private (never in the frontend or a public repository). All clients share your project's request quota (a third-party guide says about 300 requests per minute once approved) — ample for scheduled syncs; ask Google for more if you grow a lot.
Troubleshooting
- “Google rejected your API key” — the key was mistyped or deleted; copy it again from Credentials in Google Cloud Console.
- “Places API isn't enabled” / “Billing isn't enabled” — enable Places API (New) and billing on the same Google Cloud project as the key (Step 1).
- “Key is restricted to certain websites or IPs” — edit the key and set Application restrictions to None; keep only the API restriction.
- “Awaiting approval” — the Google listing didn't match your registered details, so NextInQue is checking it. To speed this up, make sure your business name, address and phone in Settings → Business Profile match your Google listing, or contact Support.
- “Not approved” — NextInQue couldn't confirm the listing is yours (the reason is shown on the card). Disconnect and connect your own business's listing.
- “Google couldn't find that business” — the Place ID is mistyped or incomplete; copy it again from the Place ID Finder.
- “Reconnect needed” — your connection was made with the earlier sign-in method. Find your business again and press Connect; nothing is lost.
- A new review isn't showing — Google can take a while to publish it, and only shares a few per check. Try Sync Now after some time.
Review Sync — Your Own Backend
This is a separate integration from the reservation API above, and runs the opposite direction — instead of your system asking NextInQue to create something, your system tells NextInQue about reviews that already exist on your own backend (a website, POS, or booking system), so they show up in your Reviews dashboard next to Google, Yelp, and survey-collected ones.
Two independent modes — use either, or both:
- Push (webhook) — your backend calls NextInQue the moment a new review lands. Real-time.
- Pull (scheduled) — NextInQue calls a read endpoint on your backend every 6 hours, the same schedule Google/Yelp sync on.
Getting Your Webhook URL & Secret
- Log into your NextInQue dashboard
- Go to Settings → Reputation → Sync Reviews → Your Own Backend
- Click Generate Webhook URL — the URL and secret are shown once, copy them immediately
Push — Webhook
/webhook/custom/:connectionId:connectionId is part of the URL you were given — it identifies which of your locations this webhook is for. No API key header here; the secret itself (as a Bearer token) is what authenticates the call, since this endpoint has no dashboard session to check.
Request
POST https://nextinque.com/api/review-sync/webhook/custom/{connectionId}
Authorization: Bearer your_webhook_secret_here
Content-Type: application/json
{
"reviews": [
{
"externalReviewId": "your-system's-own-id-for-this-review",
"rating": 5,
"text": "Great service, highly recommend!",
"authorName": "Jane Doe",
"publishedAt": "2026-01-15T14:30:00.000Z"
}
]
}Field Reference
| Parameter | Required | Type | Description |
|---|---|---|---|
| externalReviewId | Required | string | Your own unique id for this review. Sending the same id again updates that review instead of creating a duplicate. |
| rating | Required | number (1–5) | Rounded and clamped to 1–5 if it arrives outside that range. |
| text | Optional | string | The written review, if any. Feeds automatic sentiment detection. |
| authorName | Optional | string | Display name of the reviewer. |
| publishedAt | Optional | ISO 8601 date string | When the review was actually left. Defaults to "now" (the sync time) if omitted. |
Up to 500 reviews per request. A row missing externalReviewId or with a non-numeric rating is silently dropped rather than failing the whole batch — check the response's count against how many you sent if you need to confirm everything landed.
Response 200
{ "count": 1 }Errors
| Code | Scenario | Message |
|---|---|---|
401 | Missing Authorization header | Missing webhook secret |
404 | Wrong secret, or connectionId doesn't exist / isn't a Custom connection | Unknown webhook |
429 | More than 60 requests/minute to the same connectionId | Too many requests. Please wait a moment and try again. |
A wrong secret and an unknown connectionId deliberately return the same 404 — this stops someone from using the error response to probe for valid connection ids.
Pull — Your Read Endpoint
Give NextInQue a URL (and, if your endpoint needs it, an access token) in Settings → Reputation → Sync Reviews → Your Own Backend — every 6 hours, NextInQue sends a request to it and expects the same shape back that the webhook above accepts as input:
(your URL)What NextInQue Sends
GET https://your-domain.com/whatever-path-you-gave-us
Authorization: Bearer your_configured_token (only if you set one)What Your Endpoint Should Return — 200
{
"reviews": [
{
"externalReviewId": "your-system's-own-id-for-this-review",
"rating": 5,
"text": "Great service, highly recommend!",
"authorName": "Jane Doe",
"publishedAt": "2026-01-15T14:30:00.000Z"
}
]
}Same field reference and malformed-row handling as the webhook above. Returning your full review history every time is fine — reviews are matched and updated by externalReviewId, so re-sending the same ones is a safe no-op, not a duplicate.
Need help with your integration?
Contact our team — we're happy to help you get set up.