StudioMeyer API: öffentliche Website-Daten lesen
Die Basisadresse ist https://studiomeyer.io/api/v1. Für die folgenden GET-Aufrufe brauchst du weder Konto noch API-Key. Die Beispiele lesen veröffentlichte Leistungen und fiktive Demo-Seiten; sie übermitteln keine Kontaktdaten und starten keinen Kauf.
Schnellstart: curl, JavaScript und Python
GET /api/v1/services?lang=de liefert den Leistungskatalog auf Deutsch. Mit lang=en oder lang=es wählst du Englisch oder Spanisch; ohne lang ist Englisch voreingestellt. GET /api/v1/portfolio liest das Demo-Portfolio.
Das JavaScript-Beispiel nutzt fetch und lässt sich in einer .mjs-Datei mit Node.js ausführen. Das Python-Beispiel verwendet nur urllib und json aus der Standardbibliothek. Beides sind HTTP-Beispiele, keine veröffentlichten StudioMeyer-SDKs.
Python sendet mit User-Agent: StudioMeyer-API-Example/1.0 eine ausdrückliche Anwendungskennung statt der Standardkennung der Bibliothek.
curl --fail-with-body \
-H "Accept: application/json" \
"https://studiomeyer.io/api/v1/services?lang=de"
curl --fail-with-body \
-H "Accept: application/json" \
"https://studiomeyer.io/api/v1/portfolio?limit=1"const response = await fetch(
"https://studiomeyer.io/api/v1/services?lang=de",
{ headers: { Accept: "application/json" } }
);
const data = await response.json();
if (!response.ok) throw new Error(`${response.status}: ${data.message}`);
console.log(data.language, data.webdesign.packages);import json
from urllib.error import HTTPError
from urllib.request import Request, urlopen
request = Request(
"https://studiomeyer.io/api/v1/services?lang=de",
headers={
"Accept": "application/json",
"User-Agent": "StudioMeyer-API-Example/1.0",
},
)
try:
with urlopen(request, timeout=20) as response:
data = json.load(response)
print(data["language"], data["webdesign"]["packages"])
except HTTPError as error:
problem = {}
if "json" in error.headers.get("Content-Type", "").lower():
try:
problem = json.loads(error.read().decode("utf-8", errors="replace"))
except json.JSONDecodeError:
pass
if not isinstance(problem, dict):
problem = {}
message = (problem.get("message") or problem.get("detail")
or problem.get("title") or problem.get("error") or error.reason)
raise RuntimeError(f"HTTP {error.code}: {message}") from errorAntworten als Daten verarbeiten
Die Services-Antwort ist ein JSON-Objekt mit agency, website, language und den Leistungsbereichen. webdesign enthält packages, payment, scope und care. Jedes Paket nennt id, name, price, priceType und delivery. Übernimm Preise und Bedingungen aus dieser Antwort, statt eigene Preislisten im Client zu pflegen.
Das folgende JSON ist ein Ausschnitt der Services-Antwort. Das vollständige Schema steht in OpenAPI. Die Portfolio-Antwort enthält unter anderem projects, total, demos, filters und next_cursor. Jeder Portfolio-Eintrag hat type: "demo"; diese Beispiele sind keine Kundenreferenzen.
{
"agency": "StudioMeyer",
"language": "de"
}Demo-Portfolio filtern und seitenweise lesen
limit ist eine ganze Zahl von 1 bis 100, Standard ist 20. Lasse cursor beim ersten Aufruf weg. Übernimm danach next_cursor unverändert als cursor für die nächste Seite, bis next_cursor null ist. Halte Filter und Seitengröße beim Weiterblättern gleich.
industry akzeptiert immobilien, gastronomie, hotellerie oder alle; style akzeptiert premium, modern oder alle. Nutze die dokumentierten Werte: unbekannte Filterwerte schränken das Ergebnis derzeit nicht ein. Ein ungültiger Cursor oder ein limit außerhalb des erlaubten Bereichs ergibt HTTP 400.
const url = new URL("https://studiomeyer.io/api/v1/portfolio");
url.searchParams.set("limit", "2");
let cursor = null;
do {
if (cursor === null) url.searchParams.delete("cursor");
else url.searchParams.set("cursor", cursor);
const response = await fetch(url);
const page = await response.json();
if (!response.ok) throw new Error(`${response.status}: ${page.message}`);
console.log(page.projects);
cursor = page.next_cursor;
} while (cursor !== null);HTTP-Status und strukturierte Fehler beachten
Prüfe zuerst den HTTP-Status. Fehlerantworten tragen success: false sowie code, message, resolution und das bestehende error-Feld. Zusätzliche Felder hängen vom Endpunkt ab. Die Fehlertexte sind derzeit Englisch, auch wenn du Leistungen auf Deutsch liest.
GET /api/v1/portfolio?limit=0 ergibt HTTP 400 mit der folgenden Antwort. Ein nicht unterstütztes HTTP-Verfahren ergibt 405; der Allow-Header nennt die unterstützten Methoden. Korrigiere die Anfrage anhand des Vertrags und der resolution, statt unverändert weiterzusenden.
{
"success": false,
"code": "VALIDATION_ERROR",
"message": "limit must be an integer between 1 and 100",
"error": "Invalid pagination limit",
"resolution": "Check the request parameters and JSON body against the API documentation."
}Anfragegrenzen und Wiederholungen
Die öffentliche Website-API erlaubt 60 Anfragen pro Minute und IP-Adresse. RateLimit, RateLimit-Policy und die X-RateLimit-Header geben den aktuellen Stand an. Bei HTTP 429 warte mindestens die in Retry-After genannten Sekunden. Auch bei einer vorübergehend nicht verfügbaren Limitprüfung kann eine 503-Antwort Retry-After enthalten.
Verteile Aufrufe über die Zeit und plane keine sofortige Wiederholungsschleife. Die anonymen Website-Grenzen sind unabhängig von den Tageskontingenten eines Memory-Produktkontos.
Kontaktanfragen brauchen eine Freigabe
POST /api/v1/consultation ist eine unverbindliche Kontaktanfrage. Ein Mensch vereinbart den Termin anschließend; die API bucht keinen Termin. Sende den Aufruf nur, wenn der Nutzer die Kontaktaufnahme verlangt und die Weitergabe seiner Kontaktdaten genehmigt hat. Diese Anleitung führt keinen Kontaktaufruf aus.
Für eine genehmigte Anfrage unterstützt der Endpunkt optional Idempotency-Key. Verwende eine zufällige UUID für genau eine beabsichtigte Anfrage und bei Wiederholungen denselben Schlüssel mit demselben JSON-Body. Ein geänderter Body ergibt 409 IDEMPOTENCY_CONFLICT. Bei 409 IDEMPOTENCY_IN_PROGRESS beachte Retry-After und verwende weiter denselben Schlüssel und Body. Bleibt der Vorgang unvollständig, kläre ihn mit dem Support; wechsle nicht automatisch auf einen neuen Schlüssel.
Diese Idempotenzregel gilt für den dokumentierten Anfrage-Endpunkt, nicht pauschal für jede API. Konto- und Zahlungsflüsse haben separate Verträge und Berechtigungsgrenzen.
Verträge und weitere Dokumentation
OpenAPI beschreibt Parameter, JSON-Schemas, Statuscodes und Header. Die interaktive Swagger-Dokumentation verwendet denselben öffentlichen Vertrag. Prüfe vor einem schreibenden Aufruf immer dessen Wirkung und die erforderliche Nutzerfreigabe.
Die Memory API ist ein eigener Dienst mit eigenem OpenAPI-Vertrag. Die GitHub-Organisation ist ein Einstieg zu verfügbaren Repositories; daraus folgt nicht, dass jede StudioMeyer-Komponente öffentlich ist.