Keri sisuni

Brand Partner API

Väike ja etteaimatav REST API mintboti tellimuste loomiseks, nende oleku pärimiseks ja elutsükli sündmuste vastuvõtmiseks. JSON sisse, JSON välja. Bearer-tokeniga autentimine. Idempotentsed kirjutamised. Allkirjastatud webhookid.

API juurdepääsu töölaud Hüppa webhookide juurde


Kiirülevaade

Base URL https://mint.mintbot.ai/api/v1
Autentimine Authorization: Bearer mo_live_…
Idempotentsus Idempotency-Key: <uuid> igal POST-päringul, välja arvatud POST /dns/records
Sisutüüp application/json
Päringulimiit 120 päringut / 60 s partneri kohta
Webhookid Allkirjastatud HMAC-SHA256-ga, kuni 7 korduskatset

Autentimine

Iga päring saadab partneri API võtme Authorization-päises. Võtme saad luua või roteerida töölaual.

Authorization: Bearer mo_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json

Roteerimisel üleminekuaega ei ole

Võtme roteerimine tühistab eelmise võtme atomaarselt. Planeeri uue väärtuse vahetus oma konfiguratsioonis, enne kui klõpsad Rotate.

Idempotentsus

Iga POST vajab Idempotency-Key päist — välja arvatud POST /dns/records, mis on pakkuja kihis loomupäraselt idempotentne ja võtab korduskatseid vastu ka ilma selleta. Sobib suvaline UUID iga eraldi päringu kohta.

  • Hoiame vastust vahemälus 24 tundi. Sama võtmega korduskatse esitab algse vastuse uuesti, päisega Idempotent-Replay: true.
  • Sama võtme kasutamine teistsuguse päringukehaga tagastab 409 idempotency_key_mismatch.

Tellimused

Tellimuse loomine

POST /orders

Loob tellimuse ja tagastab Stripe Checkouti URL-i. Kui makse kinnitatakse, paigaldab mintbot agendi ja partneri osa tulusündmus salvestatakse automaatselt.

Päring

{
  "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
Üks väärtustest trial, s1, s2, s4.
duration_months
Serveri eluiga kalendrikuudes. Üks väärtustest 1, 3 või 12.
credit_usd
Valikuline. Tellimusega kaasa pandud ettemakstud vestluskrediit.
language
Valikuline. Määrab Stripe Checkouti keele ja tervituskirja keele.
external_id
Valikuline. Kajastub igas webhookis ja tellimuse vastuses — kasuta seda mintboti tellimuste sidumiseks oma süsteemi kirjetega.
success_url · cancel_url
Stripe Checkouti tagasisuunamise URL-id. {ORDER_ID} asendatakse serveri poolel.
webhook_url
Valikuline. Tellimusepõhine ülekirjutus partneri tasemel määratud webhooki URL-ile.

Vastus — 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
}

Näide

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"]

Tellimuse pärimine

GET /orders/{id}

Toob ühe tellimuse selle mintboti ID järgi. Vastuse kuju on sama mis POST /orders puhul.

curl https://mint.mintbot.ai/api/v1/orders/42 \
  -H "Authorization: Bearer $MINTBOT_API_KEY"

Tellimuste loend

GET /orders

Kursoripõhise lehitsemisega loend, uusimad ees.

Päringuparameetrid

status
Valikuline. Filtreeri väärtuste awaiting_payment, completed, deployed, deploy_failed või expired järgi.
cursor
Valikuline. Jätkamiseks anna eelmise lehe next_cursor.

Vastus

{
  "items": [ /* OrderResponse … */ ],
  "next_cursor": "37"
}

next_cursor on null, kui rohkem lehekülgi pole.


Tellimuse pikendamine

POST /orders/{id}/renew

Pikendab olemasolevat agenti veel duration_months võrra. Ainult taristu — uut vestluskrediiti kaasa ei panda. Tagastab uue tellimuse ID ja värske Stripe Checkouti URL-i.

Päring

{
  "duration_months": 1,
  "external_id": "your-side-id",
  "success_url": "https://your.app/thanks?id={ORDER_ID}",
  "cancel_url":  "https://your.app/account"
}

Tulu

Tulu pärimine

GET /revenue

Kogusummad ja kuni 200 viimast tuluraamatu sündmust.

Päringuparameetrid

include_paid
Valikuline, vaikimisi true. Sea false, et näha ainult veel välja maksmata sündmusi.

Vastus

