TrustAge API v1
Basis-URL: https://api.trustage.eu/v1 · Transport: ausschließlich HTTPS · Format: application/json; charset=utf-8
1. Authentifizierung
Jeder Request trägt zwei Header:
X-API-Key-Id: <key_id>
X-API-Secret: <secret>
Content-Type: application/json
Schlüssel werden im Consumer-Bereich unter „API-Schlüssel" erzeugt. Das Secret wird nur einmal bei der Erstellung angezeigt. Optional kann pro Schlüssel eine IP-Whitelist (einzelne IPs oder CIDR) gesetzt werden.
Serverseitige Prüfreihenfolge:
key_idexistiert und ist aktiv – sonst401 invalid_credentialssecretpasst – sonst401 invalid_credentials- Consumer-Konto aktiv – sonst
403 account_suspended - Kein Zahlungsverzug – sonst
403 payment_overdue - Innerhalb des Freikontingents nutzbar; ist es erschöpft und es liegt keine Zahlungsart/Rechnungsfreigabe vor –
403 payment_required - Falls IP-Whitelist gesetzt: Quell-IP muss passen – sonst
403 ip_not_allowed
Falsche key_id und falsches Secret liefern dieselbe Meldung (401 invalid_credentials), um Enumeration zu verhindern.
2. Request-Schema
{
"code": "AB3F-K9P2",
"checks": { ... }
}
code (Pflicht): Client-Code wie eingegeben. Bindestriche und Groß-/Kleinschreibung sind egal – der Server normalisiert und prüft die Prüfziffer. checks (Pflicht): Inhalt je nach Endpunkt.
3. POST /verify
Universeller Endpunkt für Alter, Geschlecht oder beides kombiniert.
Alter – Grenzen inklusiv, mindestens eine angeben:
{ "age": { "min": 18 } } // 18 oder älter
{ "age": { "max": 15 } } // 15 oder jünger
{ "age": { "min": 13, "max": 15 } } // 13 bis 15
Geschlecht – Mengenabfrage, erlaubte Werte male, female, diverse:
{ "gender": { "in": ["male", "diverse"] } }
Kombiniert:
{
"code": "AB3F-K9P2",
"checks": {
"age": { "min": 13, "max": 15 },
"gender": { "in": ["female"] }
}
}
Antwort (HTTP 200):
{
"request_ref": "a1b2c3d4e5f6…",
"status": "verified",
"match": true,
"checks": {
"age": { "match": true },
"gender": { "match": true }
},
"billed": true
}
match(oben) = logisches UND aller Teil-Checks.- Jeder Teil-Check liefert sein eigenes
match. request_refist die einzige ID, die der Consumer sieht – kein Code, kein Personenbezug.billed= ob die Anfrage berechnet wird.
Altersberechnung ist monatsgenau: Im Geburtsmonat gilt die Person bereits als X Jahre alt. Geboren 2008-06, Anfrage 2026-06 → 18; Anfrage 2026-05 → 17.
4. POST /cohort
Gibt die Alterskohorte zurück. Eigener Preis. Nur möglich, wenn der Client zugestimmt hat.
{ "code": "AB3F-K9P2" }
Antwort (Erfolg):
{
"request_ref": "…",
"status": "verified",
"cohort": { "min": 18, "max": 24, "label": "18-24" },
"billed": true
}
Ohne Zustimmung (HTTP 200, nicht berechnet):
{ "request_ref": "…", "status": "consent_required", "cohort": null, "billed": false }
Standard-Kohorten: 0–15, 16–17, 18–24, 25–39, 40–59, 60+.
5. Statuscodes & Abrechnung
| Situation | status | billed |
|---|---|---|
| Code gültig, Bedingung erfüllt | verified | ja* |
| Code gültig, Bedingung nicht erfüllt | verified | ja* |
| Code existiert nicht / Prüfziffer falsch | not_verifiable | nein |
| Code inaktiv / gesperrt / abgelaufen | not_verifiable | nein |
| Kohorte ohne Zustimmung | consent_required | nein |
* Berechnet, sobald das monatliche Freikontingent erschöpft ist. Ein gültiger Code, der die Bedingung nicht erfüllt, wird berechnet (echte Verifizierung). Nicht verifizierbare Codes sind immer kostenlos und liefern HTTP 200 (Anti-Enumeration).
6. Beispiel (curl)
curl -X POST https://api.trustage.eu/v1/verify \
-H "X-API-Key-Id: key_abc123" \
-H "X-API-Secret: ihr_geheimes_secret" \
-H "Content-Type: application/json" \
-d '{"code":"AB3F-K9P2","checks":{"age":{"min":18}}}'