GetAff
Artikel

Affiliate-Gewinnung mit der REST-API von GetAff automatisieren

Die REST-API von GetAff bietet dieselben Operationen wie die Ansichten zur Partnergewinnung: Suchkriterien, eine Suche über alle Quellen, die Auswahl, Interessenten und ihre E-Mail-Adressen sowie die Aufnahme in eine Ansprache-Sequenz. Ein nächtlicher Job kann also eine Suche aktualisieren, die besten neuen Creator behalten und ihre Ansprache vorbereiten, ohne dass jemand die App öffnet.

Dieser Artikel begleitet diesen Job von der ersten bis zur letzten Anfrage, mit den drei Regeln, die eine Automatisierung sicher machen: Kostenpflichtige Aufrufe werden mit einer Zahl bestätigt, Schreibzugriffe tragen einen Idempotenzschlüssel, und der Client liest die Ratenlimit-Header, statt zu raten.

Aktualisiert am

Einen Schlüssel mit den richtigen Scopes erstellen

Melden Sie sich an, öffnen Sie die Seite API-Schlüssel und erstellen Sie einen Schlüssel pro Integration – so können Sie einen widerrufen, ohne die anderen zu stoppen. Der Wert wird genau einmal angezeigt: GetAff speichert nur einen Hash.

  • read ist immer enthalten: Websites, Kriterien, Ergebnisse, Interessenten, Sequenzen.
  • search für Suchen, die keine Credits verbrauchen (Index, ähnliche Creator, Wettbewerber).
  • write, um Kriterien, die Auswahl und Interessenten zu ändern und in eine Sequenz aufzunehmen.
  • spend für Live-Suchen bei den Anbietern und kostenpflichtige E-Mail-Suchen – nur für eine Integration, der Sie zutrauen, ein Budget einzuhalten.

Bewahren Sie den Schlüssel serverseitig auf, in einem Secret-Manager oder einer Umgebungsvariablen. Die API lehnt bewusst jeden Browser-Origin ab: Ein Schlüssel im JavaScript einer Seite ist ein veröffentlichter Schlüssel. Details unter Authentifizierung.

Erster Aufruf: Ihre Websites

Die Basis-URL lautet https://www.getaff.org/api/v1. Jede Partnersuche gehört zu einer Website, also listen Sie diese zuerst auf:

curl -s https://www.getaff.org/api/v1/sites \
  -H "Authorization: Bearer $GETAFF_API_KEY"

Jede Website wird mit ihrem Programm geliefert. GET /v1/sites/{id}/criteria gibt die Kriterien zurück, die die nächste Suche verwendet, und diejenigen, die GetAff aus der Website ableitet; PATCH auf demselben Pfad ersetzt die gesendeten Felder und behält die übrigen.

POST /v1/sites/{id}/partner-search führt dieselbe Suche aus wie die App: den Creator-Index von GetAff, sortiert für Ihr Programm, ähnliche Creator wie in Ihrer Auswahl, die Promoter Ihrer Wettbewerber und – mit includeLive – die Live-Anbieter für Creator-Daten. Die Ergebnisse werden zusammengeführt, dedupliziert und sortiert, jedes mit einem Passungswert und seinen Gründen; statuses zeigt, was jede Quelle getan hat.

Nur kostenlose Quellen
SITE_ID=Wq3b9ZK1
curl -s -X POST https://www.getaff.org/api/v1/sites/$SITE_ID/partner-search \
  -H "Authorization: Bearer $GETAFF_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: nightly-$SITE_ID-$(date +%F)" \
  -d '{"limit": 50}'

Der Lauf ersetzt die letzte Suche (30 Tage aufbewahrt) und wird zu den gespeicherten Suchen hinzugefügt, sodass GET /v1/sites/{id}/partner-search/latest und die Verlaufs-Endpunkte sie später erneut lesen können, ohne etwas auszuführen.

Kostenpflichtige Aufrufe: der 402-Handshake

Zwei Operationen verbrauchen Anbieter-Credits: die Partnersuche mit includeLive: true und POST /v1/prospects/find-emails. Beide benötigen den Scope spend UND ein confirmCost, das mindestens der Schätzung entspricht. Fehlt es, wird nichts ausgegeben und die API antwortet mit 402 cost_confirmation_required, die genaue Schätzung in error.details.estimate.

  1. Senden Sie die Anfrage ohne confirmCost.
  2. Lesen Sie error.details.estimate.credits aus der 402.
  3. Vergleichen Sie den Wert mit Ihrem Budget – oder zeigen Sie ihn einem Menschen.
  4. Senden Sie dieselbe Anfrage erneut, mit confirmCost gleich dieser Zahl oder einer höheren Obergrenze.