{
  "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
    }
  ]
}

Partneri profiil

Profiili pärimine

GET /partner

Tagastab sinu partneriprofiili koos välja maksmata saldoga — mugav viis näidata oma tulu omaenda halduspaneelis, ilma et peaksid seda ise salvestama.

Vastus

{
  "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"
}

Seaded

Seadete pärimine

GET /settings

Tagastab kogu sinu mittesalajase partnerikonfiguratsiooni ühe vastusena — valitud režiimid, peadomeen, DNS-pakkuja, boti pakkuja, kohandushoidla, alamdomeenide muster (koos renderdatud näidissildiga), paketipõhised hinnad, API võtme metaandmed, webhooki metaandmed ning sama valmiduse ja jaotisepõhise oleku info, mis juhib MintOffice'i töölaua bännerit.

Mõeldud integratsiooniagentidele, kes peavad teada saama, kuidas partner on seadistatud, ilma töölauda kraapimata või operaatorit küsitlemata. Tüüpiline kasutaja on koodiagent, kes paigaldab sinu white-label lahendust värskele serverile — ta saab seda otspunkti lugeda, hargneda readiness.status järgi ja öelda operaatorile täpselt, millised jaotised vajavad veel tähelepanu.

Ühtegi saladust ei tagastata kunagi

Kõik, mille partner on sisestanud tunnusena — Telegrami boti token, Zone.ee API võti, webhooki allkirjastamise saladus, API võtme avatekst ise —, paistab välja ainult *_set-tõeväärtusena. Webhooki saladuse puhul näidatakse lisaks sama 8-märgilist eesliidet, mis on juba töölaual näha, nii et päringu tegija saab kinnitada, milline saladus on seadistatud, ilma väärtust kunagi nägemata.

Vastus

{
  "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
  }
}

Väljade kirjeldus

status
Partneri elutsükkel. Üks väärtustest onboarding, live, paused. Kuni olek on onboarding, lükkab Brand Partner API kirjutamised tagasi.
domain.mode
byo (kasutad oma peadomeeni) või hosted (mintbot annab *.mintbot.ai alamdomeeni). Kui režiim on hosted, on DNS-pakkuja väljad meelega tühjad, olenemata sellest, mida partner varem sisestas.
domain.subdomain_label_preview
Renderdatud silt, mille saaks esimene kliendiagent (agent1, 1, 001, …) praeguste subdomain_prefix, subdomain_numbering ja subdomain_pad_width väärtuste juures. Kasuta seda eelvaateks stiilis „nii näevad seda sinu kliendid“, ilma nummerdusreegleid ise uuesti realiseerimata.
bot.mode
own (partneri enda Telegrami bot), borrow (testimise ajaks laenatud mintboti bot) või web (ainult paneel, Telegramita).
template.mode
default (Agent customization repo't pole — agent töötab tavalisel brändita baasil) või custom (partneri Agent customization repo aadressil repo_url). Kui režiim on custom, kloonib agendi enda VPS selle hoidla pärast standardpaigaldust ja käivitab selle install.sh / update.sh, et rakendada baasi peale sinu persona, paneeli teema ja lisatööriistad — keskne osa ei käivita hoidlat kunagi ise. Kui soovid oma brändingut, suuna repo_url oma GitHubi HTTPS Agent customization repo'le.
api.webhook_secret_prefix
Webhooki allkirjastamise saladuse esimesed 8 märki; olemas ainult siis, kui saladus on seadistatud. Võimaldab päringu tegijal eristada, milline saladus on kasutusel, ilma täisväärtust nägemata. Töölaud näitab sama eesliidet.
readiness.missing_fields
Töölaua väljade nimede loend, mis on enne Go Live'i veel kohustuslikud. Tühi, kui ready on true. Piisavalt stabiilne, et selle põhjal oma halduspaneelis „mis on veel puudu“ vaadet kuvada.
readiness.dns_blocker
Lühike põhjusekood, kui DNS-i kontroll ebaõnnestub (nt nameservers_not_pointing, glue_record_missing). Muul juhul null.
section_status.*.issue
Jaotisepõhine inimloetav vihje, kui see jaotis takistab Go Live'i. Peegeldab töölaua jaotisepõhiseid olekusilte.

Näide

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"])

Kataloog

Sinu poe müüdavate pakettide loend — avalikud paketid (trial / starter / pro) koos sinu lõplike hindadega sinu hinnavaluutas. Renderda oma paketikaardid selle põhjal, selle asemel et pakettide tunnuseid ja hindu koodi kirjutada: käibelt kadunud paketid kaovad iseenesest ning hinna või valuuta muudatus, mille töölaual teed, jõuab sinu poodi vahemälu aegumise jooksul — uuesti paigaldamata.

Just see otspunkt hoiab ära olukorra, kus pood reklaamib eilseid pakette. Näidisportaal kutsub seda igal maandumislehe / /buy / /extend renderdamisel (vahemäluga ja püsiva varuvariandiga).

Kuvatavad tekstid jäävad sinu omaks

display_name / description / featured on mintboti kanoonilised paketi metaandmed. Kui tahad paketi oma brändi jaoks ümber nimetada või selle kirjelduse ümber kirjutada, tee seda oma poes (näidisportaalis on täpselt selleks PLAN_OVERRIDES vastendus) — kataloog on tõeallikas selle kohta, millised paketid on olemas ja mida need maksavad, mitte sinu turundustekstide kohta.

Kataloogi pärimine

GET /api/v1/catalog

Parameetreid pole. Ainult Bearer-autentimine — aktiveerimisväravat ei ole, nii et pood saab kataloogi renderdada juba enne, kui sinu partnerikonto on live'iks lülitatud.

Vastus

{
  "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 }
    }
  ]
}
Väli Tähendus
currency Sinu hinnavaluuta. Iga allolev price_cents on selles valuutas.
packages[] Üks kirje iga avaliku paketi kohta, pakkumise/kuvamise järjekorras.
tier Tunnus, mille annad POST /orders / POST /subscriptions päringule.
display_name / description / featured Kanoonilised kuvatavad tekstid (soovi korral kirjuta oma poes üle).
default_credit_usd Paketiga kaasa pandud LLM-krediidi vihje (informatiivne).
durations[] Perioodid, milleks seda paketti osta saab. months on väärtus, mille saadad duration_months väljas; price_cents on summa, mille tellimus arvele paneb. Kuupaketid pakuvad 1 / 3 / 12 kuud; trial pakub ainult ühte 24-tunnist perioodi.
subscription available on true pakettidel, mida saab osta igakuiselt automaatselt uueneva tellimusena POST /subscriptions kaudu; price_cents on kuusumma. trial ei ole kunagi tellimusena saadaval.

