GetAff
Documentation API

Serveur MCP

Tout ce que font les écrans de recrutement de partenaires, sous forme d’outils qu’un assistant IA peut appeler — via le Model Context Protocol, avec votre clé d’API.

Point d’accès
https://www.getaff.org/api/mcp
Transport
Streamable HTTP · 2025-11-25

Point d’accès

Une URL, transport Streamable HTTP (spécification MCP 2025-11-25 ; les clients 2025-06-18, 2025-03-26 et 2024-11-05 sont acceptés). Sans état : chaque requête porte sa propre clé, les réponses sont du JSON simple et le serveur n’ouvre aucun flux vers le client.

Authentification et portées

Envoyez Authorization: Bearer gaff_live_… — les mêmes clés, portées et limites de débit que l’API REST. La découverte (initialize, tools/list) répond sans clé pour qu’un client puisse afficher les outils ; chaque appel d’outil en demande une. Un outil dont la portée manque à la clé renvoie une erreur lisible par l’assistant. Créez une clé dédiée par assistant, avec seulement les portées utiles.

Clés d’API

Connecter un client

Conservez la clé dans une variable d’environnement ou le coffre de secrets du client — jamais dans un fichier de configuration partagé.

Claude Code

Une commande ; l’en-tête est envoyé à chaque requête.

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

Claude Desktop

Via la passerelle mcp-remote, qui ajoute l’en-tête. Modifiez claude_desktop_config.json (Réglages › Développeur), puis redémarrez Claude.

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"
      }
    }
  }
}

Connecteurs personnalisés de claude.ai

Les connecteurs personnalisés ajoutés dans claude.ai se connectent par OAuth, que GetAff ne propose pas encore (voir plus bas). D’ici là, utilisez Claude Desktop avec la configuration ci-dessus, ou Claude Code.

Cursor

Dans ~/.cursor/mcp.json (ou .cursor/mcp.json dans un projet). La clé est lue dans votre environnement.

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

VS Code

Dans .vscode/mcp.json ; VS Code demande la clé une fois et la garde dans son stockage de secrets.

.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 et l’API OpenAI

Les connecteurs ajoutés dans l’application ChatGPT se connectent par OAuth : indisponible tant que GetAff ne le prend pas en charge. Depuis l’API OpenAI (Responses API ou Agents SDK), déclarez GetAff comme outil MCP distant avec l’en-tête — en gardant les approbations activées.

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)

Tout autre client

Tout client qui parle Streamable HTTP et sait envoyer un en-tête fonctionne. Les SDK MCP (TypeScript, Python) prennent l’en-tête en option.

Confirmation du coût

Les outils qui dépensent des crédits de fournisseur — search_partners avec includeLive, find_emails — ne dépensent jamais au premier appel :

  1. Le premier appel ne dépense rien. Il renvoie l’estimation (crédits, fournisseur, reste du jour) et un confirmToken.
  2. L’assistant montre le coût à l’utilisateur et attend un oui explicite.
  3. Le même appel, avec les mêmes arguments plus confirmToken, s’exécute — en dépensant au plus les crédits confirmés. Le jeton est lié à la clé, à l’outil et aux arguments, et expire au bout de 15 minutes ; un appel confirmé répété rejoue son premier résultat au lieu de payer deux fois.

La même règle en REST

Les clients REST confirment par un nombre : sans confirmCost au moins égal à l’estimation, l’appel répond 402 cost_confirmation_required avec l’estimation dans error.details.estimate, et ne dépense rien.

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();

Outils

Chaque outil appelle la même opération que le point d’accès REST correspondant. Les indications suivent la spécification MCP : les clients s’en servent pour décider quoi demander à l’utilisateur avant d’exécuter.

Outils
OutilCe qu’il faitPortéesIndications
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.readlecture seule
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.readlecture seule
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.readlecture seule
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.readwriteécrit
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.readwriteécrit
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*écrit · payant, confirmé · appelle des services externes
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.readlecture seule
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).readlecture seule
shortlist_listThe creators selected for a site ("Ma sélection"), with their prospect status.readlecture seule
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.readwriteécrit
shortlist_removeRemove creators from the site shortlist by key. Prospects already created are kept.readwriteécrit · supprime des données
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).readwriteécrit
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*écrit · payant, confirmé · appelle des services externes
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.readlecture seule
get_prospectOne prospect: status, contact channel, address if known, provenance (where the data comes from).readlecture seule
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.readsearchwriteécrit · appelle des services externes
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.readsearchwriteécrit · appelle des services externes
competitors_getThe competitor list of a site, the last lookup summary, and where each competitor recruits in the GetAff directory.readlecture seule
competitors_setReplace the competitor list of a site (up to 5 domains, optional brand name). Then competitors_run finds who promotes them.readwriteécrit
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.readsearchwriteécrit · appelle des services externes
competitors_latestThe last competitor lookup of a site with its findings and their public evidence (video links, coupons).readlecture seule
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.readsearchlecture seule
get_creatorOne creator of the index, by platform and platform id or handle.readlecture seule
lookalikesIndex creators similar to seed creators — given by key parts (creators), handles or profile URLs (handles), or the user accepted creator prospects (accepted: true).readsearchlecture seule
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.readlecture seule
found_to_prospectsTurn creators of the found library into private prospects, by key (free: no credit spent; counts on the discovery quota).readwriteécrit
list_mailboxesThe mailboxes connected in GetAff that outreach sequences can send from (connecting one is done in the app).readlecture seule
list_sequencesThe outreach sequences of the account and the state of each of their three steps. Read-only.readlecture seule
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.readwriteécrit · appelle des services externes
Ce que le serveur ne fera pas
  • Dépenser des crédits sans un jeton de confirmation émis pour cet appel précis.
  • Envoyer un e-mail : enrol_in_sequence programme une séquence avec tous les contrôles de l’application (conformité, liste d’exclusion, réglages d’expéditeur) ; GetAff l’envoie ensuite depuis votre boîte.
  • Accepter une session de navigateur : seule la clé d’API authentifie, un navigateur connecté n’accorde rien.
  • Renvoyer une clé, un jeton ou un identifiant de plateforme, dans aucun outil.
  • Faire passer le texte d’un créateur pour des instructions : noms, identifiants et bios viennent de profils publics et sont signalés comme données tierces dans chaque résultat.

Exemples

Un appel JSON-RPC brut avec curl, puis le même avec les SDK officiels.

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 : pas encore

La spécification d’autorisation MCP (OAuth 2.1 avec enregistrement dynamique des clients) est ce qu’utilisent les connecteurs de claude.ai et de ChatGPT pour se connecter. GetAff ne l’implémente pas encore ; quand ce sera le cas, les mêmes outils seront disponibles pour ces connecteurs sans coller de clé. D’ici là, les clés d’API sont le seul accès — révocables à tout moment depuis /docs/keys.