GetAff
API-Dokumentation

MCP-Server

Alles, was die Bildschirme zur Partnergewinnung können, als Werkzeuge, die ein KI-Assistent aufrufen kann — über das Model Context Protocol, mit Ihrem API-Schlüssel.

Endpunkt
https://www.getaff.org/api/mcp
Transport
Streamable HTTP · 2025-11-25

Endpunkt

Eine URL, Transport Streamable HTTP (MCP-Spezifikation 2025-11-25; Clients mit 2025-06-18, 2025-03-26 und 2024-11-05 werden akzeptiert). Zustandslos: Jede Anfrage trägt ihren eigenen Schlüssel, die Antworten sind einfaches JSON, und der Server öffnet keinen Stream zum Client.

Authentifizierung und Geltungsbereiche

Senden Sie Authorization: Bearer gaff_live_… — dieselben Schlüssel, Geltungsbereiche und Ratenlimits wie bei der REST-API. Die Erkennung (initialize, tools/list) antwortet ohne Schlüssel, damit ein Client die Werkzeuge anzeigen kann; jeder Werkzeugaufruf braucht einen. Fehlt dem Schlüssel der Geltungsbereich eines Werkzeugs, kommt ein für den Assistenten lesbarer Fehler zurück. Erstellen Sie pro Assistent einen eigenen Schlüssel mit nur den nötigen Geltungsbereichen.

API-Schlüssel

Einen Client verbinden

Bewahren Sie den Schlüssel in einer Umgebungsvariablen oder im Geheimnisspeicher des Clients auf — nie in einer geteilten Konfigurationsdatei.

Claude Code

Ein Befehl; der Header wird bei jeder Anfrage gesendet.

shell
claude mcp add --transport http getaff https://www.getaff.org/api/mcp \
  --header "Authorization: Bearer $GETAFF_API_KEY"

Claude Desktop

Über die Brücke mcp-remote, die den Header ergänzt. Bearbeiten Sie claude_desktop_config.json (Einstellungen › Entwickler) und starten Sie Claude neu.

claude_desktop_config.json
{
  "mcpServers": {
    "getaff": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://www.getaff.org/api/mcp",
        "--header",
        "Authorization:${GETAFF_AUTH}"
      ],
      "env": {
        "GETAFF_AUTH": "Bearer gaff_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
      }
    }
  }
}

Benutzerdefinierte Konnektoren in claude.ai

In claude.ai hinzugefügte benutzerdefinierte Konnektoren melden sich per OAuth an, das GetAff noch nicht anbietet (siehe unten). Bis dahin nutzen Sie Claude Desktop mit der obigen Konfiguration oder Claude Code.

Cursor

In ~/.cursor/mcp.json (oder .cursor/mcp.json in einem Projekt). Der Schlüssel wird aus Ihrer Umgebung gelesen.

~/.cursor/mcp.json
{
  "mcpServers": {
    "getaff": {
      "url": "https://www.getaff.org/api/mcp",
      "headers": {
        "Authorization": "Bearer ${env:GETAFF_API_KEY}"
      }
    }
  }
}

VS Code

In .vscode/mcp.json; VS Code fragt einmal nach dem Schlüssel und bewahrt ihn im Geheimnisspeicher auf.

.vscode/mcp.json
{
  "inputs": [
    {
      "type": "promptString",
      "id": "getaff-key",
      "description": "GetAff API key",
      "password": true
    }
  ],
  "servers": {
    "getaff": {
      "type": "http",
      "url": "https://www.getaff.org/api/mcp",
      "headers": {
        "Authorization": "Bearer ${input:getaff-key}"
      }
    }
  }
}

ChatGPT und die OpenAI-API

In der ChatGPT-App hinzugefügte Konnektoren melden sich per OAuth an: nicht verfügbar, solange GetAff es nicht unterstützt. Über die OpenAI-API (Responses API oder Agents SDK) deklarieren Sie GetAff als entferntes MCP-Werkzeug mit dem Header — mit aktivierten Freigaben.

