API-Dokumentation

meersys Bestell-API

Kunden anlegen, Domain-Verfügbarkeit prüfen und Produkte bestellen – direkt aus euren eigenen Projekten, ohne Zugriff auf den Admin-Bereich.

Überblick

Was die API kann

Eine schlanke REST-API für Subprojekte, die Bestellungen bei meersys auslösen sollen – ganz ohne Login im Kundenportal.

Über die Bestell-API könnt ihr aus eigenen Anwendungen heraus Kunden anlegen, Domain-Verfügbarkeit prüfen und Bestellungen auslösen – zum Beispiel Domain-Registrierungen, -Transfers oder andere Produkte aus dem meersys-Katalog.

Alle Antworten sind JSON. Das Bestellmodell ist bewusst „pay-first": eine Bestellung erzeugt zunächst einen Service (Status pending) und eine Rechnung – erst nach Zahlungseingang wird tatsächlich etwas beim Registrar registriert oder transferiert. Ein Fehler in dieser API kann also nie versehentlich echte Kosten auslösen.

Endpunkt
/api/v1.php
Authentifizierung
Bearer API-Key
Format
JSON (Request & Response)
Rate-Limit
konfigurierbar pro Key (Standard 60/min)
Zugang

Authentifizierung

Jeder Request braucht einen API-Key im Authorization-Header.

HEADER
Authorization: Bearer msk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Alternativ als Query-Parameter (nur falls kein Header möglich ist – landet sonst in Logs):

# nur wenn kein Header möglich
GET /api/v1.php?resource=ping&api_key=msk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Es gibt zwei Arten von Keys:

  • Unbegrenzt – voller Zugriff, customer_id muss im Request mitgegeben werden.
  • An einen Kunden gebunden – sieht/erstellt ausschließlich Daten dieses einen Kunden; customer_id wird automatisch verwendet und im Request ignoriert.

Kontaktiert uns für einen Key: [email protected].

Bei ungültigem oder fehlendem Key antwortet die API mit 401 und {"ok": false, "error": "Invalid API key"}. Jede Antwort enthält außerdem die Header X-RateLimit-Limit und X-RateLimit-Remaining.

Referenz

Endpunkte

Acht Ressourcen – von der Verbindungsprüfung bis zur fertigen Bestellung.

GET ?resource=ping

Verbindungstest – zeigt an, welcher Key genutzt wird und ob er an einen Kunden gebunden ist.

Beispiel-Antwort

{
  "ok": true,
  "version": "1.0",
  "app": "MeerSYS CCP",
  "key": "Mein Projekt",
  "customer_id": 0,
  "time": "2026-07-29T09:10:06+02:00"
}
GET ?resource=customers&id=123

Einzelnen Kunden lesen. Ohne id (nur mit unbegrenztem Key) liefert &limit=50 eine Liste (max. 100).

POST ?resource=customers nur unbegrenzter Key

Neuen Kunden anlegen – inklusive Portal-Login. Ohne vollständige Adresse käme später ohnehin keine echte Domain-Registrierung beim Registrar durch, deshalb wird das schon hier geprüft.

Parameter

FeldPflichtHinweis
emailPflichtgültige E-Mail-Adresse
first_name / last_namePflicht**oder company
companyoptional**oder first_name+last_name
phone / mobilePflicht**mindestens eines von beiden
streetPflichtStraße
house_numberoptionalHausnummer
zipPflichtPostleitzahl
cityPflichtOrt
countryoptionalISO-2, Standard DE

Beispiel-Request

{
  "email": "[email protected]",
  "first_name": "Max", "last_name": "Mustermann",
  "phone": "+49 30 1234567",
  "street": "Musterstraße", "house_number": "12",
  "zip": "12345", "city": "Berlin", "country": "DE"
}

Beispiel-Antwort

{
  "ok": true,
  "customer_id": 42,
  "customer_number": "K-2026-1234",
  "user_created": true
}

Es wird automatisch ein Portal-Login angelegt (falls noch keins existiert) und eine „Konto einrichten"-Mail mit 7 Tage gültigem Link zum Passwort-Festlegen verschickt. Existiert die E-Mail bereits, wird die vorhandene ID zurückgegeben ("existing": true) statt eines Duplikats.

GET ?resource=products

