How I Built A Substack API With Hermes And Codex
I wanted Hermes to schedule my Substack Notes. A missing scheduling feature turned into an open-source tool built across Hermes, Codex, and a set of independent checks.
By the middle of June, I had dozens of Substack Notes sitting in markdown files with dates and publishing times. I had rewritten the awkward ones, removed repeated ideas, and mixed the topics so two similar Notes wouldn’t appear one after another.
But there was that one task I kept postponing in Asana: Finish Notes Scheduled Setup.
Scheduling a single Note inside Substack takes about 30 seconds. Keeping several days’ worth of posts organized turns into admin work fast, especially when one edit changes the order and every publishing time after it.
On June 12, I asked Hermes to find an old Substack tool installed somewhere in my Projects folder. Other software used it to talk to my Substack account, and I wanted to know whether it supported scheduled Notes. I expected a quick yes or no, followed by a small fix if I got lucky.
Hermes found the forgotten package beside old test files and a database from my Notes analysis project. Publishing worked. Scheduling didn’t.
One missing feature pulled me much further than expected. A few weeks later, I had published the Unofficial Substack SDK, a reusable Substack toolkit for other apps. Five versions shipped in three days, followed by 500+ downloads during its first week.
I use two agents to run my workflows, and this project showed me why the split matters. One agent handling every stage carries its early assumptions all the way to the finish line.
Hermes handled the messy beginning, pulling context from old conversations, forgotten files, licences, and competing projects. Codex stepped in once the work fit inside one project folder and I knew what a successful result looked like.
In today’s edition, I’ll walk you through how I built the SDK and show why the handoff between Hermes and Codex mattered more than either agent working alone.
In this piece
How Hermes turned a half-remembered package into a real starting point
Why Codex became more useful once the job got smaller
How one wrong field name exposed the danger of plausible AI answers
A handoff format for splitting your next build without losing context
The Package I Forgot
I remembered using the old tool to collect Substack data, though I had forgotten its name, where it lived, and how much of it still worked. Hermes identified it as substack-api and traced it back to an open-source project.
Reading profiles, posts, comments, and Notes already worked. Publishing worked too. Scheduling notes support was missing.
Hermes searched the project, looked through public clues left in Substack’s website, and checked similar tools. Instructions for publishing a Note were already known, while scheduling remained undocumented. Nobody had confirmed the label Substack expected for the publishing time.
Hermes proposed scheduled_at. Plenty of online services use a label like this, and it looked completely at home beside the existing instructions. Hermes still warned me about the missing proof and listed other names Substack might expect.
I nearly ignored the warning because the feature looked finished. Doing so would’ve left me with a neat scheduling button sending a label Substack never promised to read.
Version 0.2.2 uses trigger_at. An automated check reads the exact instruction sent to Substack and fails if the label changes. Proof now lives outside the AI conversation.
Getting the first field wrong became the most useful part of the build because it forced me to separate finding an answer from earning trust in it.
Hermes Found The Ground
Starting from scratch would’ve been wasteful. Jakub Slys had already spent years learning how Substack’s private machinery worked, and his project carried working instructions plus a large set of checks.
Hermes traced the installed tool back to his GitHub project, checked the MIT licence, and kept the original credit. His research remains credited in the finished project.
From there, Hermes compared the other available projects instead of treating the first one as the automatic winner. Some were ready-made services for apps and AI agents. Others only read public posts. I wanted a small building block speaking directly to Substack without sending a user’s login through somebody else’s server.
An early experiment turned the inherited project into a small online service running on Cloudflare. Hermes removed parts tied to a traditional server and locked it to read-only access. All 230 automated checks passed before the project moved into my account.
Substack blocked requests coming from Cloudflare, so the first version hit a dead end. I moved the SDK to my VPS and built a small server interface around it, giving my other apps a stable way to use it.
Hermes handled this part well because the problem stretched beyond one project folder. Old conversations, forgotten files, licensing, and the safety of each user’s digital login key all affected the decision.
A coding agent focused on one project sees the files in front of it. Hermes also saw why I had them, what I had tried before, and which surrounding work mattered.
.I covered a similar choice in my guide to choosing AI tools. Tool choice starts before the interface. First decide whether the messy part is finding the work or doing it.
Codex Needed a More Targeted Job
Once Hermes had found the right starting point and cleared up the wider questions, I moved the project into VS Code.
I use Codex through the VS Code extension, and this is where it works best for me. I point it at a specific file, ask for one change, review the result, and keep moving without reopening the whole project discussion.
I asked Codex to run the version Hermes had prepared beside my other services without rewriting anything. It downloaded the project, installed what it needed, passed the checks, and started the service.
Then I opened my Files app and couldn’t see it.
Codex had placed the project inside a private folder on the server, while my Files app only showed a different Projects folder. Every command had succeeded, yet the result still lived somewhere I didn’t use.
I corrected the path, and Codex moved the project before restarting the service. One small mistake exposed a useful limit: a coding agent understands the project in front of it, while personal conventions still need to be stated clearly.
Once everything ran from the right place, I asked Codex to launch Jakub’s newer project beside mine. His version already worked as a complete service for regular apps and AI agents. Mine did less, though its smaller size made it easier to reuse inside other products.
Running both made the decision easier. Jakub’s project was the stronger ready-made service, while my smaller toolkit made more sense as a building block for the server I wanted to control.
OpenAI had also given me banked resets, small refills for my Codex allowance whenever I reached the limit. Hermes burned through those resets much faster than Codex inside VS Code because it carried a wider working history into every session, including old conversations and surrounding files.
Codex stayed focused on the active project and the exact edit in front of it. For small changes, this made the VS Code extension faster and cheaper to run.
No model comparison or architecture discussion would’ve given me the same confidence. Hermes found and framed the right project, then Codex handled the precise edits without dragging the entire history behind it.
The Server Had To Prove It
Next came a small server for making the toolkit available to other apps through a web address. Codex downloaded it, ran its checks, started it locally, and confirmed it was healthy before I added my Substack login details.
After setup, I asked for my latest Substack notification. A live video alert came back from my account. Five recent replies followed when I asked for my latest mentions.
Documentation examples are easy to fake, so I had to know this would be working as expected. A response from my account proved the toolkit had completed the full trip to Substack and returned with real data.
Live use also exposed a design problem. Loading one Substack login at startup meant every person using the service would’ve appeared as me. A multi-user app needed a private and secure way of storing each account's data and selecting the right login for every request.
I am building an app for that and will soon have it ready. I’m thinking of calling it StackedHQ.
Let The Tests Argue
scheduled_at and trigger_at both sound reasonable as labels for a publishing time. An AI has seen enough software to defend either one with enough detail to waste your afternoon and usage quota.
Tests settle the argument by opening the instruction before it leaves the toolkit. One scheduling check expects trigger_at. Another caught missing image information and led to a tiny correction.
Version 0.2.2 passes 25 tests covering 52 expected behaviors. GitHub reruns them before every release, then publishes with one-time approval instead of storing a permanent publishing password.
I don’t care which agent sounds more certain once a request has an observable answer. Real responses, changed files, and passing checks get the final vote.
This is the part I missed inside one AI thread. Whoever researched the problem also wrote the code and explained why it looked correct. Moving the final decision into a check broke the loop.
This habit follows the same direction as The Agentic Engineering Shift. More AI responsibility requires stronger proof outside the conversation.
The Split I Use Now
I didn’t sit down before this project and design a three-part method. Each phase kept failing for a different reason, and the split appeared from those failures.
Hermes worked best while the starting point was messy. I use it when the request sounds like “find the package we used before,” “check what we decided last month,” or “compare this with the rest of my setup.” It searches across the wider project and brings back a prepared job.
Codex worked best after the task fit inside one project folder. I use it once I know where the work lives, what needs to change, and what success looks like. “Improve the Substack tool” leaves too much room. “Run both versions and tell me which one fits an app used by AI agents” gives the work an edge.
Tests take over wherever the answer belongs to the machine. A field name, an installable file, or a response from my real account shouldn’t end as a debate between two models.
I think of those roles as scout, specialist, and referee.
A scout finds the right ground. A specialist works inside a defined surface. A referee ignores confidence and checks what happened.
Choose the role before choosing the model. A stronger model won’t rescue a job whose boundaries are still mixed together.
Copy This Handoff
My handoff between Hermes and Codex now fits inside one short file:
Goal
[one result the project should produce]
Starting point
[where the work lives and what already works]
Known evidence
[useful files observations and previous attempts]
Limits
[what the AI must avoid]
Checks
[how we will prove the result works]
Stop and ask
[what needs my approval before continuing]
Hermes fills the first version from the wider context. I remove weak assumptions, cut extra scope, and make the checks specific. Codex receives the file with the project and works until a check passes or it reaches something needing my approval.
When a check fails, the next request gets smaller. I don’t reopen the whole project. I send the failed behavior back as one specific correction.
This handoff works outside software too. Research produces a sourced brief, writing turns it into a draft, and a publication checklist checks the result. My article about file-based AI workflows covers the wider system.
What Shipped
Version 0.2.2 of the Unofficial Substack SDK gives other apps a reusable way to work with Substack. It reads profiles, posts, comments, engagement numbers, and subscriber data. It also publishes Notes, schedules them, edits drafts, and adds images.
What feels crazy to me is that npm recorded 708 downloads from July 13 through July 19. Those are downloads rather than 708 individual people, and I won’t pretend otherwise. I still find the number encouraging for a new tool solving a problem I found in an old folder on my server.
If you want to give this a test you must know that Substack might change its private API without warning. Tests make breakage easier to find, though they don’t turn an unofficial tool into a promise from Substack.
Two Agents One Workflow
This project started because I wanted Hermes to schedule my Substack Notes. It ended with an open-source SDK, a server running on my VPS, and a much clearer idea of where each agent belongs.
Hermes earned its place at the messy beginning. It found the forgotten package, pulled in old conversations, compared the available projects, and followed the work when Cloudflare blocked the first version. Carrying all this context also made Hermes burn through my OpenAI-banked resets much faster.
Codex worked better once the problem became smaller. In VS Code, it stayed close to the active files and handled precise edits without loading the full project history. This made it faster and cheaper for the small changes where a focused coding agent has the advantage.
Independent checks sat between both agents and the finished package. Real account responses and passing tests overruled every confident answer before anything shipped.
One setup detail matters if you want to try the SDK. I deliberately left the Substack cookie out of the npm package because it gives access to your account. Ask your agent to read the setup instructions and tell you what needs configuring, then add the value of your substack.sid cookie yourself as a trusted server-side environment variable and pass it as sessionToken. Never paste the cookie into your codebase or anywhere likely to save and share it.
Substack blocked requests from Cloudflare during my build, which is why I added a server interface and ran it on my VPS. Your setup might behave differently, though your login cookie should always stay on a server you trust.
Look at your last AI project sprawling across one long conversation. Give the messy discovery work to the agent with the widest view, hand the focused edits to the agent closest to the files, and let independent checks decide when the result is ready.
Tell me where your handoff keeps breaking in the comments. I want to collect real examples and turn the common failure points into a follow-up piece.
I’m working on Hermes 101, and it should be ready soon. It starts from the same idea: one visible workflow, a clear place for human judgment, and more autonomy only after the loop earns trust.
For the wider tool decision, read When to Use MCPs CLIs or Your Own Tool. For the responsibility behind the work, read The Agentic Engineering Shift.
Use the agent with the widest view to find the path, use the focused agent to make the change, and trust neither until the work passes a check.