Hinnad on täpselt need, mida arvele pannakse

Iga price_cents arvutatakse sama hinnaloogikaga, mida kasutab tellimuste otspunkt, nii et kaardil kuvatav hind võrdub alati selle (tier, duration_months) kombinatsiooni lõpliku Stripe Checkouti summaga.

Näide

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-kirjed

Brändipartneri integratsioonidel on sageli vaja luua DNS-kirjeid partneri peadomeenil — suunata @, www või kliendipõhised alamdomeenid õigesse serverisse. MintOffice pakub selleks pakkujast sõltumatut proksit, nii et saad seda teha, ilma et DNS-pakkuja API võti sinu enda taristusse kunagi jõuaks. Liitumisel salvestatud tunnused (praegu zone.ee; cloudflare ja route53 on plaanis sama kujuga) püsivad MintOffice'is krüpteeritult; sinu päring tuleb sisse Bearer mo_live_… võtmega ja meie teeme pakkuja poole päringu sinu nimel.

Ulatus on partneri enda seadistatud peadomeen (domain.client_apex_domain päringust GET /settings). Tsoonis, mis sulle ei kuulu, ei saa sa ühtegi kirjet puutuda.

Praegu toetab proksi neid toiminguid, mida paigaldustoru ise kasutab — A-kirjed (loo/uuenda, loend, kustuta ID järgi). CNAME- / TXT- / MX-tugi järgib sama kuju, kui aluseks olev pakkuja abstraktsioon neid toetama hakkab.

Idempotency-Key pole siin nõutav

Erinevalt tellimuste loomise otspunktidest on DNS-i loomis-/uuenduspäringud pakkuja kihis loomupäraselt idempotentsed (sama (subdomain, ip) paariga kordamine ei muuda midagi ja aegunud duplikaadid koristatakse igal päringul). Idempotency-Key päist ei pea saatma — korduskatsed jõuavad alati ühe A-kirjeni FQDN-i kohta.

A-kirje loomine või uuendamine

POST /dns/records

Suunab <subdomain>.<sinu-peadomeen> idempotentselt IPv4-aadressile. Peadomeeni enda jaoks anna "" (või "@").

