Matthew, Miro, and Claude
I’ve run a lot of workshops. The boards I build for them follow a predictable workflow: a client brief becomes a planning document, the planning document becomes a Miro spec, and the Miro spec eventually becomes a board. The first two steps are relatively fast. The last one used to take much of a day and was boring.
For a recent client engagement, I needed a board with eight frames: a lobby, participant intro cards, a current-state swimlane, a pain point harvest, a scoring grid, a closing section, and a parking lot. Done manually, that's two to three hours of clicking, aligning, and reformatting.
I built it with code instead, using Claude and the Miro REST API v2. The scripts ran in under ten minutes. The full session took just under thirty minutes, with most of that being Claude and myself talking through each frame, checking the output, and deciding what came next. So, how did this all work? Because I wasn't sure it would.
The spec-first approach
Before I touch a Miro board, I always write a spec. It describes each frame in detail: what it contains, what participants will do with it, and what the visual structure should look like. I iterate on that document until I'm happy with it, just as a developer often iterates on a design doc before writing code.
While this sounds like extra work., in practice, it saves me hours. At the document stage, the board-building questions answer themselves: where does each section go, how many zones, what's the right participant prompt for each exercise? Changing your mind costs nothing at this stage and allows you to work quickly. By the time the spec is done, the board is designed and what remains is construction. Construction is what used to take me much of a day.
Plugging in the API
The Miro REST API v2 is well-documented and reasonably straightforward. If you have a Business account, you have access to it. Frames, shapes, text items, and sticky notes can be created by posting JSON to an endpoint.
I used Python with the requests library. One config file held the access token and board ID. Each frame got its own script, so I could build, test, and iterate section by section without touching the rest of the board.
The tricky part ended up being the coordinates: items parented to a frame use frame-local coordinates, not board-absolute ones, and getting that wrong produces boards that look nothing like the spec. It was weird.
Anyway, I gave Claude the spec and asked it to write Python scripts to build each frame. My expectations, initially, were really low. I was just experimenting. We worked through it one frame at a time. Claude flagged things I hadn't thought through: whether certain position values would push items outside their parent boundaries, or that the minimum shape height the API accepts is 8px, not 2px. Some of those caught errors before they happened. Others we found by running the scripts and reading what came back from the API.
I ran the session in split screen: Claude Code in VS Code on the left, the Miro desktop app on the right. About 5 minutes into the session I decided to screen capture it, because something sort of crazy was happening. Each time a script finished, I could watch the frame appear in Miro in real time. Watching a fully structured workshop board construct itself, frame by frame, sticky notes and all, was one of those moments where you just stop and stare at the screen. I've included a 30 minutes session in video crunched to 4 minutes if you're interested in seeing it in action.
What the API doesn't tell you
A few things aren't in the documentation the way you'd expect.
The coordinate behaviour is the one most likely to waste your time. When you parent an item to a frame, (0, 0) becomes the top-left corner of the frame, not the board origin. The API returns a relativeTo field in GET responses that documents this, but including it in a POST request gets rejected. You just have to know it going in.
A few others: bold text has no fontWeight property — you wrap content in <strong> tags inside a <p> element, because the API accepts HTML content strings throughout. Sticky note colors are named strings from a fixed palette, not hex codes; the valid values are things like light_yellow, light_pink, light_blue. Shapes have a minimum height of 8px, so a 2px divider line gets rejected. And fillOpacity expects a float string: "1.0", not "1".
These are all just petty irritants. They're the kind of thing that costs you twenty minutes the first time, but because I learned from the experience, won't happen the next time around.
I really was surprised
Partway through the build, something shifted. Claude started asking questions before I prompted it, flagging that a frame hadn't been tested yet, suggesting we verify the coordinate logic before moving to the next script, pointing out that a constant in one script would need to match a value in the next one, or the layout would break.
I'd started the session as the person giving instructions. By the end, it and I was working the problem together, and with Claude as a valuable sounding board preventing errors.
In the end, the board was built to my spec, using my workshop methodology, for my client's specific situation. Claude took the construction burden off my plate and flagged things I might have missed, the way a good colleague would.
My work, but with force multiplication
There's a version of the AI conversation that frames it as: give AI a brief, and it does the work. That's not what happened here. I spent the time that matters on understanding the client, designing the workshop, and writing the spec. Claude handled the execution building the Miro board.
The hours I got back weren't hours I'd been spending on the interesting part of the work. They were hours I'd been spending on manual construction that anybody (or anything) could do once the design was finished.
The workshop still reflects the thinking I put into it. That's not something you can automate, and I wasn't trying to. But boy, did it save me a lot of time.
NOTE: Yes, there is an emdash in this article. No, AI did not put it there.



Comments