Felo API PlatformFelo API Platform

Research

Maak van één zoekopdracht een SEO-contentbrief

Bekijk welke pagina’s de zoekopdracht nu beantwoorden, lees ze als Markdown, breng de vragen in kaart die ze wel en niet behandelen en schrijf een brief waar de redacteur direct een outline van kan maken.

Tijd25 minutenNiveauGevorderdBijgewerkt2026-10-30
Voor wieContentmarketingSEO-specialistenRedacteuren

Prompt kopiëren

Vervang de velden tussen blokhaken en plak in Claude Code, Codex of een AI met terminaltoegang. Die installeert de Felo-skill, vraagt voor credits en voert de workflow uit.

Schrijf een SEO-contentbrief voor de query [doelquery] voor [product of site].

Publiek: [lezer]. Markt en taal: [regio], [taal]. Invalshoek: [gids / vergelijking / productpagina]. Beslissing die het ondersteunt: [nieuw artikel / opfrissen / gat vullen].

Lees eerst wat deze query nu beantwoordt voordat je een outline maakt. Lever een Markdown-brief met:
1. De doelquery en de intentie die je afleidt, met het bewijs voor die lezing.
2. Wat de huidige pagina’s dekken: titel, URL en de eerste secties.
3. Vragen die de huidige pagina’s beantwoorden en vragen die ze missen.
4. Een voorgestelde outline met één regel per sectie over wat die moet bewijzen.
5. Bewijs en voorbeelden uit de bronnen, met links.
6. Een volledige bronnenlijst.

Regels:
- Beweer geen zoekvolume, keywordmoeilijkheid, positie of verkeer. Deze workflow meet dat niet; schrijf ‘Hier niet gemeten’ in plaats van een getal.
- Verzin geen statistieken, citaten of beweringen over content van concurrenten.
- Beschrijf intentie als een lezing van de pagina’s, niet als een gemeten feit.
- Houd citaten kort, met bron en link.
- Zet de regio en taal om in expliciete waarden.
- Voordat er credits worden gebruikt, toon je de geplande API-aanroepen en wacht je op mijn goedkeuring.
- Publiceer, plan of verstuur niets.
- Schrijf het resultaat naar ./seo-brief.md en vat het samen in de chat.

De kopie bevat ook de installatiestappen en veiligheidsregels.

Wat je krijgt

Voorbeelduitvoer van een run. Geen live generatie.

Voorbeeldbrief (fragment)

SEO-brief — “hoe automatiseer je supporttriage”

Doelquery en intentie

Query: “hoe automatiseer je supporttriage”. De teruggegeven pagina’s beginnen met implementatiestappen, niet met productpagina’s, dus de intentie leest als how-to. Dit is een lezing van de pagina’s, geen gemeten intentielabel.

Wat de huidige pagina’s dekken

PaginaURLBegint met
Supporttriage automatiseren: praktische gidshttps://example.com/guideRoutingregels, dan tags
Checklist voor triage-automatiseringhttps://example.com/checklistDe checklist zelf

Vragen die de pagina’s beantwoorden

  • Wat triage-automatisering verandert
  • Met welke routingregels beginnen

Vragen die ze missen

  • Hoe je meet of triage echt beter werd
  • Wat te doen als de classifier het mis heeft

Voorgestelde opbouw

  1. Wat triage-automatisering verandert — bewijs dat het om de wachtrij gaat, niet om headcount.
  2. De eerste drie routingregels die automatisering waard zijn — bewijs elk met een voorbeeld.
  3. Hoe je het de eerste maand meet — bewijs met een metric die een ops-lead kan ophalen.
  4. Wanneer de automatisering fout zit — bewijs het menselijke fallbackpad.

Bewijs

  • Voorbeeld van een routingregel, geciteerd uit https://example.com/guide (gecontroleerd op 2026-10-30)

Hier niet gemeten

Zoekvolume, keywordmoeilijkheid en positie. Deze workflow leest publieke pagina’s; hij bevraagt geen zoekindex of ranktracker.

Bronnen

  • https://example.com/guide
  • https://example.com/checklist

De exacte aanroepen

Voor ontwikkelaars: dezelfde workflow als kopieerbare code in uitvoeringsvolgorde.

