Dokumentation
Ein Script-Tag pro Website, eine REST-API und ein MCP-Server zur Verwaltung sowie signierte Webhooks für verifizierte Käufe. Ersetze Platzhalter wie site_your_site_key, provedly_your_key und pp_your_widget_token durch die Werte aus deinem Dashboard.
Auf deiner Website installieren
Füge dein Website-Snippet auf jeder Seite vor dem schließenden body-Tag ein. Es lädt alle aktiven Widgets und CTA-Leisten dieser Website asynchron in einem Shadow DOM.
Jede Website hat ihren eigenen Schlüssel. Kopiere die genaue Zeile unter Sites, deine Website, Install on this site. Widgets und Leisten im Dashboard oder über einen KI-Assistenten pausieren, fortsetzen oder anlegen erfordert keine Codeänderung. Änderungen im Dashboard erreichen deine Besucher in etwa einer Minute.
...
<script src="https://provedly.app/w/site.js" data-site="site_your_site_key" async></script>
</body>
</html>Shopify-App und WordPress-Plugin
Wenn du die Provedly-App für Shopify nutzt, musst du nichts installieren: Das App-Embed im Theme lädt alles. Das WordPress-Plugin funktioniert unverändert weiter.
Fortgeschritten: ein Tag pro Element
Das Website-Snippet deckt fast jeden Fall ab. Jedes Widget und jede Leiste hat zusätzlich ein eigenes Tag, unter Advanced im Tab Embed, für zwei Situationen: eine Inline-Leiste, die an einer genauen Stelle der Seite erscheinen muss (sie erscheint dort, wo ihr Tag eingefügt ist), und Page-Builder, die Code nur pro Block erlauben. Eine Seite mit beiden Arten von Tags lädt ein Element nie doppelt.
Erlaubte Domains
Der Konfigurations-Endpoint antwortet nur für Domains, die bei der Website eingetragen sind. Subdomains sind eingeschlossen, example.com deckt also auch shop.example.com ab. Staging-Hosts trägst du ausdrücklich ein. Eine leere Liste erlaubt jede Domain, was wir nicht empfehlen.
Was beim Laden passiert
- Das Website-Snippet stellt eine einzige Anfrage,
GET https://provedly.app/api/s/{site key}/manifest. Sie liefert jedes aktive Widget und jede aktive Leiste mit Einstellungen und bis zu 30 aktuellen Datensätzen pro Widget sowie die aktuelle Codeversion. - Danach lädt es den Widget-Code und den Leisten-Code, aber nur, wenn die Seite sie braucht. Beides sind versionierte Dateien, die dein Browser bis zum nächsten Release im Cache behält.
- Der Benachrichtigungszyklus startet nach deiner Startverzögerung. Jede Anzeige sendet eine Impression an
/track. - Solange der Tab offen ist, ruft ein Heartbeat alle 30 Sekunden
/presencefür den Live-Zähler auf.
Live-Zahl direkt in deiner Seite anzeigen
Füge ein Element dort ein, wo die Zahl erscheinen soll, zum Beispiel unter dem Produkttitel oder dem In-den-Warenkorb-Button. Auf Shopify nutzt du dafür einen Custom-liquid-Block im Theme-Editor. Das Website-Snippet füllt ihn mit derselben echten Zahl wie die Benachrichtigung (Besucher der letzten 90 Sekunden) und blendet ihn unter deinem Minimum aus.
<div data-provedly-live data-template="{n} people are viewing this product right now"></div>Füge data-style="card" hinzu für eine Kartenversion mit großer Zahl und einem Verify-Link zu deiner Verifizierungsseite, oder data-dot="off", um den Punkt auszublenden. Bei mehreren Widgets auf einer Seite gibst du im Attribut (data-provedly-live="pp_…") ein Widget-Token an, um eins auszuwählen.
Video-Anleitungen: beliebige Website oder WordPress und Shopify.
API-Schlüssel
Lege Schlüssel unter Settings, API keys an. Ein Schlüssel funktioniert für die REST-API, den MCP-Server und den Statistik-Feed. In jedem Tarif verfügbar, auch im Free-Tarif.
| Zugriff | Darf lesen | Darf ändern |
|---|---|---|
| Nur lesen | Listen und Statistiken | Nichts |
| Lesen und schreiben | Listen und Statistiken | Widgets und Leisten pausieren und fortsetzen, Leisten anlegen und bearbeiten, Datensätze hinzufügen |
So funktionieren Schlüssel
- Schlüssel beginnen mit
provedly_und gehören zum Workspace, nicht zu einem einzelnen Widget. - Der Schlüssel wird nur einmal angezeigt, beim Anlegen. Wir speichern nur einen Hash, also kopiere ihn sofort.
- Du kannst einen Schlüssel jederzeit auf derselben Seite widerrufen. Anfragen mit einem widerrufenen Schlüssel erhalten 401.
REST API
Lies deine Websites, Widgets, Leisten und Statistiken und nimm dieselben Änderungen vor wie im Dashboard. Antworten sind JSON in einem data-Feld.
https://provedly.app/api/v1
Authorization: Bearer provedly_your_key| Endpoint | Schlüssel | Hinweise |
|---|---|---|
| GET /account | read | Tarif, Nutzung und Limits. |
| GET /sites | read | |
| GET /sites/{site}/snippet | read | Der Installationscode dieser Website. |
| GET /widgets[?site=] | read | Optional nach Website gefiltert. |
| GET /widgets/{widget} | read | |
| PATCH /widgets/{widget} | write | Beliebige von name, status und den Widget-Einstellungen unten. Nur die gesendeten Felder ändern sich. Fortsetzen über das Widget-Limit des Tarifs hinaus wird abgelehnt. |
| GET /bars[?site=] | read | Optional nach Website gefiltert. |
| GET /bars/{bar} | read | |
| POST /bars | write | Legt eine Leiste an. Neue Leisten starten pausiert. |
| PATCH /bars/{bar} | write | Beliebige von name, kind, message, button_text, button_url, ends_at, status und den Leisten-Einstellungen unten. Ein neuer kind wechselt den Typ und behält Statistiken, Design und Targeting der Leiste; countdown braucht ein Enddatum. Beendete oder archivierte Leisten lassen sich nicht bearbeiten. |
| GET /stats?days=30[&site=] | read | days von 1 bis 365. |
| POST /widgets/{token}/records | write | Die Records-API. Akzeptiert auch den eigenen Schlüssel des Widgets. |
IDs
Widgets und Leisten akzeptieren ihre ID (eine UUID) oder ihr Token. Websites akzeptieren ihre ID oder ihre Domain.
curl -X PATCH https://provedly.app/api/v1/widgets/pp_your_widget_token \
-H "Authorization: Bearer provedly_your_key" \
-H "Content-Type: application/json" \
-d '{"status": "paused"}'Leiste anlegen (POST /bars)
| Feld | Regeln | Hinweise |
|---|---|---|
| site | Pflicht | ID oder Domain der Website. |
| name | Pflicht | |
| kind | Pflicht | Einer von: countdown, evergreen, counter, orders, static. |
| message | Pflicht | Setze {timer} dort ein, wo der Timer stehen soll. Fehlt er bei Timer-Typen, wird er angehängt. |
| button_text | optional | |
| button_url | optional | |
| ends_at | optional | "2026-12-01 09:00" in der Zeitzone der Leiste gelesen, oder ISO 8601. Countdowns laufen standardmäßig 7 Tage. |
| timezone | optional | IANA-Name. Standard ist UTC. |
Neue Leisten werden pausiert angelegt. Aktiviere eine mit PATCH /bars/{bar} {"status": "active"}.
Einstellungen, die du ändern kannst
Lesezugriffe liefern dieselben Felder, du kannst also ein Widget oder eine Leiste lesen, einen Wert ändern und alles zurückschicken. URL-Regeln akzeptieren eine Liste von Pfaden oder einen Pfad pro Zeile. Wenn die Änderung zwei aktive Elemente an dieselbe Stelle derselben Seiten setzt, enthält die Antwort einen warnings-Eintrag.
| Element | Endpoint | Felder |
|---|---|---|
| Widgets | PATCH /widgets/{widget} | message_template, theme, position, device, url_include, url_exclude, start_delay, display_seconds, gap_seconds, max_per_session, click_url, click_new_tab, verified_only, live_counter_enabled, live_counter_template, live_counter_min_show |
| Leisten | PATCH /bars/{bar} | theme, position, target_id (Inline-Leisten: werden im Element mit dieser ID angezeigt), device, url_include, url_exclude, delay_seconds, finish_action, finish_url, finish_message, evergreen_minutes, counter_start, counter_end, counter_step, counter_interval, orders_window_hours (24, 168, 720), orders_min |
Branding, die öffentliche Verifizierungsseite, Beispieldatensätze und das detaillierte Design bleiben im Dashboard.
Statistiken (GET /stats)
Impressionen und Klicks von Widgets und Leisten, verifizierte Bestellungen und Umsatz, durch Proof unterstützte Bestellungen und Umsatz sowie eine Aufschlüsselung pro Widget für die gewählte Anzahl Tage.
Fehler und Limits
{ "error": "...", "message": "..." }
401 missing or invalid key
403 read-only key used for a change
404 not in this workspace
422 refused: validation, plan limit, or an ended or archived barJeder Schlüssel kann 120 Anfragen pro Minute stellen.
MCP: Claude, Cursor und andere KI-Tools
Verbinde einen KI-Assistenten über den MCP-Server mit deinem Workspace. Er nutzt denselben API-Schlüssel und folgt denselben Regeln wie das Dashboard.
https://provedly.app/mcp (streamable HTTP)
Authorization: Bearer provedly_your_keyclaude mcp add --transport http provedly https://provedly.app/mcp --header "Authorization: Bearer provedly_YOUR_KEY"Tools
get_account, list_sites, list_widgets, list_bars, get_stats, set_widget_status, update_widget, set_bar_status, create_bar, update_bar, add_record, get_install_snippet.
Regeln
- Es gelten dieselben Tariflimits wie im Dashboard.
- Leisten, die ein Assistent anlegt, starten pausiert, bis du sie aktivieren lässt.
- Ein Nur-Lesen-Schlüssel kann nichts ändern.
- Datensätze, die über die API oder MCP hinzugefügt werden, werden nie als verifiziert markiert. Das gilt nur für signierte Webhooks von Stripe, Shopify und WooCommerce.
Beispiel-Prompts
- „Wie viele Impressionen und verifizierte Bestellungen hatten meine Widgets in den letzten 7 Tagen?“
- „Leg auf example.com eine Countdown-Leiste für den Winter-Sale an, der am 1. Dezember um 9 Uhr New Yorker Zeit endet.“
- „Pausiere alle Widgets auf meiner Staging-Website.“
- „Gib mir den Installationscode für meinen Shop.“
Statistik-Feed
Ein einzelner Nur-Lesen-Endpoint mit den wichtigsten Zahlen deines Workspaces, gebaut für Desktop-Widgets und Dashboards. Ein Nur-Lesen-Schlüssel reicht.
GET https://provedly.app/api/widget/summary?tz=America/New_York
X-API-Key: provedly_your_key
# or
Authorization: Bearer provedly_your_keycurl "https://provedly.app/api/widget/summary?tz=America/New_York" \
-H "X-API-Key: provedly_your_key"Was er liefert
Nur die Zahlen dieses Workspaces. Der Parameter tz ist optional.
| Feld | Inhalt | Hinweise |
|---|---|---|
| impressions | Reihe | |
| clicks | Reihe | |
| ctr | Klickrate | |
| visitors | live, unique_today | |
| orders | verified, assisted_30d, revenue_30d, assisted_revenue_30d, currency | verified ist eine Reihe. |
| product | sites, widgets_active, bars_active | |
| usage | impressions_month, impressions_limit, percent | Dieser Monat im Vergleich zu deinem Tarif. |
Reihenfelder enthalten today, yesterday, change_pct, last_7d, last_30d, total, trend_24h, trend_7d, trend_30d.
Die Zahlen werden höchstens einmal pro Minute neu berechnet. Jeder Schlüssel kann 60 Anfragen pro Minute stellen.
Records-API
Sende bei jedem Kauf einen Datensatz aus deinem Backend. Nur von Server zu Server. Nutze den eigenen Schlüssel des Widgets, den du im Tab Data erneuern kannst, oder einen Konto-Schlüssel mit Lese- und Schreibrechten.
POST https://provedly.app/api/v1/widgets/pp_your_widget_token/records
Authorization: Bearer pk_your_api_key
Content-Type: application/jsoncurl -X POST https://provedly.app/api/v1/widgets/pp_your_widget_token/records \
-H "Authorization: Bearer pk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "Jane Doe",
"city": "Berlin",
"country": "DE",
"product_name": "Pro Plan",
"price": "€49",
"external_id": "order_123",
"occurred_at": "2026-10-15T14:03:00Z"
}'| Feld | Regeln | Hinweise |
|---|---|---|
| name | Pflicht, Text, max. 120 | Wird vor der Anzeige gemäß deiner Einstellung für das Namensformat formatiert. |
| city | optional, max. 100 | |
| state | optional, max. 100 | Wird vom Standortformat „Stadt, Bundesland“ verwendet. |
| country | optional, 2 Buchstaben | ISO 3166-1 alpha-2. Wird in Großbuchstaben gespeichert. |
| product_name | optional, max. 150 | Fällt auf den Standard-Produktnamen des Widgets zurück. |
| price | optional, max. 30 | Freitext, z. B. „$49“ oder „€39“. |
| avatar_url | optional, URL | Wird verwendet, wenn der Avatar-Stil „image“ ist. |
| external_id | optional, max. 120 | Eindeutig pro Widget. Eine Wiederholung liefert 422. |
| occurred_at | optional, Datum | ISO 8601. Standard ist jetzt. |
Antworten
201 Created
{ "id": 812, "hash": "9c1e0b7a…", "verified": false, "occurred_at": "2026-10-15T14:03:00+00:00" }
401 Unauthorized wrong or missing bearer key
422 Unprocessable validation errors, including a duplicate external_idDas Widget zeigt API-Datensätze an, markiert sie aber nie als verifiziert. Die Verifiziert-Markierung ist signierten Webhooks vorbehalten. Siehe Webhooks.
CSV-Import
Importiere deinen Verlauf aus einer Tabelle im Tab Data des Widgets. Nur der Name ist Pflicht.
name,city,state,country,product_name,price,avatar_url,occurred_at
Sarah Mitchell,Austin,TX,US,Pro Plan,$49,,2026-10-15T13:49:00Z
Hugo Martin,Paris,,FR,Annual Pass,€39,,2026-10-15T11:03:00Z
Yui Tanaka,Tokyo,,JP,Lifetime,,,2026-10-14T14:03:00ZRegeln
- Kopfzeile erforderlich, Spalten in beliebiger Reihenfolge, zusätzliche Spalten werden ignoriert.
- Datumsangaben in ISO 8601. Fehlt ein Datum, gilt der Zeitpunkt des Imports.
- „Skip duplicates“ überspringt Zeilen, deren Name und Stadt innerhalb einer Stunde mit einem vorhandenen Datensatz übereinstimmen.
- Importierte Zeilen haben die Quelle
csvund sind nicht verifiziert. Zeilen, die älter als dein Anzeigezeitraum sind, werden gespeichert, aber nicht angezeigt.
Webhooks (verifizierte Käufe)
Nur Datensätze aus Webhooks bekommen die Verifiziert-Markierung. Füge den Endpoint im Tab Data des Widgets hinzu, füge das Signing Secret ein und registriere die URL dann beim Anbieter. In jedem Tarif verfügbar, auch im kostenlosen.
Stripe
- Füge im Tab Data des Widgets eine Stripe-Quelle hinzu. Kopiere die Endpoint-URL:
https://provedly.app/api/hooks/stripe/pp_your_widget_token- Gehe in Stripe zu Developers, Webhooks, Add endpoint. Füge die URL ein und wähle die Events, die dein Checkout sendet:
checkout.session.completedfür einmalige Checkout-Zahlungen,invoice.paidfür Abos undpayment_intent.succeedednur, wenn du Payment Intents ohne Checkout belastest. Ein Kauf wird nur einmal erfasst, auch wenn mehrere davon ausgelöst werden. - Kopiere das Signing Secret (
whsec_…) in das Secret-Feld der Quelle in Provedly. - Sende ein Test-Event aus Stripe. Die Quelle zeigt innerhalb weniger Sekunden „last event“ an.
Wir lesen den Namen des Kunden, Land und Stadt aus Liefer- oder Rechnungsadresse (falls vorhanden), die erste Position als Produkt und den formatierten Gesamtbetrag als Preis.
Shopify-App (empfohlen für Shopify-Shops)
- Installiere Provedly aus dem Shopify App Store (Eintrag folgt in Kürze).
- Klicke auf der Startseite der App auf „Open theme editor“, prüfe, dass das Provedly-App-Embed aktiviert ist, und speichere. Kein Code, kein Script-Tag.
- Bestellungen werden automatisch zu verifizierten Datensätzen: Die letzten 60 Tage werden bei der Installation importiert, und jede neue Bestellung kommt über einen signierten Webhook.
Die App läuft in deinem Shopify-Admin mit denselben Design-, Daten- und Analyse-Tools wie dieses Dashboard. Tarife werden über Shopify auf deiner normalen Shopify-Rechnung abgerechnet; der Free-Tarif braucht keine Zahlungsmethode. Namen und Städte von Käufern erscheinen erst, wenn Shopify der App den Zugriff auf Kundendaten genehmigt hat; bis dahin lauten die Benachrichtigungen „Someone just purchased…“.
Shopify-Webhook (manuell)
- Füge im Tab Data eine Shopify-Quelle hinzu und kopiere die URL:
https://provedly.app/api/hooks/shopify/pp_your_widget_token- Lege im Shopify-Admin unter Settings, Notifications, Webhooks einen Webhook für
Order payment(orders/paid) im JSON-Format mit dieser URL an.Order creationfunktioniert auch, wenn du unbezahlte Bestellungen einbeziehen willst; dieselbe Bestellung wird nie doppelt erfasst. - Kopiere das unter der Webhook-Liste angezeigte Shared Secret in das Secret-Feld der Quelle.
Payloads werden über den HMAC-SHA256-Header geprüft. Eine fehlgeschlagene Prüfung wird protokolliert und verworfen. Ohne Secret werden Events angenommen, aber in deinem Dashboard als „No signing secret set“ angezeigt und nicht als verifiziert markiert.
WooCommerce (WordPress-Plugin oder manueller Webhook)
- Füge im Tab Data eine WooCommerce-Quelle hinzu, kopiere die URL und wähle ein Signing Secret (eine beliebige Zeichenfolge mit mindestens 8 Zeichen):
https://provedly.app/api/hooks/woocommerce/pp_your_widget_token- Mit dem Plugin: Installiere Provedly von WordPress.org (Plugins, Installieren, nach „Provedly“ suchen), öffne Provedly im Admin-Menü, füge Widget-Token, URL und Secret ein und speichere. Das Plugin gibt die Script-Tags aus, legt den WooCommerce-Webhook an und übergibt für die Attribution die Besucher-ID an jede Bestellung.
- Manuell: WooCommerce, Settings, Advanced, Webhooks, Add webhook. Thema
Order updated, die Zustell-URL von oben, dasselbe Secret, API-VersionWP REST API v3.
WooCommerce signiert jede Zustellung mit HMAC-SHA256 in X-WC-Webhook-Signature. Nur Bestellungen im Status Processing oder Completed werden zu Datensätzen, jeweils einmal. Ausstehende, fehlgeschlagene und stornierte Bestellungen erscheinen nie.
Attribution (durch Proof unterstützte Bestellungen)
Das Dashboard zählt eine Bestellung nur dann als durch Proof unterstützt, wenn der Käufer eine Besucher-ID hatte, die in den 30 Tagen vor dem Kauf eine Benachrichtigung desselben Widgets gesehen hat. Nichts wird geschätzt. In Shopify-Shops mit der App passiert das automatisch: Das Widget schreibt die Besucher-ID als Attribut provedly_visitor in den Warenkorb, und der Bestell-Webhook liest sie wieder aus.
Überall sonst gibst du die Besucher-ID selbst weiter. Das Widget speichert sie im First-Party-Cookie pv_vid und stellt sie als window.Provedly.visitorId() bereit.
- Stripe: Setze
metadata.provedly_visitorauf der Checkout Session oder dem PaymentIntent. - Records-API: Sende sie im optionalen Feld
visitor.
// at checkout time, on your site
const visitor = window.Provedly?.visitorId();
// Stripe: pass it as metadata.provedly_visitor
// Records API: POST { ..., "visitor": visitor }Verifizierungsseite
Jedes Widget hat eine öffentliche Seite mit seinen Quellen, seiner Richtlinie und den Ledger-Roots. Das Badge in der Benachrichtigung verlinkt darauf. Du kannst sie auch von überall sonst verlinken.
https://provedly.app/verify/pp_your_widget_tokenWas sie zeigt
Anzahl verifizierter Käufe für 24 Stunden, 7 Tage und insgesamt; Zeitfenster und Minimum des Live-Zählers; ob Beispiele angezeigt werden; ob nur verifizierte Käufe angezeigt werden; jede Quelle mit Zahlen und letztem Datensatz; verbundene Anbieter; aktuelle verifizierte Käufe als Hashes; und die nächtlichen SHA-256-Ledger-Roots. Namen und Städte erscheinen nie. Die Begründung findest du auf der Vertrauensseite.
Einen Datensatz gegen einen Root prüfen
Der Hash jedes Datensatzes wird zurückgegeben, wenn du ihn über die API anlegst. Der Root eines Tages ist der SHA-256 der sortierten Liste der Datensatz-Hashes dieses Tages. Bewahre deine Hashes auf, dann kannst du den Root selbst nachrechnen.
Fehlerbehebung
Das Widget ist installiert, zeigt aber nichts an
Wenn „Verified purchases only“ aktiviert ist und das Widget noch keine verifizierten Datensätze hat, gibt es nichts anzuzeigen. Die Widget-Seite weist darauf hin. Schalte die Einstellung aus oder verbinde einen Shop.
Eine Änderung im Dashboard ist noch nicht auf meiner Website
Warte etwa eine Minute und lade die Seite neu. Mit den Snippets pro Element können neue Codeversionen ein paar Minuten dauern.
Auf meiner Website wird nichts angezeigt
- Öffne die Browser-Konsole. Ein 403 bei
/api/w/…/configbedeutet, dass die Domain der Seite nicht zu den erlaubten Domains der Website gehört. - Das Widget braucht mindestens einen Datensatz innerhalb des Anzeigezeitraums. Füge zum Testen einen Beispieldatensatz hinzu.
- Prüfe, ob der Widget-Status „active“ ist und der Workspace diesen Monat noch Impressionen übrig hat.
- Pfad-Targeting: Eine Einschlussliste, die nicht zum aktuellen Pfad passt, lässt das Widget stumm.
Der Live-Zähler erscheint nie
Er bleibt unter dem eingestellten Minimum ausgeblendet (Standard 2). Öffne die Seite in zwei Browsern oder in einem privaten Fenster und warte auf den ersten Heartbeat. Außerdem muss „Enable live counter“ aktiviert sein.
Webhook-Events kommen an, aber die Datensätze sind nicht verifiziert
Das Signing Secret fehlt oder ist falsch. Die Karte der Quelle zeigt „No signing secret set“ oder die Zahl der Events steigt nicht mehr. Füge das Secret erneut ein und sende ein Test-Event.
Die Benachrichtigung liegt hinter meinem Cookie-Banner
Erhöhe den z-index im Abschnitt Look des Widgets. Der Standard ist 9999.