◉CLAUDE LABJP
●2.1.310 — Monitor tool now works on Bedrock, Vertex and Foundry, and gateway failures are fixed (10/23)●2.1.307 — Fixes MCP failing to reconnect after sleep or a keychain lock (10/21). 2.1.306 also fixed the false claude -p login message●SONNET 4.5 — Retires on the Claude API on 11/30, 36 days left. Migrate to Sonnet 5.5●WINDOWS — Reports say hooks break silently only on Japanese-locale Windows; check the character encoding first●API — In API version 2026-10-21, passing temperature, top_p or top_k returns a 400 error●NEW — I Put a Ten-Line Promise File at the To…●2.1.310 — Monitor tool now works on Bedrock, Vertex and Foundry, and gateway failures are fixed (10/23)●2.1.307 — Fixes MCP failing to reconnect after sleep or a keychain lock (10/21). 2.1.306 also fixed the false claude -p login message●SONNET 4.5 — Retires on the Claude API on 11/30, 36 days left. Migrate to Sonnet 5.5●WINDOWS — Reports say hooks break silently only on Japanese-locale Windows; check the character encoding first●API — In API version 2026-10-21, passing temperature, top_p or top_k returns a 400 error●NEW — I Put a Ten-Line Promise File at the To…
Articles/API & SDK
⬡ API & SDK/2026-06-12Intermediate

Handing Monthly Revenue CSVs to the Claude API Code Execution Tool — Files API Wiring, Container Reuse, and Billing Traps

How I moved monthly revenue-CSV reconciliation into the Claude API Code Execution tool — a pre-upload sanity check, Files API integration, container reuse, the 5-minute billing minimum, and the file recovery that pause_turn quietly drops.

claude-api83code-execution3files-api3python22data-analysis

✦ Premium Article

At the end of every month, my downloads folder fills up with CSVs. There is the financial report from App Store Connect, the estimated earnings export from AdMob, and then the reports from the three networks riding in my mediation stack — Unity Ads, Liftoff, and InMobi. The currencies do not match, the reporting periods do not match, and the column names certainly do not match. Reconciling them all into one trustworthy monthly number has been a fixture of my month-end for years.

Every additional revenue source adds another report to that month-end pile. For a long time I handled the reconciliation with local pandas scripts, and for just as long I kept performing the same small repair: some network renames a column or shuffles its export layout, the script falls over on a missing key, I patch the column mapping, and the cycle repeats a month or two later. None of the individual fixes were hard. It was the recurrence that wore me down.

What made it worse was the timing. The breakage always surfaced on closing day itself, so the hunt for the cause and the re-run of the aggregation landed on the one day with no slack in it.

Earlier this year I moved this monthly closing work onto the Claude API Code Execution tool. The shape of the change matters: instead of pasting CSV contents into the prompt as tokens, the files travel into a sandboxed container as files, and pandas runs on the other side. Claude writes the code, executes it next to the data, and sends back only the conclusions. Actually wiring this up revealed a few gaps between the minimal examples in the documentation and what production use requires. Billing that starts the moment a file is attached — even if the tool never runs — and the pause_turn stop reason that surfaces mid-task are the two big ones. What follows is the working code, together with how to step over each of those gaps.

Why I Stopped Maintaining the Local Aggregation Scripts

To be clear, I did not replace everything, and I want to draw the boundary precisely because the boundary is the useful part. My daily KPI check still runs on the local pipeline I described in A Daily Revenue Pipeline for 4 Wallpaper Apps: 8 Weeks Running App Store Connect API + AdMob With Claude Code, and it runs reliably. When the input format is stable and the question is identical every morning — yesterday's revenue, by app, by network — a plain script is faster, cheaper, and easier to reason about. Nothing about the Code Execution tool changes that calculus.

What kept breaking was the monthly close, and the reason was structural rather than accidental. After I added Unity Ads, Liftoff, and InMobi to my mediation setup last year — and finished the payment profiles and W-8BEN paperwork that made their payouts real — the variety of incoming reports jumped from two formats to five. Revenue arrives in a mix of USD and JPY. One network cuts its reporting periods on calendar days, another on Pacific time. The same concept is called revenue in one file and estimated_earnings in another, and a column that existed in March quietly disappears in April. Code that absorbs this kind of naming drift case-by-case accumulates conditionals, and it becomes less readable with every patch. I knew the script had become a liability the day I hesitated to open it.

