REST-API-Referenz
Pay4Feedback stellt eine mandantenbezogene REST-API bereit, mit der Sie dieselben Daten und Aktionen programmatisch nutzen wie im Dashboard. Damit automatisieren Sie Kampagnenerstellung, spiegeln Responses ins Data Warehouse oder bauen eigene Approval-Workflows auf unserem KI-Scoring auf.
Base-URL
https://app.pay4feedback.com
Alle öffentlichen Endpunkte liegen unter /api/v1/. Stabilitätszusage:
- Wir ergänzen neue Felder im Response ohne Ankündigung — parsen Sie defensiv.
- Wir entfernen in v1 keine Felder und ändern keine Typen. Breaking Changes erscheinen als
/api/v2/.
Interaktive Docs (Swagger)
Die stets aktuelle Referenz mit „Try it out"-Buttons:
https://app.pay4feedback.com/swagger-ui/index.html
API-Key oben via Authorize einfügen; jede generierte Beispiel-Anfrage trägt ihn dann. Die rohe OpenAPI-3.0-Spec liegt unter /v3/api-docs — praktisch für Client-Generatoren.
Authentifizierung
Jede /api/v1/*-Anfrage benötigt einen API-Key.
Erstellen im Dashboard: Einstellungen → API Keys → Create key. Der Klartext wird einmalig bei der Erstellung angezeigt; danach sehen Sie nur noch den Prefix. Wie ein Datenbank-Passwort in Ihren Secret Manager übernehmen.
Zwei akzeptierte Header-Formen (eine wählen):
Authorization: Bearer p4f_live_abc...xyz
X-API-Key: p4f_live_abc...xyz
Eigenschaften der Keys:
- Mandantenbezogen — ein Key sieht und ändert nur den Tenant, in dem er erstellt wurde.
- At-Rest gehasht — wir speichern SHA-256. Verlorene Keys sind nicht wiederherstellbar; neuen erstellen, alten widerrufen.
- Sofort widerrufbar — Revocation gilt ab dem nächsten Request, keine Schonfrist.
Rate-Limits
60 Requests pro Minute pro Tenant. Der 61. in 60 Sekunden:
HTTP/1.1 429 Too Many Requests
Retry-After: 12
Content-Type: application/json
{"success":false,"error":"Rate limit exceeded. Retry in 12s."}
Mehr Durchsatz nötig? sales@pay4feedback.com — Enterprise hebt das Limit an.
Response-Hülle
Jede erfolgreiche Antwort hat dieselbe Struktur:
{
"success": true,
"data": { /* endpunktspezifische Payload */ },
"timestamp": "2026-04-19T14:22:51Z"
}
Fehler:
{
"success": false,
"error": "Menschenlesbare Meldung",
"timestamp": "2026-04-19T14:22:51Z"
}
HTTP-Statuscodes folgen der REST-Konvention: 200 ok, 400 Validierungsfehler, 401 fehlender/ungültiger Key, 404 nicht gefunden, 409 Statuskonflikt, 429 Rate Limit, 500 Server-Fehler.
Endpunkte auf einen Blick
| Method | Path | Zweck |
|---|---|---|
| GET | /api/v1/me | Smoketest Ihres Keys — liefert den zugeordneten Tenant |
| GET | /api/v1/campaigns | Alle Kampagnen |
| GET | /api/v1/campaigns/{id} | Eine Kampagne |
| POST | /api/v1/campaigns | Kampagne anlegen (Start als DRAFT) |
| PATCH | /api/v1/campaigns/{id} | Kampagne aktualisieren |
| POST | /api/v1/campaigns/{id}/pause | Pausieren — Widget liefert nichts mehr aus |
| POST | /api/v1/campaigns/{id}/resume | Fortsetzen aus Pause |
| GET | /api/v1/responses | Feedback-Responses listen |
| GET | /api/v1/responses/{id} | Ein Response inkl. Antworten + Quality-Breakdown |
| POST | /api/v1/responses/{id}/approve | Belohnung freigeben |
| POST | /api/v1/responses/{id}/reject | Belohnung ablehnen (optional { "reason": "…" }) |
| GET | /api/v1/webhooks | Webhook-Subscriptions |
| POST | /api/v1/webhooks | Subscription anlegen |
| DELETE | /api/v1/webhooks/{id} | Subscription löschen |
Die Ereignisse der ausgehenden Webhooks haben eine eigene Seite: Webhooks.
Quickstart — curl
export P4F=p4f_live_your_key_here
# 1. Key testen
curl -H "Authorization: Bearer $P4F" \
https://app.pay4feedback.com/api/v1/me
# 2. Kampagnen listen
curl -H "Authorization: Bearer $P4F" \
https://app.pay4feedback.com/api/v1/campaigns
# 3. Letzte 50 Responses
curl -H "Authorization: Bearer $P4F" \
https://app.pay4feedback.com/api/v1/responses
# 4. Einen Response freigeben
curl -X POST \
-H "Authorization: Bearer $P4F" \
https://app.pay4feedback.com/api/v1/responses/RESPONSE_UUID/approve
# 5. Webhook abonnieren
curl -X POST \
-H "Authorization: Bearer $P4F" \
-H "Content-Type: application/json" \
-d '{
"url":"https://api.yourapp.com/p4f-webhook",
"events":["reward_approved","payout_completed"],
"secret":"whsec_generate_a_random_one"
}' \
https://app.pay4feedback.com/api/v1/webhooks
Quickstart — Node
const P4F = process.env.P4F_API_KEY;
const BASE = 'https://app.pay4feedback.com/api/v1';
async function p4f(path, init = {}) {
const res = await fetch(BASE + path, {
...init,
headers: {
Authorization: `Bearer ${P4F}`,
'Content-Type': 'application/json',
...(init.headers ?? {}),
},
});
if (res.status === 429) {
const wait = Number(res.headers.get('Retry-After') ?? 30);
await new Promise(r => setTimeout(r, wait * 1000));
return p4f(path, init);
}
const body = await res.json();
if (!body.success) throw new Error(body.error);
return body.data;
}
const campaigns = await p4f('/campaigns');
const response = await p4f(`/responses/${id}`);
await p4f(`/responses/${id}/approve`, { method: 'POST' });
Quickstart — Python
import os, time, requests
P4F = os.environ["P4F_API_KEY"]
BASE = "https://app.pay4feedback.com/api/v1"
def p4f(path, method="GET", json=None):
r = requests.request(method, BASE + path,
headers={"Authorization": f"Bearer {P4F}"},
json=json, timeout=10)
if r.status_code == 429:
time.sleep(int(r.headers.get("Retry-After", 30)))
return p4f(path, method, json)
body = r.json()
if not body.get("success"):
raise RuntimeError(body.get("error"))
return body["data"]
campaigns = p4f("/campaigns")
p4f(f"/responses/{id}/approve", method="POST")
Paginierung
List-Endpunkte liefern aktuell bis zu 500 Zeilen, neueste zuerst. Cursor-Paginierung kommt in v1.1 — die Hülle erhält dann ein next-Feld, mit ?cursor=<token> holen Sie die nächste Seite. Bis dahin: Bleiben Sie via passender Webhook-Events synchron.
Idempotenz
POST-Endpunkte sind heute nicht idempotent. Läuft ein Request in ein Timeout, fragen Sie den Ressourcenstatus per GET ab, bevor Sie wiederholen. Idempotency-Keys (Idempotency-Key-Header) landen in v1.1.
Fehler, die Sie tatsächlich sehen
| Status | Bedeutung | Was tun |
|---|---|---|
| 400 | Ungültiger Body (fehlende Felder, kaputte UUID) | error-Feld nennt das problematische Feld |
| 401 | Key fehlt / ungültig / widerrufen | Neuen Key im Dashboard erstellen |
| 404 | Ressource nicht in Ihrem Tenant | ID prüfen — Cross-Tenant-Zugriff gibt bewusst 404, nicht 403 |
| 409 | Zustandskonflikt (z. B. bereits bearbeiteter Reward) | Aktuellen Zustand zuerst laden |
| 429 | Rate Limit | Retry-After beachten |
| 500 | Unser Bug | Exponentieller Backoff-Retry; bleibt der Fehler, Mail an support@pay4feedback.com mit dem timestamp |
Changelog
v1.0 — 2026-04
Erstveröffentlichung.
- Kampagnen-CRUD + Pause/Resume
- Response-Liste + Detail + approve/reject
- Webhook-Subscriptions
- Self-Identity-Endpunkt (
/me)
Geplant für v1.1: Cursor-Paginierung, Idempotency-Keys, Query-Filter auf /responses (nach Kampagne, Status, Datum).
Verwandt
- Webhooks — die Gegenrichtung: Events abonnieren, HMAC-signierte POSTs empfangen
- API & Integrationen — Roadmap + geplante Pre-Built-Integrationen (Zapier, Segment)
- Kontakt & Support