PPrimeTaxiHub Pricing APIv1Admin console

Pricing API reference

Overview

One HTTPS + JSON API that tells your website or app whether a trip is serviceable and exactly what it costs. Any language that can send an HTTPS request can integrate.

Send coordinates, a vehicle code and a service type. The engine checks the pickup against geofenced service areas, applies outstation route rules, picks the live pricing version and returns an itemised fare with a quote ID. The engine is the source of truth for price — requests that include a fare are rejected.

Base URL   https://api.primetaxihub.com/api/v1
Format     JSON (UTF-8), request body ≤ 32 KB
Timezone   Send pickup_at as ISO-8601 with offset. Night/peak/weekend rules use the pickup's local time.

Authentication

Every request except /health needs your API key in the Authorization header (or X-API-Key):

Authorization: Bearer pth_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Keys are issued per client in the admin console and shown once. Keep them on your server. If a key is ever exposed in browser code or a repository, revoke it and issue a new one. Clients can additionally be restricted to IP addresses and browser origins.

Request signing (optional)

If your client has Require HMAC signature enabled, add two headers. The signature is hex(HMAC-SHA256(api_secret, timestamp + "." + raw_body)); timestamps older than 5 minutes are rejected, which blocks replays.

import crypto from "node:crypto";

const body = JSON.stringify(payload);
const ts = Math.floor(Date.now() / 1000).toString();
const sig = crypto.createHmac("sha256", process.env.PTH_API_SECRET).update(`${ts}.${body}`).digest("hex");