So I redrew the boundary. Stable, repetitive aggregation stays local; format-drifting, exploratory reconciliation goes to the sandbox. The reasoning is almost mechanical: the maintenance cost of a script is proportional to how often its input format changes. For inputs that never change, that cost rounds to zero and a script wins. For inputs that change every few months in unannounced ways, you are effectively rewriting the parser on a schedule — and letting Claude absorb the column-name drift at read time is simply cheaper than editing code every time a network ships a new export layout.

The second reason is context economy, and at this file size it is decisive. Paste a CSV into the message body and every row becomes billable input tokens that also crowd the context window. With the Code Execution tool plus the Files API, files load directly into the container and Claude reads them with pandas. The only things that land in your token budget are the code Claude writes and the printed output it chooses to show. For a monthly job that touches several megabytes of reports, this is not an optimization — it is the difference between the approach working and not working at all. I will put numbers on that in the billing section.

Where the Tool Stands Today — Old Tutorials Will Mislead You

The tool has been revised several times since its first public beta, and the gap between early write-ups and the current shape is now wide enough to cause real confusion. I lost a morning to this myself, so here is the sorted version.

  • code_execution_20250522 (legacy): the original Python-only release. Many tutorials still assume it, along with its code-execution-2025-05-22 beta header and its old single response-block format
  • code_execution_20250825: adds Bash commands and file operations on top of Python. The response format changed here — results arrive as separate bash and text-editor block families, and every later version inherits that shape
  • code_execution_20260120: adds REPL state persistence and programmatic tool calling from inside the sandbox
  • code_execution_20260521: the same runtime as 20260120. What differs is the tool description, which tells Claude about the 90-second wall-clock limit on each Python cell, so it budgets long-running work itself

One correction to something I had wrong for months. I assumed the versions were gated by model generation. They are not — every currently supported model accepts all three of the current tool types. Haiku 4.5 will happily take code_execution_20260120; it simply loses programmatic tool calling and REPL persistence and behaves like 20250825. So when you raise the tool version and nothing changes, the thing to suspect is this quiet degradation, not a rejected request.

One more dependency worth noting: pairing code execution with web search or web fetch requires code_execution_20260120 or later. The billing note further down — that pairing them removes the execution charge — does not apply if you are still pinned to an older tool type.

The runtime, as of this writing, is a Linux container running Python 3.11 with 5GiB of memory, 5GiB of disk, and one CPU. The libraries that matter for reconciliation work are preinstalled — pandas, numpy, scipy, statsmodels for the analysis itself; matplotlib and seaborn for charts; openpyxl, xlsxwriter, and pyarrow for the file formats finance teams love. One constraint shapes everything else: the container has no internet access whatsoever. No pip install, no calling out to an exchange-rate API, no fetching a reference table from a URL. Whatever facts the analysis needs from the outside world must arrive in the prompt or in the uploaded files. The full specification lives in the official documentation.

One more practical note before the code: the current minimal examples run code execution without any beta header. The only beta flag you need is files-api-2025-04-14, and only when you bring the Files API into the picture. Update the anthropic package before you start — older SDK versions do not know the newer response types, and the resulting attribute errors look far more mysterious than they are.

✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦Stop re-patching brittle local aggregation scripts — hand raw CSVs to a sandbox that handles the cleanup, joins, and charting
✦Walk away with working Python for a pre-upload sanity check, Files API uploads, response-block parsing, and container reuse that you can run as-is
✦Avoid the traps that bite first — billing that starts the moment files are attached, and a pause_turn loop that silently loses generated files, both reproduced and fixed
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

Related Articles

⬡ API & SDK2026-04-24
Running the Claude API in Python Production — Rate Limits, Retries, and Timeouts
If you put Claude API into a real backend service, how you handle 429, 503, and read timeouts decides your reliability ceiling. This is the design I settled on after operating it in production.
⬡ API & SDK2026-09-22
Character counts won't predict PDF input tokens — bracket the cost per page before you send
How to estimate the input tokens of a PDF before sending it to the Claude API, by bracketing from page count rather than character count. Includes a measured 6.6x gap on a nine-page A4 document, the two separate increases that come with current models, and the count_tokens limitation that bites when you use file_id.
⬡ API & SDK2026-09-07
A 75% cheaper cache read moved one bill by 29% and another by 2.8%
Fable 5.1 and Mythos 5.1 changed the cache read multiplier from 0.1 to 0.025. Here is how to estimate your own saving from your token mix, and how to fix code that hard-codes the multiplier.