Alle aktiven, bestellbaren Produkte inkl. Netto- und Bruttopreis. Domain-Produkte mit fester Endung (z.B. „.de-Domain") liefern die erkannte Endung in fixed_tld – exakt die Endung, die eine bestellte Domain bei orders haben muss.

Beispiel-Antwort

{
  "ok": true, "vat_rate": 19,
  "products": [
    { "id": 4, "name": ".de-Domain", "category": "domain",
      "billing_cycle": "yearly", "is_domain_product": true,
      "fixed_tld": "de", "price_net": 7.08, "price_gross": 8.43 },
    { "id": 1, "name": "Webhosting Basic", "category": "hosting",
      "billing_cycle": "monthly", "is_domain_product": false,
      "fixed_tld": null, "price_net": 4.99, "price_gross": 5.94 }
  ]
}
GET ?resource=domain_check&domain=example.de

Einzelne Domain auf Verfügbarkeit prüfen, plus aktueller Registrierungspreis (netto) falls hinterlegt.

Beispiel-Antwort

{
  "ok": true, "domain": "example.de",
  "available": false, "status": "unavailable",
  "error": null, "price_net": 7.08
}

available ist true / false / null (null = Antwort nicht eindeutig interpretierbar – im Zweifel wie „unklar" behandeln). Ist die Verfügbarkeitsprüfung nicht konfiguriert, kommt 503.

POST ?resource=orders

Bestellung anlegen. Erzeugt einen Service (pending) plus Rechnung – keine echte Registrierung/Transfer beim Registrar. Das passiert erst nach bestätigtem Zahlungseingang, komplett getrennt von dieser API.

Parameter

FeldPflichtHinweis
customer_idPflicht**entfällt bei gebundenem Key
product_idPflichtID aus resource=products
domainPflicht**wenn Produkt ein Domain-Produkt ist
is_transferoptionaltrue = Transfer statt Neuregistrierung
auth_codePflicht**bei is_transfer: true

Beispiel-Request

{
  "customer_id": 42, "product_id": 4,
  "domain": "example.de"
}

Beispiel-Antwort

{
  "ok": true, "service_id": 123,
  "invoice_id": 456, "domain": "example.de", "error": null
}

Bei Domain-Produkten mit fester Endung muss domain exakt darauf enden. Ohne Transfer wird die Verfügbarkeit live geprüft – vergeben oder unklar ergibt 422 mit Begründung.

GET ?resource=invoices&id=456

Rechnung inklusive Positionen lesen.

GET ?resource=services&id= | &customer_id=

Service(s) inkl. Status (pending/active/…), Fälligkeit und Preis – damit lässt sich pollen, ob eine Bestellung schon bezahlt/aktiv wurde.

Praxis

Kompletter Ablauf

Kunde anlegen → Domain prüfen → bestellen → Status verfolgen.

# 0. Verbindung testen
curl -s -H "Authorization: Bearer $KEY" \
  "https://euer-server/api/v1.php?resource=ping"

# 1. Kunde anlegen (oder vorhandene ID verwenden)
curl -s -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","first_name":"Max","last_name":"Mustermann","phone":"+49 30 1234567","street":"Musterstraße","zip":"12345","city":"Berlin"}' \
  "https://euer-server/api/v1.php?resource=customers"

# 2. Domain prüfen
curl -s -H "Authorization: Bearer $KEY" \
  "https://euer-server/api/v1.php?resource=domain_check&domain=example.de"

# 3. Bestellen
curl -s -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"customer_id":42,"product_id":4,"domain":"example.de"}' \
  "https://euer-server/api/v1.php?resource=orders"

# 4. Später: Status prüfen
curl -s -H "Authorization: Bearer $KEY" \
  "https://euer-server/api/v1.php?resource=services&customer_id=42"
Referenz

Fehlercodes

HTTPBedeutung
400Pflichtfeld fehlt oder ungültig
401API-Key fehlt oder ungültig
403Gebundener Key versucht auf fremde Daten zuzugreifen
404Ressource/ID nicht gefunden
422Domain-Validierung fehlgeschlagen (Endung passt nicht, nicht verfügbar, Auth-Code fehlt)
429Rate-Limit überschritten (Retry-After-Header beachten)
503Domain-Verfügbarkeitsprüfung nicht konfiguriert

API-Keys sind Klartext-Secrets – wie Passwörter behandeln, nicht in Frontend-Code oder öffentliche Repos einchecken.