Exacte API-aanroepen tonen
  1. Kijk wie nu antwoordt

    Vraag Chat naar de zoekopdracht en krijg het antwoord en de geciteerde pagina’s. Die pagina’s zijn de huidige concurrentinhoud.

    seo-brief.ts
    const BASE = "https://openapi.felo.ai";
    const headers = {
      Authorization: `Bearer ${process.env.FELO_API_KEY}`,
      "Content-Type": "application/json",
    };
    
    async function felo<T>(path: string, body?: unknown): Promise<T> {
      const res = await fetch(`${BASE}${path}`, {
        method: body ? "POST" : "GET",
        headers,
        body: body ? JSON.stringify(body) : undefined,
      });
      if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
      return res.json() as Promise<T>;
    }
    
    type ChatData = {
      data: {
        answer: string;
        resources: { link: string; title: string; snippet: string }[];
      };
    };
    
    const query = "how to automate support triage";
    const ourSite = "example.com";
    
    const coverage = await felo<ChatData>("/v2/chat", {
      query: `What pages currently answer the search query "${query}"? List the pages and what each one covers.`,
    });
    
    const candidates = coverage.data.resources
      .filter((resource) => !resource.link.includes(ourSite))
      .slice(0, 5)
      .map((resource) => ({ url: resource.link, title: resource.title }));

    Voorbeelduitvoer

    {
      "answer": "Readers searching this usually want a step-by-step …",
      "sources": [
        { "link": "https://example.com/guide", "title": "…", "snippet": "…" }
      ]
    }
  2. Lees de pagina’s als Markdown

    Haal de drie tot vijf sterkste pagina’s met Web Fetch als Markdown op en bewaar koppen en vragen.

    seo-brief.ts
    type ExtractData = { data: { content: string } };
    
    const pages = await Promise.all(
      candidates.map(async (page) => {
        const res = await felo<ExtractData>("/v2/web/extract", {
          url: page.url,
          output_format: "markdown",
          with_readability: true,
          with_cache: true,
        });
        const checkedAt = new Date().toISOString().slice(0, 10);
        return { ...page, checkedAt, content: res.data.content };
      }),
    );

    Voorbeelduitvoer

    {
      "url": "https://example.com/guide",
      "checkedAt": "2026-10-30",
      "content": "# Automating support triage\n\n## Routing rules\n…"
    }
  3. Breng dekking en gaten in kaart

    Extraheer H2/H3 en FAQ-vragen per pagina en maak een tabel: welke vragen zijn beantwoord en welke niet?

    seo-brief.ts
    type Heading = { page: string; heading: string };
    
    const headings: Heading[] = pages.flatMap((page) =>
      page.content
        .split("\n")
        .filter((line) => line.startsWith("## "))
        .map((line) => ({
          page: page.title,
          heading: line.replace(/^##\s+/, ""),
        })),
    );
    
    const questions = headings.filter((item) => item.heading.includes("?"));
    
    const byTopic = new Map<string, string[]>();
    for (const item of headings) {
      byTopic.set(item.heading, [...(byTopic.get(item.heading) ?? []), item.page]);
    }

    Voorbeelduitvoer

    // questions
    [
      { "page": "…", "heading": "What routes should you automate first?" }
    ]
  4. Schrijf de brief

    Beschrijf doelzoekopdracht, intentie, dekkingsvergelijking, ontbrekende vragen, voorgestelde outline en bronnenlijst.

    seo-brief.ts
    const today = new Date().toISOString().slice(0, 10);
    
    const brief = [
      `# SEO brief — "${query}"`,
      `Checked ${today}. Site: ${ourSite}.`,
      "",
      "## Intent read",
      "The pages returned for this query lead with: " +
        headings.slice(0, 6).map((item) => item.heading).join("; ") +
        ". This is a reading of their structure, not a measured intent label.",
      "",
      "## What the pages cover",
      "| Page | URL | Checked |",
      "| --- | --- | --- |",
      ...pages.map((page) => `| ${page.title} | ${page.url} | ${page.checkedAt} |`),
      "",
      "## Questions the pages answer",
      ...questions.map((item) => `- ${item.heading} (${item.page})`),
      "",
      "## Topics more than one page covers",
      ...[byTopic.entries()]
        .filter(([, pageTitles]) => pageTitles.length > 1)
        .map(([heading, pageTitles]) => `- ${heading} (${pageTitles.length} pages)`),
      "",
      "## Proposed outline",
      ...questions.slice(0, 5).map((item, index) => `${index + 1}. ${item.heading}`),
      "",
      "## Questions they miss",
      "<!-- Only questions none of the fetched pages answer. Delete this comment when filled. -->",
      "",
      "## Not measured here",
      "Search volume, keyword difficulty, and ranking position. This workflow reads public pages; it does not query a search index or a rank tracker.",
      "",
      "## Sources",
      ...pages.map((page) => `- ${page.title}: ${page.url}`),
    ].join("\n");
    
    console.log(brief);

    Voorbeelduitvoer

    # SEO brief — "how to automate support triage"
  5. Sla op in de LiveDoc

    Sla brief en paginalinks op in de LiveDoc, zodat de volgende update alleen wijzigingen ophaalt.

    seo-brief.ts
    type LiveDocData = { data: { short_id: string } };
    
    const briefDoc = await felo<LiveDocData>("/v2/livedocs", {
      name: `SEO briefs: ${ourSite}`,
      description: "One document resource per target query",
    });
    
    await felo(`/v2/livedocs/${briefDoc.data.short_id}/resources/urls`, {
      urls: pages.map((page) => ({ url: page.url, title: page.title })),
    });
    
    await felo(`/v2/livedocs/${briefDoc.data.short_id}/resources/doc`, {
      title: `SEO brief — ${query}`,
      content: brief,
    });
    
    console.log(briefDoc.data.short_id); // the next query adds to this archive

    Voorbeelduitvoer

    { "short_id": "PvyKouzJirXjFdst4uKRK3" }

Wat inbegrepen is

  • Onderbouwde paginalijst uit Chat en links naar het antwoord
  • Huidige toppagina’s als Markdown
  • Koppen en vragen die ze behandelen
  • Een brief waar direct een outline uit komt
  • LiveDoc met bronnen voor de volgende update

Wat het niet doet

  • Meet geen posities, zoekvolume, keywordmoeilijkheid of verkeer
  • Alleen openbare pagina’s; login en paywall kunnen falen
  • Publiceert of herschrijft het artikel niet
  • Eén run per zoekopdracht; meerdere vragen jouw eigen lus
  • Garandeert geen posities

Vragen

Meet het zoekvolume of posities?

Nee. Het leest openbare pagina’s en beoordeelt welke inhoud nu antwoordt; posities en volume horen in je SEO-tools.

Waar komen de data vandaan?

Chat geeft onderbouwde pagina’s en Web Fetch maakt ze Markdown. Elke beoordeling in de brief wijst naar een concrete pagina en datum.

Kan ik meerdere zoekopdrachten doen?

Ja, maar één per keer. Herhaal de stappen per zoekopdracht en sla aparte brieven op.

Voor welke zoekopdrachten werkt het?

Informatieve, vergelijkende en ‘hoe doe ik’-vragen, omdat openbare pagina’s genoeg signaal geven. Transactionele vragen hebben je product- en conversiedata nodig.

Schrijft het het artikel?

Nee. Het levert brief en outline; het schrijven doet de redacteur of je schrijfagent.

Wat kost een run?

Chat en pagina-extractie verbruiken credits; actuele tarieven staan op de prijspagina. De prompt vraagt goedkeuring voor uitgaven.

Gerelateerde workflows

Maak het van jou

Hetzelfde recept, aangepast aan hoe je echt oplevert.

Alleen vergelijkende zoekopdrachten

Beperk tot ‘X vs Y’ en ‘beste X’ om de differentiatiehoek beter te zien.

Voeg je productpagina toe

Neem de productpagina als extra bron op, zodat de outline op je functies en prijzen landt.

Elk kwartaal vernieuwen

Draai opnieuw in dezelfde LiveDoc en kijk hoe concurrentpagina’s en outline veranderen.

De referentiepagina’s achter dit recept en de volgende stappen.