Overview
Build your own astrology app without building an astrology backend: list our pandits in your app and let your users chat with them. Every reply comes from the same chat engine as the Apna AI Pandit app — it reads the user's real birth chart (planets, houses, running dasha, transits), remembers the conversation and earlier facts the user shared, and answers in the user's language. You only send messages and show replies.
Same key, account and wallet as the Report API (x-api-key header, keys on the APIs page). Keep the key on your server — your app talks to your server, your server talks to us.
GET /public/pandits→ show pandits.POST /public/chat/sessionswith the user's birth details + first question →sessionId+ reply.POST /public/chat/sessions/{sessionId}/messagesfor every next message.POST /public/chat/sessions/{sessionId}/endwhen the user closes the chat.
Pandit list
GET https://apnaaipandit.com/api/v1/public/pandits?language=hi-IN (language optional)
→ 200 { "items": [ { "id", "order", "name", "slug", "imageUrl", "shortBio", "bio", "specializations": ["Marriage", …],
"languages": ["hi-IN"], "experienceYears", "pricePerMinute": 6, "rating": 4.8, "reviews",
"consultations", "online", "featured", "recommended", "greeting" }, … ],
"currency": "INR", "minSessionMinutes": 5 }
Items are already in our display order (order 1 = first). Cache the list for a few minutes.
Start a session
POST https://apnaaipandit.com/api/v1/public/chat/sessions
{
"panditId": "…",
"user": {
"id": "your-user-42", // YOUR id for this person (1–64 chars A-Z a-z 0-9 _ . : @ -)
"name": "Rahul",
"gender": "male", // male | female | other (optional)
"language": "hi-IN", // reply language (default hi-IN) — see below
"birth": { "date": "1995-08-21", "time": "10:30", // time optional: omit when unknown
"timezone": "Asia/Kolkata", "latitude": 28.6139, "longitude": 77.209, "place": "New Delhi" }
},
"message": "Meri shaadi kab hogi?" // 1–2000 characters
}
→ 200 { "sessionId", "messageId", "reply", "paragraphs": ["…", "…"],
"billing": { "ratePerMinute": 6, "sessionStartedAt", "minutesBilled": 1, "chargedNow": 6, "walletBalance": 494 },
"user": { "id": "your-user-42", "profileName": "Rahul" } }
The same user.id always maps to the same chart and memory, across sessions. Send corrected birth details with the same id and the chart is updated. Languages: hi-IN (Hindi, Devanagari), hi-Latn (Hinglish), en-IN, bn-IN, bn-Latn, ta-IN, ta-Latn, te-IN, te-Latn, mr-IN, mr-Latn.
Replies take about 3–10 s (use a 120 s timeout). paragraphs = the reply split on blank lines, if you want to show it as several chat bubbles like our app. Like a real consultation, Pandit ji may end a reply with a short question (for example whether the person is single) — just send the user's answer as the next message.
Send a message
POST https://apnaaipandit.com/api/v1/public/chat/sessions/{sessionId}/messages
{ "message": "Abhi single hoon" }
→ 200 { "sessionId", "messageId", "reply", "paragraphs", "billing": { … } }
One message at a time per session: a second message while Pandit ji is still answering gets 409 SESSION_BUSY.
History, suggestions, status, end
GET /public/chat/sessions/{sessionId} → status, user, pandit, messages, minutesBilled, amountBilled, walletBalance
GET /public/chat/sessions/{sessionId}/messages?limit=30 → { items: [ { id, role: "user" | "pandit", content, createdAt } ], hasMore }
&before={messageId} → older page
GET /public/chat/sessions/{sessionId}/suggestions → { suggestions: ["…", "…"] } (tap-to-send ideas for the next message, free)
POST /public/chat/sessions/{sessionId}/end → { status: "ended", chargedNow, minutesBilled, amountBilled, walletBalance }
Billing & wallet
- Price = the pandit's
pricePerMinute(the same as in our app), charged from your Apna AI Pandit wallet. Every started minute counts (1 min 20 s = 2 min). - To start, the wallet must hold at least
pricePerMinute × minSessionMinutes; otherwise402 INSUFFICIENT_BALANCEand nothing is charged. - Minutes are charged when a message arrives (and on
end) — the time since the session started that was not billed yet. No message = no further charge. - Wallet runs out mid-session → that message gets
402and the session ends; start a new one after recharging. - If our AI cannot answer (
503 PANDIT_UNAVAILABLE), the charge for that message is returned automatically. - Sessions idle for 20 minutes end automatically (no charge for the idle time).
- Pandit list, history, status and suggestions are free.
Limits & abuse protection
- Per-minute request limit per account (default 30 / min, shared with the Report API) →
429 RATE_LIMITED. Ask support to raise it. - Too many requests with wrong keys from one IP → that IP is blocked for the rest of the minute (
429 TOO_MANY_FAILED_ATTEMPTS). - Keys are compared in constant time and stored only as a hash; sessions of other accounts always look like
404. - Messages ≤ 2000 characters, request body ≤ 100 KB, one running reply per session.
- Pandit ji never gives medical, legal or financial guarantees and stays on astrology; abusive use can get the account suspended.
Errors
Same envelope as the Report API: { "success": false, "data": null, "error": { "code": "…", "message": "…" } }
| HTTP | code | Meaning |
|---|---|---|
| 400 | VALIDATION_ERROR | Body / query field missing or wrong format (message lists the fields); unknown fields are rejected |
| 400 | INVALID_BIRTH_DATA | Impossible date / time, unknown IANA timezone |
| 401 | INVALID_API_KEY | Missing, malformed, wrong or revoked x-api-key |
| 402 | INSUFFICIENT_BALANCE | Wallet below the minimum to start (rate × minimum minutes) or to continue — recharge; the session ends on low balance |
| 403 | CLIENT_SUSPENDED / ACCOUNT_INACTIVE / ACCOUNT_NOT_LINKED | API account or the app account behind it is blocked / missing |
| 403 | CHAT_NOT_ALLOWED | Your account is limited to other products — ask support to add "chat" |
| 404 | PANDIT_NOT_FOUND | panditId unknown or the pandit is not available |
| 404 | SESSION_NOT_FOUND / MESSAGE_NOT_FOUND | Unknown session id (or a session of another account) / unknown "before" message id |
| 409 | SESSION_BUSY | Pandit ji is still answering the previous message of this session (or the same user is starting a session) — wait for the reply |
| 410 | SESSION_ENDED | Session ended (closed, low balance or idle too long) — start a new session; the same user.id keeps the chart and memory |
| 429 | RATE_LIMITED | Per-minute request limit of your account exceeded (shared with the Report API) |
| 429 | TOO_MANY_FAILED_ATTEMPTS | Too many failed authentications from your IP this minute |
| 503 | PANDIT_UNAVAILABLE | AI providers did not answer — send the message again (the charge for this message was returned) |
| 500 | INTERNAL_ERROR | Unexpected error — contact support with the time and session id |
Code examples
# 1. pandits (show them in your app: photo, specialities, price / min)
curl https://apnaaipandit.com/api/v1/public/pandits -H "x-api-key: $API_KEY"
# 2. start a session with the first question
curl -X POST https://apnaaipandit.com/api/v1/public/chat/sessions \
-H "Content-Type: application/json" -H "x-api-key: $API_KEY" \
-d '{ "panditId": "PANDIT_ID",
"user": { "id": "your-user-42", "name": "Rahul", "gender": "male", "language": "hi-IN",
"birth": { "date": "1995-08-21", "time": "10:30", "timezone": "Asia/Kolkata",
"latitude": 28.6139, "longitude": 77.209, "place": "New Delhi" } },
"message": "Meri shaadi kab hogi?" }'
# 3. next messages
curl -X POST https://apnaaipandit.com/api/v1/public/chat/sessions/SESSION_ID/messages \
-H "Content-Type: application/json" -H "x-api-key: $API_KEY" -d '{ "message": "Abhi single hoon" }'
# 4. end (bills the last started minute)
curl -X POST https://apnaaipandit.com/api/v1/public/chat/sessions/SESSION_ID/end -H "x-api-key: $API_KEY"<?php
function call($method, $path, $body = null) {
$ch = curl_init('https://apnaaipandit.com/api/v1' . $path);
curl_setopt_array($ch, [CURLOPT_CUSTOMREQUEST => $method, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 120,
CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'x-api-key: ' . getenv('API_KEY')],
CURLOPT_POSTFIELDS => $body ? json_encode($body) : null]);
$res = json_decode(curl_exec($ch), true);
if (!$res['success']) throw new Exception($res['error']['code'] . ': ' . $res['error']['message']);
return $res['data'];
}
$pandits = call('GET', '/public/pandits')['items'];
$s = call('POST', '/public/chat/sessions', [
'panditId' => $pandits[0]['id'],
'user' => ['id' => 'your-user-42', 'name' => 'Rahul', 'language' => 'hi-IN',
'birth' => ['date' => '1995-08-21', 'time' => '10:30', 'timezone' => 'Asia/Kolkata', 'latitude' => 28.6139, 'longitude' => 77.209, 'place' => 'New Delhi']],
'message' => 'Meri shaadi kab hogi?']);
echo $s['reply'];
$r = call('POST', "/public/chat/sessions/{$s['sessionId']}/messages", ['message' => 'Abhi single hoon']);
call('POST', "/public/chat/sessions/{$s['sessionId']}/end");import os, requests
B, H = 'https://apnaaipandit.com/api/v1', {'x-api-key': os.environ['API_KEY']}
def call(method, path, body=None):
r = requests.request(method, B + path, json=body, headers=H, timeout=120).json()
if not r['success']: raise RuntimeError(f"{r['error']['code']}: {r['error']['message']}")
return r['data']
pandit = call('GET', '/public/pandits')['items'][0]
s = call('POST', '/public/chat/sessions', {
'panditId': pandit['id'],
'user': {'id': 'your-user-42', 'name': 'Rahul', 'language': 'hi-IN',
'birth': {'date': '1995-08-21', 'time': '10:30', 'timezone': 'Asia/Kolkata',
'latitude': 28.6139, 'longitude': 77.209, 'place': 'New Delhi'}},
'message': 'Meri shaadi kab hogi?'})
print(s['reply'])
print(call('POST', f"/public/chat/sessions/{s['sessionId']}/messages", {'message': 'Abhi single hoon'})['reply'])
call('POST', f"/public/chat/sessions/{s['sessionId']}/end")const B = 'https://apnaaipandit.com/api/v1';
async function call(method, path, body) {
const r = await fetch(B + path, { method, headers: { 'Content-Type': 'application/json', 'x-api-key': process.env.API_KEY }, body: body && JSON.stringify(body) });
const res = await r.json();
if (!res.success) throw new Error(`${res.error.code}: ${res.error.message}`);
return res.data;
}
const [pandit] = (await call('GET', '/public/pandits')).items;
const s = await call('POST', '/public/chat/sessions', {
panditId: pandit.id,
user: { id: 'your-user-42', name: 'Rahul', language: 'hi-IN',
birth: { date: '1995-08-21', time: '10:30', timezone: 'Asia/Kolkata', latitude: 28.6139, longitude: 77.209, place: 'New Delhi' } },
message: 'Meri shaadi kab hogi?',
});
console.log(s.reply, s.billing);
const next = await call('POST', `/public/chat/sessions/${s.sessionId}/messages`, { message: 'Abhi single hoon' });
await call('POST', `/public/chat/sessions/${s.sessionId}/end`);
Privacy
Birth details and chat messages are stored with the conversation so Pandit ji can remember it (the same way as for app users) and are used only to answer that user. Your usage log contains request ids, times and amounts — never message text. Tell your users that their questions are answered by an AI astrologer. Guidance for self-reflection, not medical, legal or financial advice.