Felo API PlatformFelo API Platform

Research

Bouw een concurrentieanalyse die je salesteam direct kan gebruiken

Verzamel de pagina’s van de concurrent, de berichtgeving eromheen en wat kopers op X zeggen, en zet een analyse in elkaar waarin elke bewering bron, datum en status heeft.

Tijd30 minutenNiveauGevorderdBijgewerkt2026-10-30
Voor wieProductmarketingCompetitive intelligenceSales enablement

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.

Maak een concurrentiële teardown van [naam concurrent] voor [ons product].

Bereik: [segment], [regio], [taal]. Tijdvenster: [laatste 90 dagen / laatste 12 maanden]. Beslissing die het ondersteunt: [prijswijziging / lanceringspositionering / omgaan met bezwaren].
Startbronnen: [domein concurrent], [URL prijspagina], [URL changelog].

Lever een Markdown-teardown met:
1. Hoe zij zich positioneren, in hun eigen woorden.
2. Een bewijstabel: bewering, titel van de bron, URL, datum, status (Verified / Vendor claim / Third-party / Signal / Inference / Not verified).
3. Prijzen: wat de pagina zegt, met de link en de controledatum. Neem nooit een tarief over zonder pagina en datum.
4. Waar kopers tegensputteren, met X-accounts en datums, gemarkeerd als signaal.
5. Wat wij hierna moeten doen, gemarkeerd als aanbeveling.
6. Een volledige bronnenlijst.

Regels:
- Citeer hun positionering; herformuleer die niet sterker.
- Scheid leveranciersclaims, berichtgeving van derden en je eigen gevolgtrekkingen. Label elke rij.
- Verzin nooit een prijs, cijfer, klantnaam of benchmark. Ontbrekende data heet ‘Niet beschikbaar’.
- Zet het tijdvenster en de regio om in expliciete waarden.
- Voordat er credits worden gebruikt, toon je de geplande API-aanroepen en wacht je op mijn goedkeuring.
- Publiceer, verstuur, plan niets en schrijf niets in een CRM.
- Schrijf het resultaat naar ./competitor-teardown.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.

Voorbeeldteardown (fragment)

Concurrentieteardown — [concurrent], gecontroleerd op 2026-10-30

Hoe zij zich positioneren

Homepage-kop: “Het platform voor groeiende supportteams.” Categoriepagina: “Alles wat je supportteam nodig heeft.” Beide leveranciersclaims, letterlijk geciteerd.

Bewijstabel

ClaimBronDatumStatus
Positioneert zich als platform, niet als puntoplossinghttps://example.com/competitor/home2026-10-30Verified
Levert wekelijks wijzigingenhttps://example.com/competitor/changelog2026-10-28Verified
Genoemd in onafhankelijke roundupshttps://example.com/roundup2026-10-27Third-party
Kopers noemen trage onboardinghieronder geciteerde X-post2026-10-14Signal
Enterprise is hun grootste segmentNiet beschikbaar—Not verified

Prijzen

De prijspagina noemt een gelaagd plan en een verbruiksplan. Tarieven worden hier niet herhaald; controleer de live pagina en datum: https://example.com/competitor/pricing (2026-10-30).

Waar kopers tegensputteren

@example_dev, 2026-10-14: “de installatie duurde langer dan de demo suggereerde.” Eén gedateerde post; een klacht, geen frequentieschatting.

Aanbeveling

Zet tijd-tot-eerste-resultaat vooraan op de vergelijkingspagina. Dit is onze gevolgtrekking, geen claim van de concurrent.

Bronnen

  • https://example.com/competitor/home
  • https://example.com/competitor/pricing
  • https://example.com/competitor/changelog

De exacte aanroepen

Voor ontwikkelaars: dezelfde workflow als kopieerbare code in uitvoeringsvolgorde.

