Brand Partner API¶
Pieni ja ennustettava REST-rajapinta mintbot-tilausten luomiseen, niiden tilan kyselyyn ja elinkaaritapahtumien vastaanottoon. JSON sisään, JSON ulos. Bearer-token-autentikointi. Idempotentit kirjoitukset. Allekirjoitetut webhookit.
API-käytön hallintapaneeli Siirry webhookeihin
Yleiskuva¶
| Perus-URL | https://mint.mintbot.ai/api/v1 |
| Autentikointi | Authorization: Bearer mo_live_… |
| Idempotenssi | Idempotency-Key: <uuid> jokaisessa POST-pyynnössä paitsi POST /dns/records |
| Sisältötyyppi | application/json |
| Nopeusraja | 120 pyyntöä / 60 s per kumppani |
| Webhookit | Allekirjoitettu HMAC-SHA256:lla, uudelleenyrityksiä enintään 7 |
Autentikointi¶
Jokainen pyyntö lähettää kumppanin API-avaimen Authorization-otsakkeessa. Luo tai kierrätä avain hallintapaneelissa.
Authorization: Bearer mo_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
Kierrätyksessä ei ole siirtymäaikaa
Avaimen kierrätys mitätöi edellisen avaimen atomisesti. Valmistaudu vaihtamaan arvo konfiguraatioosi ennen kuin klikkaat Rotate.
Idempotenssi¶
Jokainen POST vaatii Idempotency-Key-otsakkeen – paitsi POST /dns/records, joka on palveluntarjoajan tasolla luonnostaan idempotentti ja hyväksyy uudelleenyritykset ilman sitä. Mikä tahansa UUID käy, kunhan se on erillinen jokaiselle eri pyynnölle.
- Vastaus säilytetään välimuistissa 24 tuntia. Uudelleenyritys samalla avaimella toistaa alkuperäisen vastauksen otsakkeella
Idempotent-Replay: true. - Saman avaimen käyttö eri pyyntörungolla palauttaa virheen
409 idempotency_key_mismatch.
Tilaukset¶
Luo tilaus¶
POST /orders
Luo tilauksen ja palauttaa Stripe Checkout -URL:n. Kun maksu on vahvistettu, mintbot provisioi agentin, ja kumppanin osuuden tulotapahtuma kirjataan automaattisesti.
Pyyntö
{
"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- Yksi arvoista
trial,s1,s2,s4. duration_months- Palvelimen elinaika kalenterikuukausina. Sallitut arvot:
1,3tai12. credit_usd- Valinnainen. Tilaukseen sisällytettävä, ennakkoon maksettu chat-krediitti.
language- Valinnainen. Vaikuttaa Stripe Checkoutin kieleen ja tervetulosähköpostin kieleen.
external_id- Valinnainen. Palautetaan jokaisessa webhookissa ja tilausvastauksessa – käytä sitä mintbot-tilausten kytkemiseen oman järjestelmäsi riveihin.
success_url·cancel_url- Stripe Checkoutin paluu-URL:t.
{ORDER_ID}korvataan palvelinpuolella. webhook_url- Valinnainen. Tilauskohtainen ohitus kumppanitason webhook-URL:lle.
Vastaus – 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
}
Esimerkki
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"]
Hae tilaus¶
GET /orders/{id}
Hakee yhden tilauksen sen mintbot-id:llä. Palauttaa saman rakenteen kuin POST /orders.
curl https://mint.mintbot.ai/api/v1/orders/42 \
-H "Authorization: Bearer $MINTBOT_API_KEY"
Listaa tilaukset¶
GET /orders
Kursorilla sivutettu lista, uusin ensin.
Kyselyparametrit
status- Valinnainen. Suodata arvolla
awaiting_payment,completed,deployed,deploy_failedtaiexpired. cursor- Valinnainen. Jatka antamalla edellisen sivun
next_cursor.
Vastaus
{
"items": [ /* OrderResponse … */ ],
"next_cursor": "37"
}
next_cursor on null, kun sivuja ei ole enempää.
Uusi tilaus¶
POST /orders/{id}/renew
Jatkaa olemassa olevan agentin elinaikaa uudella duration_months-jaksolla. Vain infrastruktuuri – uutta chat-krediittiä ei sisällytetä. Palauttaa uuden tilaus-id:n ja uuden Stripe Checkout -URL:n.
Pyyntö
{
"duration_months": 1,
"external_id": "your-side-id",
"success_url": "https://your.app/thanks?id={ORDER_ID}",
"cancel_url": "https://your.app/account"
}
Tulot¶
Lue tulot¶
GET /revenue
Kokonaissummat sekä 200 viimeisintä kirjanpitotapahtumaa.
Kyselyparametrit
include_paid- Valinnainen, oletus
true. Aseta arvoonfalse, jos haluat nähdä vain tapahtumat, joita ei ole vielä tilitetty.
Vastaus
{
"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
}
]
}
Kumppaniprofiili¶
Hae profiili¶
GET /partner
Palauttaa kumppaniprofiilisi sekä tilittämättömän saldon – kätevä, kun haluat näyttää ansiot omassa hallintakäyttöliittymässäsi tallentamatta niitä itse.
Vastaus
{
"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"
}
Asetukset¶
Hae asetukset¶
GET /settings
Palauttaa koko ei-salaisen kumppanikonfiguraatiosi yhdellä kertaa – valitut tilat, apex-verkkotunnuksen, DNS-palveluntarjoajan, bottipalveluntarjoajan, mukautusrepon, aliverkkotunnuskaavan (renderöidyn esikatselunimen kera), tasokohtaisen hinnoittelun, API-avaimen metatiedot, webhookin metatiedot sekä saman valmius- ja osiokohtaisen tilan, joka ohjaa MintOfficen hallintapaneelin banneria.
Suunniteltu integraatioagenteille, joiden täytyy selvittää, miten kumppani on määritetty, kaapimatta hallintapaneelia tai kuulustelematta operaattoria. Tyypillinen kutsuja on koodausagentti, joka asentaa white-label-kokoonpanoasi tuoreelle palvelimelle – se voi lukea tämän päätepisteen, haarautua readiness.status-kentän perusteella ja kertoa operaattorille täsmälleen, mitkä osiot vaativat vielä huomiota.
Salaisuuksia ei koskaan palauteta
Kaikki, minkä kumppani on antanut tunnistetietona – Telegram-botin token, Zone.ee:n API-avain, webhookin allekirjoitussalaisuus, itse API-avaimen selkoteksti – näkyy vain *_set-totuusarvona. Webhook-salaisuudesta paljastetaan lisäksi sama 8 merkin näyttöetuliite, joka näkyy jo hallintapaneelissa, jotta kutsuja voi varmistaa, mikä salaisuus on käytössä, näkemättä koskaan itse arvoa.
Vastaus
{
"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
}
}
Kenttäviite¶
status- Kumppanin elinkaaritila. Yksi arvoista
onboarding,live,paused. Brand Partner API hylkää kirjoitukset tilassaonboarding. domain.modebyo(tuot oman apex-verkkotunnuksesi) taihosted(mintbot tarjoaa*.mintbot.ai-aliverkkotunnuksen). TilassahostedDNS-palveluntarjoajan kentät ovat tarkoituksella tyhjiä riippumatta siitä, mitä kumppani on aiemmin syöttänyt.domain.subdomain_label_preview- Renderöity nimi, jonka ensimmäinen asiakasagentti saisi (
agent1,1,001, …) nykyisilläsubdomain_prefix-,subdomain_numbering- jasubdomain_pad_width-arvoilla. Käytä sitä ”tältä tämä näyttää asiakkaillesi” -esikatseluun toteuttamatta numerointisääntöjä itse uudelleen. bot.modeown(kumppanin oma Telegram-botti),borrow(mintbotin botti lainassa testauksen ajan) taiweb(vain paneeli, ei Telegramia).template.modedefault(ei agentin mukautusrepoa – agentti pyörii tavallisella, brändäämättömällä pohjalla) taicustom(kumppanin agentin mukautusrepo osoitteessarepo_url). Tilassacustomagentin oma VPS kloonaa repon vakiokäyttöönoton jälkeen ja ajaa seninstall.sh- /update.sh-skriptit, jotka lisäävät persoonasi, paneelin teeman ja mahdolliset lisätyökalut pohjan päälle – keskuspalvelin ei koskaan aja repoa itse. Osoitarepo_urlagentin mukautusrepon GitHub HTTPS -osoitteeseen, kun haluat oman brändäyksen.api.webhook_secret_prefix- Webhookin allekirjoitussalaisuuden 8 ensimmäistä merkkiä; mukana vain, kun salaisuus on määritetty. Antaa kutsujan erottaa, mikä salaisuus on käytössä, näkemättä koko arvoa. Hallintapaneeli näyttää saman etuliitteen.
readiness.missing_fields- Lista hallintapaneelin kenttien nimistä, jotka vaaditaan vielä ennen Go Live -vaihetta. Tyhjä, kun
readyontrue. Riittävän vakaa ohjaamaan ”mitä vielä puuttuu” -näkymää omassa hallintakäyttöliittymässäsi. readiness.dns_blocker- Lyhyt syykoodi, kun DNS-tarkistus epäonnistuu (esim.
nameservers_not_pointing,glue_record_missing). Muulloinnull. section_status.*.issue- Osiokohtainen, ihmiselle luettava vihje, kun kyseinen osio estää Go Live -vaiheen. Vastaa hallintapaneelin osiokohtaisia tilamerkkejä.
Esimerkki
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"])
Katalogi¶
Verkkokauppasi myytävien pakettien lista – julkiset paketit
(trial / starter / pro) yhdistettynä sinun ratkaistuun hinnoitteluusi,
sinun hinnoitteluvaluutassasi. Rakenna pakettikorttisi tämän perusteella sen
sijaan, että kovakoodaisit tasotunnisteet ja hinnat: poistuneet paketit
katoavat itsestään, ja hallintapaneelissa tekemäsi hinnan tai valuutan muutos
näkyy verkkokaupassasi sen välimuistiajan sisällä – ilman uutta julkaisua.
Tämä on se päätepiste, joka estää verkkokauppaa mainostamasta eilisiä
paketteja. Referenssiportaali kutsuu sitä jokaisella aloitussivun, /buy- ja
/extend-sivun renderöinnillä (välimuistitettuna, pysyvällä varakopiolla).
Näyttötekstit pysyvät sinun käsissäsi
display_name / description / featured ovat mintbotin kanonisia
pakettien metatietoja. Jos haluat nimetä paketin uudelleen tai kirjoittaa
sen kuvauksen brändillesi sopivaksi, ohita ne omassa verkkokaupassasi
(referenssiportaalissa on juuri tätä varten PLAN_OVERRIDES-taulukko) –
katalogi on totuuden lähde sille, mitä paketteja on olemassa ja mitä ne
maksavat, ei markkinointiteksteillesi.
Hae katalogi¶
GET /api/v1/catalog
Ei parametreja. Vain Bearer-autentikointi – aktivointiporttia ei ole, joten verkkokauppa voi renderöidä katalogin jo ennen kuin kumppanitilisi on kytketty live-tilaan.
Vastaus
{
"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 }
}
]
}
| Kenttä | Merkitys |
|---|---|
currency |
Hinnoitteluvaluuttasi. Jokainen alla oleva price_cents on tässä valuutassa. |
packages[] |
Yksi rivi per julkinen paketti, tarjonta-/näyttöjärjestyksessä. |
tier |
Tunniste, jonka annat päätepisteille POST /orders / POST /subscriptions. |
display_name / description / featured |
Kanoniset näyttötekstit (voit ohittaa ne omassa verkkokaupassasi). |
default_credit_usd |
Pakettiin sisältyvän LLM-krediitin ohjearvo (informatiivinen). |
durations[] |
Kestot, joilla paketin voi ostaa. months on arvo, jonka lähetät kenttänä duration_months; price_cents on summa, jonka tilaus veloittaa. Kuukausipaketit tarjotaan 1 / 3 / 12 kuukaudeksi; trial tarjotaan vain yhdellä 24 tunnin kestolla. |
subscription |
available on true paketeille, jotka voi ostaa kuukausittain automaattisesti uusiutuvana päätepisteen POST /subscriptions kautta; price_cents on kuukausisumma. trial ei koskaan tue kuukausitilausta. |
Hinnat vastaavat todellista veloitusta
Jokainen price_cents lasketaan samalla hinnoittelulogiikalla kuin
tilauspäätepisteessä, joten kortin hinta on aina sama kuin lopullinen Stripe
Checkout -summa kyseiselle (tier, duration_months)-yhdistelmälle.
Esimerkki¶
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-tietueet¶
Brand Partner -integraatiot tarvitsevat usein DNS-tietueita kumppanin apex-verkkotunnukseen – @-, www- tai asiakaskohtaisten aliverkkotunnusten osoittamista oikeaan palvelimeen. MintOffice tarjoaa tähän toimittajariippumattoman välityspalvelun, jotta voit tehdä sen käsittelemättä koskaan DNS-palveluntarjoajan API-avainta omassa infrastruktuurissasi. Käyttöönotossa tallentamasi tunnistetiedot (tällä hetkellä zone.ee; cloudflare ja route53 ovat tiekartalla samalla rakenteella) pysyvät salattuina MintOfficessa; kutsusi tulee Bearer mo_live_…-tokenilla, ja me teemme kutsun palveluntarjoajalle puolestasi.
Toiminta rajoittuu kumppanin omaan, määritettyyn apex-verkkotunnukseen (domain.client_apex_domain päätepisteestä GET /settings). Et voi koskea tietueisiin vyöhykkeellä, jota et omista.
Tällä hetkellä välityspalvelu tukee samoja operaatioita, joita käyttöönottoputki itse käyttää – A-tietueita (upsert / listaus / poisto id:llä). CNAME-, TXT- ja MX-tuki seuraa samalla rakenteella, kun taustalla oleva palveluntarjoaja-abstraktio laajenee niihin.
Idempotency-Key ei ole tarpeen tässä
Toisin kuin tilausten luontipäätepisteet, DNS-upsertit ovat palveluntarjoajan tasolla luonnostaan idempotentteja (saman (subdomain, ip)-parin ajaminen uudelleen ei muuta mitään, ja vanhentuneet kaksoiskappaleet siivotaan jokaisella kutsulla). Idempotency-Key-otsaketta ei tarvitse lähettää – uudelleenyritykset päätyvät aina yhteen A-tietueeseen per FQDN.
Luo tai päivitä A-tietue¶
POST /dns/records
Osoittaa <subdomain>.<your-apex>-nimen idempotentisti IPv4-osoitteeseen. Anna "" (tai "@") itse apex-verkkotunnukselle.
Pyyntö
{
"subdomain": "www",
"ip": "203.0.113.10"
}
subdomain hyväksyy:
""tai"@"– itse apex-verkkotunnus (example.com).- Yksittäinen DNS-nimiosa –
"www","api"– nimelle<label>.<apex>. - Pisteellä erotetut nimiosat –
"api.eu"– sisäkkäisille aliverkkotunnuksille (api.eu.example.com).
ip on oltava pisteillä erotettu IPv4-osoite. Jokainen nimiosa on muotoa [a-z0-9_-], 1–63 merkkiä, ei --merkkiä alussa tai lopussa.
Vastaus – 200
{
"apex": "example.com",
"provider": "zone_ee",
"fqdn": "www.example.com",
"records": [
{ "id": "9182734", "name": "www.example.com", "destination": "203.0.113.10" }
]
}
Kirjoituksen jälkeinen records-lista kuvaa aina palveluntarjoajan senhetkisen näkymän FQDN:stä kaksoiskappaleiden siivouksen jälkeen – joten onnistunut vastaus, jossa on täsmälleen yksi tietue, on merkki siitä, ettei mitään vanhentunutta ole jäljellä.
Listaa tietueet¶
GET /dns/records
Palauttaa kaikki määritetyn apex-verkkotunnuksen A-tietueet. Lisää ?name=<label-or-fqdn>, jos haluat rajata yhteen FQDN:ään – arvo voi olla pelkkä nimiosa ("www"), pisteellinen aliverkkotunnus ("api.eu") tai täysi FQDN ("www.example.com").
Vastaus – 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" }
]
}
Poista tietue¶
DELETE /dns/records/{record_id}
record_id on palveluntarjoajan tunniste, jonka GET /dns/records palauttaa (zone.ee antaa kokonaisluku-id:t, jotka muunnetaan merkkijonoiksi API-rajalla). Jo poistetun tietueen poistaminen tulkitaan onnistuneeksi – päätepiste on asiakkaan näkökulmasta idempotentti.
Vastaus – 200
{ "deleted": true, "id": "9182734" }
Virheet¶
| HTTP | error.code |
Syy |
|---|---|---|
| 401 | unauthenticated / invalid_api_key |
Puuttuva tai virheellinen Bearer-token. |
| 422 | validation_error |
Virheellinen aliverkkotunnus tai kohde ei ole IPv4-osoite. |
| 422 | dns_not_configured |
Kumppanilla ei ole client_apex_domain-arvoa tai määritetyn palveluntarjoajan tunnistetiedot puuttuvat. Korjaa kohdassa Settings → Domain. |
| 422 | dns_provider_unsupported |
Kumppanin DNS-palveluntarjoajaa ei ole vielä kytketty MintOfficen välityspalveluun (esim. cloudflare-paikkamerkki). Vaihda toistaiseksi arvoon zone_ee. |
| 502 | dns_provider_error |
Palveluntarjoaja palautti 4xx/5xx-virheen tai yhteys epäonnistui. Virheen message sisältää palveluntarjoajan tilakoodin ja lyhyen, salaisuuksista siivotun otteen vastauksesta. Uudelleenyritys on turvallinen. |
Esimerkki¶
# 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"])
Webhookit¶
Kun tilaukselle tapahtuu jotain, lähetämme POST-pyynnöllä allekirjoitetun JSON-tapahtuman määrittämääsi webhook-URL:iin.
Webhookit ovat valinnaisia
Kohdan Settings → API access kentät Webhook URL ja Webhook signing secret ovat täysin valinnaisia – jätä ne tyhjiksi käyttöönotossa, jos sinulla ei vielä ole vastaanotinta. Hallintapaneeli ja muu API toimivat mainiosti ilman webhookeja; voit sen sijaan seurata elinkaarta kyselemällä päätepistettä GET /api/v1/orders/{id}. Lisää URL (ja luo salaisuus), kun olet valmis – uutta aktivointia ei tarvita.
Tapahtumatyypit¶
| Tapahtuma | Milloin se laukeaa |
|---|---|
order.created |
Stripe Checkout -istunto luotu, odottaa maksua. |
order.paid |
Stripe vahvisti maksun. Tulotapahtuma kirjattu. |
order.cancelled |
Tilaus vanheni tai peruttiin erikseen. |
agent.provisioning_started |
Käyttöönottoputki käynnistyi tälle tilaukselle. |
agent.ready |
Käyttöönotto onnistui. Hyötykuorma sisältää kentät panel_url ja expires_at. |
agent.failed |
Käyttöönottoputki epäonnistui. Katso error-kentästä, mikä vaihe rikkoutui. |
agent.expired |
Agentin elinaika päättyi. Kumppani voi uusia sen päätepisteellä POST /orders/{id}/renew. |
agent.resumed |
Aiemmin vanhentunut agentti uusittiin siirtymäajan sisällä ja on taas käytössä. Tapahtuman agent.expired palautumisvastine. |
Toimitus ja uudelleenyritykset¶
- Enintään 7 yritystä eksponentiaalisella aikataululla:
0s, 30s, 2m, 10m, 1h, 6h, 24h. - Viimeisen yrityksen jälkeen toimitus merkitään tilaan
exhausted, eikä sitä yritetä enää. - Kuittaa vastaanotto vastaamalla
2xx-tilakoodilla 10 sekunnin sisällä.
Pyynnön otsakkeet¶
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
Esimerkkihyötykuorma – 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"
}
Allekirjoituksen tarkistus¶
Allekirjoitus on HMAC-SHA256(secret, "{timestamp}.{raw_body}"). Tarkista aina pyynnön raaka runko – jäsennetyn JSONin sarjallistaminen uudelleen rikkoo vertailun.
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"),
);
}
Idempotentit vastaanottimet
Käytä X-Mintbot-Event-Id-arvoa deduplikointiavaimena – uudelleenyritykset käyttävät samaa id:tä, joten rivitason INSERT … ON CONFLICT DO NOTHING kyseiseen sarakkeeseen pitää käsittelijäsi turvassa.
Referenssiportaali¶
Ajettava, kokonainen referenssitoteutus löytyy osoitteesta mintbot-ai/partner-portal-example – FastAPI + SQLite, Docker-paketoitu, mukana esimerkkibrändi ExampleAI, jonka forkkaat ja vaihdat omaasi. Arkkitehtuurikuva – miten verkkokauppa, tämä API, käyttöönottotyöntekijä ja mukautusrepo sopivat yhteen – on sivulla MintOffice – Tekninen. Portaali toteuttaa:
- aloitus-, pakettivalinta-, kiitos- ja peruutussivut,
POST /buy→POST /api/v1/orders→ Stripe-uudelleenohjaus,POST /webhooks/mintofficeyllä kuvatulla HMAC-tarkistuksella,- HTTP Basic -autentikoidun
/admin-tapahtumaselaimen toimitusten silmäilyyn.
Forkkaa se, aseta .env-tiedostoon PARTNER_BRAND, MINTOFFICE_API_KEY ja MINTOFFICE_WEBHOOK_SECRET, aja docker compose up ja osoita kumppanirivisi webhook-URL osoitteeseen https://<your-host>/webhooks/mintoffice. Koko läpikäynti: MintOffice → Referenssiportaali.
Virheet¶
Jokaisessa virhevastauksessa on vakaa code, jonka perusteella voit haarauttaa ohjelmallisesti. message-kenttä on ihmiselle luettava vihje ja voi muuttua julkaisujen välillä. request_id on sama kuin vastauksen X-Request-Id-otsake – liitä se tukipyyntöihin.
{
"error": {
"code": "invalid_api_key",
"message": "API key is unknown or revoked.",
"request_id": "f0c2d6c4-…"
}
}
| Koodi | Merkitys |
|---|---|
unauthenticated |
Puuttuva tai virheellisesti muodostettu Authorization-otsake. |
invalid_api_key |
API-avain on tuntematon tai se on kierrätetty pois käytöstä. |
rate_limited |
Kumppani- tai IP-kohtainen nopeusraja ylittyi – katso Retry-After. |
missing_idempotency_key |
POST-pyyntö ilman Idempotency-Key-otsaketta. |
idempotency_key_mismatch |
Samaa avainta käytettiin uudelleen eri pyyntörungolla. |
validation_error |
Pyyntörunko ei läpäissyt skeemavalidointia. |
not_found |
Resurssia ei ole olemassa tai se ei kuulu kumppanillesi. |
payment_gateway_error |
Stripe hylkäsi Checkout-istunnon luonnin. |
dns_not_configured |
POST /dns/records kumppanille, jolla ei ole apex-verkkotunnusta tai DNS-tunnistetietoja. Korjaa kohdassa Settings → Domain. |
dns_provider_unsupported |
Kumppanin dns_provider-arvoa ei ole vielä kytketty MintOfficen välityspalveluun. |
dns_provider_error |
DNS-palveluntarjoaja palautti virheen – viesti sisältää siivotun otteen. |
quota_exceeded |
Kumppani on käyttänyt kaikki käyttöönottopaikkansa (oletus 10). Ota yhteyttä mintbotin tukeen rajan nostamiseksi. Palauttavat POST /orders ja POST /orders/{id}/renew. Runko sisältää kentät deploys_used ja deploy_quota. |
Nopeusrajat¶
- 120 pyyntöä / 60 s liukuva ikkuna per kumppani. Purskeet ja tasainen liikenne jakavat saman kiintiön.
- 60 pyyntöä / 60 s erillinen IP-kohtainen kiintiö autentikoimattomille ja epäonnistuneen autentikoinnin pyynnöille – estää Bearer-tokenien arvailua kuluttamasta kumppanin kiintiötä.
- Ylimenevät pyynnöt palauttavat
429 rate_limitedjaRetry-After-otsakkeen (odotusaika sekunteina).
Tarvitsetko apua?¶
Nämä dokumentit on kirjoitettu kumppaneille, jotka oikeasti käyttävät API:a. Jos jotain puuttuu, on epäselvää tai vanhentunutta, mainitse siitä mintbot-agentillesi – se välittää palautteen eteenpäin, ja me päivitämme sivun.