Brand Partner API¶
mintbot orders তৈরি করা, তাদের status poll করা, এবং lifecycle events গ্রহণ করার জন্য ছোট, 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 | প্রতি partner 120 req / 60 s |
| Webhooks | HMAC-SHA256 দিয়ে signed, সর্বোচ্চ 7 বার retry |
Authentication¶
প্রতিটি request Authorization header-এ একটি partner API key পাঠায়। dashboard-এ key generate বা rotate করুন।
Authorization: Bearer mo_liv...xxxx
Content-Type: application/json
Rotation-এর কোনো grace window নেই
Key rotate করলে আগের key atomically revoke হয়। Rotate-এ click করার আগে আপনার config-এ value swap করার পরিকল্পনা করুন।
Idempotency¶
প্রতিটি POST-এর জন্য Idempotency-Key header দরকার। আলাদা request প্রতি যেকোনো UUID কাজ করে।
- আমরা response 24 hours cache করি। একই key দিয়ে retry করলে original response
Idempotent-Replay: trueসহ replay হয়। - একই 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 back হয় — আপনার নিজের system-এর rows-এর সঙ্গে mintbot orders thread করতে এটি ব্যবহার করুন।
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}
তার mintbot id দিয়ে একটি single order fetch করে। POST /orders-এর মতো একই 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"
}
আর কোনো page না থাকলে next_cursor হলো null।
Order renew করুন¶
POST /orders/{id}/renew
Existing agent-কে আরেক 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 এবং সর্বশেষ 200 ledger events।
Query parameters
include_paid- Optional, default
true. শুধু এখনও paid out হয়নি এমন events দেখতেfalseset করুন।
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 দেখাতে সুবিধাজনক, নিজে 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, awaiting payment. |
order.paid |
Stripe payment confirm করেছে। Revenue event recorded। |
order.cancelled |
Order timed out হয়েছে বা explicitly cancelled হয়েছে। |
agent.provisioning_started |
এই order-এর জন্য deploy pipeline started। |
agent.ready |
Deploy succeeded। 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 হিসেবে ব্যবহার করুন — retries একই id reuse করে, তাই ওই column-এ row-level INSERT … ON CONFLICT DO NOTHING আপনার handler নিরাপদ রাখে।
Errors¶
প্রতিটি error response একটি stable code বহন করে, যাতে আপনি programmatically branch করতে পারেন। message field human-readable hint এবং releases-এর মধ্যে change হতে পারে। 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 |
Authorization header missing বা malformed। |
invalid_api_key |
API key unknown বা rotate out হয়ে গেছে। |
rate_limited |
Per-partner বা per-IP rate limit exceeded — Retry-After দেখুন। |
missing_idempotency_key |
Idempotency-Key ছাড়া POST request। |
idempotency_key_mismatch |
একই key different request body দিয়ে reuse করা হয়েছে। |
validation_error |
Request body schema validation failed। |
not_found |
Resource নেই বা আপনার partner-এর নয়। |
payment_gateway_error |
Stripe Checkout session creation reject করেছে। |
Rate limits¶
- প্রতি partner 120 requests / 60 s rolling window। Burst এবং steady-state একই bucket share করে।
- Unauthenticated এবং failed-auth requests-এর জন্য আলাদা per-IP bucket: 60 requests / 60 s — bearer brute-force-কে partner quota খেয়ে ফেলা থেকে আটকায়।
- Excess requests
Retry-Afterheader (কত seconds back off করতে হবে) সহ429 rate_limitedreturn করে।
Help দরকার?¶
এই ডকস সেই partners-দের জন্য লেখা যারা সত্যিই API ব্যবহার করেন। কিছু missing, confusing, বা stale হলে আপনার mintbot agent-কে বলুন — তারা feedback forward করবে এবং আমরা page update করব।