Exacte API-aanroepen tonen
  1. Begin met een onderbouwde basis

    Chat geeft een antwoord en de gebruikte pagina’s terug, een kaart van waar de concurrent wordt besproken. Behandel het antwoord als aanwijzing, niet als bron: bewaar de links, zij leveren de derde-partijrijen in de bewijstabel. De helper stuurt de sleutel één keer en gooit een fout bij niet-2xx.

    competitor.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 competitor = "Example Competitor";
    const segment = "mid-market support teams";
    
    const baseline = await felo<ChatData>("/v2/chat", {
      query: `How does ${competitor} position itself for ${segment}? Include pricing and recent launches.`,
    });
    
    const seedSources = baseline.data.resources.slice(0, 5);

    Voorbeelduitvoer

    {
      "answer": "The competitor positions itself as …",
      "sources": [
        { "link": "https://example.com/competitor", "title": "…", "snippet": "…" }
      ]
    }
  2. Haal de pagina’s op die zij beheren

    Derde-partijberichtgeving laat zien wat mensen denken; hun eigen pagina’s laten zien wat zij claimen. Extraheer homepage, prijzen en changelog als Markdown met leesbaarheid en zet de ophaaldatum erop: een prijspagina zonder datum is een valkuil.

    competitor.ts
    type ExtractData = { data: { content: string } };
    
    const ownedPages = [
      { url: "https://example.com/competitor/home", title: "Homepage" },
      { url: "https://example.com/competitor/pricing", title: "Pricing" },
      { url: "https://example.com/competitor/changelog", title: "Changelog" },
    ];
    
    const fetched = await Promise.all(
      ownedPages.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/competitor/pricing",
      "checkedAt": "2026-10-30",
      "content": "# Pricing\n\nExtracted page text…"
    }
  3. Kijk wat kopers op X zeggen

    Zoek op X naar bezwaren en workarounds over de concurrent. Bewaar account en datum van elke post; één gedateerd citaat bewijst een klacht, niet hoe vaak die voorkomt. De analyse markeert het als signaal en maakt van enkele posts nooit een percentage.

    competitor.ts
    type XData = {
      data: {
        tweets: {
          content: string;
          author: { username: string };
          created_at: string;
          metrics: { retweet_count: number; favorite_count: number };
        }[];
      };
    };
    
    const since = Math.floor((Date.now() - 90 * 24 * 60 * 60 * 1000) / 1000);
    
    const buyerSignal = await felo<XData>("/v2/x/tweet/search", {
      query: `"${competitor}" (pricing OR onboarding OR migration)`,
      limit: 25,
      since_time: since,
    });
    
    const objections = buyerSignal.data.tweets.slice(0, 5);

    Voorbeelduitvoer

    { "data": { "tweets": [
      {
        "content": "setup took longer than the demo suggested",
        "author": { "username": "example_dev" },
        "created_at": "2026-10-14T09:20:00Z",
        "metrics": { "retweet_count": 3, "favorite_count": 24 }
      }
    ] } }
  4. Zet de analyse in elkaar met een bewijstabel

    Dit is de redactionele stap: maak van pagina’s en X-posts beweringen en geef elke bewering bron, datum en status. De statuskolom houdt het document eerlijk: Verified voor wat de pagina zegt, Vendor claim voor marketing, Third-party voor externe berichtgeving, Signal voor een gedateerde post, Inference voor jouw lezing en Not verified zonder bewijs.

    competitor.ts
    const today = new Date().toISOString().slice(0, 10);
    
    const row = (claim: string, source: string, date: string, status: string) =>
      `| ${claim} | ${source} | ${date} | ${status} |`;
    
    const teardown = [
      `# Competitor teardown — ${competitor}`,
      `Scope: ${segment}. Checked ${today}.`,
      "",
      "| Claim | Source | Date | Status |",
      "| --- | --- | --- | --- |",
      row("Free tier listed on the pricing page", ownedPages[1].url, fetched[1].checkedAt, "Verified"),
      row("Positions as a platform, not a point tool", ownedPages[0].url, fetched[0].checkedAt, "Vendor claim"),
      row("Discussed in independent coverage", seedSources[0]?.link ?? "Not available", today, "Third-party"),
      row("Buyers report onboarding friction", "X post, quoted below", today, "Signal"),
      row("Most revenue comes from enterprise", "Not available", "—", "Not verified"),
      "",
      "## Recommendation",
      "Lead with time-to-first-result on the comparison page. Inference, not a competitor claim.",
    ].join("\n");
    
    console.log(teardown);

    Voorbeelduitvoer

    | Free tier listed on the pricing page | https://example.com/competitor/pricing | 2026-10-30 | Verified |
  5. Bewaar in de LiveDoc voor de volgende ronde

    Maak één LiveDoc per concurrent, voeg de opgehaalde pagina’s toe als URL-resources en de analyse als document. Opnieuw toevoegen van URL’s wordt gededupliceerd, zodat je volgend kwartaal alleen wijzigingen ophaalt en de vorige analyse in hetzelfde archief blijft.

    competitor.ts
    type LiveDocData = { data: { short_id: string } };
    
    const teardownDoc = await felo<LiveDocData>("/v2/livedocs", {
      name: `Teardown: ${competitor}`,
      description: `Sources and teardown checked ${today}`,
    });
    
    await felo(`/v2/livedocs/${teardownDoc.data.short_id}/resources/urls`, {
      urls: fetched.map((page) => ({ url: page.url, title: page.title })),
    });
    
    await felo(`/v2/livedocs/${teardownDoc.data.short_id}/resources/doc`, {
      title: `Teardown ${today}`,
      content: teardown,
    });
    
    console.log(teardownDoc.data.short_id); // the next refresh reuses this LiveDoc

    Voorbeelduitvoer

    { "short_id": "PvyKouzJirXjFdst4uKRK3" }

