Das Wichtigste in Kürze
- Eine API ist ein Vertrag: Sie legt fest, welche Anfragen erlaubt sind und wie die Antworten aussehen – nicht, wie der Server intern arbeitet.
- Bei REST-artigen HTTP-APIs bestimmen URL (Ressource), Methode (Aktion) und Statuscode (Ergebnis) das Verhalten; JSON ist das übliche Datenformat.
- fetch() wirft bei einem 404 oder 500 keinen Fehler – du musst response.ok selbst prüfen.
- Webhooks drehen die Richtung um: Der Anbieter ruft dich bei einem Ereignis auf; eine HMAC-Signatur zeigt, dass die Nachricht echt ist.
Was ist eine API?
Eine API (Application Programming Interface) ist die Schnittstelle, über die ein Programm die Funktionen oder Daten eines anderen Programms nutzt. Sie funktioniert wie ein Vertrag: Der Anbieter beschreibt, welche Anfragen er versteht und welche Antworten du bekommst. Wie er die Antwort intern erzeugt, bleibt verborgen.
Wenn im Alltag von einer „API-Schnittstelle“ die Rede ist, ist fast immer eine Web-API gemeint: Dein Programm schickt eine HTTP-Anfrage an eine URL und erhält Daten zurück, meist als JSON. Auf diese Weise sprechen Newsletter-Tools mit dem CRM, ein Shop mit dem Versanddienstleister oder ein Automatisierungs-Workflow mit allem dazwischen. Die Mechanik ist immer dieselbe, deshalb lohnt es sich, sie einmal zu verstehen.
REST: Ressourcen, Methoden und Statuscodes
REST ist ein Architekturstil für Web-APIs. In der Praxis bedeutet er: Dinge, mit denen die API arbeitet, sind Ressourcen mit eigener URL, und die HTTP-Methode sagt, was du mit ihnen tun willst.
| Anfrage | Bedeutung | Typische Antwort |
|---|---|---|
GET /tasks | Liste lesen | 200 mit JSON-Liste |
GET /tasks/3 | Einzelnes Objekt lesen | 200, oder 404 wenn es fehlt |
POST /tasks | Neues Objekt anlegen | 201 mit dem neuen Objekt |
PUT /tasks/3 | Objekt ersetzen | 200 oder 204 |
PATCH /tasks/3 | Objekt teilweise ändern | 200 oder 204 |
DELETE /tasks/3 | Objekt löschen | 204 ohne Inhalt |
Die Eigenschaften der Methoden sind festgelegt (Stand der MDN-Dokumentation am 28.10.2026):
| Methode | Sicher (safe) | Idempotent | Cachebar |
|---|---|---|---|
| GET | ja | ja | ja |
| POST | nein | nein | nur mit expliziten Frische-Informationen und passendem Content-Location-Header |
| PUT | nein | ja | nein |
| PATCH | nein | nein | nur unter denselben Bedingungen wie POST |
| DELETE | nein | ja | nein |
„Sicher“ heißt: Die Anfrage verändert nichts auf dem Server. „Idempotent“ heißt: Wiederholst du dieselbe Anfrage, ist der Zustand danach derselbe wie nach der ersten. Das ist praktisch relevant: Ein abgebrochenes PUT oder DELETE kannst du bedenkenlos wiederholen, ein abgebrochenes POST kann dagegen einen zweiten Datensatz erzeugen. Prüfe in der Dokumentation, ob der Anbieter dafür einen Idempotenz-Schlüssel anbietet.
Statuscodes lesen
Der Statuscode sagt dir, ob und warum eine Anfrage funktioniert hat. Die wichtigsten, mit den Bedeutungen laut MDN:
| Code | Name | Bedeutung |
|---|---|---|
| 200 | OK | Anfrage erfolgreich |
| 201 | Created | Neue Ressource wurde angelegt |
| 204 | No Content | Erfolg, aber kein Inhalt zu senden |
| 400 | Bad Request | Server kann oder will die Anfrage wegen eines Clientfehlers nicht verarbeiten (z. B. ungültiges JSON) |
| 401 | Unauthorized | Gemeint ist „nicht authentifiziert“: Du musst dich ausweisen |
| 403 | Forbidden | Du bist bekannt, hast aber keine Berechtigung |
| 404 | Not Found | Die Ressource wurde nicht gefunden |
| 409 | Conflict | Die Anfrage kollidiert mit dem aktuellen Zustand |
| 422 | Unprocessable Content | Anfrage ist wohlgeformt, aber inhaltlich nicht verarbeitbar |
| 429 | Too Many Requests | Zu viele Anfragen in einem Zeitraum (Rate Limit) |
| 500 | Internal Server Error | Allgemeiner Serverfehler |
| 503 | Service Unavailable | Server vorübergehend nicht bereit, z. B. Wartung oder Überlastung |
Als Faustregel: 2xx heißt Erfolg, 4xx liegt an deiner Anfrage, 5xx am Server. Bei 5xx und 429 lohnt sich ein Wiederholungsversuch mit Wartezeit, bei 4xx wie 400 oder 404 nicht – dort musst du die Anfrage ändern.
JSON: das gemeinsame Datenformat
JSON (JavaScript Object Notation) ist ein textbasiertes Format aus Objekten ({}), Listen ([]), Strings, Zahlen, Booleans und null. Fast jede Programmiersprache kann es lesen und schreiben. Beim Senden setzt du den Header Content-Type: application/json, damit der Server den Body richtig interpretiert.
{
"items": [{ "id": 1, "title": "Newsletter planen", "done": false }],
"page": 1,
"total": 2
}Eine API in der Praxis aufrufen
Damit die Beispiele nachvollziehbar sind, läuft die API hier nicht bei einem Drittanbieter, sondern als kleiner Test-Server auf deinem Rechner. Er kennt GET /tasks, POST /tasks und GET /tasks/<id>, verlangt einen Bearer-Token und liefert die Statuscodes aus der Tabelle oben. Der Server selbst ist nur Kulisse; wichtig ist der Client-Teil.
Mit curl
curl -i -H "Authorization: Bearer demo-token" "http://localhost:8787/tasks?limit=1&page=1"HTTP/1.1 200 OK
Content-Type: application/json
{"items":[{"id":1,"title":"Newsletter planen","done":false}],"page":1,"total":2}(Weitere Header wie Date und Connection sind hier weggelassen.) Ohne den Authorization-Header antwortet der Server mit 401. Ein POST mit JSON-Body:
curl -i -X POST -H "Authorization: Bearer demo-token" -H "Content-Type: application/json" \
-d '{"title":"Test"}' http://localhost:8787/tasksHTTP/1.1 201 Created
Content-Type: application/json
Location: /tasks/3
{"id":3,"title":"Test","done":false}Fehlt das Feld title, kommt 422, bei kaputtem JSON 400. Das Location-Header ist die übliche Art, die URL der neu angelegten Ressource mitzuteilen.
Mit fetch (JavaScript)
Wichtig laut MDN: fetch() lehnt das Promise bei einem Serverfehler wie 404 nicht ab. Es wird nur bei Netzwerkfehlern oder Abbrüchen abgelehnt. Du musst response.ok selbst prüfen (true bei Status 200–299).
const BASE = "http://localhost:8787";
const headers = { Authorization: "Bearer demo-token", "Content-Type": "application/json" };
async function api(path, options = {}) {
const response = await fetch(BASE + path, { headers, ...options });
if (!response.ok) {
throw new Error(`HTTP ${response.status} bei ${path}`);
}
return response.json();
}
console.log(await api("/tasks?limit=1&page=1"));
console.log(await api("/tasks", {
method: "POST",
body: JSON.stringify({ title: "Webhook einrichten" }),
}));
try {
await api("/tasks/99");
} catch (error) {
console.log(error.message);
}{
items: [ { id: 1, title: 'Newsletter planen', done: false } ],
page: 1,
total: 2
}
{ id: 3, title: 'Webhook einrichten', done: false }
HTTP 404 bei /tasks/99Gegen einen echten Dienst sähe der Aufruf identisch aus, nur mit anderer Basis-URL (hier illustrativ, nicht ausgeführt):
const response = await fetch("https://api.example.com/v1/contacts", {
headers: { Authorization: `Bearer ${process.env.API_TOKEN}` },
});Mit Python (urllib aus der Standardbibliothek)
import json
import urllib.request
req = urllib.request.Request(
"http://localhost:8787/tasks/1",
headers={"Authorization": "Bearer demo-token", "Accept": "application/json"},
)
with urllib.request.urlopen(req) as resp:
print(resp.status, json.load(resp))200 {'id': 1, 'title': 'Newsletter planen', 'done': False}Authentifizierung: API-Keys und OAuth 2.0
Die meisten APIs wollen wissen, wer anfragt. Zwei Verfahren begegnen dir ständig:
- API-Key oder Token: ein geheimer String, den du im Header mitsendest (häufig
Authorization: Bearer …). Er ist ein Passwort für ein Programm. Lege ihn nie in Frontend-Code, in ein öffentliches Repository oder in eine URL; lies ihn aus Umgebungsvariablen oder einem Secret-Speicher. Alles, was im Browser ankommt, kann jeder Besucher auslesen. - OAuth 2.0: ein Framework, mit dem eine Anwendung eingeschränkten Zugriff auf einen HTTP-Dienst erhält, entweder im Namen eines Nutzers nach dessen Zustimmung oder in eigenem Namen (so fasst RFC 6749 es zusammen). Du bekommst dabei kein Passwort, sondern ein Zugriffstoken mit begrenzten Rechten und begrenzter Lebensdauer. Das Verfahren steckt hinter „Mit Google anmelden“ und hinter vielen Marketing-Integrationen, bei denen du einem Tool Zugriff auf dein Konto erlaubst.
Vergib Schlüsseln nur die Rechte, die die Integration braucht, und lege für jede Integration einen eigenen an. Dann lässt sich ein kompromittierter Schlüssel widerrufen, ohne alles andere zu stören.
Rate Limits und Pagination
Anbieter begrenzen, wie viele Anfragen du pro Zeitraum stellen darfst. Wirst du gebremst, antwortet der Server mit 429 Too Many Requests. Wie lange du warten musst und ob ein Header die Wartezeit nennt, steht in der Dokumentation des jeweiligen Anbieters – verlass dich nicht auf Annahmen. Baue Wiederholungsversuche mit wachsender Wartezeit ein und frage nicht in einer engen Schleife ab.
Listen kommen selten auf einmal. Üblich ist Pagination, also seitenweises Laden. Der Test-Server oben nutzt limit und page; andere APIs liefern stattdessen einen Cursor oder eine „next“-URL. Prüfe immer, ob die Antwort vollständig war, sonst fehlen dir stillschweigend Datensätze.
Webhooks statt Polling
Beim Polling fragst du in festen Abständen: „Gibt es etwas Neues?“ Das kostet Anfragen und liefert verzögert. Ein Webhook dreht die Richtung um: Du hinterlegst beim Anbieter eine URL, und der Anbieter schickt dir bei einem Ereignis selbst eine HTTP-Anfrage (meist POST mit JSON).
Polling: Dein System ── GET /orders?since=… ──▶ Anbieter (alle paar Minuten, meist leer)
Webhook: Anbieter ── POST /hooks/order-created ──▶ Dein Endpunkt (nur bei einem Ereignis)Dein Endpunkt sollte schnell mit 200 oder 204 antworten und die eigentliche Arbeit danach erledigen. Rechne außerdem damit, dass dieselbe Nachricht mehrfach ankommt, etwa weil der Absender bei einem Timeout wiederholt. Speichere deshalb die Ereignis-ID und ignoriere Duplikate.
Webhooks mit HMAC-Signatur prüfen
Dein Endpunkt ist öffentlich erreichbar, also kann jeder dorthin senden. Viele Anbieter signieren deshalb den Body mit einem gemeinsamen Geheimnis per HMAC (Hash-based Message Authentication Code) und senden die Signatur in einem Header. Du berechnest sie mit demselben Geheimnis selbst und vergleichst. Welcher Header, welcher Hash-Algorithmus und welches Format gelten, legt jeder Anbieter fest; SHA-256 ist verbreitet. Das folgende Beispiel zeigt das Prinzip:
import hashlib
import hmac
import json
SECRET = b"demo-shared-secret" # in der Praxis aus der Umgebung lesen
def sign(body: bytes) -> str:
return hmac.new(SECRET, body, digestmod=hashlib.sha256).hexdigest()
def is_valid(body: bytes, signature: str) -> bool:
return hmac.compare_digest(sign(body), signature)
body = json.dumps({"event": "contact.created", "id": 42}).encode()
signature = sign(body) # das schickt der Absender im Header
print("Original: ", is_valid(body, signature))
print("Manipuliert:", is_valid(body.replace(b"42", b"43"), signature))
print("Falsche Sig:", is_valid(body, "0" * 64))Original: True
Manipuliert: False
Falsche Sig: FalseZwei Details sind entscheidend. Erstens signierst du die rohen Bytes des Bodys, so wie sie ankommen – wer das JSON erst parst und neu serialisiert, verändert unter Umständen die Bytes und die Prüfung schlägt fehl. Zweitens vergleichst du mit hmac.compare_digest() statt mit ==: Die Python-Dokumentation empfiehlt das, um die Anfälligkeit für Timing-Angriffe zu verringern. Manche Anbieter senden zusätzlich einen Zeitstempel, den du gegen Wiederholungen prüfen kannst; auch das steht dann in deren Dokumentation.
Der Marketing-Blick: CRM, Newsletter und Automatisierung
Für Marketing-Teams ist die API der Weg, Systeme ohne Copy-and-paste zu verbinden. Typische Muster:
- Formular → CRM: Ein Webhook oder eine
POST-Anfrage legt aus einer Anfrage einen Kontakt an. - Newsletter-Tool → Auswertung: Eine nächtliche
GET-Abfrage mit Pagination zieht Anmeldungen in eine Tabelle. - Ereignis → Benachrichtigung: Ein Webhook meldet „Bestellung erstellt“ an einen Workflow.
Achte dabei auf zwei Punkte außerhalb der Technik: Personenbezogene Daten, die du über APIs weitergibst, unterliegen weiterhin dem Datenschutzrecht – prüfe Rechtsgrundlage und Auftragsverarbeitung, dieser Artikel ist keine Rechtsberatung. Und teste neue Integrationen zuerst mit Testdaten, denn ein POST in einer Schleife kann echte Kontakte vervielfachen.
Dein nächster Schritt
Wähle einen Dienst, den du ohnehin nutzt, und öffne seine API-Dokumentation. Suche vier Dinge: Basis-URL, Authentifizierung, ein Beispiel für GET auf eine Liste und das Rate Limit. Rufe dann genau diese Liste mit curl ab und lies den Statuscode. Wenn das klappt, bist du bei jeder weiteren API ähnlich weit. Als Nächstes lohnt es sich, den Client in einer Sprache deiner Wahl zu schreiben, etwa mit den Python-Grundlagen oder typsicher mit TypeScript. Wenn du nicht weißt, wo du beginnen sollst, hilft die Entscheidungshilfe zur ersten Programmiersprache, und für Änderungen an deinem Client-Code sind die wichtigsten Git-Befehle nützlich.
Häufige Fragen
Ist jede Web-API eine REST-API?
Nein. REST ist ein Architekturstil. Viele Dienste nutzen HTTP und JSON, ohne alle REST-Prinzipien einzuhalten; im Alltag wird „REST-API“ oft nur als „HTTP-API mit JSON“ verwendet. Entscheidend ist die Dokumentation des Anbieters.
Brauche ich für eine API-Integration Programmierkenntnisse?
Für einfache Fälle nicht: Viele Automatisierungsdienste bieten fertige Konnektoren. Sobald ein Dienst keinen Konnektor hat oder du Daten umformen musst, helfen Grundkenntnisse in HTTP und JSON, wie dieser Artikel sie vermittelt.
Quellen
- HTTP request methods MDN Web Docs (Mozilla) · abgerufen am 28. Oktober 2026
- HTTP response status codes MDN Web Docs (Mozilla) · abgerufen am 28. Oktober 2026
- Using the Fetch API MDN Web Docs (Mozilla) · abgerufen am 28. Oktober 2026
- hmac – Keyed-Hashing for Message Authentication Python Software Foundation (docs.python.org) · abgerufen am 28. Oktober 2026
- RFC 6749: The OAuth 2.0 Authorization Framework IETF · abgerufen am 28. Oktober 2026