Was brauche ich zuerst?
- Öffnen Sie in der App „Einstellungen“, dann „API-Schlüssel“, und erstellen Sie einen Schlüssel mit dem Bereich write. Ein read-Schlüssel kann Korrekturen auflisten und Nachweise lesen, aber ein POST damit erhält 403. Kopieren Sie den Schlüssel sofort: Er wird nur einmal angezeigt.
- Ermitteln Sie Ihre brand_id. GET /v1/brands listet mit demselben Schlüssel Ihre Marken und deren IDs.
- Rufen Sie die API von einem Server auf, nie aus einem Browser, damit der Schlüssel privat bleibt. Jede Anfrage sendet ihn als Authorization: Bearer, gefolgt vom Schlüssel.
Wie plane und starte ich eine Korrektur?
Zwei Aufrufe, damit nichts ohne ein Ja läuft, dieselbe Regel wie bei Ask Proof in der App. Der erste Aufruf sendet ask, also was korrigiert werden soll, in einfachen Worten (bis zu 2.000 Zeichen). Er liefert den Plan: was die Korrektur tut, wo sie Änderungen vornimmt, wie sie sich rückgängig machen lässt, und eine plan_id. Noch ist nichts gestartet.
curl -s https://app.proofsource.co/v1/missions \
-H "Authorization: Bearer $PROOFSOURCE_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"brand_id":"brd_123","ask":"Get us named when people ask for the best CRM for small agencies"}'
# 200: nothing has started yet
# {"state":"planned","plan_id":"act_456","brand_id":"brd_123",
# "what":"...","where":"...","undo":"...","plan":{...},"next":"..."}Lesen Sie den Plan. Um ihn zu starten, senden Sie die plan_id zurück. Die Korrektur reserviert zuerst ihre Credits, startet dann genau diesen Plan und antwortet mit 201 und der mission_id der neuen Korrektur. Ein Plan lässt sich einmal beantworten: Dieselbe plan_id erneut zu senden ergibt 409.
curl -s https://app.proofsource.co/v1/missions \
-H "Authorization: Bearer $PROOFSOURCE_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: start-act_456" \
-d '{"brand_id":"brd_123","plan_id":"act_456"}'
# 201: the fix is running
# {"state":"done","plan_id":"act_456",
# "result":{"mission_id":"msn_789","state":"running","steps_total":4,
# "live_fix_path":"/fixes/live/msn_789"}}Darf ich eine Anfrage wiederholen?
Ja, mit einem Idempotency-Key-Header, den jeder schreibende Aufruf annimmt. Läuft eine Anfrage in eine Zeitüberschreitung, senden Sie sie mit demselben Schlüssel erneut: Sie erhalten die erste Antwort zurück, markiert mit Idempotent-Replay: true, und die Korrektur startet nie zweimal. Eine Wiederholung, die eintrifft, während die erste noch läuft, wartet auf sie. Schlüssel werden 24 Stunden gespeichert. Eine fehlgeschlagene Anfrage wird nicht gespeichert, sodass derselbe Schlüssel erneut laufen kann, sobald die Ursache behoben ist. Verwenden Sie für jede neue Anfrage einen neuen Schlüssel.
Wie verfolge ich eine Korrektur und lese ihren Nachweis?
GET /v1/missions listet die Korrekturen einer Marke, die neueste zuerst, jeweils mit Zustand (planned, running, waiting_for_you, sleeping, needs_help, proven, flat, cancelled oder rolled_back) und Ziel. Mit status=proven sehen Sie nur die Korrekturen, die gewirkt haben. Jede Korrektur trägt proof_url, ihren Nachweis: das Ergebnis, die Fragen, an denen sie gemessen wurde, die Messungen davor und danach und das Urteil. Solange eine Korrektur kein Ergebnis hat, antwortet der Nachweis mit 409 und status not_ready.
curl -s "https://app.proofsource.co/v1/missions?brand_id=brd_123&status=proven" \
-H "Authorization: Bearer $PROOFSOURCE_API_KEY"
curl -s https://app.proofsource.co/v1/missions/msn_789/receipt \
-H "Authorization: Bearer $PROOFSOURCE_API_KEY"Wie erfahre ich, dass eine Korrektur gewirkt hat?
- Öffnen Sie in der App „Integrationen“, dann „Benachrichtigungen & Webhooks“, und wählen Sie „Webhook hinzufügen“ mit Ihrer HTTPS-URL.
- Haken Sie „Meilensteine“ an. Eine erfolgreiche Korrektur ist ein Meilenstein und wird als Typ mission.proven gesendet.
- Kopieren Sie das Signatur-Secret, das beim Speichern angezeigt wird, oder legen Sie Ihr eigenes fest. Mit dem Test-Versand prüfen Sie Ihren Endpunkt.
Jede Zustellung ist ein POST mit einem JSON-Body und drei Headern: proofsource-event (der Typ), proofsource-delivery (eine ID pro Zustellung) und proofsource-signature im Format t=<Unix-Sekunden>,v1=<hex>. v1 ist HMAC-SHA256 von <t>.<roher Body> mit Ihrem Signatur-Secret. Berechnen Sie ihn über die rohen Bytes vor dem Parsen, vergleichen Sie in konstanter Zeit und lehnen Sie ein t ab, das älter als fünf Minuten ist.
{
"id": "evt_...",
"type": "mission.proven",
"api_version": "2026-10-03",
"created_at": "2026-11-21T09:00:00Z",
"org_id": "org_...",
"data": {
"brand_id": "brd_123",
"brand_name": "Acme",
"title": "A fix worked for Acme",
"summary": "Fix: ... The goal was reached and the result is saved with its proof.",
"dashboard_url": "https://app.proofsource.co/fixes/live/msn_789",
"kind": "mission_proven",
"mission_id": "msn_789",
"items": [{ "kind": "mission_proven", "title": "A fix worked for Acme", "detail": "..." }]
}
}// Node (Express): verify before trusting the body.
import crypto from "node:crypto";
import express from "express";
const app = express();
app.post("/hooks/fixes", express.raw({ type: "application/json" }), (req, res) => {
const header = req.get("proofsource-signature") ?? "";
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
const expected = crypto
.createHmac("sha256", process.env.WEBHOOK_SECRET)
.update(`${parts.t}.${req.body}`)
.digest("hex");
const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
const ok = fresh && parts.v1?.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected));
if (!ok) return res.sendStatus(400);
const event = JSON.parse(req.body);
if (event.type === "mission.proven") {
// De-duplicate on event.id: delivery is at least once.
console.log("Fix worked:", event.data.mission_id, event.data.title);
}
res.sendStatus(200);
});Antworten Sie innerhalb von 10 Sekunden mit einem beliebigen 2xx. Eine Zeitüberschreitung, 408, 409, 425, 429 oder 5xx wird nach 1 Minute, 5 Minuten, 30 Minuten, 2 Stunden, 6 Stunden und 24 Stunden wiederholt. Die Zustellung erfolgt mindestens einmal, deduplizieren Sie also über id und rufen Sie dann den Nachweis mit data.mission_id ab.
Wie sehen Fehler aus?
Jeder Fehler ist application/problem+json mit einem stabilen type und einem Satz in detail. Verzweigen Sie nach type, nie nach dem Wortlaut.
| Status | Typ | Wann |
|---|---|---|
| 400 | validation_failed | brand_id fehlt, ask und plan_id wurden beide oder keines gesendet, ask ist eine Frage statt einer Korrektur, oder status ist kein Zustand einer Korrektur. |
| 401 | unauthenticated | Kein Schlüssel, oder der Schlüssel ist unbekannt oder widerrufen. |
| 403 | forbidden | Ein read-Schlüssel bei einem POST. |
| 403 | approver_required | Der Inhaber des Schlüssels darf keine Korrekturen freigeben. Inhaber und Admins dürfen es; ein Mitglied braucht die Freigabeberechtigung. |
| 404 | not_found | Die Marke, die Korrektur oder der Plan gehört nicht zu Ihrem Workspace. |
| 409 | conflict | Der Plan wurde bereits beantwortet, oder eine Wiederholung mit demselben Idempotency-Key läuft noch. |
| 503 | upstream_unreachable | Die Korrektur ließ sich gerade nicht planen oder starten. Nichts wurde gestartet; versuchen Sie es erneut. |
Der vollständige Vertrag mit jedem Feld und dem Webhook steht in der OpenAPI-Spezifikation unter app.proofsource.co/v2/openapi.json, sodass Sie in jeder Sprache einen Client erzeugen können.