Brand Partner API¶
mintbot orders बनाने, उनका status poll करने, और lifecycle events receive करने के लिए एक छोटा, predictable REST API। JSON in, JSON out। Bearer-token auth। Idempotent writes। Signed webhooks।
API access dashboard Webhooks पर जाएँ
एक नज़र में¶
| Base URL | https://mint.mintbot.ai/api/v1 |
| Auth | `Authorization: Bearer *** |
| Idempotency | हर POST पर Idempotency-Key: <uuid> |
| Content type | application/json |
| Rate limit | 120 req / 60 s per partner |
| Webhooks | HMAC-SHA256 से signed, 7 बार तक retry |
Authentication¶
हर request Authorization header में partner API key भेजती है। Key dashboard में generate या rotate करें।
Authorization: Bearer mo_liv...xxxx
Content-Type: application/json
Rotation में grace window नहीं है
Key rotate करने से previous key atomically revoke हो जाती है। Rotate पर click करने से पहले अपने config में value swap करने की planning करें।
Idempotency¶
हर POST के लिए Idempotency-Key header चाहिए। अलग-अलग request के लिए कोई भी UUID चलेगा।
- हम response को 24 hours तक cache करते हैं। Same key के साथ retry original response को
Idempotent-Replay: trueके साथ replay करता है। - Same key को different body के साथ reuse करने पर
409 idempotency_key_mismatchreturn होता है।
Orders¶
Order बनाएँ¶
POST /orders
Order बनाता है और Stripe Checkout URL return करता है। Payment confirm होते ही mintbot agent provision करता है और partner-cut revenue event automatically record हो जाता है।
Request
{
"tier": "s1",
"duration_months": 1,
"credit_usd": 10,
"language": "en",
"external_id": "your-side-id",
"success_url": "https://your.app/thanks?id={ORDER_ID}",
"cancel_url": "https://your.app/cart",
"webhook_url": "https://your.app/mintbot-webhook"
}
tiertrial,s1,s2,s4में से एक।duration_months- सर्वर जीवनकाल कैलेंडर महीनों में।
1,3, या12में से एक होना चाहिए। credit_usd- Optional. Order के साथ bundled pre-funded chat credit।
language- Optional. Stripe Checkout locale और welcome-email language को affect करता है।
external_id- Optional. हर webhook और order response में वापस echo होता है — इसका इस्तेमाल mintbot orders को अपने system की rows से जोड़ने के लिए करें।
success_url·cancel_url- Stripe Checkout return URLs।
{ORDER_ID}server-side substitute होता है। webhook_url- Optional. Partner-level webhook URL का per-order override।
Response — 201 Created
{
"id": 42,
"tier": "s1",
"duration_months": 1,
"credit_usd": 10,
"amount_cents": 1200,
"currency": "usd",
"status": "awaiting_payment",
"checkout_url": "https://checkout.stripe.com/c/pay/cs_test_…",
"panel_url": null,
"expires_at": null,
"language": "en",
"external_id": "your-side-id",
"created_at": "2026-05-16 09:58:00",
"paid_at": null
}
Example
curl -X POST https://mint.mintbot.ai/api/v1/orders \
-H "Authorization: Bearer *** \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"tier": "s1",
"duration_months": 1,
"credit_usd": 10,
"success_url": "https://your.app/thanks?id={ORDER_ID}",
"cancel_url": "https://your.app/cart"
}'
import os, uuid, requests
r = requests.post(
"https://mint.mintbot.ai/api/v1/orders",
headers={
"Authorization": f"Bearer {os.environ['MINTBOT_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"tier": "s1",
"duration_months": 1,
"credit_usd": 10,
"success_url": "https://your.app/thanks?id={ORDER_ID}",
"cancel_url": "https://your.app/cart",
},
timeout=10,
)
r.raise_for_status()
order = r.json()
redirect_to = order["checkout_url"]
Order लें¶
GET /orders/{id}
एक single order को उसके mintbot id से fetch करता है। POST /orders जैसी same shape return करता है।
curl https://mint.mintbot.ai/api/v1/orders/42 \
-H "Authorization: Bearer ***
Orders list करें¶
GET /orders
Cursor-paginated list, newest first।
Query parameters
status- Optional.
awaiting_payment,completed,deployed,deploy_failed, याexpiredसे filter करें। cursor- Optional. Continue करने के लिए previous page से
next_cursorpass करें।
Response
{
"items": [ /* OrderResponse … */ ],
"next_cursor": "37"
}
जब और pages नहीं होते, next_cursor null होता है।
Order renew करें¶
POST /orders/{id}/renew
Existing agent को another duration_months के लिए extend करता है। Infra-only — fresh chat credit bundled नहीं होता। New order id और fresh Stripe Checkout URL return करता है।
Request
{
"duration_months": 1,
"external_id": "your-side-id",
"success_url": "https://your.app/thanks?id={ORDER_ID}",
"cancel_url": "https://your.app/account"
}
Revenue¶
Revenue पढ़ें¶
GET /revenue
Totals plus latest 200 ledger events।
Query parameters
include_paid- Optional, default
true. सिर्फ वे events देखने के लिएfalseset करें जिनका payout अभी नहीं हुआ है।
Response
{
"currency": "usd",
"gross_cents": 12000,
"partner_cut_cents": 2000,
"mintbot_cut_cents": 10000,
"unpaid_cents": 800,
"events": [
{
"id": 7,
"order_id": 42,
"kind": "order_paid",
"gross_cents": 1200,
"partner_cut_cents": 200,
"mintbot_cut_cents": 1000,
"currency": "usd",
"created_at": "2026-05-16 09:58:00",
"payout_id": null,
"payout_at": null
}
]
}
Partner profile¶
Profile लें¶
GET /partner
आपकी partner profile और unpaid balance echo करता है — अपने admin UI के अंदर earnings दिखाने के लिए handy है, उन्हें खुद store किए बिना।
Response
{
"id": 12,
"email": "you@kliendifirma.com",
"pricing_currency": "usd",
"balance_unpaid_cents": 800,
"webhook_url": "https://your.app/mintbot-webhook",
"api_key_prefix": "mo_live_a12b"
}
Webhooks¶
जब किसी order के साथ कुछ होता है, हम आपके configured webhook URL पर signed JSON event POST करते हैं।
Event types¶
| Event | कब fire होता है |
|---|---|
order.created |
Stripe Checkout session minted, payment का इंतज़ार। |
order.paid |
Stripe ने payment confirm किया। Revenue event recorded। |
order.cancelled |
Order timed out या explicitly cancelled। |
agent.provisioning_started |
इस order के लिए deploy pipeline शुरू हुई। |
agent.ready |
Deploy successful। Payload में panel_url और expires_at हैं। |
agent.failed |
Deploy pipeline errored। टूटे हुए step के लिए error field check करें। |
agent.expired |
Agent TTL elapsed। Partner POST /orders/{id}/renew से renew कर सकता है। |
Delivery & retries¶
- Exponential schedule पर 7 attempts तक:
0s, 30s, 2m, 10m, 1h, 6h, 24h। - Last attempt के बाद delivery
exhaustedmark हो जाती है और retry बंद हो जाता है। - Acknowledge करने के लिए 10 seconds के अंदर
2xxstatus के साथ respond करें।
Request headers¶
Content-Type: application/json
User-Agent: mintbot-webhook/1.0
X-Mintbot-Signature: t=<unix_ts>,v1=<hex_hmac_sha256>
X-Mintbot-Event-Id: evt_42_order.paid_1747371234567
X-Mintbot-Event-Type: order.paid
Sample payload — order.paid¶
{
"id": 42,
"tier": "s1",
"duration_months": 1,
"credit_usd": 10,
"amount_cents": 1200,
"currency": "usd",
"status": "completed",
"external_id": "your-side-id",
"paid_at": "2026-05-16 10:02:14"
}
Signature verify करना¶
Signature HMAC-SHA256(secret, "{timestamp}.{raw_body}") है। हमेशा raw request body verify करें — parsed JSON को re-serialise करने से comparison टूट जाएगा।
import hmac, hashlib, time
def verify(secret: str, body: bytes, header: str, tolerance: int = 300) -> bool:
try:
ts_part, v1_part = header.split(",", 1)
ts = int(ts_part.split("=", 1)[1])
sig = v1_part.split("=", 1)[1]
except Exception:
return False
if abs(int(time.time()) - ts) > tolerance:
return False
expected = hmac.new(
secret.encode(),
f"{ts}.".encode() + body,
hashlib.sha256,
).hexdigest()
return hmac.compare_digest(expected, sig)
const crypto = require("crypto");
function verify(secret, rawBody, header, toleranceSec = 300) {
const [tsPart, v1Part] = header.split(",");
const ts = Number(tsPart.split("=")[1]);
const sig = v1Part.split("=")[1];
if (Math.abs(Date.now() / 1000 - ts) > toleranceSec) return false;
const expected = crypto
.createHmac("sha256", secret)
.update(`${ts}.`)
.update(rawBody)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected, "hex"),
Buffer.from(sig, "hex"),
);
}
Idempotent receivers
X-Mintbot-Event-Id को अपनी dedup key के रूप में use करें — retries same id reuse करते हैं, इसलिए उस column पर row-level INSERT … ON CONFLICT DO NOTHING आपके handler को safe रखता है।
Errors¶
हर error response एक stable code carry करता है जिस पर आप programmatically branch कर सकते हैं। message field human-readable hint है और releases के बीच बदल सकता है। request_id, X-Request-Id response header को echo करता है — इसे support tickets में include करें।
{
"error": {
"code": "invalid_api_key",
"message": "API key is unknown or revoked.",
"request_id": "f0c2d6c4-…"
}
}
| Code | Meaning |
|---|---|
unauthenticated |
Missing या malformed Authorization header। |
invalid_api_key |
API key unknown है या rotate होकर बाहर हो गई है। |
rate_limited |
Per-partner या per-IP rate limit exceeded — Retry-After देखें। |
missing_idempotency_key |
Idempotency-Key के बिना POST request। |
idempotency_key_mismatch |
Same key different request body के साथ reuse हुई। |
validation_error |
Request body schema validation fail हुआ। |
not_found |
Resource मौजूद नहीं है या आपके partner से belong नहीं करता। |
payment_gateway_error |
Stripe ने Checkout session creation reject किया। |
Rate limits¶
- 120 requests / 60 s rolling window, per partner। Burst और steady-state same bucket share करते हैं।
- 60 requests / 60 s unauthenticated और failed-auth requests के लिए separate per-IP bucket — bearer brute-force को partner quota consume करने से रोकता है।
- Excess requests
429 rate_limitedके साथRetry-Afterheader return करती हैं (back off करने के seconds)।
Help चाहिए?¶
ये docs उन partners के लिए लिखे गए हैं जो API सच में इस्तेमाल करते हैं। अगर कुछ missing, confusing, या stale है, तो अपने mintbot agent को बताएँ — वे feedback forward करेंगे और हम page update कर देंगे।