Python — OpenAI Responses API
from openai import OpenAI
import os

client = OpenAI()
response = client.responses.create(
    model="gpt-5",
    tools=[{
        "type": "mcp",
        "server_label": "getaff",
        "server_url": "https://www.getaff.org/api/mcp",
        "headers": {"Authorization": f"Bearer {os.environ['GETAFF_API_KEY']}"},
        "require_approval": "always",
    }],
    input="List my GetAff sites, then find wedding creators in France for the first one.",
)
print(response.output_text)

Jeder andere Client

Jeder Client, der Streamable HTTP spricht und einen Header senden kann, funktioniert. Die MCP-SDKs (TypeScript, Python) nehmen den Header als Option.

Kostenbestätigung

Werkzeuge, die Anbieter-Credits verbrauchen — search_partners mit includeLive, find_emails — verbrauchen beim ersten Aufruf nie etwas:

  1. Der erste Aufruf verbraucht nichts. Er liefert die Schätzung (Credits, Anbieter, Rest für heute) und ein confirmToken.
  2. Der Assistent zeigt dem Nutzer die Kosten und wartet auf ein ausdrückliches Ja.
  3. Derselbe Aufruf mit denselben Argumenten plus confirmToken wird ausgeführt und verbraucht höchstens die bestätigten Credits. Das Token ist an Schlüssel, Werkzeug und Argumente gebunden und läuft nach 15 Minuten ab; ein wiederholter bestätigter Aufruf liefert sein erstes Ergebnis erneut, statt zweimal zu zahlen.

Dieselbe Regel über REST

REST-Clients bestätigen mit einer Zahl: Ohne confirmCost von mindestens der Schätzung antwortet der Aufruf mit 402 cost_confirmation_required, die Schätzung in error.details.estimate, und verbraucht nichts.

JavaScript — REST
const base = 'https://www.getaff.org/api';
const headers = {
  Authorization: `Bearer ${process.env.GETAFF_API_KEY}`,
  'Content-Type': 'application/json',
  'Idempotency-Key': crypto.randomUUID(), // a retry never pays twice
};
const url = `${base}/v1/sites/${siteId}/partner-search`;

let res = await fetch(url, { method: 'POST', headers, body: JSON.stringify({ includeLive: true }) });
if (res.status === 402) {
  const { error } = await res.json(); // error.code === "cost_confirmation_required"
  const credits = error.details.estimate.credits;
  if (!(await askTheUser(`Spend about ${credits} credits?`))) return;
  headers['Idempotency-Key'] = crypto.randomUUID();
  res = await fetch(url, {
    method: 'POST',
    headers,
    body: JSON.stringify({ includeLive: true, confirmCost: credits }),
  });
}
const { data } = await res.json();

Werkzeuge

Jedes Werkzeug ruft dieselbe Operation auf wie der entsprechende REST-Endpunkt. Die Hinweise folgen der MCP-Spezifikation: Clients entscheiden damit, was sie den Nutzer vor der Ausführung fragen.