Päring

{
  "subdomain": "www",
  "ip": "203.0.113.10"
}

subdomain võib olla:

  • "" või "@" — peadomeen ise (example.com).
  • Üks DNS-i silt — "www", "api" — kujule <silt>.<peadomeen>.
  • Punktidega alamsildid — "api.eu" — pesastatud alamdomeenideks (api.eu.example.com).

ip peab olema punktidega IPv4-aadress. Iga silt koosneb märkidest [a-z0-9_-], on 1–63 märki pikk ega alga ega lõpe --ga.

Vastus — 200

{
  "apex": "example.com",
  "provider": "zone_ee",
  "fqdn": "www.example.com",
  "records": [
    { "id": "9182734", "name": "www.example.com", "destination": "203.0.113.10" }
  ]
}

Kirjutamisjärgne records-loend peegeldab alati pakkuja hetkevaadet sellele FQDN-ile pärast duplikaatide koristust — nii et õnnestunud vastus täpselt ühe kirjega on märk, et midagi aegunut alles ei jäänud.

Kirjete loend

GET /dns/records

Tagastab kõik A-kirjed seadistatud peadomeenil. Lisa ?name=<silt-või-fqdn>, et piirata tulemus ühe FQDN-iga — väärtus võib olla paljas silt ("www"), punktidega alamdomeen ("api.eu") või täielik FQDN ("www.example.com").

Vastus — 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" }
  ]
}

Kirje kustutamine

DELETE /dns/records/{record_id}

record_id on pakkuja identifikaator, mille tagastab GET /dns/records (zone.ee väljastab täisarvulisi ID-sid, mis API piiril teisendatakse sõneks). Juba kadunud kirje kustutamist käsitletakse õnnestumisena — otspunkt on kliendi poolelt idempotentne.

Vastus — 200

{ "deleted": true, "id": "9182734" }

Vead

HTTP error.code Põhjus
401 unauthenticated / invalid_api_key Bearer-token puudub või on vigane.
422 validation_error Vigane alamdomeen või sihtaadress pole IPv4.
422 dns_not_configured Partneril puudub client_apex_domain või seadistatud pakkuja tunnused on puudu. Paranda jaotises Settings → Domain.
422 dns_provider_unsupported Partneri DNS-pakkuja pole veel MintOffice'i proksiga ühendatud (nt cloudflare'i kohatäide). Kasuta praegu zone_ee.
502 dns_provider_error Pakkuja tagastas 4xx/5xx vea või ühendus ebaõnnestus. Vea message sisaldab pakkuja staatust ja lühikest, saladustest puhastatud väljavõtet vastuse kehast. Võib turvaliselt uuesti proovida.

Näide

# 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"])

Webhookid

Kui tellimusega midagi juhtub, saadame sinu seadistatud webhooki URL-ile POST-päringuga allkirjastatud JSON-sündmuse.

Webhookid on valikulised

Webhook URL ja webhooki allkirjastamise saladus jaotises Settings → API access on täiesti valikulised — kui sul pole veel vastuvõtjat, jäta need liitumisel tühjaks. Töölaud ja ülejäänud API töötavad ilma webhookideta täiesti hästi; elutsükli jälgimiseks võid selle asemel pärida GET /api/v1/orders/{id}. Lisa URL (ja genereeri saladus) siis, kui oled valmis — uuesti aktiveerima ei pea.

Sündmuste tüübid

Sündmus Millal käivitub
order.created Stripe Checkouti sessioon on loodud, makse ootel.
order.paid Stripe kinnitas makse. Tulusündmus salvestatud.
order.cancelled Tellimus aegus või tühistati selgesõnaliselt.
agent.provisioning_started Selle tellimuse paigaldustoru käivitus.
agent.ready Paigaldus õnnestus. Sündmuse keha sisaldab panel_url ja expires_at.
agent.failed Paigaldustoru andis vea. Katkise sammu leiad väljalt error.
agent.expired Agendi eluiga sai täis. Partner saab pikendada POST /orders/{id}/renew kaudu.
agent.resumed Varem aegunud agent pikendati armuaja jooksul ja see töötab taas. agent.expired taastumise vaste.

Saatmine ja korduskatsed

  • Kuni 7 katset eksponentsiaalse graafikuga: 0s, 30s, 2m, 10m, 1h, 6h, 24h.
  • Pärast viimast katset märgitakse saadetis olekusse exhausted ja korduskatsed lõpevad.
  • Kinnitamiseks vasta 10 sekundi jooksul 2xx staatusekoodiga.

