<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Keep Video</title>
    <description>The latest articles on DEV Community by Keep Video (@keepvideo).</description>
    <link>https://dev.to/keepvideo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4231983%2Fe244256c-b4c1-48f2-b07c-cf0e5c943e96.png</url>
      <title>DEV Community: Keep Video</title>
      <link>https://dev.to/keepvideo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/keepvideo"/>
    <language>en</language>
    <item>
      <title>One key, several coding agents: making API bills readable</title>
      <dc:creator>Keep Video</dc:creator>
      <pubDate>Sun, 08 Nov 2026 05:59:30 +0000</pubDate>
      <link>https://dev.to/keepvideo/one-key-several-coding-agents-making-api-bills-readable-1d14</link>
      <guid>https://dev.to/keepvideo/one-key-several-coding-agents-making-api-bills-readable-1d14</guid>
      <description>&lt;p&gt;Running Claude Code, Codex and Cursor in the same team is normal. The friction rarely shows up while writing code. It shows up at the end of the month: three bills, three billing units, three vocabularies, and nobody able to say where the money went. The only decision left is "use it less".&lt;/p&gt;

&lt;p&gt;What follows is a repeatable accounting method. It does not depend on one platform; Nbility is used as the example because the relevant pages sit together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step one: make spend attributable
&lt;/h2&gt;

&lt;p&gt;A bill becomes unreadable when every request leaves through one key. The log then says "this much was used on Tuesday" and nothing about which tool or project spent it.&lt;/p&gt;

&lt;p&gt;The fix is unglamorous: one token per tool. One for Claude Code, one for Codex, another for batch scripts. Name them by purpose, such as &lt;code&gt;claude-code-laptop&lt;/code&gt; or &lt;code&gt;codex-backend-refactor&lt;/code&gt;. Filtering request logs by token then separates spend by tool automatically.&lt;/p&gt;

&lt;p&gt;If several people share a budget, split by person as well and use a workspace: members keep their own accounts, enterprise-key usage is charged to the owner’s wallet, and audits can move from the aggregate down to an individual.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step two: understand what a "group" really is
&lt;/h2&gt;

&lt;p&gt;Multi-model gateways usually offer several groups. The same model costs different amounts in different groups, and the difference typically comes from the upstream route, its stability and its concurrency headroom. Switching to the cheapest group without testing tends to surface a different problem: rate limits, timeouts, or behaviour that does not match expectations.&lt;/p&gt;

&lt;p&gt;Treat a group as a trade-off rather than a discount:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get the workflow working on the default group first, confirming client, parameters and response format.&lt;/li&gt;
&lt;li&gt;Move non-critical work (tests, comments, documentation) to a cheaper group afterwards.&lt;/li&gt;
&lt;li&gt;Keep the critical path on a stable group, especially where long context and continuous tool calls matter.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pricing pages usually place the official price next to the group multiplier. That is more useful than memorising unit prices: you can see how much a route costs relative to the official rate without converting between billing units.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step three: count the retries
&lt;/h2&gt;

&lt;p&gt;One cost is routinely missed: retries. A timeout that triggers three retries appears as four calls in the ledger, while only one produced the result you wanted.&lt;/p&gt;

&lt;p&gt;Request logs answer three concrete questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which tool fails most often? If errors cluster around 401 or 403, the problem is authentication or group permissions, not the model.&lt;/li&gt;
&lt;li&gt;Are failed requests billed? That depends on which layer failed; check the specific error and the billing rules.&lt;/li&gt;
&lt;li&gt;Did average latency or time-to-first-token degrade in a particular window? That usually points at upstream congestion, where changing groups helps more than rewriting prompts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The status page helps here: if the group’s recent success rate has dropped, suspect the route before suspecting your own configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step four: decide with one week of records
&lt;/h2&gt;

&lt;p&gt;Do not decide "is it worth it" by feel. Take an ordinary work week and note three things every time you hit a limit or a slowdown:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What you were doing, and whether it had to finish right then.&lt;/li&gt;
&lt;li&gt;How long the interruption lasted, and whether you switched to other useful work meanwhile.&lt;/li&gt;
&lt;li&gt;What you would have paid to avoid that interruption.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A week later, two patterns usually appear. Some interruptions were "wait a few minutes" cases whose real cost was far below the felt cost. Others cluster around one specific task, which is where an upgrade or a different route is actually justified.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finally: write the conclusions down
&lt;/h2&gt;

&lt;p&gt;The point of accounting is not to save money; it is to give the decision something behind it. Put these in the team handbook: which tool uses which token, which tasks may run on a low-cost group, and who to ask when a particular error appears. The next time someone asks why this month cost more, the answer should be in the logs rather than in a guess.&lt;/p&gt;