Werkzeuge
WerkzeugWas es tutGeltungsbereicheHinweise
list_sitesList the GetAff sites of the account, with the affiliate programme each one runs. Call this first: every partner-search tool takes a siteId.readnur lesend
get_siteOne site: its programme, the criteria the next search will use, shortlist size, the last search, and what a live search would cost today.readnur lesend
get_criteriaThe partner-search criteria of a site (keywords, niches, platforms, countries, languages, audience bands, recency), those GetAff derives from the site, and the generated TOPIC TERMS the ranking matches (with the user corrections). Use correct_topic_term to fix a term.readnur lesend
correct_topic_termCorrect one generated topic term of a site, as in the app "Terms used" panel: negative (off-topic, penalised), remove (no longer a match), restore (undo), dismiss (drop a suggestion). The next search ranks with it.readwriteschreibt
update_criteriaChange the partner-search criteria of a site. Each field given REPLACES the current one (send the full list you want); fields left out are kept. reset: true goes back to the derived criteria. Does not run a search: call search_partners next.readwriteschreibt
search_partnersRun ONE partner search for a site across every source: the GetAff creator index ranked for this programme, lookalikes of the shortlist, competitor findings and — with includeLive: true (Pro) — live creator-data providers. Returns merged, ranked creators with a fit score and per-source status. Free sources cost nothing. Live sources spend credits: the first call then returns only an estimate and a confirmToken; tell the user the cost, and only after they agree call again with the same arguments plus confirmToken. criteria changes apply to this run only.readsearchspend*schreibt · kostenpflichtig, bestätigt · ruft externe Dienste auf
get_latest_resultsThe ranked results of the last partner search of a site (kept 30 days), paginated, optionally filtered by minimum fit score or source. No new search is run.readnur lesend
explain_rankingWhy one creator of the latest search ranks where it does: rank, fit score (0-100) and its reasons (topic match, market, language, reach, recent activity, competitor evidence, similarity to the shortlist).readnur lesend
shortlist_listThe creators selected for a site ("Ma sélection"), with their prospect status.readnur lesend
shortlist_addAdd creators of the LATEST partner search to the site shortlist, by their key (e.g. "instagram:1784140"). Up to 50 per call; the shortlist holds 100.readwriteschreibt
shortlist_removeRemove creators from the site shortlist by key. Prospects already created are kept.readwriteschreibt · entfernt Daten
shortlist_to_prospectsTurn shortlisted creators into private prospects (free: no credit spent; counts on the discovery quota). Without keys, every shortlisted creator not yet a prospect. To get e-mail addresses afterwards, use find_emails (paid).readwriteschreibt
find_emailsPaid e-mail lookups at the creator-data providers, for prospects still without an address (Pro). The first call returns only the estimate and a confirmToken: tell the user the cost, and only after they agree call again with the same ids plus confirmToken. Never replaces an existing address.readspendspend*schreibt · kostenpflichtig, bestätigt · ruft externe Dienste auf
list_prospectsThe private prospects of the account, most recently collected first, filtered by status, site, platform or whether they have an address. Paginated by cursor.readnur lesend
get_prospectOne prospect: status, contact channel, address if known, provenance (where the data comes from).readnur lesend
chatSend one message to the GetAff partner-search assistant of a site (any language), e.g. "find wedding creators in Belgium with 10k-100k followers". It may change the criteria, run a free search, select creators or explain a rank. It never spends credits: a paid step comes back as pending — show the user its cost and, if they agree, call chat_confirm. One conversation per site; reset: true starts over.readsearchwriteschreibt · ruft externe Dienste auf
chat_confirmRun (decision "confirm") or drop (decision "cancel") the paid action a chat turn proposed. Confirming spends the credits shown in pending — only call it with "confirm" after the user explicitly agreed. Pending actions expire after 15 minutes.readsearchwriteschreibt · ruft externe Dienste auf
competitors_getThe competitor list of a site, the last lookup summary, and where each competitor recruits in the GetAff directory.readnur lesend
competitors_setReplace the competitor list of a site (up to 5 domains, optional brand name). Then competitors_run finds who promotes them.readwriteschreibt
competitors_runLook for public creators whose videos link to, or give a coupon for, the site competitors. Confirmed promoters become prospects (discovery quota). No credit of the user is spent; at most two runs an hour; takes up to two minutes.readsearchwriteschreibt · ruft externe Dienste auf
competitors_latestThe last competitor lookup of a site with its findings and their public evidence (video links, coupons).readnur lesend
creators_searchSearch the GetAff index of public creator profiles with filters (text, platforms, countries, niches, languages, audience, engagement, activity). Counts one of the plan index pages per day. rank: "fit" ranks by fit for the user programme. For a programme-aware search across every source, prefer search_partners.readsearchnur lesend
get_creatorOne creator of the index, by platform and platform id or handle.readnur lesend
lookalikesIndex creators similar to seed creators — given by key parts (creators), handles or profile URLs (handles), or the user accepted creator prospects (accepted: true).readsearchnur lesend
list_found_creatorsThe private library of creators that live providers already returned to this account ("Found creators"): reusable without spending credits again, with the sites each was found for and its fit. Filter by platform, niche, country, language, audience band, text or site.readnur lesend
found_to_prospectsTurn creators of the found library into private prospects, by key (free: no credit spent; counts on the discovery quota).readwriteschreibt
list_mailboxesThe mailboxes connected in GetAff that outreach sequences can send from (connecting one is done in the app).readnur lesend
list_sequencesThe outreach sequences of the account and the state of each of their three steps. Read-only.readnur lesend
enrol_in_sequenceSchedule the three-step outreach sequence (opening + two follow-ups) for ONE prospect, from a connected mailbox, with every check GetAff makes: valid and unsuppressed address, the recipient country compliance regime (pass the attestations that apply), complete sender settings, a published programme. E-mails are then sent by GetAff at the scheduled times — confirm with the user before calling. Without draft, the draft saved in GetAff for this prospect is used.readwriteschreibt · ruft externe Dienste auf
Was der Server nicht tut
  • Credits ohne ein für genau diesen Aufruf ausgestelltes Bestätigungstoken verbrauchen.
  • Eine E-Mail senden: enrol_in_sequence plant eine Sequenz mit allen Prüfungen der Anwendung (Rechtskonformität, Sperrliste, Absendereinstellungen); GetAff sendet sie später aus Ihrem Postfach.
  • Eine Browsersitzung akzeptieren: Nur der API-Schlüssel authentifiziert, ein angemeldeter Browser gewährt nichts.
  • Einen Schlüssel, ein Token oder Netzwerk-Zugangsdaten zurückgeben, in keinem Werkzeug.
  • Creator-Text als Anweisung ausgeben: Namen, Handles und Bios stammen aus öffentlichen Profilen und sind in jedem Ergebnis als Drittdaten gekennzeichnet.

