Brand Partner API¶
Mazs un paredzams REST API, ar ko izveidot mintbot pasūtījumus, sekot to statusam un saņemt dzīvescikla notikumus. JSON iekšā, JSON ārā. Bearer-token autentifikācija. Idempotenti rakstīšanas pieprasījumi. Parakstīti webhooki.
API piekļuves panelis Pāriet uz webhookiem
Īsumā¶
| Bāzes URL | https://mint.mintbot.ai/api/v1 |
| Autentifikācija | Authorization: Bearer mo_live_… |
| Idempotence | Idempotency-Key: <uuid> katram POST, izņemot POST /dns/records |
| Satura tips | application/json |
| Pieprasījumu limits | 120 pieprasījumi / 60 s katram partnerim |
| Webhooki | Parakstīti ar HMAC-SHA256, atkārtoti līdz 7 reizēm |
Autentifikācija¶
Katrs pieprasījums Authorization galvenē nosūta partnera API atslēgu. Atslēgu ģenerē vai rotē vadības panelī.
Authorization: Bearer mo_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
Rotācijai nav pārejas perioda
Atslēgas rotācija iepriekšējo atslēgu atsauc atomāri. Sagatavojies nomainīt vērtību savā konfigurācijā, pirms klikšķini Rotate.
Idempotence¶
Katram POST ir vajadzīga Idempotency-Key galvene — izņemot POST /dns/records, kas nodrošinātāja līmenī ir dabiski idempotents un pieņem atkārtotus mēģinājumus arī bez tās. Der jebkurš UUID, ja vien katram atsevišķam pieprasījumam tas ir savs.
- Atbildi glabājam kešatmiņā 24 stundas. Atkārtots mēģinājums ar to pašu atslēgu atgriež sākotnējo atbildi ar
Idempotent-Replay: true. - Tās pašas atslēgas izmantošana ar citu pieprasījuma saturu atgriež
409 idempotency_key_mismatch.
Pasūtījumi¶
Izveidot pasūtījumu¶
POST /orders
Izveido pasūtījumu un atgriež Stripe Checkout URL. Kad maksājums ir apstiprināts, mintbot sagatavo aģentu, un partnera daļas ieņēmumu notikums tiek ierakstīts automātiski.
Pieprasījums
{
"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"
}
tier- Viens no
trial,s1,s2,s4. duration_months- Servera darbības laiks kalendārajos mēnešos. Jābūt
1,3vai12. credit_usd- Neobligāts. Pasūtījumā iekļautais iepriekš apmaksātais tērzēšanas kredīts.
language- Neobligāts. Nosaka Stripe Checkout valodu un sveiciena e-pasta valodu.
external_id- Neobligāts. Tiek atgriezts katrā webhookā un pasūtījuma atbildē — izmanto to, lai sasaistītu mintbot pasūtījumus ar ierakstiem savā sistēmā.
success_url·cancel_url- Stripe Checkout atgriešanās URL.
{ORDER_ID}tiek aizstāts servera pusē. webhook_url- Neobligāts. Pārraksta partnera līmeņa webhook URL tikai šim pasūtījumam.
Atbilde — 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
}
Piemērs
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"]
Iegūt pasūtījumu¶
GET /orders/{id}
Nolasa vienu pasūtījumu pēc tā mintbot id. Atgriež tādu pašu struktūru kā POST /orders.
curl https://mint.mintbot.ai/api/v1/orders/42 \
-H "Authorization: Bearer $MINTBOT_API_KEY"
Pasūtījumu saraksts¶
GET /orders
Ar kursoru lapots saraksts, jaunākie vispirms.
Vaicājuma parametri
status- Neobligāts. Filtrē pēc
awaiting_payment,completed,deployed,deploy_failedvaiexpired. cursor- Neobligāts. Padod
next_cursorno iepriekšējās lapas, lai turpinātu.
Atbilde
{
"items": [ /* OrderResponse … */ ],
"next_cursor": "37"
}
next_cursor ir null, kad vairs nav nākamo lapu.
Pagarināt pasūtījumu¶
POST /orders/{id}/renew
Pagarina esošu aģentu vēl par duration_months. Tikai infrastruktūra — jauns tērzēšanas kredīts netiek iekļauts. Atgriež jaunu pasūtījuma id un jaunu Stripe Checkout URL.
Pieprasījums
{
"duration_months": 1,
"external_id": "your-side-id",
"success_url": "https://your.app/thanks?id={ORDER_ID}",
"cancel_url": "https://your.app/account"
}
Ieņēmumi¶
Nolasīt ieņēmumus¶
GET /revenue
Kopsummas un pēdējie 200 virsgrāmatas notikumi.
Vaicājuma parametri
include_paid- Neobligāts, noklusējums
true. Iestatifalse, lai redzētu tikai vēl neizmaksātos notikumus.
Atbilde
{
"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
}
]
}
Partnera profils¶
Iegūt profilu¶
GET /partner
Atgriež tavu partnera profilu kopā ar neizmaksāto atlikumu — ērti, lai rādītu ieņēmumus savā administrēšanas saskarnē, tos pašam neglabājot.
Atbilde
{
"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"
}
Iestatījumi¶
Iegūt iestatījumus¶
GET /settings
Atgriež visu tavu nesekrēto partnera konfigurāciju vienā atbildē — izvēlētos režīmus, apex domēnu, DNS nodrošinātāju, bota nodrošinātāju, pielāgojumu repozitoriju, apakšdomēnu šablonu (ar sagatavotu priekšskatījuma etiķeti), cenas katram līmenim, API atslēgas metadatus, webhooka metadatus un to pašu gatavības / sadaļu statusu, kas darbina MintOffice vadības paneļa baneri.
Paredzēts integrācijas aģentiem, kuriem jānoskaidro, kā partneris ir iestatīts, neskrāpējot vadības paneli un neiztaujājot operatoru. Tipisks izsaucējs ir kodēšanas aģents, kas uz jauna servera instalē tavu white-label iestatījumu — tas var nolasīt šo galapunktu, sazaroties pēc readiness.status un precīzi pateikt operatoram, kuras sadaļas vēl jāsakārto.
Neviens noslēpums netiek atgriezts
Viss, ko partneris ievadījis kā akreditācijas datus — Telegram bota tokens, Zone.ee API atslēga, webhooka parakstīšanas noslēpums, pati API atslēga atklātā tekstā — parādās tikai kā *_set būla vērtība. Webhooka noslēpumam papildus ir pieejams tas pats 8 rakstzīmju priedēklis, kas jau redzams vadības panelī, lai izsaucējs varētu pārliecināties, kurš noslēpums ir konfigurēts, nekad neredzot pašu vērtību.
Atbilde
{
"id": 12,
"email": "you@kliendifirma.com",
"status": "live",
"created_at": "2026-05-12 14:22:01",
"onboarded_at": "2026-05-12 14:48:33",
"activated_at": "2026-05-13 09:10:05",
"last_login_at": "2026-05-20 00:51:18",
"preferred_language": "en",
"pricing_currency": "usd",
"balance_unpaid_cents": 800,
"domain": {
"mode": "byo",
"client_apex_domain": "agent99.cc",
"dns_provider": "zone.ee",
"zone_ee_username": "you@kliendifirma.com",
"zone_ee_api_key_set": true,
"subdomain_prefix": "agent",
"subdomain_numbering": "natural",
"subdomain_pad_width": 3,
"subdomain_label_preview": "agent1"
},
"bot": {
"mode": "own",
"provider": "telegram",
"telegram_bot_username": "agent99cc_bot",
"telegram_bot_token_set": true
},
"template": {
"mode": "default",
"repo_url": null
},
"api": {
"key_prefix": "mo_live_a12b",
"key_created_at": "2026-05-13 09:11:42",
"webhook_url": "https://your.app/mintbot-webhook",
"webhook_secret_set": true,
"webhook_secret_prefix": "ab12cd34"
},
"pricing": {
"mode": "default",
"currency": "usd",
"tiers": {
"trial": { "price_cents": 0, "partner_cut_cents": 0, "updated_at": null },
"s1": { "price_cents": 1200, "partner_cut_cents": 200, "updated_at": "2026-05-13 09:05:00" },
"s2": { "price_cents": 2400, "partner_cut_cents": 400, "updated_at": "2026-05-13 09:05:00" },
"s4": { "price_cents": 4800, "partner_cut_cents": 800, "updated_at": "2026-05-13 09:05:00" }
}
},
"readiness": {
"ready": true,
"missing_fields": [],
"dns_blocker": null,
"status": "live"
},
"section_status": {
"domain": { "status": "ready", "mode": "byo", "issue": null, "dns_blocker": null },
"bot": { "status": "ready", "mode": "own", "issue": null, "dns_blocker": null },
"template": { "status": "ready", "mode": "default", "issue": null, "dns_blocker": null },
"api": { "status": "ready", "mode": "live", "issue": null, "dns_blocker": null },
"all_ready": true
}
}
Lauku apraksts¶
status- Partnera dzīvescikls. Viens no
onboarding,live,paused. Kamēr statuss ironboarding, Brand Partner API rakstīšanas pieprasījumus noraida. domain.modebyo(tu izmanto savu apex domēnu) vaihosted(mintbot piešķir*.mintbot.aiapakšdomēnu). RežīmāhostedDNS nodrošinātāja lauki apzināti ir tukši neatkarīgi no tā, ko partneris ievadījis iepriekš.domain.subdomain_label_preview- Sagatavotā etiķete, ko saņemtu pirmais klienta aģents (
agent1,1,001, …) ar pašreizējiemsubdomain_prefix,subdomain_numberingunsubdomain_pad_width. Izmanto to priekšskatījumam „lūk, ko redzēs tavi klienti“, nepārrakstot numerācijas noteikumus pats. bot.modeown(partnera Telegram bots),borrow(testēšanas laikā tiek izmantots mintbot bots) vaiweb(tikai panelis, bez Telegram).template.modedefault(aģenta pielāgojumu repozitorija nav — aģents darbojas uz vienkāršās bāzes bez zīmola) vaicustom(partnera aģenta pielāgojumu repozitorijs adresērepo_url). Režīmācustomaģenta paša VPS pēc standarta izvietošanas klonē šo repozitoriju un palaiž tāinstall.sh/update.sh, lai virs bāzes uzliktu tavu personu, paneļa tēmu un jebkurus papildu rīkus — centrālā sistēma repozitoriju nekad nepalaiž. Ja vēlies savu zīmolu, norādirepo_urluz sava aģenta pielāgojumu repozitorija GitHub HTTPS adresi.api.webhook_secret_prefix- Webhooka parakstīšanas noslēpuma pirmās 8 rakstzīmes; atgriež tikai tad, ja noslēpums ir konfigurēts. Ļauj izsaucējam atšķirt, kurš noslēpums ir spēkā, neredzot pilno vērtību. Vadības panelis rāda to pašu priedēkli.
readiness.missing_fields- Vadības paneļa lauku nosaukumi, kas vēl jāaizpilda pirms Go Live. Tukšs, kad
readyirtrue. Pietiekami stabils, lai uz tā balstītu sadaļu „kas vēl trūkst“ savā administrēšanas saskarnē. readiness.dns_blocker- Īss iemesla kods, kad DNS pārbaude neizdodas (piem.,
nameservers_not_pointing,glue_record_missing). Citādinull. section_status.*.issue- Cilvēkam lasāms norādījums katrai sadaļai, kas bloķē Go Live. Atbilst vadības paneļa sadaļu statusa etiķetēm.
Piemērs
curl https://mint.mintbot.ai/api/v1/settings \
-H "Authorization: Bearer $MINTBOT_API_KEY"
import os, requests
r = requests.get(
"https://mint.mintbot.ai/api/v1/settings",
headers={"Authorization": f"Bearer {os.environ['MINTBOT_API_KEY']}"},
timeout=10,
)
r.raise_for_status()
settings = r.json()
if not settings["readiness"]["ready"]:
print("Still missing:", settings["readiness"]["missing_fields"])
Katalogs¶
Pārdodamo pakešu saraksts tavam veikalam — publiskās paketes
(trial / starter / pro) kopā ar tavām aprēķinātajām cenām tavā
cenu valūtā. Veido plānu kartītes no šī saraksta, nevis iekodē līmeņu
identifikatorus un cenas: izņemtās paketes pazūd pašas, un cenas vai
valūtas maiņa, ko veic vadības panelī, sasniedz tavu veikalu kešatmiņas
loga ietvaros — bez atkārtotas izvietošanas.
Tieši šis galapunkts neļauj veikalam reklamēt vakardienas paketes.
Atsauces portāls to izsauc katrā sākumlapas / /buy / /extend
attēlošanas reizē (ar kešatmiņu un noturīgu rezerves vērtību).
Attēlojamie teksti paliek tavi
display_name / description / featured ir kanoniskie mintbot
pakešu metadati. Ja vēlies paketi pārsaukt vai pārrakstīt tās aprakstu
savam zīmolam, pārraksti to savā veikalā (atsauces portālam tieši šim
nolūkam ir PLAN_OVERRIDES karte) — katalogs ir patiesības avots tam,
kuras paketes pastāv un cik tās maksā, nevis tavam mārketinga tekstam.
Iegūt katalogu¶
GET /api/v1/catalog
Bez parametriem. Tikai Bearer autentifikācija — aktivizācijas vārtu nav,
tāpēc veikals var attēlot katalogu vēl pirms tava partnera konta
pārslēgšanas uz live.
Atbilde
{
"currency": "usd",
"packages": [
{
"tier": "trial",
"display_name": "Trial",
"description": "One day to kick the tires.",
"featured": false,
"default_credit_usd": 5,
"durations": [
{ "months": 1, "label": "24 hours", "price_cents": 0 }
],
"subscription": { "available": false, "price_cents": null }
},
{
"tier": "starter",
"display_name": "Starter",
"description": "A month of assistant time.",
"featured": true,
"default_credit_usd": 10,
"durations": [
{ "months": 1, "label": "1 month", "price_cents": 1500 },
{ "months": 3, "label": "3 months", "price_cents": 4500 },
{ "months": 12, "label": "12 months", "price_cents": 18000 }
],
"subscription": { "available": true, "price_cents": 1500 }
}
]
}
| Lauks | Nozīme |
|---|---|
currency |
Tava cenu valūta. Katrs price_cents zemāk ir izteikts tajā. |
packages[] |
Viens ieraksts katrai publiskajai paketei piedāvājuma / attēlošanas secībā. |
tier |
Identifikators, ko nodod POST /orders / POST /subscriptions. |
display_name / description / featured |
Kanoniskie attēlojamie teksti (savā veikalā vari tos pārrakstīt). |
default_credit_usd |
Paketē iekļautā LLM kredīta orientējošā vērtība (informatīva). |
durations[] |
Iestatīšanas periodi, uz kādiem šo paketi var iegādāties. months ir vērtība, ko sūti kā duration_months; price_cents ir summa, ko pasūtījums iekasēs. Mēneša paketēm ir 1 / 3 / 12 mēnešu periodi; trial piedāvā vienu 24 stundu periodu. |
subscription |
available ir true paketēm, ko var iegādāties kā ikmēneša automātiski atjaunojamu abonementu caur POST /subscriptions; price_cents ir mēneša summa. trial nekad nav pieejams kā abonements. |
Cenas sakrīt ar to, kas tiks iekasēts
Katrs price_cents tiek aprēķināts ar to pašu cenu risinātāju, ko
izmanto pasūtījumu galapunkts, tāpēc kartītes cena vienmēr ir vienāda ar
galīgo Stripe Checkout kopsummu šim (tier, duration_months) pārim.
Piemērs¶
curl -s https://mint.mintbot.ai/api/v1/catalog \
-H "Authorization: Bearer $MINTBOT_API_KEY" | jq
import os, requests
r = requests.get(
"https://mint.mintbot.ai/api/v1/catalog",
headers={"Authorization": f"Bearer {os.environ['MINTBOT_API_KEY']}"},
timeout=10,
)
r.raise_for_status()
catalog = r.json()
for pkg in catalog["packages"]:
month1 = next(d for d in pkg["durations"] if d["months"] == 1)
print(pkg["display_name"], month1["price_cents"], catalog["currency"])
DNS ieraksti¶
Brand Partner integrācijām bieži jāizveido DNS ieraksti partnera apex domēnā — jānorāda @, www vai katra klienta apakšdomēns uz pareizo serveri. MintOffice piedāvā no nodrošinātāja neatkarīgu starpniekservisu, lai to varētu darīt, nekad neapstrādājot augšupējā nodrošinātāja API atslēgu savā infrastruktūrā. Akreditācijas dati, ko saglabāji ievadīšanas laikā (šobrīd zone.ee; cloudflare un route53 ir plānoti ar tādu pašu struktūru), paliek šifrēti MintOffice; tavs pieprasījums ienāk ar Bearer mo_live_…, un mēs tavā vārdā izsaucam augšupējo nodrošinātāju.
Tvērums ir partnera paša konfigurētais apex domēns (domain.client_apex_domain no GET /settings). Ierakstus zonā, kas tev nepieder, aiztikt nevar.
Šobrīd starpniekserviss atbalsta tās darbības, ko izmanto pati izvietošanas plūsma — A ierakstus (upsert / saraksts / dzēšana pēc id). CNAME / TXT / MX atbalsts sekos ar tādu pašu struktūru, tiklīdz pamatā esošā nodrošinātāju abstrakcija tos apgūs.
Idempotency-Key šeit nav vajadzīgs
Atšķirībā no pasūtījumu izveides galapunktiem DNS upsert ir dabiski idempotents nodrošinātāja līmenī (atkārtota izpilde ar to pašu (subdomain, ip) pāri neko nemaina, un novecojušie dublikāti tiek iztīrīti katrā izsaukumā). Idempotency-Key galvene nav jāsūta — atkārtoti mēģinājumi vienmēr noved pie viena A ieraksta katram FQDN.
A ieraksta upsert¶
POST /dns/records
Idempotenti norāda <subdomain>.<your-apex> uz IPv4 adresi. Pašam apex domēnam nodod "" (vai "@").
Pieprasījums
{
"subdomain": "www",
"ip": "203.0.113.10"
}
subdomain pieņem:
""vai"@"— pats apex domēns (example.com).- Vienu DNS etiķeti —
"www","api"— adresei<label>.<apex>. - Etiķetes ar punktiem —
"api.eu"— ligzdotiem apakšdomēniem (api.eu.example.com).
ip jābūt IPv4 adresei ar punktiem. Katra etiķete ir [a-z0-9_-], 1–63 rakstzīmes, bez - sākumā vai beigās.
Atbilde — 200
{
"apex": "example.com",
"provider": "zone_ee",
"fqdn": "www.example.com",
"records": [
{ "id": "9182734", "name": "www.example.com", "destination": "203.0.113.10" }
]
}
Saraksts records pēc ierakstīšanas vienmēr atspoguļo augšupējā nodrošinātāja pašreizējo skatu uz šo FQDN pēc dublikātu iztīrīšanas — tāpēc veiksmīga atbilde ar tieši vienu ierakstu ir signāls, ka nekas novecojis nav palicis.
Ierakstu saraksts¶
GET /dns/records
Atgriež visus A ierakstus konfigurētajā apex domēnā. Pievieno ?name=<label-or-fqdn>, lai filtrētu līdz vienam FQDN — vērtība var būt vienkārša etiķete ("www"), apakšdomēns ar punktiem ("api.eu") vai pilns FQDN ("www.example.com").
Atbilde — 200
{
"apex": "example.com",
"provider": "zone_ee",
"items": [
{ "id": "9182734", "name": "example.com", "destination": "203.0.113.10" },
{ "id": "9182735", "name": "www.example.com", "destination": "203.0.113.10" }
]
}
Dzēst ierakstu¶
DELETE /dns/records/{record_id}
record_id ir nodrošinātāja identifikators, ko atgriež GET /dns/records (zone.ee izsniedz veselus skaitļus, kas API robežā tiek pārvērsti virknēs). Vairs neesoša ieraksta dzēšana tiek uzskatīta par veiksmīgu — galapunkts klienta pusē ir idempotents.
Atbilde — 200
{ "deleted": true, "id": "9182734" }
Kļūdas¶
| HTTP | error.code |
Cēlonis |
|---|---|---|
| 401 | unauthenticated / invalid_api_key |
Trūkst Bearer tokena vai tas ir nederīgs. |
| 422 | validation_error |
Nederīgs apakšdomēns vai mērķis nav IPv4 adrese. |
| 422 | dns_not_configured |
Partnerim nav client_apex_domain vai trūkst konfigurētā nodrošinātāja akreditācijas datu. Labo sadaļā Settings → Domain. |
| 422 | dns_provider_unsupported |
Partnera DNS nodrošinātājs vēl nav pieslēgts MintOffice starpniekservisam (piem., cloudflare vietturis). Pagaidām pārslēdzies uz zone_ee. |
| 502 | dns_provider_error |
Augšupējais nodrošinātājs atgrieza 4xx/5xx vai neizdevās savienojums. Kļūdas message satur augšupējo statusu un īsu izvilkumu no atbildes ar aizklātiem noslēpumiem. Var droši mēģināt vēlreiz. |
Piemērs¶
# Point apex + www at your server's IP.
curl https://mint.mintbot.ai/api/v1/dns/records \
-H "Authorization: Bearer $MINTBOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"subdomain": "", "ip": "203.0.113.10"}'
curl https://mint.mintbot.ai/api/v1/dns/records \
-H "Authorization: Bearer $MINTBOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"subdomain": "www", "ip": "203.0.113.10"}'
# Verify.
curl "https://mint.mintbot.ai/api/v1/dns/records" \
-H "Authorization: Bearer $MINTBOT_API_KEY"
import os, requests
URL = "https://mint.mintbot.ai/api/v1/dns/records"
H = {"Authorization": f"Bearer {os.environ['MINTBOT_API_KEY']}"}
for sub in ("", "www"):
r = requests.post(URL, headers=H, json={"subdomain": sub, "ip": "203.0.113.10"})
r.raise_for_status()
print(sub or "@", r.json()["records"])
Webhooki¶
Kad ar pasūtījumu kaut kas notiek, mēs nosūtām (POST) parakstītu JSON notikumu uz tavu konfigurēto webhook URL.
Webhooki ir neobligāti
Webhook URL un webhooka parakstīšanas noslēpums sadaļā Settings → API access ir pilnībā neobligāti — ja saņēmēja vēl nav, ievadīšanas laikā atstāj tos tukšus. Vadības panelis un pārējais API bez webhookiem darbojas lieliski; dzīvesciklam vari sekot, aptaujājot GET /api/v1/orders/{id}. Pievieno URL (un ģenerē noslēpumu), kad esi gatavs — atkārtota aktivizācija nav vajadzīga.
Notikumu tipi¶
| Notikums | Kad tiek nosūtīts |
|---|---|
order.created |
Stripe Checkout sesija izveidota, gaida maksājumu. |
order.paid |
Stripe apstiprināja maksājumu. Ieņēmumu notikums ierakstīts. |
order.cancelled |
Pasūtījumam iestājās noilgums vai tas tika skaidri atcelts. |
agent.provisioning_started |
Šim pasūtījumam sākās izvietošanas plūsma. |
agent.ready |
Izvietošana izdevās. Payload satur panel_url un expires_at. |
agent.failed |
Izvietošanas plūsma beidzās ar kļūdu. Skati lauku error, lai redzētu, kurš solis neizdevās. |
agent.expired |
Aģenta darbības laiks beidzies. Partneris var to pagarināt ar POST /orders/{id}/renew. |
agent.resumed |
Iepriekš beidzies aģents tika pagarināts pārejas perioda laikā un atkal darbojas. Atjaunošanās pretstats notikumam agent.expired. |
Piegāde un atkārtoti mēģinājumi¶
- Līdz 7 mēģinājumiem ar eksponenciālu grafiku:
0s, 30s, 2m, 10m, 1h, 6h, 24h. - Pēc pēdējā mēģinājuma piegāde tiek atzīmēta kā
exhausted, un mēģinājumi apstājas. - Apstiprini saņemšanu, atbildot ar
2xxstatusu 10 sekunžu laikā.
Pieprasījuma galvenes¶
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
Payload paraugs — 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"
}
Paraksta pārbaude¶
Paraksts ir HMAC-SHA256(secret, "{timestamp}.{raw_body}"). Vienmēr pārbaudi neapstrādāto pieprasījuma saturu — ja parsēto JSON serializēsi no jauna, salīdzinājums vairs nesakritīs.
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"),
);
}
Idempotenti saņēmēji
Izmanto X-Mintbot-Event-Id kā deduplikācijas atslēgu — atkārtotie mēģinājumi izmanto to pašu id, tāpēc rindas līmeņa INSERT … ON CONFLICT DO NOTHING šajā kolonnā pasargā tavu apstrādātāju.
Atsauces portāls¶
Palaižams pilns atsauces piemērs atrodas repozitorijā mintbot-ai/partner-portal-example — FastAPI + SQLite, iepakots Docker konteinerā, ar piemēra zīmolu ExampleAI, ko forko un nomaini pret savu. Arhitektūras kopaina — kā veikals, šis API, izvietošanas process un pielāgojumu repozitorijs sader kopā — ir lapā MintOffice — tehniskā daļa. Portāls īsteno:
- sākumlapu / plānu izvēli / pateicības un atcelšanas lapas,
POST /buy→POST /api/v1/orders→ novirzīšanu uz Stripe,POST /webhooks/mintofficear iepriekš minēto HMAC pārbaudi,/adminnotikumu pārlūku ar HTTP Basic autentifikāciju, kur apskatīt piegādes.
Forko to, failā .env iestati PARTNER_BRAND, MINTOFFICE_API_KEY un MINTOFFICE_WEBHOOK_SECRET, palaid docker compose up un norādi sava partnera ieraksta webhook URL uz https://<your-host>/webhooks/mintoffice. Pilnu pamācību skati lapā MintOffice → Atsauces portāls.
Kļūdas¶
Katra kļūdas atbilde satur stabilu kodu code, pēc kura vari sazaroties programmatiski. Lauks message ir cilvēkam lasāms skaidrojums un starp laidieniem var mainīties. request_id atkārto atbildes galveni X-Request-Id — iekļauj to atbalsta pieteikumos.
{
"error": {
"code": "invalid_api_key",
"message": "API key is unknown or revoked.",
"request_id": "f0c2d6c4-…"
}
}
| Kods | Nozīme |
|---|---|
unauthenticated |
Trūkst Authorization galvenes vai tā ir nepareizā formā. |
invalid_api_key |
API atslēga nav zināma vai ir nomainīta rotācijā. |
rate_limited |
Pārsniegts partnera vai IP pieprasījumu limits — skati Retry-After. |
missing_idempotency_key |
POST pieprasījums bez Idempotency-Key. |
idempotency_key_mismatch |
Tā pati atslēga izmantota atkārtoti ar citu pieprasījuma saturu. |
validation_error |
Pieprasījuma saturs neizturēja shēmas validāciju. |
not_found |
Resurss neeksistē vai nepieder tavam partnerim. |
payment_gateway_error |
Stripe noraidīja Checkout sesijas izveidi. |
dns_not_configured |
POST /dns/records partnerim bez apex domēna / DNS akreditācijas datiem. Labo sadaļā Settings → Domain. |
dns_provider_unsupported |
Partnera dns_provider vērtība vēl nav pieslēgta MintOffice starpniekservisam. |
dns_provider_error |
Augšupējais DNS nodrošinātājs atgrieza kļūdu — message satur izvilkumu ar aizklātiem noslēpumiem. |
quota_exceeded |
Partneris ir izmantojis visas izvietošanas vietas (pēc noklusējuma 10). Sazinies ar mintbot atbalstu, lai palielinātu limitu. Atgriež POST /orders un POST /orders/{id}/renew. Atbilde satur deploys_used + deploy_quota. |
Pieprasījumu limiti¶
- 120 pieprasījumi / 60 s slīdošā logā katram partnerim. Pīķa un vienmērīgā slodze izmanto vienu kopīgu limitu.
- 60 pieprasījumi / 60 s atsevišķs limits katrai IP adresei neautentificētiem un neveiksmīgas autentifikācijas pieprasījumiem — lai Bearer tokena minēšana neizsmeltu partnera kvotu.
- Pārsniedzot limitu, atbilde ir
429 rate_limitedar galveniRetry-After(cik sekunžu jāpagaida).
Vajadzīga palīdzība?¶
Šī dokumentācija ir rakstīta partneriem, kuri API patiešām lieto. Ja kaut kā trūkst, kaut kas ir neskaidrs vai novecojis, pasaki to savam mintbot aģentam — tas pārsūtīs atsauksmi, un mēs atjaunināsim lapu.