Felo API PlatformFelo API Platform

Content

Maak van een YouTube-video een publiceerbaar artikel

Haal het transcript met timestamps op, vorm het tot leesbare blokken, maak outline en concept met een model dat je beheert en laat het resultaat in een LiveDoc voor review.

Tijd25 minutenNiveauGevorderdBijgewerkt2026-10-29
Voor wieContentteamsNieuwsbriefschrijversVideo- en podcastredacteuren

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.

Zet deze video om in een publiceerbaar artikel: [YouTube-URL of video-ID].

Publiek: [lezers]. Toon: [publicatiestijl]. Doellengte: [800–1200 woorden] in het [taal].
Bronbehandeling: behoud de videotitel, het kanaal en de URL. Citeer hooguit korte passages, met tijdstempels.

Lever:
1. Een werktitel.
2. Een standfirst.
3. Secties met korte alinea’s.
4. Twee of drie citaten met tijdstempel.
5. Wat de video niet behandelde.
6. Een bronnenlijst met de video en alle gelinkte pagina’s.

Regels:
- Reproduceer niet het volledige transcript. Vat samen en citeer kort.
- Elke feitelijke bewering uit de video heeft een tijdstempel nodig; beweringen uit gelinkte pagina’s een URL.
- Markeer alles wat je niet kon verifiëren als ‘Niet geverifieerd’.
- Vraag het voordat je credits uitgeeft aan transcripten of pagina-extractie.
- Publiceer, plan of verstuur niets.
- Schrijf het resultaat naar ./video-article.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.

Voorbeeldartikel (fragment)

Wat een agenttalk van 40 minuten echt zei

Standfirst

De demo was indrukwekkend; het nuttige deel was de foutafhandeling.

De claim die iedereen citeerde

> “De agent werd niet slimmer. We stopten alleen met hem zonder budget te laten retryen.” — [12:40]

Wat de video niet behandelde

Kosten per succesvolle taak, en wat er gebeurt als de opgehaalde bron fout is.

Bronnen

  • Video: https://www.youtube.com/watch?v=...
  • Gelinkte benchmark: https://example.com/benchmark

De exacte aanroepen

Voor ontwikkelaars: dezelfde workflow als kopieerbare code in uitvoeringsvolgorde.

