Brand Partner API¶
mintbot の注文作成、ステータス確認、ライフサイクルイベントの受信に使える、小さく予測しやすい REST API です。入力も出力も JSON。Bearer-token 認証。冪等な書き込み。署名付き Webhooks。
概要¶
| Base URL | https://mint.mintbot.ai/api/v1 |
| 認証 | `Authorization: Bearer *** |
| 冪等性 | すべての POST に Idempotency-Key: <uuid> |
| Content type | application/json |
| レート制限 | パートナーごとに 120 req / 60 s |
| Webhooks | HMAC-SHA256 で署名、最大 7 回再試行 |
認証¶
すべてのリクエストでは、Authorization ヘッダーでパートナー API キーを送信します。キーは ダッシュボード で生成またはローテーションできます。
Authorization: Bearer mo_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
ローテーションに猶予期間はありません
キーをローテーションすると、以前のキーはアトミックに失効します。Rotate をクリックする前に、設定内の値を差し替える計画を立ててください。
冪等性¶
すべての POST には Idempotency-Key ヘッダーが必要です。個別のリクエストごとに任意の UUID を使えます。
- レスポンスは 24 時間キャッシュされます。同じキーで再試行すると、元のレスポンスが
Idempotent-Replay: true付きで再生されます。 - 同じキーを異なる body で再利用すると、
409 idempotency_key_mismatchが返ります。
注文¶
注文を作成する¶
POST /orders
注文を作成し、Stripe Checkout URL を返します。支払いが確認されると、mintbot が agent をプロビジョニングし、パートナー取り分の収益イベントが自動的に記録されます。
リクエスト
{
"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- 任意。 注文にバンドルされる事前購入済みチャットクレジットです。
language- 任意。 Stripe Checkout のロケールとウェルカムメールの言語に影響します。
external_id- 任意。 すべての webhook と注文レスポンスでそのまま返されます — mintbot の注文を自社システム内の行にひも付けるために使えます。
success_url·cancel_url- Stripe Checkout の戻り先 URL です。
{ORDER_ID}はサーバー側で置き換えられます。 webhook_url- 任意。 パートナーレベルの webhook URL を注文単位で上書きします。
レスポンス — 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
}
例
curl -X POST https://mint.mintbot.ai/api/v1/orders \
-H "Authorization: Bearer $MINTBOT_API_KEY" \
-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"]
注文を取得する¶
GET /orders/{id}
mintbot id で単一の注文を取得します。POST /orders と同じ形式を返します。
curl https://mint.mintbot.ai/api/v1/orders/42 \
-H "Authorization: Bearer $MINTBOT_API_KEY"
注文を一覧する¶
GET /orders
カーソルページネーション付きの一覧です。新しいものが先に表示されます。
クエリパラメーター
status- 任意。
awaiting_payment、completed、deployed、deploy_failed、expiredで絞り込みます。 cursor- 任意。 続きを取得するには、前のページの
next_cursorを渡します。
レスポンス
{
"items": [ /* OrderResponse … */ ],
"next_cursor": "37"
}
ページがもうない場合、next_cursor は null です。
注文を更新する¶
POST /orders/{id}/renew
既存の agent をさらに duration_months 延長します。インフラのみです — 新しいチャットクレジットはバンドルされません。新しい注文 id と新しい Stripe Checkout URL を返します。
リクエスト
{
"duration_months": 1,
"external_id": "your-side-id",
"success_url": "https://your.app/thanks?id={ORDER_ID}",
"cancel_url": "https://your.app/account"
}
収益¶
収益を読む¶
GET /revenue
合計と最新 200 件の ledger イベントを返します。
クエリパラメーター
include_paid- 任意、デフォルトは
true。 まだ支払われていないイベントだけを見るにはfalseに設定します。
レスポンス
{
"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
}
]
}
パートナープロフィール¶
プロフィールを取得する¶
GET /partner
パートナープロフィールと未払い残高を返します — 自分で保存しなくても、自社の管理 UI 内で収益を表示するのに便利です。
レスポンス
{
"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¶
注文に何かが起きると、設定済みの webhook URL に署名付き JSON イベントを POST します。
イベントタイプ¶
| Event | 発火するタイミング |
|---|---|
order.created |
Stripe Checkout セッションが作成され、支払い待ちになります。 |
order.paid |
Stripe が支払いを確認しました。収益イベントが記録されます。 |
order.cancelled |
注文がタイムアウトしたか、明示的にキャンセルされました。 |
agent.provisioning_started |
この注文のデプロイパイプラインが開始されました。 |
agent.ready |
デプロイに成功しました。ペイロードには panel_url と expires_at が含まれます。 |
agent.failed |
デプロイパイプラインでエラーが発生しました。壊れたステップは error フィールドで確認してください。 |
agent.expired |
Agent の TTL が経過しました。パートナーは POST /orders/{id}/renew で更新できます。 |
配信と再試行¶
- 指数スケジュールで最大 7 回試行します:
0s, 30s, 2m, 10m, 1h, 6h, 24h。 - 最後の試行後、配信は
exhaustedとしてマークされ、再試行は停止します。 - 確認応答するには、10 秒以内に
2xxステータスで応答してください。
リクエストヘッダー¶
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
サンプルペイロード — 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"
}
署名を検証する¶
署名は HMAC-SHA256(secret, "{timestamp}.{raw_body}") です。必ず raw リクエスト body を検証してください — パースした JSON を再シリアライズすると比較が壊れます。
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"),
);
}
冪等な受信側
X-Mintbot-Event-Id を重複排除キーとして使ってください — 再試行では同じ id が再利用されるため、その列で行単位の INSERT … ON CONFLICT DO NOTHING を使えばハンドラーを安全に保てます。
エラー¶
すべてのエラーレスポンスには、プログラムで分岐できる安定した code が含まれます。message フィールドは人間が読めるヒントであり、リリース間で変わることがあります。request_id は X-Request-Id レスポンスヘッダーを反映します — サポートチケットに含めてください。
{
"error": {
"code": "invalid_api_key",
"message": "API key is unknown or revoked.",
"request_id": "f0c2d6c4-…"
}
}
| Code | 意味 |
|---|---|
unauthenticated |
Authorization ヘッダーがない、または形式が不正です。 |
invalid_api_key |
API key が不明、またはローテーション済みで無効です。 |
rate_limited |
パートナー単位または IP 単位のレート制限を超えました — Retry-After を参照してください。 |
missing_idempotency_key |
Idempotency-Key のない POST リクエストです。 |
idempotency_key_mismatch |
同じキーが異なるリクエスト body で再利用されました。 |
validation_error |
リクエスト body がスキーマ検証に失敗しました。 |
not_found |
リソースが存在しない、またはあなたのパートナーに属していません。 |
payment_gateway_error |
Stripe が Checkout セッションの作成を拒否しました。 |
レート制限¶
- パートナーごとに 120 requests / 60 s rolling window。バーストと定常状態は同じバケットを共有します。
- 認証なしおよび認証失敗のリクエストには、IP ごとに別枠で 60 requests / 60 s。Bearer の総当たりでパートナー枠が消費されないようにします。
- 超過したリクエストには、
Retry-Afterヘッダー(バックオフする秒数)付きで429 rate_limitedが返ります。
お困りですか?¶
このドキュメントは、実際に API を使うパートナーのために書かれています。不足、わかりにくい点、古くなった内容があれば、あなたの mintbot agent に伝えてください — フィードバックは転送され、ページを更新します。