Beispiele

Ein roher JSON-RPC-Aufruf mit curl, dann derselbe mit den offiziellen SDKs.

curl
curl -s https://www.getaff.org/api/mcp \
  -H "Authorization: Bearer $GETAFF_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
       "params":{"name":"search_partners",
                 "arguments":{"siteId":"Wq3b9ZK1","includeLive":true}}}'

# → structuredContent.status = "confirmation_required", with the estimate
#   and a confirmToken. Nothing was spent. After the user agrees:
#   same call, "arguments":{"siteId":"Wq3b9ZK1","includeLive":true,"confirmToken":"gcf_…"}
TypeScript — @modelcontextprotocol/sdk
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';

const transport = new StreamableHTTPClientTransport(new URL('https://www.getaff.org/api/mcp'), {
  requestInit: { headers: { Authorization: `Bearer ${process.env.GETAFF_API_KEY}` } },
});
const client = new Client({ name: 'my-agent', version: '1.0.0' });
await client.connect(transport);

const { tools } = await client.listTools();
const sites = await client.callTool({ name: 'list_sites', arguments: {} });
console.log(tools.map((t) => t.name), sites.structuredContent);
Python — mcp
import asyncio, os
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

async def main():
    headers = {"Authorization": f"Bearer {os.environ['GETAFF_API_KEY']}"}
    async with streamablehttp_client("https://www.getaff.org/api/mcp", headers=headers) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()
            tools = await session.list_tools()
            print([t.name for t in tools.tools])
            sites = await session.call_tool("list_sites", {})
            print(sites.structuredContent)

asyncio.run(main())

OAuth: noch nicht

Die MCP-Autorisierungsspezifikation (OAuth 2.1 mit dynamischer Client-Registrierung) nutzen die Konnektoren von claude.ai und ChatGPT zur Anmeldung. GetAff implementiert sie noch nicht; sobald das geschieht, stehen dieselben Werkzeuge diesen Konnektoren ohne eingefügten Schlüssel zur Verfügung. Bis dahin sind API-Schlüssel der einzige Zugang — jederzeit widerrufbar unter /docs/keys.