await fetch("https://api.primetaxihub.com/api/v1/fare/quote", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.PTH_API_KEY}`,
    "Content-Type": "application/json",
    "X-PTH-Timestamp": ts,
    "X-PTH-Signature": sig,
  },
  body, // send exactly the string you signed
});

Get a fare quote

POST /fare/quote

FieldTypeNotes
pickup{ lat, lng, address? }Required. The polygon decides serviceability, never the address.
drop{ lat, lng } | nullRequired except for hourly rentals.
vehiclestringVehicle code, e.g. sedan (see /vehicles).
service_typestringlocal, airport, outstation, hourly …
trip_typestringDefault one_way. round_trip doubles billable distance.
pickup_atISO-8601Default now. Up to 365 days ahead.
return_atISO-8601Round trips: decides the number of trip days.
hoursnumberHourly rentals.
waiting_minutesintegerExpected waiting time.
coupon_codestringInvalid coupons never fail the quote; see warnings.
{
  "pickup": { "lat": 28.6139, "lng": 77.2090, "address": "Connaught Place" },
  "drop":   { "lat": 28.4595, "lng": 77.0266 },
  "vehicle": "sedan",
  "service_type": "local",
  "trip_type": "one_way",
  "pickup_at": "2026-10-10T09:30:00+05:30",
  "coupon_code": "WELCOME10"
}

Response:

{
  "success": true,
  "quote_id": "QT-20261003-000001",
  "currency": "INR",
  "expires_at": "2026-10-03T09:30:00.000Z",
  "pickup_at": "2026-10-10T04:00:00.000Z",
  "service": { "type": "local", "name": "Local", "trip_type": "one_way" },
  "vehicle": { "code": "sedan", "name": "Sedan", "passenger_capacity": 4, "luggage_capacity": 2, "image_url": null },
  "location": { "pickup_area": "Delhi NCR", "drop_area": "Delhi NCR", "pickup_allowed": true, "drop_allowed": true,
                "pickup_airport": null, "drop_airport": null },
  "route": null,
  "distance": { "km": 28.4, "billable": 28.4, "unit": "KM", "duration_minutes": 72, "estimated": false },
  "pricing": { "plan": "delhi_local_sedan", "version": 2 },
  "fare": {
    "base_fare": 2500, "included_km": 80, "extra_km": 0, "extra_km_charge": 0,
    "time_charge": 0, "waiting_charge": 0, "airport_charge": 0, "night_charge": 0, "surcharge": 0,
    "toll": 0, "parking": 0, "state_tax": 0, "driver_allowance": 0, "other_charges": 0,
    "adjustments": 0, "discount": 200, "subtotal": 2300,
    "tax": 115, "taxes": [{ "name": "GST", "rate": 5, "type": "PERCENTAGE", "amount": 115 }],
    "round_off": 0, "total": 2415, "trip_days": 1
  },
  "warnings": [],
  "request_id": "6c1b2f7e-…"
}

Quotes expire (default 30 minutes). Store quote_id with the booking and call /quote/{id}/verify before confirming.

All endpoints

POST/fare/quoteCalculate a fare and create a quote. The response is the price — clients never send one.
POST/fare/recalculateRe-price an earlier quote with the current pricing version (e.g. after it expired). Returns a new quote id; the old one becomes superseded.
{ "quote_id": "QT-20261003-000001", "pickup_at": "2026-10-10T11:00:00+05:30" }
{ "success": true, "quote_id": "QT-20261003-000042", …, "recalculated_from": "QT-20261003-000001", "previous_total": 2415, "price_changed": false }
GET/quote/{quote_id}Retrieve one of your quotes, with status and validity.
POST/quote/{quote_id}/verifyCall just before confirming a booking: checks the quote is still valid and, optionally, that the amount you show matches.
{ "total": 2415 }
{ "success": true, "quote_id": "QT-…", "valid": true, "amount_matches": true, "total": 2415, "currency": "INR", "expires_at": "…" }
POST/location/validateIs pickup possible at this point? Returns the service area and airport, if any.
{ "point": { "lat": 28.5562, "lng": 77.1 }, "service_type": "airport" }
{ "success": true, "inside_service_area": true, "pickup_allowed": true, "service_available": true, "area": { "code": "delhi_ncr", "name": "Delhi NCR", … }, "airport": { "code": "DEL", … } }
POST/service-area/checkCheck pickup and drop together for a service — applies the drop policy (local) or route rules (outstation).
{ "pickup": { "lat": 28.61, "lng": 77.21 }, "drop": { "lat": 27.17, "lng": 78.0 }, "service_type": "local" }
{ "success": true, "pickup_allowed": true, "drop_allowed": false, "bookable": false, "reason": { "code": "DROP_LOCATION_NOT_ALLOWED", "message": "…" } }
POST/route/checkIs an outstation route served? Optionally include road distance.
{ "pickup": { "lat": 28.61, "lng": 77.21 }, "drop": { "lat": 26.91, "lng": 75.79 }, "service_type": "outstation", "trip_type": "one_way", "include_distance": true }
{ "success": true, "allowed": true, "route": { "name": "Delhi → Jaipur", … }, "distance": { "km": 268.3, "duration_minutes": 330 } }
GET/vehicles?service_area=delhi_ncrVehicle categories you can request (optionally only those available in an area).
GET/service-typesService types (local, airport, outstation, hourly …).
GET/trip-typesTrip types (one_way, round_trip …).
GET/citiesCities served for pickup or as outstation destinations.
GET/service-areas?include=polygonService areas, optionally with their polygons for drawing coverage maps.
GET/healthLiveness and database readiness. No authentication.

Errors

Every error uses the same envelope and an HTTP status that matches the problem:

{
  "success": false,
  "error": { "code": "OUTSIDE_SERVICE_AREA", "message": "Pickup location is outside our service area." },
  "request_id": "…"
}
CodeHTTPMeaning
INVALID_API_KEY401Missing, unknown or revoked key.
INVALID_SIGNATURE401Signing is required for this client and the signature or timestamp is wrong.
CLIENT_DISABLED403The API client was disabled by an administrator.
IP_NOT_ALLOWED403The caller's IP isn't on the client's whitelist.
ORIGIN_NOT_ALLOWED403A browser Origin header isn't in the client's allowed origins.
INVALID_REQUEST400Body failed validation. details.fields lists each problem.
INVALID_COORDINATES422Latitude/longitude out of range, or 0,0.
OUTSIDE_SERVICE_AREA422Pickup isn't inside any pickup-enabled service area.
DROP_LOCATION_NOT_ALLOWED422Drop violates the area's drop policy for local trips.
ROUTE_NOT_ALLOWED422Outstation route not served, blocked, or outside its distance limits.
VEHICLE_NOT_AVAILABLE422Unknown vehicle code, or not offered in the pickup area.
SERVICE_TYPE_NOT_AVAILABLE422Unknown service type, or not offered in the pickup area.
TRIP_TYPE_NOT_AVAILABLE422Unknown trip type code.
PRICING_PLAN_NOT_FOUND422No live pricing matches this trip.
NO_ROUTE_FOUND422No drivable route, or the routing service is down.
QUOTE_NOT_FOUND404No such quote for your client.
QUOTE_EXPIRED410The quote expired or was superseded — recalculate.
NOT_FOUND404Unknown endpoint.
METHOD_NOT_ALLOWED405Wrong HTTP method.
PAYLOAD_TOO_LARGE413Body exceeds 32 KB.
RATE_LIMIT_EXCEEDED429Too many requests. Wait Retry-After seconds.
SERVER_ERROR500Unexpected error. Quote request_id when contacting support.

Rate limits

Each client has a per-minute limit (default 60). Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. Over the limit you get 429 RATE_LIMIT_EXCEEDED with Retry-After. Ask your account manager to raise the limit.

Code examples

curl -X POST https://api.primetaxihub.com/api/v1/fare/quote \
  -H "Authorization: Bearer $PTH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"pickup":{"lat":28.6139,"lng":77.2090},"drop":{"lat":28.4595,"lng":77.0266},
       "vehicle":"sedan","service_type":"local","trip_type":"one_way"}'

Integration checklist

  • Keep the API key and secret on your server; the browser talks to your backend.
  • Show the fare from the response exactly — never compute or round it yourself.
  • Save quote_id with the booking and verify it before confirming payment.
  • Handle OUTSIDE_SERVICE_AREA, ROUTE_NOT_ALLOWED and VEHICLE_NOT_AVAILABLE with clear messages to your customer.
  • Log request_id from every response; support uses it to find the exact calculation.
  • Retry 429 and 5xx with backoff. Don't retry 4xx validation errors unchanged.