&lt;p&gt;Reference pages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Model directory and group pricing: &lt;a href="https://nbility.ai/models" rel="noopener noreferrer"&gt;https://nbility.ai/models&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Pricing and billing explanation: &lt;a href="https://nbility.ai/pricing" rel="noopener noreferrer"&gt;https://nbility.ai/pricing&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Account and billing docs: &lt;a href="https://nbility.ai/docs/billing" rel="noopener noreferrer"&gt;https://nbility.ai/docs/billing&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Model status: &lt;a href="https://nbility.ai/status" rel="noopener noreferrer"&gt;https://nbility.ai/status&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Note: Nbility is a third-party AI API gateway with no affiliation with OpenAI, Anthropic or Google. Model availability, group multipliers and prices follow the upstream providers and may change; check the site for current figures. Nothing here is a cost guarantee.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>apigateway</category>
      <category>productivity</category>
      <category>llm</category>
    </item>
    <item>
      <title>Saving video, audio and subtitles offline: where a downloader stops</title>
      <dc:creator>Keep Video</dc:creator>
      <pubDate>Sat, 07 Nov 2026 11:27:57 +0000</pubDate>
      <link>https://dev.to/keepvideo/saving-video-audio-and-subtitles-offline-where-a-downloader-stops-1cm2</link>
      <guid>https://dev.to/keepvideo/saving-video-audio-and-subtitles-offline-where-a-downloader-stops-1cm2</guid>
      <description>&lt;p&gt;Every "video downloader" question eventually turns into the same argument: why can't it just give me the best quality, why is there no audio-only option on this page, why did the subtitle file come out empty. The answers are less about the tool and more about what the source page is willing to hand over.&lt;/p&gt;

&lt;p&gt;These notes come from building and running &lt;a href="https://keep.video/" rel="noopener noreferrer"&gt;Keep Video&lt;/a&gt;, a browser-based tool with an open-source desktop app, so they are written from the boring side of the problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  The source decides the ceiling
&lt;/h2&gt;

&lt;p&gt;A downloader resolves a media URL and lists what the source exposes. It does not re-encode a better version, and it cannot invent a 4K stream that the page never served. If a platform only ships a 720p progressive file to anonymous visitors, that is the ceiling. The same goes for containers: a tool can remux, but remuxing does not create data that is not in the stream.&lt;/p&gt;

&lt;p&gt;The practical consequence for anyone building this: your UI should show the formats that actually came back from the extractor, not a fixed dropdown of "1080p / 720p / 480p". A fixed list lies to the user the moment the source changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Audio-only is a stream choice, not a conversion magic trick
&lt;/h2&gt;

&lt;p&gt;Extracting audio is usually cheap because most sources already ship separate audio streams. What a tool should not promise is vocal removal or "improving" quality: if the source audio is a 64 kbps AAC track, an MP3 conversion will preserve the loss, not repair it.&lt;/p&gt;

&lt;p&gt;For the desktop app we keep an &lt;a href="https://keep.video/guides/audio/" rel="noopener noreferrer"&gt;audio guide&lt;/a&gt; that walks through MP3 conversion and the FFmpeg settings involved, because that is where the quality questions really live.&lt;/p&gt;

&lt;h2&gt;
  
  
  Subtitles are a track you either have or you don't
&lt;/h2&gt;

&lt;p&gt;Subtitle handling is the most misunderstood part. SRT output means the source already had a subtitle track: text plus timecodes, no video processing. If a video has no captions, nothing is transcribed; that is a different product with a different cost model. The &lt;a href="https://keep.video/guides/subtitles/" rel="noopener noreferrer"&gt;subtitle guide&lt;/a&gt; covers how track selection works and why storing the SRT next to its video file helps players pick it up.&lt;/p&gt;

&lt;p&gt;Two rules that save support tickets:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Show the list of available languages from the source, not a hardcoded list.&lt;/li&gt;
&lt;li&gt;Say "existing subtitles" in the product copy, and mean it.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Server-side processing or local processing
&lt;/h2&gt;

&lt;p&gt;The browser tool at &lt;a href="https://keep.video/app/" rel="noopener noreferrer"&gt;keep.video/app&lt;/a&gt; runs on a server: paste a public URL, get a finished file, no install and no account. That trade is convenience for two costs, the server does the work and the file sits in temporary storage until you download it.&lt;/p&gt;

&lt;p&gt;The desktop builds for &lt;a href="https://keep.video/download/" rel="noopener noreferrer"&gt;macOS, Windows and Linux&lt;/a&gt; flip that trade. Processing happens locally, there are queues and local file management, and you can use your own signed-in session for sources that need one. They also ask you to bring your own runtime dependencies (yt-dlp and FFmpeg are not bundled), which keeps the installer small and the licensing clean, at the price of one setup step.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we refuse to write in the copy
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;"Unlimited free" or "100% success" claims, because site support changes weekly.&lt;/li&gt;
&lt;li&gt;"No data leaves your device" for the online tool, because that is simply false.&lt;/li&gt;
&lt;li&gt;"Automatic transcription" for a subtitle saver.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are building something in this space, the honest limits are also the best documentation: quality is capped by the source, audio is a stream choice, subtitles only exist if the source has them, and local processing is a setup decision rather than a feature bullet.&lt;/p&gt;

&lt;p&gt;The code is MIT licensed at &lt;a href="https://github.com/oiov/keep.video" rel="noopener noreferrer"&gt;github.com/oiov/keep.video&lt;/a&gt;, and the tool is at &lt;a href="https://keep.video/" rel="noopener noreferrer"&gt;keep.video&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Only download content you own or have permission to save.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>tooling</category>
    </item>
  </channel>
</rss>