Päringu päised

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

Näidiskeha — 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"
}

Allkirja kontrollimine

Allkiri on HMAC-SHA256(secret, "{timestamp}.{raw_body}"). Kontrolli alati töötlemata päringukeha — parsitud JSON-i uuesti serialiseerimine rikub võrdluse.

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"),
  );
}

Idempotentsed vastuvõtjad

Kasuta X-Mintbot-Event-Id väärtust duplikaatide tuvastamise võtmena — korduskatsed kasutavad sama ID-d, nii et reapõhine INSERT … ON CONFLICT DO NOTHING sellel veerul hoiab sinu töötleja turvalisena.

Näidisportaal

Käivitatav otsast lõpuni näidis elab hoidlas mintbot-ai/partner-portal-example — FastAPI + SQLite, dokkerdatud, tuleb kaasa näidisbrändiga ExampleAI, millest teed forki ja mille välja vahetad. Arhitektuuri üldpilt — kuidas pood, see API, deploy worker ja kohandushoidla kokku sobivad — on lehel MintOffice — tehniline. Portaal sisaldab:

  • maandumis-, paketivaliku-, tänu- ja tühistuslehte,
  • POST /buyPOST /api/v1/orders → Stripe'i suunamine,
  • POST /webhooks/mintoffice koos ülal viidatud HMAC-kontrolliga,
  • HTTP Basic -autentimisega /admin sündmuste sirvijat, kus saadetisi silmaga üle vaadata.

Tee fork, sea .env-failis PARTNER_BRAND, MINTOFFICE_API_KEY ja MINTOFFICE_WEBHOOK_SECRET, käivita docker compose up ja suuna oma partnerikonto webhooki URL aadressile https://<sinu-host>/webhooks/mintoffice. Täieliku juhendi leiad lehelt MintOffice → Näidisportaal.


Vead

Iga veavastus sisaldab stabiilset code väärtust, mille järgi saab koodis hargneda. message on inimesele mõeldud vihje ja võib versioonide vahel muutuda. request_id kordab vastuse päist X-Request-Id — lisa see toepöördumisse.

{
  "error": {
    "code": "invalid_api_key",
    "message": "API key is unknown or revoked.",
    "request_id": "f0c2d6c4-…"
  }
}
Kood Tähendus
unauthenticated Authorization-päis puudub või on vigane.
invalid_api_key API võti on tundmatu või välja roteeritud.
rate_limited Partneri- või IP-põhine päringulimiit on ületatud — vaata Retry-After.
missing_idempotency_key POST-päring ilma Idempotency-Key päiseta.
idempotency_key_mismatch Sama võtit kasutati teistsuguse päringukehaga.
validation_error Päringu keha ei läbinud skeemikontrolli.
not_found Ressurssi pole olemas või see ei kuulu sinu partnerikontole.
payment_gateway_error Stripe lükkas Checkouti sessiooni loomise tagasi.
dns_not_configured POST /dns/records partneril, kellel puudub peadomeen või DNS-i tunnused. Paranda jaotises Settings → Domain.
dns_provider_unsupported Partneri dns_provider väärtus pole veel MintOffice'i proksiga ühendatud.
dns_provider_error DNS-pakkuja tagastas vea — sõnum sisaldab puhastatud väljavõtet.
quota_exceeded Partner on ära kasutanud kõik paigalduskohad (vaikimisi 10). Limiidi tõstmiseks võta ühendust mintboti toega. Tagastavad POST /orders ja POST /orders/{id}/renew. Keha sisaldab välju deploys_used + deploy_quota.

Päringulimiidid

  • 120 päringut / 60 s libisev aken partneri kohta. Lühiajalised tipud ja püsiv koormus jagavad sama mahutit.
  • 60 päringut / 60 s eraldi IP-põhine mahuti autentimata ja ebaõnnestunud autentimisega päringutele — nii ei saa Bearer-tokeni jõurünne partneri kvooti ära süüa.
  • Liigsed päringud tagastavad 429 rate_limited koos Retry-After päisega (mitu sekundit enne uut katset oodata).

Vajad abi?

Need juhendid on kirjutatud partneritele, kes API-t päriselt kasutavad. Kui midagi on puudu, segane või aegunud, ütle seda oma mintboti agendile — ta edastab tagasiside meile ja me uuendame lehte.