Exacte API-aanroepen tonen
  1. Haal het transcript met timestamps op

    Gebruik YouTube Subtitling voor ondertitels in de doeltaal en bewaar starttijd en duur per regel.

    article.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 Transcript = {
      data: {
        title: string;
        contents: { text: string; start: number; duration: number }[];
      };
    };
    
    export async function fetchTranscript(videoId: string, language = "en") {
      const query = new URLSearchParams({
        video_code: videoId,
        language,
        with_time: "true",
      });
      const { data } = await felo<Transcript>(`/v2/youtube/subtitling?${query}`);
      if (data.contents.length === 0) throw new Error("This video has no subtitles");
      return data;
    }

    Voorbeelduitvoer

    {
      "title": "How we rebuilt onboarding",
      "contents": [
        { "text": "Welcome back to the channel.", "start": 0.32, "duration": 4.1 }
      ]
    }
  2. Vorm leesbare blokken

    Deel het transcript per thema, verwijder stopwoorden en behoud de timestamps.

    article.ts
    const toClock = (seconds: number) => {
      const minutes = Math.floor(seconds / 60);
      const rest = Math.floor(seconds % 60);
      return `${String(minutes).padStart(2, "0")}:${String(rest).padStart(2, "0")}`;
    };
    
    export function toBlocks(
      contents: Transcript["data"]["contents"],
      window = 60,
    ) {
      const grouped = new Map<number, string[]>();
      for (const line of contents) {
        const bucket = Math.floor(line.start / window) * window;
        grouped.set(bucket, [...(grouped.get(bucket) ?? []), line.text.trim()]);
      }
      return [...grouped]
        .map(([start, lines]) => `[${toClock(start)}] ${lines.join(" ")}`)
        .join("\n\n");
    }

    Voorbeelduitvoer

    [00:00] Welcome back to the channel. Today we are talking about onboarding.
    
    [01:00] The first thing we changed was the welcome screen.
  3. Haal de genoemde bronnen op

    Lees met Web Fetch de pagina’s die in de video worden genoemd en voeg links en feiten toe.

    article.ts
    type ExtractData = { data: { content: string } };
    
    export async function fetchSources(urls: string[]) {
      return Promise.all(
        urls.slice(0, 5).map(async (url) => {
          const page = await felo<ExtractData>("/v2/web/extract", {
            url,
            output_format: "markdown",
            with_readability: true,
          });
          return { url, content: page.data.content };
        }),
      );
    }

    Voorbeelduitvoer

    [
      {
        "url": "https://example.com/reference",
        "content": "# Reference\n\nExtracted page text…"
      }
    ]
  4. Maak eerst de outline, dan het concept

    Vraag eerst een outline aan het Model API en schrijf daarna het artikel volgens de outline, met korte citaten en timestamps.

    article.ts
    const MODEL_API = "https://openapi.felo.ai/api/v1";
    
    type Completion = {
      choices: { message: { content: string } }[];
      usage: { prompt_tokens: number; completion_tokens: number; total_tokens: number };
    };
    
    async function complete(model: string, prompt: string): Promise<Completion> {
      const res = await fetch(`${MODEL_API}/chat/completions`, {
        method: "POST",
        headers,
        body: JSON.stringify({ model, messages: [{ role: "user", content: prompt }] }),
      });
      if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
      return res.json() as Promise<Completion>;
    }
    
    export async function draftArticle(title: string, transcript: string) {
      const outline = await complete(
        "claude-haiku-5-5",
        "Outline a short article from this transcript. Return only headings.\n\n" + transcript,
      );
      const article = await complete(
        "claude-sonnet-5-5",
        `Write the article "${title}" from the transcript. Follow the outline and keep [mm:ss] on direct quotes.\n\nOutline:\n${outline.choices[0].message.content}\n\nTranscript:\n${transcript}`,
      );
      return {
        outline: outline.choices[0].message.content,
        article: article.choices[0].message.content,
        usage: article.usage,
      };
    }

    Voorbeelduitvoer

    {
      "outline": "1. The problem\n2. What changed\n3. What we learned",
      "article": "## The problem\n\nWhen we…",
      "usage": { "prompt_tokens": 4120, "completion_tokens": 640, "total_tokens": 4760 }
    }
  5. Laat het in de LiveDoc voor review

    Bewaar concept en citaten in de LiveDoc en geef het aan de redacteur voor correctie en goedkeuring.

    article.ts
    type LiveDocData = { data: { short_id: string } };
    type ResourceData = { data: { id: string } };
    
    export async function saveDraft(
      title: string,
      result: { outline: string; article: string },
    ) {
      const doc = await felo<LiveDocData>("/v2/livedocs", {
        name: `Article draft: ${title}`,
        description: "Draft generated from a video transcript",
      });
    
      await felo<ResourceData>(`/v2/livedocs/${doc.data.short_id}/resources/doc`, {
        title: "Draft",
        content: result.article,
      });
    
      await felo<ResourceData>(`/v2/livedocs/${doc.data.short_id}/resources/doc`, {
        title: "Outline",
        content: result.outline,
      });
    
      return doc.data.short_id;
    }

    Voorbeelduitvoer

    { "short_id": "PvyKouzJirXjFdst4uKRK3" }

Wat inbegrepen is

  • YouTube-transcript met timestamps
  • Pagina’s waarnaar de video verwijst als Markdown
  • Outline en concept van je Model API
  • LiveDoc met het concept voor redactiereview

Wat het niet doet

  • Geen volledig transcript; alleen korte citaten en herschrijving
  • De video moet ondertitels hebben
  • Controleer rechten en citaatlimiet voor publicatie
  • Het model maakt outline en concept; de eindbeslissing is aan de redacteur
  • Publiceert niet en vertaalt niet automatisch

Vragen

Moet de video ondertitels hebben?

Ja. De workflow begint bij ondertitels; ontbreken ze, dan stopt hij in plaats van te raden wat er is gezegd.

Kan ik een podcast naar artikel omzetten?

Deze workflow is voor YouTube. Maak voor een podcast eerst een transcript en gebruik dezelfde schrijfregels.

Kan het in een andere taal schrijven?

Ja. Geef de doeltaal op; citaten blijven in het origineel met vertaling waar nodig.

Wie schrijft het artikel?

De AI-agent waarin je de prompt plakt schrijft het concept; Felo levert transcript, pagina’s en de reviewomgeving.

Mag ik het volledige transcript herpubliceren?

Nee. De workflow maakt een nieuw artikel met korte citaten en kopieert het transcript niet volledig.

Wat kost een run?

Transcript en pagina-extractie worden op gebruik gefactureerd; actuele tarieven staan op de prijspagina en de prompt vraagt goedkeuring voor uitgaven.

Gerelateerde workflows

Maak het van jou

Hetzelfde recept, aangepast aan hoe je echt oplevert.

Alleen timestampcitaten

Schrijf geen artikel, maar lever een controleerbare citatenlijst voor hergebruik.

Eerst de nieuwsbriefversie

Maak het artikel korter en gesprokener voor de nieuwsbrief.

Verwerk een kanaal in batch

Herhaal de stappen per video en bewaar aparte LiveDocs.

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