Node — innerhalb eines Budgets bestätigen
async function confirmed(url, body) {
  const call = (b) =>
    fetch(url, {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${process.env.GETAFF_API_KEY}`,
        'Content-Type': 'application/json',
        'Idempotency-Key': crypto.randomUUID(),
      },
      body: JSON.stringify(b),
    });
  let res = await call(body);
  if (res.status === 402) {
    const { error } = await res.json();
    const credits = error.details.estimate.credits;
    if (credits > MAX_CREDITS_PER_RUN) throw new Error(`Over budget: ${credits}`);
    res = await call({ ...body, confirmCost: credits });
  }
  return res.json();
}

Jede bestätigte Ausgabe wird in einem Audit-Log festgehalten (Schlüssel, Aktion, Credits – nie Daten eines Creators). Die Tageskontingente Ihres Tarifs gelten zusätzlich zu jedem Budget, das Sie festlegen.

Von Ergebnissen zu Interessenten

Jedes Ergebnis trägt einen key wie instagram:1784140. Behalten Sie die, die Ihre Regeln auswählen – ein Mindest-Passungswert, ein Land, eine Mindestreichweite – und verketten Sie drei Aufrufe:

  1. POST /v1/sites/{id}/shortlist mit {"keys": [...]} fügt sie der Auswahl hinzu (sie fasst 100).
  2. POST /v1/sites/{id}/shortlist/to-prospects macht sie zu privaten Interessenten. Kostenlos; zählt auf das Entdeckungskontingent Ihres Tarifs.
  3. POST /v1/prospects/find-emails mit den ids der Interessenten sucht die fehlenden Adressen (Pro, kostenpflichtig, bestätigt wie oben). Eine vorhandene Adresse wird nie ersetzt, und die Sperrliste gilt.

GET /v1/prospects?siteId=…&hasEmail=false listet auf, was noch fehlt; die Sammlung ist per Cursor paginiert – geben Sie page.nextCursor unverändert als cursor zurück.

In eine Ansprache-Sequenz aufnehmen

POST /v1/outreach/sequences plant die dreistufige Sequenz (Erstnachricht und zwei Follow-ups) für einen Interessenten aus einem verbundenen Postfach, mit allen Prüfungen der App: vollständige Absendereinstellungen, ein veröffentlichtes Programm, eine gültige und nicht gesperrte Adresse sowie die Compliance-Regeln des Empfängerlandes.

{
  "prospectId": "kJ2p8wQxYb_ig_1784140",
  "attestations": ["b2b_role_relevant", "legitimate_interest_assessed"]
}

Ohne draft wird der in GetAff für diesen Interessenten gespeicherte Entwurf verwendet. Jede Ablehnung hat einen eigenen Code – mailbox_required, draft_required, recipient_suppressed, compliance_blocked (mit details.missing) und so weiter –, damit Ihr Job genau protokollieren kann, warum ein Interessent übersprungen wurde. Es gibt keinen Endpunkt, der direkt eine E-Mail sendet: Der Versand erfolgt später, aus Ihrem Postfach, zu den geplanten Zeiten.

Wiederholen, ohne doppelt zu zahlen

Schreibzugriffe akzeptieren einen Idempotency-Key-Header. Eine Wiederholung mit demselben Schlüssel und demselben Body innerhalb von 24 Stunden liefert den ersten Erfolg erneut (Idempotent-Replayed: true), statt erneut auszuführen – wichtig bei einer Suche, die Credits verbraucht hat. Fehler werden nicht gespeichert: Korrigieren Sie die Anfrage und wiederholen Sie sie mit demselben Schlüssel.

  • Leiten Sie den Schlüssel aus der Bedeutung des Jobs ab: nightly-<siteId>-<date>, kein Zufallswert pro Versuch.
  • Derselbe Schlüssel mit einem anderen Body ergibt idempotency_conflict; eine noch laufende Anfrage ergibt idempotency_in_progress.

Ratenbegrenzung und Fehler

Der Durchsatz wird pro Schlüssel über eine Minute gezählt: 60 Anfragen im Free-Tarif, 600 im Pro-Tarif, mit einer kontoweiten Obergrenze, die sich alle Schlüssel und der MCP-Server teilen. Jede Antwort trägt X-RateLimit-Limit, X-RateLimit-Remaining und die IETF-Header RateLimit-Policy / RateLimit; eine 429 enthält zusätzlich Retry-After. Die eigenen Obergrenzen der App gelten ebenfalls, etwa sechs Partnersuchen pro Minute.

Fehler sind Problemdokumente nach RFC 9457 mit einem stabilen error.code: Verzweigen Sie über den Code, niemals über die Meldung. Wiederholen Sie 429 und 503 (unter Beachtung von Retry-After); 400, 401, 403 und 404 ändern sich durch Wiederholen nicht. Die vollständigen Listen finden Sie unter Ratenbegrenzung und Fehler.

Nächste Schritte

Die Seite Erste Schritte zeigt den ersten Aufruf und die Versionierungsregeln, und die Referenz dokumentiert jeden Endpunkt, generiert aus den Schemas, die die Routen durchsetzen. Um auf die Antwort eines Interessenten zu reagieren, statt regelmäßig abzufragen, richten Sie einen signierten Webhook ein.

Dokumentation

Der genaue Vertrag, erzeugt aus den Schemas, die die Routen durchsetzen:

Weiterlesen