API-referentie

Met de veldhost-API kun je alles scripten wat de knoppen in het portaal doen: deploys, logs, health, staging, cron, back-ups, domeinen en DNS. De API drijft de mpc-CLI aan en werkt vanuit elke HTTP-client, CI-pipeline of AI-agent.

Authenticatie

Maak een token aan onder API tokens en stuur het mee als bearer-token:

curl -H "Authorization: Bearer mpc_..." https://manage.veldhost.eu/api/v1/sites

Bij het aanmaken van een token kies je welke sites het mag aanraken en wat het mag doen: read (altijd aan), deploy, manage (site-instellingen, domeinen, staging, cron, back-ups en herstel, webhooks), dns, en twee die je bewust aanzet: data (SQL op je databases) en billing (bestellingen voorstellen die jij goedkeurt). Scopes en rechten legt ze uit, met wie ze mag geven. Rate limit: 120 verzoeken per minuut. Een machineleesbare specificatie staat op /api/v1/openapi.json.

Sites

GET    /api/v1/sites                      your sites: state, url, health, deploy_state
POST   /api/v1/sites/{slug}/deploy        deploy from git ({"ref": "main"} optional)
GET    /api/v1/sites/{slug}/deploys       deploy history
GET    /api/v1/sites/{slug}/logs?log=app  last 200 lines (app, php, nginx-error, access)
GET    /api/v1/sites/{slug}/health        live health + open incidents
GET    /api/v1/sites/{slug}/traffic       disk + monthly traffic

Back-ups en staging

GET    /api/v1/sites/{slug}/backups       list restore points
POST   /api/v1/sites/{slug}/backups       back up now
POST   /api/v1/sites/{slug}/restore       {"backup_id": 12} — replaces live content
GET    /api/v1/sites/{slug}/staging       staging status + url
POST   /api/v1/sites/{slug}/staging       {"action": "create" | "refresh" | "off"}

Staging is alleen voor eigenaren. Op een abonnement waar het niet bij zit voegt aanmaken een betaalde add-on toe, dus antwoordt de API met 402 en requires_order: stel het dan voor als bestelling (hieronder).

Site-instellingen en domeinen

GET    /api/v1/sites/{slug}/settings      PHP/Node.js-versie, startcommando, buildstappen, domein, namen van variabelen
PUT    /api/v1/sites/{slug}/env/{KEY}     {"value": "...", "secret": true} aanmaken of vervangen (manage)
DELETE /api/v1/sites/{slug}/env/{KEY}     variabele verwijderen (manage)
PATCH  /api/v1/sites/{slug}/runtime       {"php_version": "8.4"} of node_version / start_command (manage)
PATCH  /api/v1/sites/{slug}/build         install/build/test-commando's, migraties, staging-branch (deploy)
POST   /api/v1/sites/{slug}/domain        {"domain": "example.com"} een domein koppelen (manage)

Releases

POST   /api/v1/sites/{slug}/deploys/{id}/approve    een release die op goedkeuring wacht publiceren (deploy)
POST   /api/v1/sites/{slug}/deploys/{id}/discard    weggooien; de live site blijft ongemoeid
POST   /api/v1/sites/{slug}/deploys/{id}/rollback   bestanden terug naar een eerdere release; de database verandert niet

Bestellingen

POST   /api/v1/orders                     {"kind": "plan_change", "plan": "pro"} voorstellen (billing)
GET    /api/v1/orders                     voorgestelde bestellingen en hun status
GET    /api/v1/orders/{id}                één bestelling: prijs, approve_url, uitkomst
DELETE /api/v1/orders/{id}                intrekken zolang hij wacht

De API koopt niets: de eigenaren en facturatieleden van het account krijgen een e-mail en keuren de bestelling goed in het portaal. Zie Bestellen met een AI-assistent.

Geplande taken

GET    /api/v1/sites/{slug}/cron          list jobs with their index
POST   /api/v1/sites/{slug}/cron          {"schedule": "*/5 * * * *", "command": "php artisan queue:work"}
DELETE /api/v1/sites/{slug}/cron/{index}  remove a job

Domeinen en DNS

GET    /api/v1/domains                    registered domains: expiry, auto-renew, DNSSEC
GET    /api/v1/domains/{domain}/registrar registry vs live nameservers, DNSSEC state, lock, privacy
PUT    /api/v1/domains/{domain}/nameservers  {"mode": "custom", "nameservers": ["ns1.example.com", "ns2.example.com"]}
GET    /api/v1/dns                        your DNS zones
POST   /api/v1/dns/zones/probe            {"domain": "example.com"} dry run: live zone as an import plan + registrar steps (dns scope)
GET    /api/v1/dns/{zone}/records         zone records
POST   /api/v1/dns/{zone}/records         {"name": "www", "type": "CNAME", "ttl": 3600, "content": "example.com."}
PUT    /api/v1/dns/{zone}/records/{id}    update a record
DELETE /api/v1/dns/{zone}/records/{id}    delete a record

DNS-wijzigingen staan binnen een seconde live op onze nameservers.

Nameservers wijzigen vereist de scope dns, en wordt geweigerd met een 409 en een continue_url zolang DNSSEC actief is op het domein: het register staat in voor onze ondertekeningssleutel, dus de delegatie verplaatsen voordat die is ingetrokken (en de cachetijd ervan is verstreken) zou ervoor zorgen dat validerende resolvers het domein volledig weigeren. Het portaal leidt je erdoorheen. Je zone en records blijven hier hoe dan ook bewaard, dus terugschakelen gaat direct.

E-mail

GET    /api/v1/mail                       domeinen met veldhost-e-mail, en elke mailbox met zijn status
GET    /api/v1/mail/{domain}              één domein met alleen e-mail: het verificatierecord, of de mailrecords die nog moeten worden toegevoegd
POST   /api/v1/mail/{domain}/verify       controleer het verificatierecord nu (dns-scope)

Mailboxen zelf maak je in het portaal aan: daar hoort het wachtwoord van de mailbox bij, en een wachtwoord hoort niet via een API-token te lopen. De status van een mailbox is active, locked (de betaling van het account is achterstallig: er komt nog mail binnen, maar niemand kan inloggen) of archived (verwijderd; de mail wordt bewaard tot deleted_for_good_at).

Wat de API bewust niet doet

De API neemt nooit betalingen aan en vraagt nooit om kaartgegevens: bestellingen zijn voorstellen die een persoon in het portaal goedkeurt, met dezelfde voorwaarden en checkout als wanneer je zelf bestelt. Een site, domein of DNS-zone verwijderen, tokens aanmaken en het team wijzigen zijn helemaal niet beschikbaar. Roept een AI-assistent (een OAuth-client of de MCP-server) iets aan dat niet terug te draaien is, zoals een back-up terugzetten, DNSSEC aanzetten of een warehouse-database verwijderen, dan antwoordt de eerste aanroep met 409, needs_confirmation en een confirm_token, en pas een herhaling met dat token voert het uit; een script met een persoonlijk token wordt dat niet gevraagd.