iQuanta · Integration Guide
Create a booking with no real Razorpay payment behind it — a free trial, a WBL/scholarship seat, anything booked outside the normal checkout flow. It's treated exactly like a real booking everywhere else: it shows up in Booking Management and the calendar, gets a lead record, and a Google Meet link is generated automatically.
Every request needs an X-API-Key header set to the key we'll send you separately (never in this document, and never in chat/email in plaintext if you can help it — use a secrets manager or a one-time share link). It's the same platform-wide key used by the Lead Capture API — one key, valid for every external-facing endpoint.
Call this from your server, not the browser. Anything sent to the page's own JavaScript can be read by anyone who opens dev tools. Have your form or workflow post to your own backend, and have your backend call us with the key attached.
A missing or wrong key gets 401 Unauthorized. If the key hasn't been configured on our end yet, you'll get 503 Service Unavailable instead.
phone, selectDate, and time are the only required fields — enough to make this a real, schedulable session. Everything else fills in details a real checkout would normally have collected.
| Field | Type | Notes | |
|---|---|---|---|
phone | string | Required | Any format — with or without +91, spaces, dashes. Normalized to the last 10 digits, same as everywhere else in the app, so it matches an existing lead if one exists. |
selectDate | string | Required | Must look like "25 Aug 2026" — day, 3-letter month, 4-digit year. |
time | string | Required | A precise start time like "11:37 AM - 12:22 PM" — must start with H:MM AM or H:MM PM. Not restricted to fixed slots. |
name | string | Optional | The student's name. |
email | string | Optional | Stored lowercase. |
amount | number | Optional | Rupees, not paise (e.g. 499, not 49900). Defaults to 0 for a free session. |
description | string | Optional | Internal note about what this booking is for. |
mentorEmail | string | Optional | Assigns the mentor on the lead right away, instead of leaving it to the default-assignment rule. |
{
"name": "Ananya Rao",
"phone": "9876543210",
"email": "ananya.rao@example.com",
"selectDate": "25 Aug 2026",
"time": "11:00 AM - 12:00 PM",
"amount": 0,
"description": "Free trial — referred by Shubhangi",
"mentorEmail": "shubhangi@iquanta.pro"
}
{
"paymentId": "manual_mt1nsco66emegf"
}
That id is how this booking is addressed everywhere else — the detail drawer, reschedule, status changes, the Meet link.
{ "error": "Session date must be in the form \"18 Aug 2026\"." }
{ "error": "Invalid or missing X-API-Key." }
{ "error": "Manual Booking API is not configured." }
Call this endpoint with your key attached, whenever a free trial or scholarship seat gets booked on your end.
The booking appears immediately in the dashboard — Booking Management, the calendar, and the lead's timeline all pick it up right away.
curl -X POST https://razorpay-dashboard-4cba2.web.app/api/public/bookings \ -H "Content-Type: application/json" \ -H "X-API-Key: YOUR_KEY_HERE" \ -d '{"name":"Ananya Rao","phone":"9876543210","selectDate":"25 Aug 2026","time":"11:00 AM - 12:00 PM"}'
await fetch('https://razorpay-dashboard-4cba2.web.app/api/public/bookings', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-API-Key': process.env.IQUANTA_BOOKINGS_KEY }, body: JSON.stringify({ name, phone, selectDate, time, amount: 0 }) });
// requires the cURL extension $ch = curl_init('https://razorpay-dashboard-4cba2.web.app/api/public/bookings'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', 'X-API-Key: ' . getenv('IQUANTA_BOOKINGS_KEY') ]); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([ 'name' => $name, 'phone' => $phone, 'selectDate' => $selectDate, 'time' => $time ])); $response = curl_exec($ch);
This runs through the exact same code path a real Razorpay webhook payment does — it's built into a payment-shaped record with a synthetic id (prefixed manual_, so it never collides with a real pay_... id), marked captured, and upserted the normal way. That means: a lead is found or created by phone, the booking gets the default status (usually "Booked"), and a Google Meet link is generated the same way it would be for a paid session — all with nothing special-cased for the manual case.
Calling this twice with the same details doesn't merge or dedupe — each call creates a brand-new booking with its own id. There's no idempotency key here, unlike the Lead Capture API's phone-based merge.