Wat inbegrepen is

  • Onderbouwde basis van de Chat API en de pagina’s erachter
  • Homepage, prijzen en changelog van de concurrent als Markdown
  • Gedateerde koperreacties uit X, gemarkeerd als signaal en niet als bewijs
  • Bewijstabel die geverifieerde feiten, leveranciersclaims en inferentie scheidt
  • LiveDoc met de bronnen zodat de volgende ronde niet bij nul begint

Wat het niet doet

  • Alleen openbare bronnen; geen win/loss-gesprekken, CRM-notities of privédashboards
  • Prijzen worden gelinkt en gedateerd, nooit zonder controledatum in een tabel vastgezet
  • X-dekking is onvolledig en geen representatieve koperssteekproef
  • Het kiest je positionering niet; aanbevelingen zijn als inferentie gemarkeerd
  • Het publiceert de analyse niet en schrijft niet in battlecardtools

Vragen

Waar komt het bewijs vandaan?

De Chat API geeft een onderbouwde basis en de gebruikte pagina’s, Web Fetch maakt de pagina’s van de concurrent Markdown en X Search voegt gedateerde koperposts toe. Elke rij behoudt bron en datum, inferentie heeft een eigen status.

Kan ik meerdere concurrenten doen?

Ja. Draai dezelfde prompt per concurrent en houd één LiveDoc per bedrijf. Een vergelijkingspagina voegt alleen rijen met status ‘geverifieerd’ samen, zonder bewijs uit twee runs te mengen.

Mag ik hun prijzen citeren?

De workflow legt vast wat de prijspagina zegt, met link en controledatum. Tarieven worden niet in tekst vastgezet, omdat leveranciersprijzen veranderen en een verouderd getal slechter is dan geen getal.

En onze win/loss-notities?

Hij leest alleen openbare bronnen. Voeg interne notities als apart document in de LiveDoc toe en markeer ze intern; ze worden nooit in klantmateriaal geciteerd.

Hoe vaak vernieuwen?

Op trigger, niet op kalender: prijswijziging, launch of start van een verkoopcyclus. Draai opnieuw in dezelfde LiveDoc zodat het vorige kwartaal naast het nieuwe staat.

Wat kost een analyse?

Elke chat-, extractie- en X Search-aanroep verbruikt gebruikscredits; 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.

Vernieuw op trigger, niet op kalender

Draai dezelfde workflow bij een prijswijziging, grote launch of voor een verkoopcyclus. Houd elke analyse als gedateerd document in dezelfde LiveDoc, zodat het vorige kwartaal naast het nieuwe staat.

Maak er battlecards van

Schrijf uit dezelfde bewijstabel één pagina per rol — economische koper, champion, technische reviewer — met alleen `Verified`-rijen en de links erbij. Laat `Inference` buiten klantmateriaal.

Vergelijk twee concurrenten

Draai de workflow per concurrent met aparte LiveDocs en bouw een vergelijkingspagina met alleen rijen die in beide runs `Verified` zijn. Voeg twee runs nooit samen zonder statuskolom.

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