Hyppää sisältöön

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, 3 tai 12.
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_failed tai expired.
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 arvoon false, 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 tilassa onboarding.
domain.mode
byo (tuot oman apex-verkkotunnuksesi) tai hosted (mintbot tarjoaa *.mintbot.ai-aliverkkotunnuksen). Tilassa hosted DNS-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- ja subdomain_pad_width-arvoilla. Käytä sitä ”tältä tämä näyttää asiakkaillesi” -esikatseluun toteuttamatta numerointisääntöjä itse uudelleen.
bot.mode
own (kumppanin oma Telegram-botti), borrow (mintbotin botti lainassa testauksen ajan) tai web (vain paneeli, ei Telegramia).
template.mode
default (ei agentin mukautusrepoa – agentti pyörii tavallisella, brändäämättömällä pohjalla) tai custom (kumppanin agentin mukautusrepo osoitteessa repo_url). Tilassa custom agentin oma VPS kloonaa repon vakiokäyttöönoton jälkeen ja ajaa sen install.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. Osoita repo_url agentin 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 ready on true. 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). Muulloin null.
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 /buyPOST /api/v1/orders → Stripe-uudelleenohjaus,
  • POST /webhooks/mintoffice yllä 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_limited ja Retry-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.