[{"data":1,"prerenderedAt":1031},["ShallowReactive",2],{"footer-vacatures-en":3,"cases-en":4,"case-overview-en":935},[],[5,187,337,485,626,781],{"id":6,"title":7,"approach":8,"body":23,"build":30,"card":43,"connections":47,"cta":48,"dataExamples":47,"description":27,"extension":54,"facts":55,"featured":70,"guardrails":71,"hero":84,"integrations":47,"key":89,"meta":90,"navigation":70,"offers":91,"order":101,"path":102,"proof":103,"relations":116,"result":137,"seo":149,"situation":152,"stem":165,"summary":166,"usecases":167,"visuals":179,"__hash__":186},"cases_en\u002Fcases\u002Frobo-helma.md","Robo Helma: AI support that knows what it is talking about",{"title":9,"steps":10},"How did we approach it?",[11,14,17,20],{"title":12,"text":13},"Split knowledge by function","We treat behaviour and support rules as OpenAI Skills, product documentation as searchable knowledge in a vector store and current customer or system information as external context. This gives every kind of information a clear place.\n",{"title":15,"text":16},"Retrieve context before answering","For each support question, Helma first gathers the relevant context. Product knowledge comes via File Search, customer information can be retrieved through an external MCP connection and current incident information comes from a separate controlled source.\n",{"title":18,"text":19},"Connect engineering and support","A support ticket can be linked to an existing GitHub issue. Helma follows the technical status read-only. When engineering closes or reopens an issue, the new status can be included in a customer-safe draft answer without exposing internal development information.\n",{"title":21,"text":22},"People keep the final say","Helma drafts an answer for human review. The support agent can send it directly or edit it. Both the original AI answer and the answer that was eventually sent are stored, so we can measure how useful the AI really is.\n",{"type":24,"value":25,"toc":26},"minimark",[],{"title":27,"searchDepth":28,"depth":28,"links":29},"",2,[],{"title":31,"intro":32,"points":33},"What did we build?","Robo Helma is a complete support workflow in which AI, knowledge, integrations, ticketing and feedback come together, not a standalone chatbot next to an existing helpdesk.\n",[34,37,40],{"title":35,"text":36},"A configurable knowledge layer","Every brand can use its own OpenAI Skills and its own vector store. Skills contain, for example, support behaviour, tone of voice and escalation policy. The vector store holds product knowledge such as FAQs, policies, known issues and documentation.\n",{"title":38,"text":39},"Context from real systems","Helma can combine product knowledge with customer-specific information, current incidents, previous customer interactions and linked engineering context. That way the model does not have to make up critical facts itself.\n",{"title":41,"text":42},"A complete support environment","Around the AI we built a multi-tenant inbox, ticket statuses, internal notes, attachments, reporting, feedback tracking and integrations with, among others, email, Facebook Messenger, app store reviews and GitHub.\n",{"tag":44,"title":7,"summary":45,"metric":46},"AI support · human-in-the-loop","Robo Helma combines product documentation, support rules, customer data, incident information and GitHub status in one controlled AI workflow.","67% of generated replies are sent without edits.",null,{"title":49,"body":50,"primaryCta":51,"secondaryCta":52,"local":53},"Building AI that has to do more than generate neat text?","Show us which knowledge and systems are involved in your process. We help you work out how to turn that into a reliable AI workflow, including integrations, guardrails and human-in-the-loop.\n","Book a call","View offer","Senior AI and software engineering from Delft, for organisations in Delft, The Hague, Rotterdam and the surrounding area.\n","md",{"title":56,"items":57},"The case in brief",[58,61,64,67],{"label":59,"value":60},"Ready to send","67% sent without edits",{"label":62,"value":63},"Small edit","18%",{"label":65,"value":66},"Fully rewritten","15%",{"label":68,"value":69},"Knowledge","Skills, vector search and live context",true,{"title":72,"intro":73,"points":74},"Reliable AI takes more than good prompts","Customers can put anything in a message and external sources can contain outdated or unreliable information. That is why we do not automatically treat that input as an instruction for the model.\n",[75,78,81],{"title":76,"text":77},"Prompt injection is checked explicitly","Helma checks customer messages for attempts to manipulate instructions, safety rules, tools or hidden prompts.\n",{"title":79,"text":80},"Every source has its own role","Product documentation determines product facts, customer data determines customer-specific information and GitHub only provides technical status. One source cannot simply override another.\n",{"title":82,"text":83},"No automatic promises from engineering data","A closed GitHub issue, for example, does not automatically mean that a fix has been deployed or is available. That boundary is explicitly built into the AI workflow.\n",{"headline":85,"intro":86,"primaryCta":87,"secondaryCta":88},"Two out of three AI answers are good enough to send right away.","A language model can write a friendly answer in seconds. The hard part is making sure the answer is correct: with the right product knowledge, support rules, current customer information and the status of technical issues. Robo Helma brings those sources together and drafts an answer that a support agent reviews before it goes to the customer.\n","See how Helma works","Tell us what you want to build","robo-helma",{},{"eyebrow":92,"primary":93},"Matching offer",{"key":94,"title":95,"text":96,"price":97,"result":98,"duration":99,"nextStep":100},"build-integrate","Build & Integrate","Do you have an AI challenge of your own where multiple knowledge sources, existing systems and reliable AI need to come together? Then we design and build the workflow and integrations around your situation.\n","Fixed price after scoping","Production-ready AI integrated into your existing environment","Depends on scope","First we determine which knowledge, systems and controls are really needed",0,"\u002Fcases\u002Frobo-helma",{"title":104,"intro":105,"points":106},"Proof","The reliability comes from the engineering around the model. Robo Helma stores the context used for every AI run and measures what support agents eventually do with the generated answer.\n",[107,110,113],{"title":108,"text":109},"67% direct AI acceptance","Two out of three generated answers are currently sent without substantive edits. Another 18% is only slightly adjusted.\n",{"title":111,"text":112},"Source information is visible","In the AI analysis, a support agent can see which knowledge references were used via File Search, including the files used and available relevance scores.\n",{"title":114,"text":115},"Improvement is part of the system","Reporting compares the generated draft with the answer that was actually sent and classifies it as accepted, edited or rejected. That way we can measure whether the AI is getting better and where improvement is needed.\n",{"buyerTriggerKeys":117,"useCaseKeys":119,"offerKeys":125,"solutionKey":89,"capabilityKeys":126},[118],"ai-laten-bouwen",[120,121,122,123,124],"ai-agent-laten-bouwen","interne-ai-assistent-laten-ontwikkelen","eigen-data-en-kennis-gebruiken-met-ai","ai-toevoegen-aan-bestaande-software","tests-evals-monitoring-voor-ai",[94],[127,128,129,130,131,132,133,134,135,136],"ai-engineering","software-engineering","retrieval","vector-search","ai-agents","integrations","human-in-the-loop","evaluation","monitoring","security",{"title":138,"items":139},"What does it deliver?",[140,143,146],{"title":141,"text":142},"67% can go straight to the customer","Currently, 67% of the support answers generated by Robo Helma are sent without edits. The support agent only needs to review and send the answer.\n",{"title":144,"text":145},"Another 18% only needs an edit","For 18%, the generated answer is largely usable, but a support agent adjusts something before it is sent.\n",{"title":147,"text":148},"The remaining 15% shows where we can improve further","About 15% of the answers are fully rewritten. Because we store the original AI draft and the final answer, we can see exactly where Helma still falls short and keep improving on that.\n",{"title":150,"description":151},"Robo Helma: AI helpdesk with knowledge and integrations | 9to5 software","Case: how 9to5 software built Robo Helma, an AI helpdesk that combines product documentation, skills, customer data and GitHub. 67% of the AI answers are currently sent without edits.\n",{"title":153,"intro":154,"points":155},"Where was the real problem?","Automating support looks like a prompt problem at first sight. In practice, the difficulty lies elsewhere. A good answer requires different kinds of knowledge, each with its own source, freshness and reliability.\n",[156,159,162],{"title":157,"text":158},"Product knowledge changes constantly","FAQs, manuals, policies, known issues and other documentation must be available to the AI without stuffing everything into one huge prompt or hard-coding knowledge by hand.\n",{"title":160,"text":161},"Not all knowledge is documentation","Tone of voice, support policy, escalation rules and ways of working are instructions. Customer data and current incidents are live data. You cannot reliably treat these different kinds of context as if they were all the same.\n",{"title":163,"text":164},"A convincing answer can still be wrong","A model can neatly make up something that sounds plausible. For support, that is not enough. The AI must know which sources are leading, when information is missing and when a person must review or take over.\n","cases\u002Frobo-helma","Robo Helma is an AI-first helpdesk that helps support agents give good answers faster. Instead of just putting a language model on an inbox, we combine product documentation, support rules, customer data, incident information and GitHub status into one controlled AI workflow. Currently, 67% of the generated answers are sent to the customer without edits.\n",{"title":168,"items":169},"Where is this relevant?",[170,173,176],{"title":171,"text":172},"Our support agents keep gathering the same information","Product knowledge, customer data and technical status are spread over different systems before anyone can give a good answer.\n",{"title":174,"text":175},"We want AI support, but not a hallucinating chatbot","Answers must be based on verifiable knowledge and current data, with clear limits on what the AI may and may not assume.\n",{"title":177,"text":178},"We want to know whether the AI is actually getting better","Not just counting generated answers, but measuring how many drafts are usable without changes and where support agents still need to correct them.\n",{"hero":180,"situation":181,"approach":182,"build":183,"proof":184,"teaser":185},"\u002Fmedia\u002Fscreenshots\u002Fhelma-hero.webm","\u002Fmedia\u002Fscreenshots\u002Fhelma-knowledge.webp","ls-workflow-flow","\u002Fmedia\u002Fscreenshots\u002Fhelma-analysis.webp","\u002Fmedia\u002Fscreenshots\u002Fhelma-reporting.webp","\u002Fmedia\u002Fscreenshots\u002Fhelma-teaser.webm","7y61CkSiqDr7SMbpk_FIqfwfxBE2egC3_6tKSFy5DHQ",{"id":188,"title":189,"approach":190,"body":204,"build":208,"card":220,"connections":47,"cta":225,"dataExamples":47,"description":27,"extension":54,"facts":228,"featured":242,"guardrails":47,"hero":243,"integrations":47,"key":248,"meta":249,"navigation":70,"offers":250,"order":259,"path":260,"proof":261,"relations":273,"result":287,"seo":299,"situation":302,"stem":315,"summary":316,"usecases":317,"visuals":329,"__hash__":336},"cases_en\u002Fcases\u002Fsoftwareplatform-overnemen-en-professionaliseren.md","From maintenance mode to active development again",{"title":9,"steps":191},[192,195,198,201],{"title":193,"text":194},"First understand the system","We mapped the architecture, active functionality, databases, parsers, integrations and infrastructure. Not on the assumption that everything had to be replaced, but to determine what was good and where change was really needed.\n",{"title":196,"text":197},"Organise feedback and monitoring","Among other things, we set up coverage measurement, error monitoring and an acceptance environment. This made it visible sooner what changes did, so problems no longer had to be discovered through users or manual checks.\n",{"title":199,"text":200},"Targeted refactoring and testing","We removed unused code, introduced more structure and conventions, and improved components as soon as we understood them well enough. At the same time, we systematically expanded the automated tests.\n",{"title":202,"text":203},"Then continue development","As the codebase became better known, tested and manageable, we could develop features again and carry out larger technical improvements without treating every change as a gamble.\n",{"type":24,"value":205,"toc":206},[],{"title":27,"searchDepth":28,"depth":28,"links":207},[],{"title":31,"intro":209,"points":210},"The most important result was a professional technical foundation under an existing product. We made the backend more explicit, more testable and easier to manage without needlessly replacing working parts.\n",[211,214,217],{"title":212,"text":213},"A backend we actually understood","We examined and improved the code until it was clear which components were responsible for what. Old, duplicate or unclear implementations could then be removed or improved in a targeted way.\n",{"title":215,"text":216},"Tests as a safety net","Test coverage became part of the normal development workflow. The relevant backend code grew from around 10% coverage at the start to 92%, with tests on the parts where they actually added value.\n",{"title":218,"text":219},"Professional engineering around the code","Besides the code itself, we also improved the environment around it, including error monitoring, coverage tooling, acceptance, infrastructure and the technical management needed to responsibly keep developing a production platform.\n",{"tag":221,"title":222,"summary":223,"metric":224},"Software rescue","From maintenance mode back to active development","An existing software platform had become so difficult to change that regular development had almost ground to a halt. We brought the backend, tests, monitoring and development process back under control.","Test coverage from around 10% to 92%.",{"title":226,"body":227,"primaryCta":51,"secondaryCta":52,"local":53},"Software nobody dares to touch anymore?","Explain what is there, where development gets stuck and what you are trying to achieve. We look into the technology and quickly tell you what is sensible to keep, repair or rebuild.\n",{"title":56,"items":229},[230,233,236,239],{"label":231,"value":232},"Result","From maintenance mode to active development",{"label":234,"value":235},"Test coverage","From around 10% to 92%",{"label":237,"value":238},"Delivered","Refactoring, tests, monitoring and technical control",{"label":240,"value":241},"Follow-up","Years of further development on the same foundation",false,{"headline":244,"intro":245,"primaryCta":246,"secondaryCta":247},"Making a platform that could only be maintained ready for development again.","The software worked, but changing it was risky. The previous development partner no longer did regular development and only stepped in when something broke. We did not start by rebuilding everything. First we had to understand what was there, what was good and where the real technical blockers were.\n","See the result","Tell us about your problem","softwareplatform-overnemen-en-professionaliseren",{},{"eyebrow":92,"primary":251},{"key":252,"title":253,"text":254,"price":255,"result":256,"duration":257,"nextStep":258},"vibe-code-rescue-audit","Vibe Code Rescue Audit","We examine what is there, where the real technical risks are and what should be kept, repaired or replaced.\n","€2,950 excl. VAT","Technical analysis with a concrete rescue plan","Fixed scope","Afterwards you know whether a Rescue Sprint or a larger approach is needed",1,"\u002Fcases\u002Fsoftwareplatform-overnemen-en-professionaliseren",{"title":104,"intro":262,"points":263},"The progress was not only visible in cleaner code. We could measure it and then prove it in practice for years by further expanding the platform. The original analysis also showed that not everything was bad. Parts of the infrastructure, scalability and performance were already in decent shape. That is why we chose targeted professionalisation instead of automatically rebuilding everything.\n",[264,267,270],{"title":265,"text":266},"10% → 92% line coverage","At the start, an important backend component had around 3,400 lines of code and barely 10% line coverage. In the end, the relevant backend code reached 92% test coverage.\n",{"title":268,"text":269},"From break-fix to years of new features","Before the takeover, the agreement was that the previous development partner would only intervene when something broke. After the professionalisation we developed the platform for years with new functionality and technical improvements.\n",{"title":271,"text":272},"Later even our own machine learning","One of the later developments was a self-trained model for recognising offers in PDF store flyers. A good example of how much technical room had opened up again after the takeover and professionalisation.\n",{"buyerTriggerKeys":274,"useCaseKeys":276,"offerKeys":280,"capabilityKeys":282},[275],"vastgelopen-met-ai",[277,278,279],"ai-project-overnemen-van-andere-leverancier","developmentteam-loopt-vast-met-ai","prototype-naar-onderhoudbaar-softwareproduct",[252,281,94],"rescue-sprint",[128,283,284,135,285,286],"backend-engineering","testing","refactoring","machine-learning",{"title":288,"items":289},"What changed?",[290,293,296],{"title":291,"text":292},"From around 10% to 92% test coverage","The most important backend code started with about 10% line coverage. During the professionalisation we brought test coverage to 92%. Changes could therefore be verified much faster and with considerably more certainty.\n",{"title":294,"text":295},"New development got going again","The platform did not stay stuck in maintenance. In the years that followed we developed a lot of new functionality and made larger technical improvements on the same codebase.\n",{"title":297,"text":298},"The foundation became strong enough for new technology","The technical foundation became stable and understandable enough to keep innovating. Later, for example, we trained our own machine learning model to automatically recognise offers in PDFs of store flyers.\n",{"title":300,"description":301},"Taking over and professionalising an existing software platform | 9to5 software","Case: 9to5 software took over a stalled software platform, professionalised the backend and raised test coverage from around 10% to 92%. New functionality was built on it for years afterwards.\n",{"title":303,"intro":304,"points":305},"Where did it get stuck?","The platform consisted of several apps, web environments and an extensive backend. The existing software held a lot of value, but technical debt made new development increasingly difficult. Before changing anything, we therefore first systematically examined the existing code and architecture.\n",[306,309,312],{"title":307,"text":308},"New development had practically stopped","The previous development partner no longer did regular development. They only intervened when something actually broke. The platform ran, but technically it was hardly moving forward.\n",{"title":310,"text":311},"The backend was hard to understand","Functionality was spread over several Elixir apps within an umbrella structure. Names like old, new, v2 and v3 lived side by side, documentation was missing in important places, and different development styles and conventions made it hard to see which code was still leading.\n",{"title":313,"text":314},"Critical code was barely covered","In one important backend component we measured about 10% line coverage on around 3,400 lines of code at the start. Other components also had limited or virtually no test coverage. As a result, a change could silently break existing functionality.\n","cases\u002Fsoftwareplatform-overnemen-en-professionaliseren","An existing software platform had become so hard to change technically that the previous development partner only did maintenance. We took over the system, brought the backend under control and professionalised the code, tests, monitoring and development process. Test coverage grew from around 10% to 92%, and in the years that followed we were able to develop the platform extensively again.\n",{"title":318,"items":319},"Does this sound familiar?",[320,323,326],{"title":321,"text":322},"We have software nobody dares to touch anymore","Every change feels risky because tests, documentation or knowledge of the code are missing.\n",{"title":324,"text":325},"Our previous development partner is gone or cannot move forward","The system needs to be taken over without first spending months rebuilding everything.\n",{"title":327,"text":328},"Maintenance still works, but new development does not","The product runs, but technical debt makes new features increasingly expensive and unpredictable.\n",{"hero":330,"situation":331,"approach":332,"build":333,"proof":334,"teaser":335},"sq-tangle-knot","\u002Fmedia\u002Fscreenshots\u002Fsoftware-rescue-situation.webp","ls-rescue-repair","\u002Fmedia\u002Fscreenshots\u002Fsoftware-rescue-build.webp","\u002Fmedia\u002Fscreenshots\u002Fsoftware-rescue-coverage.webp","\u002Fmedia\u002Fscreenshots\u002Fsoftware-rescue-teaser.webp","oNFFM_t42kZnbXMyeVr9Ih81Bzf6OVtCfy_h4YhRVtc",{"id":338,"title":339,"approach":340,"body":355,"build":359,"card":371,"connections":376,"cta":389,"dataExamples":47,"description":27,"extension":54,"facts":392,"featured":242,"guardrails":47,"hero":406,"integrations":47,"key":410,"meta":411,"navigation":70,"offers":412,"order":28,"path":417,"proof":418,"relations":431,"result":438,"seo":450,"situation":453,"stem":466,"summary":467,"usecases":468,"visuals":479,"__hash__":484},"cases_en\u002Fcases\u002Frobos-ai-agents-die-echt-werk-doen.md","Robos: AI agents that do real work",{"title":341,"steps":342},"How do we build the Robos?",[343,346,349,352],{"title":344,"text":345},"One Robo, one clear problem","We do not start with the model but with the task. Helma does support, Mae works on software maintenance, Indie on incidents, Mark on marketing and Nola on meetings. This keeps the context small enough to understand and test well.\n",{"title":347,"text":348},"AI gets access to the right context","Depending on the task we use, among other things, Skills, vector stores, repository snapshots, live APIs, historical data, business rules and current information from connected systems.\n",{"title":350,"text":351},"Output becomes part of the workflow","A Robo delivers more than a suggestion. Output can end up in a helpdesk ticket, GitHub issue, incident record, marketing schedule, backlog or minutes with action items.\n",{"title":353,"text":354},"People stay where they add value","For us, human-in-the-loop is a design choice. Helma has answers reviewed, Indie has an incident adjusted or confirmed first, and Mark has review moments before customer-facing content goes ahead.\n",{"type":24,"value":356,"toc":357},[],{"title":27,"searchDepth":28,"depth":28,"links":358},[],{"title":31,"intro":360,"points":361},"The Robos are separate tools and products, each with its own workflow and integrations. Not every Robo needs an application of its own. Together they form our internal lab for AI that actually has to work in production.\n",[362,365,368],{"title":363,"text":364},"Customers and marketing","Robo Helma combines support knowledge, customer context and technical information for customer answers. Robo Mark picks up signals from sources such as RSS, Slack and ideas, creates content, supports review and planning, publishes and uses performance as input for the next generation.\n",{"title":366,"text":367},"Engineering and operations","At fixed moments, Robo Mae analyses a commit-pinned snapshot of a repository, combines it with current first-party documentation and can create validated maintenance issues in GitHub. Robo Indie turns a Slack thread into a structured incident draft with an internal explanation, a customer-safe explanation and a workaround where available. Stanley works directly from ChatGPT: he watches our GitHub backlog and runs the weekly stand-up, so open issues do not go unnoticed.\n",{"title":369,"text":370},"Meetings, media and the Robo landscape","Robo Nola retrieves Google Meet recordings and uses its own Dutch ASR pipeline to create transcripts, summaries, action items and minutes. Robo Vidar is our video generation workspace for tools such as Seedance and Veo. Robo Dolly keeps track of active Robos and their history. Robo Rolf is the rollout Robo under construction; the current application deliberately contains only the technical foundation until the release workflow is defined sharply enough.\n",{"tag":372,"title":373,"summary":374,"metric":375},"AI agents","Robo's: AI agents that do real work","Specialist Robo's carry out specific tasks in support, software maintenance, marketing, incident management, meetings and other operational workflows.","AI connected to real knowledge, systems and actions, with clear boundaries.",{"title":377,"intro":378,"points":379},"The Robos are not isolated from each other","As more processes are automated, specialised agents can also use each other's controlled output. The result is a network of small systems with clear responsibilities instead of one big all-knowing super agent.\n",[380,383,386],{"title":381,"text":382},"Indie feeds Helma","Robo Indie is the source of truth for current incidents and offers a protected read-only API for it. Robo Helma can use that information when a support answer depends on a current outage.\n",{"title":384,"text":385},"GitHub is a work environment for several agents","Mae uses GitHub to record maintenance work as concrete issues. Stanley uses the same backlog in a different way: watching what gets left behind and periodically bringing attention back to open work.\n",{"title":387,"text":388},"Dolly keeps the whole visible","Robo Dolly gives an internal overview of which Robos are active and stores their history. This keeps the growing landscape of specialised agents itself manageable too.\n",{"title":390,"body":391,"primaryCta":51,"secondaryCta":52,"local":53},"Which recurring task at your organisation deserves a Robo?","Show us which work now goes back and forth by hand between people and systems. We look at where AI can really take something over and what is needed to make that work reliably in production.\n",{"title":56,"items":393},[394,397,400,403],{"label":395,"value":396},"Support","67% of Helma's answers usable right away",{"label":398,"value":399},"Software maintenance","Mae examines repositories and creates concrete issues",{"label":401,"value":402},"Marketing","Mark goes from signal to publication and feedback",{"label":404,"value":405},"Meetings","Nola creates Dutch transcripts and minutes",{"headline":407,"intro":408,"primaryCta":409,"secondaryCta":88},"AI that becomes part of the work, not a chatbot that gives advice.","An agent only gets interesting when it goes beyond generating text. Our Robos read information from real systems, make decisions within a defined task, create concrete output and move processes forward. Sometimes on their own, sometimes with a person as a checkpoint. That is how we are building, step by step, a team of specialised AI tools for our own work.\n","Meet the Robos","robos-ai-agents-die-echt-werk-doen",{},{"eyebrow":92,"primary":413},{"key":94,"title":95,"text":414,"price":97,"result":415,"duration":99,"nextStep":416},"We design and build an AI agent around a concrete process, including the required knowledge sources, system integrations, guardrails and human-in-the-loop.\n","A production-ready AI workflow that is truly part of your process","First we determine exactly which task the agent must carry out and which systems it needs","\u002Fcases\u002Frobos-ai-agents-die-echt-werk-doen",{"title":419,"intro":420,"points":421},"These are not standalone AI demos","Behind the Robos are ordinary software engineering principles: authentication, authorisation, queues, retries, structured output, tests, monitoring and explicit data boundaries. The language model is one part of the system, not the system itself.\n",[422,425,428],{"title":423,"text":424},"Measurable quality instead of AI magic","Robo Helma, for example, measures what support agents actually do with an AI draft. Currently 67% is sent directly, 18% slightly adjusted and 15% fully rewritten. That lets us keep improving in a targeted way.\n",{"title":426,"text":427},"Autonomy is earned per task","Within a preconfigured maintenance job, Mae may automatically publish a limited number of strictly validated GitHub issues. Indie, on the other hand, first creates a draft that an employee can adjust, cancel or confirm. The degree of autonomy follows the risk.\n",{"title":429,"text":430},"Not every agent needs an application of its own","Some Robos have a complete interface and backend of their own. Others can be deployed much more lightly. Stanley, for example, works as an agent in ChatGPT and uses GitHub as a work environment for backlog management and the weekly stand-up. The form follows the problem, not the other way around.\n",{"buyerTriggerKeys":432,"useCaseKeys":433,"offerKeys":435,"capabilityKeys":436},[118],[120,121,434,122,123],"processen-automatiseren-met-ai",[94],[127,131,128,132,437,129,133,134,135,136],"workflow-automation",{"title":439,"items":440},"What does this approach deliver?",[441,444,447],{"title":442,"text":443},"AI really takes over a defined piece of work","The Robos do not stop at analysis. They deliver a usable artefact or move a workflow forward: an answer, GitHub issue, incident, publication, backlog action or set of minutes.\n",{"title":445,"text":446},"Integrations make the difference","The value comes from connecting AI to the systems where the work actually happens. A concrete example is Robo Helma, which can use current incident information from Robo Indie when answering support questions.\n",{"title":448,"text":449},"We learn from real production problems","Because we use the Robos ourselves, problems with context, permissions, retries, security, evaluation and human-in-the-loop do not first surface at a customer. We solve them while the system is really being used.\n",{"title":451,"description":452},"AI agents that do real work | Robos by 9to5 software","Case: how 9to5 software builds specialised AI agents for support, marketing, software maintenance, incident management and meetings. AI connected to real data, systems and workflows.\n",{"title":454,"intro":455,"points":456},"Why not just one AI assistant?","Many business processes seem suitable for AI, but in practice they have very different context, permissions, risks and actions. A generic assistant with a bit of access to everything quickly becomes hard to control. That is why we choose specialised Robos, each with a clear area of work.\n",[457,460,463],{"title":458,"text":459},"The work is spread over real systems","The information an agent needs is not in a single prompt. It lives in GitHub, Slack, product documentation, mailboxes, customer data, Google Calendar, Meet, Drive, RSS feeds and other operational systems.\n",{"title":461,"text":462},"Just generating an answer solves little","A maintenance agent must be able to deliver a usable GitHub issue. An incident agent must turn information into a manageable incident. The process has to actually move forward.\n",{"title":464,"text":465},"Every task needs different boundaries","Sometimes a Robo may act on its own. Sometimes an employee must review or confirm first. We design that boundary per workflow, instead of hoping afterwards that the model does the right thing.\n","cases\u002Frobos-ai-agents-die-echt-werk-doen","At 9to5 software we build specialised Robos that each carry out a concrete piece of work, not a collection of chatbots. Answering support, flagging software maintenance, logging incidents, creating marketing content, processing meetings or watching a GitHub backlog. Every Robo combines AI with real knowledge, systems, actions and clear boundaries.\n",{"title":168,"items":469},[470,473,476],{"title":471,"text":472},"We want an AI agent that actually takes action","AI that retrieves information, carries out a task and brings the result back into your existing process, instead of another chat window.\n",{"title":474,"text":475},"Our knowledge is spread over different systems","The agent must combine documentation, live data and applications without copying everything into one prompt or a new database.\n",{"title":477,"text":478},"We want to automate without losing control","Some steps may be automatic, others need human review. We design those boundaries explicitly into the workflow.\n",{"hero":480,"situation":481,"approach":482,"build":483,"proof":184,"teaser":480},"\u002Fmedia\u002Fproducts\u002Frobos\u002Fdolly-team.jpg","\u002Fmedia\u002Fproducts\u002Frobos\u002Fdolly-specialists.jpg","ls-agentic-loop","\u002Fmedia\u002Fscreenshots\u002Fnola-meeting-results.webp","JStSF95HQRC_lZNXV2vBOf21E2RAD0j6_-vIR6bl36M",{"id":486,"title":487,"approach":488,"body":502,"build":506,"card":518,"connections":47,"cta":523,"dataExamples":47,"description":27,"extension":54,"facts":526,"featured":242,"guardrails":47,"hero":540,"integrations":47,"key":544,"meta":545,"navigation":70,"offers":546,"order":551,"path":552,"proof":553,"relations":566,"result":578,"seo":589,"situation":592,"stem":605,"summary":606,"usecases":607,"visuals":618,"__hash__":625},"cases_en\u002Fcases\u002Fomgevingsalert-data-bruikbaar-maken.md","OmgevingsAlert: from scattered data to relevant alerts",{"title":9,"steps":489},[490,493,496,499],{"title":491,"text":492},"Retrieve every source reliably","For each source we built the right integration: scheduled imports, API connections, XML processing, RSS and HTML imports and processes that continuously listen to live data streams. Import work runs asynchronously so large or slow sources do not block the rest of the product.\n",{"title":494,"text":495},"Translate everything into one shared model","Source records keep their own specific information, but are then indexed into a shared Feature model. This means apps and other consumers do not need to understand how a KNMI warning, announcement or public transport message was originally delivered.\n",{"title":497,"text":498},"Geography at the core","With PostgreSQL and PostGIS we link points, areas and other geometry to the locations users follow. Assets can be, for example, addresses, points, polygons or imported KML areas.\n",{"title":500,"text":501},"Only then decide what is relevant","After the geographic selection we apply filters on, among other things, category, distance, words that must appear and words that must be excluded. Only relevant combinations are linked to a user's inbox.\n",{"type":24,"value":503,"toc":504},[],{"title":27,"searchDepth":28,"depth":28,"links":505},[],{"title":31,"intro":507,"points":508},"The core is a data platform that reduces very different sources to one usable stream of local information. On top of that sit matching, filtering, notifications and several product interfaces.\n",[509,512,515],{"title":510,"text":511},"A broad import layer","The platform processes, among other things, official publications, zoning plans, police reports, KNMI weather warnings, NDW roadworks, NDOV disruptions, local news, earthquakes and municipalities' own messages.\n",{"title":513,"text":514},"One normalised Feature pipeline","Every source is translated into shared fields such as category, publication date, geometry, source information and the parts needed to show the message in the different products. New source types therefore do not have to be implemented separately in every client again.\n",{"title":516,"text":517},"A geographic matching engine","New data is linked to relevant locations and objects. For consumers that can be a point with a radius; professional users can also monitor larger areas or their own geometry. Matching for larger numbers of assets is processed in batches to keep the background queues manageable.\n",{"tag":519,"title":520,"summary":521,"metric":522},"Data platform","OmgevingsAlert: from scattered data to relevant notifications","A wide range of public and live data sources are imported, normalised and linked geographically before being turned into relevant information for the right user.","Since 2012 · from government XML to live public transport feeds.",{"title":524,"body":525,"primaryCta":51,"secondaryCta":52,"local":53},"Plenty of data, but no usable system yet?","Show us where the information comes from and what eventually needs to happen with it. We help set up the data flow so that other software can reliably build on it.\n",{"title":56,"items":527},[528,531,534,537],{"label":529,"value":530},"Product","In development since 2012",{"label":532,"value":533},"Data sources","From government XML to live public transport feeds",{"label":535,"value":536},"Matching","Geographic and content-based per location",{"label":538,"value":539},"Output","Apps, dashboard, website, push and email",{"headline":541,"intro":542,"primaryCta":543,"secondaryCta":88},"Collecting data is easy. Working out which piece matters to whom is the real work.","OmgevingsAlert started in 2012 with a simple idea: choose a location and receive relevant permits and spatial developments in the neighbourhood. Today the platform processes many more kinds of information. Every source has its own format, rhythm, quality and geographic logic. Most of the engineering is in everything that has to happen before you can show any data.\n","See how the data flow works","omgevingsalert-data-bruikbaar-maken",{},{"eyebrow":92,"primary":547},{"key":94,"title":95,"text":548,"price":97,"result":549,"duration":99,"nextStep":550},"We build the technical layer between your data sources and the product that has to work with them: imports, API connections, normalisation, processing, matching and reliable integrations.\n","A production-ready data flow integrated into your software","First we map sources, volumes, processing and the desired output",3,"\u002Fcases\u002Fomgevingsalert-data-bruikbaar-maken",{"title":554,"intro":555,"points":556},"The complexity is under the hood","OmgevingsAlert shows well why data engineering is more than reading an API and storing records. The value only emerges when unreliable, changing and dissimilar input can move safely through a complete production chain.\n",[557,560,563],{"title":558,"text":559},"Batch, real-time and periodic side by side","One source is checked daily, police data every ten minutes and public transport messages arrive through a permanently listening pub\u002Fsub process. The backend has to process all these forms reliably side by side.\n",{"title":561,"text":562},"PostGIS decides what is relevant where","Features and assets contain real geometry. Matching uses spatial calculations, distance rules and area relations instead of just textual place names or postcodes.\n",{"title":564,"text":565},"The pipeline does not end at storage","Import is followed by normalisation, matching, filtering, inbox status, access rules and notification. Push can be sent immediately or bundled, and Pro users can receive relevant alerts via an email digest.\n",{"buyerTriggerKeys":567,"useCaseKeys":568,"offerKeys":569,"solutionKey":570,"capabilityKeys":571},[118],[122,123],[94],"omgevingsalert",[128,283,572,132,573,574,575,576,577],"data-engineering","geospatial","postgresql","postgis","background-processing","api-engineering",{"title":138,"items":579},[580,583,586],{"title":581,"text":582},"One product on top of completely different data sources","To the user, a permit, a road closure or a weather warning feels like the same kind of product experience, while the underlying sources technically have little in common.\n",{"title":584,"text":585},"From national data to personal relevance","The backend translates large streams of general information into a much smaller selection per location. Users do not have to search government sites, news feeds and traffic sources themselves.\n",{"title":587,"text":588},"A foundation we can keep building on","New categories can use the same import, normalisation, matching and notification infrastructure. On that basis we later also added AI filters that can judge, for certain workflows, whether an alert is relevant in terms of content.\n",{"title":590,"description":591},"OmgevingsAlert: bringing complex data sources together | 9to5 software","Case: how 9to5 software imports, normalises, geographically matches and makes available a wide range of public and live data sources for OmgevingsAlert in apps, dashboards and notifications.\n",{"title":593,"intro":594,"points":595},"Where is the complexity?","The user only wants to know one thing: what is happening around me that matters to me? Behind that simple question is a data platform in which information from different organisations, protocols and formats has to come together.\n",[596,599,602],{"title":597,"text":598},"Every source works differently","Official publications come from mutation-event XML and metadata, roadworks from a gzipped DATEX feed, public transport disruptions via a continuous ZeroMQ pub\u002Fsub channel, weather warnings via KNMI open data and local news via RSS, Atom or HTML. So there is no such thing as one generic importer.\n",{"title":600,"text":601},"Source data does not say who it is relevant to","A permit, traffic measure or warning may be available nationwide, but a user only wants information for their own home, neighbourhood, route or managed property. For that, the data needs reliable geographic information and then has to be matched against locations and areas.\n",{"title":603,"text":604},"The same data has to work in several places","The normalised information is used by the mobile apps, Mijn OmgevingsAlert, OmgevingsAlert Pro, the public website and OverUwBuurt. The same backend also drives push notifications, email digests and other product flows.\n","cases\u002Fomgevingsalert-data-bruikbaar-maken","OmgevingsAlert brings a wide range of public and live data sources together in one product. Official announcements, zoning plans, police reports, weather warnings, roadworks, public transport disruptions, local news and other sources all arrive differently. We built the backend that imports this data, normalises it, links it geographically to locations and ultimately delivers only the relevant information to the right user.\n",{"title":168,"items":608},[609,612,615],{"title":610,"text":611},"We have lots of data, but cannot turn it into a usable product yet","The information sits in different sources, formats and systems and has to be brought together before users can do anything with it.\n",{"title":613,"text":614},"Our data needs to be linked to locations or other context","Just storing the records is not enough. The system must be able to determine which information is relevant to which customer, location, object or process.\n",{"title":616,"text":617},"We want to add new sources without rebuilding the whole product","A good normalisation layer prevents every new integration from requiring changes in all apps, dashboards and other consumers again.\n",{"hero":619,"situation":620,"approach":621,"build":622,"proof":623,"teaser":624},"\u002Fmedia\u002Fscreenshots\u002Fomgevingsalert-hero.webm","\u002Fmedia\u002Fproducts\u002Fomgevingsalert-sources.webp","ls-route-converge","\u002Fmedia\u002Fscreenshots\u002Fomgevingsalert-map.webp","\u002Fmedia\u002Fscreenshots\u002Fomgevingsalert-notifications.webp","\u002Fmedia\u002Fscreenshots\u002Fomgevingsalert-teaser.webm","5tcmk_JIpVjwxiJRbyubwU5fpZtzx4NXZRmSGGAEO1g",{"id":627,"title":628,"approach":629,"body":643,"build":647,"card":659,"connections":47,"cta":664,"dataExamples":667,"description":27,"extension":54,"facts":680,"featured":242,"guardrails":47,"hero":694,"integrations":47,"key":698,"meta":699,"navigation":70,"offers":700,"order":705,"path":706,"proof":707,"relations":720,"result":733,"seo":744,"situation":747,"stem":760,"summary":761,"usecases":762,"visuals":773,"__hash__":780},"cases_en\u002Fcases\u002Fnummi-data-driven-product.md","nummi: steering product development with data",{"title":9,"steps":630},[631,634,637,640],{"title":632,"text":633},"First measure where it really goes wrong","We analysed not just totals, but the whole user journey: first open, signup, first actions, engagement, D1 and D30 retention, acquisition source, social interaction, platform and user value. That let us tell bottlenecks apart from symptoms.\n",{"title":635,"text":636},"From analysis to a concrete product choice","The retention data showed that the registration wall lost many users, while players showed healthy playing behaviour after signup. Instead of building more gameplay features first, we added guest accounts so new players can start right away.\n",{"title":638,"text":639},"Roll out new ideas measurably","New onboarding is not simply switched on for everyone. The apps support a control and treatment variant via remote configuration and log separate milestones throughout the onboarding. That way we can assess afterwards where behaviour actually changes.\n",{"title":641,"text":642},"Link product data to business data","Besides gameplay and retention we look at subscriptions, ad revenue, acquisition and attribution. This lets us assess, for example per platform, which revenue model and which product investment make the most sense.\n",{"type":24,"value":644,"toc":645},[],{"title":27,"searchDepth":28,"depth":28,"links":646},[],{"title":31,"intro":648,"points":649},"Data-driven product development takes more than an analytics script. Measurability has to run through the entire technical architecture, without the product itself becoming dependent on one dashboard or tool.\n",[650,653,656],{"title":651,"text":652},"A complete production backend","The Rails backend manages accounts, games, moves, friends, rankings, ratings, chat, bots, puzzles, subscriptions, notifications and a growing number of individual user statistics. Background work and recurring processes run via job queues.\n",{"title":654,"text":655},"Product analytics in both mobile apps","Firebase Analytics is the primary product analytics layer. The apps record events around, among other things, signup, gameplay, invitations, puzzles, ads, purchases, streaks and onboarding. Relevant user properties are also tracked so behaviour can be compared between groups.\n",{"title":657,"text":658},"Experiments and acquisition made measurable","Onboarding has its own measurable funnel with milestones from exposure and the first practice action to guest account creation, invitations, practice games and completion. Android also uses AppsFlyer for specific acquisition and purchase attribution.\n",{"tag":660,"title":661,"summary":662,"metric":663},"Product engineering","nummi: using data to guide product development","An online multiplayer product where retention, onboarding, engagement, acquisition, ads and subscriptions directly inform product decisions.","Only 54% made it past signup\u002Flogin. That analysis led to guest accounts.",{"title":665,"body":666,"primaryCta":51,"secondaryCta":52,"local":53},"Plenty of product data, but few answers yet?","Show us what your product does, what data you already collect and which decisions are now mostly made on gut feeling. We help set up both the software and the measurable product flow properly.\n",{"title":668,"intro":669,"points":670},"More than one dashboard","We only combine data that helps make a product decision.\n",[671,674,677],{"title":672,"text":673},"Retention and activation","We look at where users first drop off, when they come back and which behaviour is associated with longer use.\n",{"title":675,"text":676},"Engagement and social effects","The analysis showed, for example, that 25.3% of users started games with friends and that active chatters sent almost thirty messages on average. Social interaction therefore turned out to be a more interesting retention signal than simply more solo functionality.\n",{"title":678,"text":679},"Revenue and acquisition","Ads, subscriptions, attribution and user value are compared with product behaviour. That way you can tell whether growth comes from more users, better retention, better monetisation or merely from more expensive paid traffic.\n",{"title":56,"items":681},[682,685,688,691],{"label":683,"value":684},"Biggest bottleneck found","Only 54% got past signup\u002Flogin",{"label":686,"value":687},"Product decision","Retention data led to guest accounts",{"label":689,"value":690},"Experiments","Onboarding with control\u002Fvariant and its own funnel",{"label":692,"value":693},"Platform","Backend, iOS, Android, analytics and monetisation",{"headline":695,"intro":696,"primaryCta":697,"secondaryCta":88},"Measure where users drop off instead of guessing what they need.","With a digital product you can build features endlessly. The harder question is which change actually makes a difference. That is why at nummi we combine product development with analytics, cohort analyses, experiments and business data. Sometimes the data confirms an idea. Sometimes it shows that we were about to work on the wrong problem.\n","See how we work with data","nummi-data-driven-product",{},{"eyebrow":92,"primary":701},{"key":94,"title":95,"text":702,"price":97,"result":703,"duration":99,"nextStep":704},"We build or professionalise a software product in which data, product logic, analytics and existing systems come together. From backend and integrations to the measuring points that help you make better product decisions afterwards.\n","Production-ready software with a measurable product flow","First we determine which decisions the software and data actually need to support",4,"\u002Fcases\u002Fnummi-data-driven-product",{"title":708,"intro":709,"points":710},"Data changes the conversation","We learned the most from the assumptions that turned out right or wrong. That makes product development much more concrete.\n",[711,714,717],{"title":712,"text":713},"The registration wall became visible","Only 54% got past signup\u002Flogin. Of the people who did start, 68% already reached the first important gameplay threshold of 30 points. So the problem sat much earlier in the funnel than we could have seen from feature usage alone.\n",{"title":715,"text":716},"Not every new user is equally valuable","In the retention analysis, D1 retention of CPC users was around 21%, compared with about 39% for organic users. That was an important signal not to simply buy more paid traffic while the onboarding itself still had friction.\n",{"title":718,"text":719},"Platform data shapes the business model","In the same analysis, Android and iOS had comparable engagement, but a clearly different measured 120-day user value. That gave a concrete reason to approach monetisation differently per platform: more ad optimisation where that works and more attention to subscriptions where ad revenue lags behind.\n",{"buyerTriggerKeys":721,"useCaseKeys":722,"offerKeys":724,"solutionKey":725,"capabilityKeys":726},[118],[123,122,723],"ai-toevoegen-aan-bestaand-product",[94],"nummi",[128,283,727,572,728,729,730,731,576,732],"product-engineering","analytics","experimentation","mobile-development","subscriptions","production-engineering",{"title":288,"items":734},[735,738,741],{"title":736,"text":737},"Data pointed us to signup, not to yet another feature","In the analysis, only 54% of new users got past signup and login, and about 44 to 45% came back on day 1. At the same time, users who did start already took many actions on average on their first day. That made it clear that the first product threshold mattered more than extra gameplay behind it.\n",{"title":739,"text":740},"Guest accounts came straight from that analysis","New players can now start right away without first creating a full account. After the introduction we already saw fewer drop-offs. This decision started with behaviour we could point to in the data, not with a brainstorm.\n",{"title":742,"text":743},"We can actually compare the next onboarding","A more extensive onboarding is now in the product as an experiment. Control and variant stay consistent per installation and every important step has its own analytics. So soon we will not only be able to say that a flow 'feels better', but see whether more users actually become activated.\n",{"title":745,"description":746},"nummi: building a data-driven software product | 9to5 software","Case: how 9to5 software builds and develops nummi based on product data, retention, experiments, analytics and production engineering. From backend and mobile apps to dashboards, subscriptions and A\u002FB tests.\n",{"title":748,"intro":749,"points":750},"Where was the challenge?","Technically, nummi is an extensive product: multiplayer games, friends, chat, rankings, bots, puzzles, notifications, ads and subscriptions. But building more functionality does not automatically make the product better. To improve in a targeted way, product behaviour, technical events and business results had to be connected.\n",[751,754,757],{"title":752,"text":753},"A feature can feel logical and still deliver little","Leaderboards, badges, streaks, bots, onboarding, ads and subscriptions can all sound interesting. Without data, though, you do not know which investment solves the biggest problem.\n",{"title":755,"text":756},"The problem can be somewhere other than you think","Our retention analysis showed, for example, that users who actually started were already playing quite actively. The biggest drop-off happened before that: only 54% of new users got past signup and login.\n",{"title":758,"text":759},"Product, technology and business affect each other","A change in onboarding can affect retention. Acquisition affects the quality of new users. Ad revenue differs per platform and subscriptions call for different product choices again. You cannot make those decisions in isolation.\n","cases\u002Fnummi-data-driven-product","nummi is an online multiplayer product we have been building and developing for years. We use data to decide what to build, not just for reporting afterwards. Retention, onboarding, engagement, acquisition, advertising, subscriptions and gameplay are measured and used to make product decisions. A retention analysis, for example, led directly to guest accounts, and we build new onboarding as a measurable experiment instead of as a big gamble.\n",{"title":168,"items":763},[764,767,770],{"title":765,"text":766},"We build lots of features, but do not know what really makes a difference","Product development has a backlog full of ideas, but reliable data to set priorities is missing.\n",{"title":768,"text":769},"We have analytics, but mainly use them for reporting","The events already exist, but metrics and product decisions are not yet linked.\n",{"title":771,"text":772},"We want to experiment without making our product needlessly complex","New flows must be rolled out in a controlled way, measured and rolled back if needed, without building a separate experimentation world next to the real product.\n",{"hero":774,"situation":775,"approach":776,"build":777,"proof":778,"teaser":779},"\u002Fmedia\u002Fproducts\u002Fnummi-hero.webm","\u002Fmedia\u002Fproducts\u002Fnummi-situation.webp","ls-optimize-flow","\u002Fmedia\u002Fproducts\u002Fnummi-build.webp","\u002Fmedia\u002Fproducts\u002Fnummi-proof.webp","\u002Fmedia\u002Fproducts\u002Fnummi-teaser.webm","Fln_QYDpljCbM0fHL8o90W11XXbZWa_t82qFEUK3j8s",{"id":782,"title":783,"approach":784,"body":798,"build":802,"card":814,"connections":47,"cta":818,"dataExamples":47,"description":27,"extension":54,"facts":821,"featured":242,"guardrails":47,"hero":834,"integrations":838,"key":851,"meta":852,"navigation":70,"offers":853,"order":858,"path":859,"proof":860,"relations":873,"result":886,"seo":898,"situation":901,"stem":914,"summary":915,"usecases":916,"visuals":927,"__hash__":934},"cases_en\u002Fcases\u002Fparkmybike-software-en-hardware.md","ParkMyBike: software that has to work beyond the browser",{"title":9,"steps":785},[786,789,792,795],{"title":787,"text":788},"One domain for different hardware","In the backend we model locations, lockers, locks, ports and IoT devices independently of the specific brand. That way the same reservation and user logic keeps working on top of different technical solutions.\n",{"title":790,"text":791},"The backend decides what has to happen","The mobile app does not need to know all protocols and lock logic on its own. In BLE flows, the backend coordinates the session and issues commands for, among other things, connect, read, write and disconnect. The phone does the local Bluetooth work and sends the results back.\n",{"title":793,"text":794},"Connect existing hardware where that is smarter","We do not automatically build our own solution for everything. ParkMyBike integrates with, among others, Particle, EVVA, SAS and iLOQ, and we also built an integration through which Epsilon Cities hardware communicates with our backend via a messaging infrastructure.\n",{"title":796,"text":797},"Build our own hardware where needed","For use cases where existing hardware does not fit well enough, we also develop our own BLE controller firmware. That way software, protocol and physical control can be designed as one system instead of as separate parts.\n",{"type":24,"value":799,"toc":800},[],{"title":27,"searchDepth":28,"depth":28,"links":801},[],{"title":31,"intro":803,"points":804},"ParkMyBike is a chain of software and hardware that together deliver a physical service.\n",[805,808,811],{"title":806,"text":807},"Apps that operate real locks","The iOS and Android apps support reservations, subscriptions and opening bike lockers. For BLE, the phone connects locally to the device, while the backend coordinates the workflow, authorisation and protocol steps.\n",{"title":809,"text":810},"A backend for both software and physical infrastructure","The Elixir backend manages users, locations, reservations, subscriptions, payments, lockers, locks, IoT devices and ports. It also processes real-time updates, hardware events, maintenance tasks and integrations with external systems.\n",{"title":812,"text":813},"Controller and manufacturer integrations","We have supported several hardware paths, from Particle devices and BLE controllers to external lock platforms. For Epsilon Cities, for example, we built two-way communication in which devices report their status and the backend can send actions to specific ports.\n",{"tag":815,"title":783,"summary":816,"metric":817},"Software + hardware","Mobile apps, backend, dashboard, payments, BLE, IoT and physical locks come together in one production-ready system.","2025: 23 new locations · 122 parking spaces · 900 new users.",{"title":819,"body":820,"primaryCta":51,"secondaryCta":52,"local":53},"Does your software also have to make something happen in the real world?","Show us which hardware, suppliers and existing systems you have to work with. We help design and build the complete chain, including the tricky parts between API, app and physical device.\n",{"title":56,"items":822},[823,825,828,831],{"label":529,"value":824},"App, dashboard, backend and hardware",{"label":826,"value":827},"Hardware","BLE, IoT and different lock systems",{"label":829,"value":830},"Expansion in 2025","23 new locations and 122 parking spaces",{"label":832,"value":833},"In practice","900 new users in that same expansion",{"headline":835,"intro":836,"primaryCta":837,"secondaryCta":88},"The software is only done when the lock actually opens.","In many software projects, responsibility ends at an API or screen. At ParkMyBike, that is exactly where an important part of the problem begins. A cyclist reserves a spot in the app, then stands physically in front of a locker and expects exactly the right lock to open. For that, app, backend, permissions, reservation, network connection, controller and hardware all have to tell the same story.\n","See how the system works",{"title":839,"intro":840,"points":841},"One platform, several kinds of hardware","We do not try to force reality into one technical model. Different installations sometimes call for different forms of communication, as long as the product flow on top stays consistent.\n",[842,845,848],{"title":843,"text":844},"Cloud-connected controllers","Particle hardware can send events to the backend and receive commands from the platform. Incoming events are first queued durably before further processing takes place.\n",{"title":846,"text":847},"Bluetooth close to the user","With BLE, the phone is physically close to the lock. The app handles scanning and GATT communication, while the server decides which actions are allowed and which protocol step comes next.\n",{"title":849,"text":850},"External ecosystems","For systems such as iLOQ and other hardware partners, we integrate with their own access technology and infrastructure instead of reinventing it. ParkMyBike remains the product layer for the user, reservation and management.\n","parkmybike-software-en-hardware",{},{"eyebrow":92,"primary":854},{"key":94,"title":95,"text":855,"price":97,"result":856,"duration":99,"nextStep":857},"We build the software layer around existing systems and hardware, including backend, integrations, apps, protocols, monitoring and the error handling needed to make it work reliably in practice.\n","Production-ready integration between software and the real world","First we map systems, hardware, protocols and critical failure modes",5,"\u002Fcases\u002Fparkmybike-software-en-hardware",{"title":861,"intro":862,"points":863},"The integration does not stop at an API call","What makes ParkMyBike interesting is that errors do not stay abstract. If an integration is wrong, someone is standing in front of a locker that does not open. That is why reliability, retries, state management and observability are at the core of the product.\n",[864,867,870],{"title":865,"text":866},"Bluetooth with timeouts and retries","The mobile BLE flows have explicit timeouts for, among other things, scanning, connecting and commands. For recoverable errors, sessions can be rebuilt, while old callbacks must not disturb a new connection.\n",{"title":868,"text":869},"The physical action is part of the business flow","A successful open action can move a reservation from 'reserved' to 'rented' and start real-time updates. Hardware behaviour is therefore part of the product logic itself and not a separate technical integration.\n",{"title":871,"text":872},"Hardware is monitored operationally","IoT devices have, among others, online, offline and low-battery statuses. Hardware events are processed and actions are stored, so problems can be investigated and maintenance carried out in a targeted way.\n",{"buyerTriggerKeys":874,"useCaseKeys":875,"offerKeys":879,"solutionKey":880,"capabilityKeys":881},[118],[876,877,878],"ai-koppelen-aan-bestaande-systemen","tools-vervangen-door-maatwerkflow","ai-prototype-naar-productie",[94],"parkmybike",[128,283,730,132,882,883,884,885,732,135],"iot","bluetooth","embedded-software","realtime-systems",{"title":887,"items":888},"What does that deliver?",[889,892,895],{"title":890,"text":891},"The same software can work with different physical solutions","A provider does not always have to replace its entire hardware fleet to use ParkMyBike. By putting the hardware behind a clear integration layer, different lockers, controllers and access technologies can coexist within the same platform.\n",{"title":893,"text":894},"Hardware problems become manageable in software","Status, last-seen information, battery warnings, lock events and maintenance flows make visible what happens outdoors. This lets support determine much more precisely whether a problem lies in the account, reservation, app, network, controller or physical lock.\n",{"title":896,"text":897},"The system works at real locations","In 2025, ParkMyBike expanded with 23 locations and 122 new parking spaces, including in the United Kingdom and Belgium. In the same period, about 900 new users joined. So the technology does not just run in a lab, but in real bicycle parking infrastructure.\n",{"title":899,"description":900},"ParkMyBike: integrating software and hardware | 9to5 software","Case: how 9to5 software brings together mobile apps, backend, BLE, IoT, smart locks, payments and hardware integrations for ParkMyBike into one production-ready platform for smart bicycle parking.\n",{"title":902,"intro":903,"points":904},"Why is software + hardware hard?","In an ideal world, the app sends a command and a lock opens. In the real world there are Bluetooth permissions, poor connections, different controllers, batteries, external suppliers, timeouts, outdated status information and users literally standing in front of a closed door.\n",[905,908,911],{"title":906,"text":907},"Not every location uses the same hardware","ParkMyBike supports different types of locks, controllers and IoT setups. Some locks are controlled through a cloud connection, others directly via Bluetooth or an external access solution. The software has to absorb those differences without becoming a new product for every installation.\n",{"title":909,"text":910},"Digital status and physical reality can diverge","A backend thinking a command was sent successfully does not automatically mean a mechanical lock actually moved. That is why we record actions, hardware status, connections and lock events and handle errors explicitly throughout the chain.\n",{"title":912,"text":913},"Problems happen outdoors","Poor coverage, Bluetooth switched off, a flat battery, a wrong port configuration or a controller that does not respond: these are production problems you do not encounter in a tidy local development environment.\n","cases\u002Fparkmybike-software-en-hardware","ParkMyBike is a smart bicycle parking platform in which mobile apps, backend, dashboard, payments and physical locks form one product. A reservation only succeeds when the cyclist is actually standing in front of a locker and the right lock opens. So we did not only build the software, but also the integration layer to BLE controllers, IoT devices, external lock systems and hardware from different manufacturers.\n",{"title":168,"items":917},[918,921,924],{"title":919,"text":920},"Our software has to communicate with physical devices","An app or backend must not only process data, but also reliably operate a device, machine, sensor or access solution.\n",{"title":922,"text":923},"We have existing hardware that needs to be connected","The business logic must be able to work on top of suppliers' equipment without replacing the entire existing system.\n",{"title":925,"text":926},"A prototype works, but now it has to be reliable outdoors","The happy flow already works, but timeouts, poor connections, state differences, monitoring and maintenance make production much more complicated than the demo.\n",{"hero":928,"situation":929,"approach":930,"build":931,"proof":932,"teaser":933},"\u002Fmedia\u002Fproducts\u002Fparkmybike-hero.webm","\u002Fmedia\u002Fproducts\u002Fparkmybike-situation.webp","ls-system-connect","\u002Fmedia\u002Fscreenshots\u002Fparkmybike-build.webp","\u002Fmedia\u002Fscreenshots\u002Fparkmybike-controller.webp","\u002Fmedia\u002Fproducts\u002Fparkmybike-teaser.webm","tV5Ym6hwcucWR6m2dxoQbKtcWEs9rc-UrAo5RGNLokk",{"id":936,"title":937,"body":938,"collection":942,"cta":946,"description":27,"extension":54,"featured":952,"hero":956,"meta":961,"navigation":70,"path":962,"sampler":963,"seo":1023,"stem":1026,"teaserCta":1027,"visuals":1028,"__hash__":1030},"caseOverview_en\u002Fpages\u002Fcases.md","Cases",{"type":24,"value":939,"toc":940},[],{"title":27,"searchDepth":28,"depth":28,"links":941},[],{"eyebrow":943,"title":944,"intro":945},"All case studies","What we've built and solved.","Every case starts with the problem that needed solving. You'll see the systems, the technical decisions and the results.\n",{"title":947,"body":948,"primaryCta":949,"secondaryCta":950,"local":951},"Do you have something that really needs to work?","Explain what you're trying to achieve, what you've already built and where things get complicated. We'll quickly tell you whether and how we can help.\n","Talk through your idea","Need help with AI?","Delft · The Hague · Rotterdam · and remotely where it makes sense.",{"eyebrow":953,"title":954,"intro":955},"Featured","An AI workflow that needs to work in real support.","Robo Helma shows what it takes when AI has to do more than generate something impressive: deliver reliable output, using real knowledge, real systems and human oversight.\n",{"eyebrow":957,"headline":958,"lead":959,"primaryCta":960,"secondaryCta":88},"Case studies","This is what we've built.","From AI workflows and integrations to software + hardware and technical rescue. These are real systems, with the decisions and results behind them.\n","View the case studies",{},"\u002Fpages\u002Fcases",{"eyebrow":964,"title":965,"intro":966,"clusters":967,"note":1021,"cta":1022},"Sound familiar?","Are you facing something similar?","From a first AI question to a problem in production. Find the challenge closest to yours.\n",[968,986,1003],{"label":969,"title":970,"useCases":971},"Explore","First, we need to know what makes sense.",[972,975,978,980,983],{"useCaseKey":973,"label":974},"ai-idee-technisch-haalbaar","Is our AI idea technically feasible?",{"useCaseKey":976,"label":977},"is-ai-nodig","Does this problem actually need AI?",{"useCaseKey":434,"label":979},"Which processes can we automate?",{"useCaseKey":981,"label":982},"interne-ai-assistent-met-eigen-kennis","Can we build an assistant using our own knowledge?",{"useCaseKey":984,"label":985},"ai-betrouwbaar-genoeg","Which approach is reliable enough for real users?",{"label":987,"title":988,"useCases":989},"Build","We know what we want to build.",[990,992,994,997,1000],{"useCaseKey":120,"label":991},"We want to have an AI agent built.",{"useCaseKey":123,"label":993},"We want to add AI to existing software.",{"useCaseKey":995,"label":996},"documenten-en-mails-automatisch-verwerken","We want to process documents automatically.",{"useCaseKey":998,"label":999},"ai-prototype-laten-bouwen","We want a working AI prototype.",{"useCaseKey":1001,"label":1002},"product-goed-opzetten-voor-ai-development","We want to build it ourselves, but get the foundation right first.",{"label":1004,"title":1005,"useCases":1006},"Stuck","We've built something, but it doesn't work well enough.",[1007,1009,1012,1015,1018],{"useCaseKey":878,"label":1008},"Our AI prototype needs to go into production.",{"useCaseKey":1010,"label":1011},"ai-agent-niet-betrouwbaar","Our agent isn't reliable enough.",{"useCaseKey":1013,"label":1014},"gegenereerde-code-niet-meer-begrijpelijk","No one understands the generated code any more.",{"useCaseKey":1016,"label":1017},"ai-code-breekt-steeds","Every change breaks something else.",{"useCaseKey":1019,"label":1020},"vibe-code-project-vastgelopen","We've vibe-coded ourselves into a corner.","Don't see your situation here? That probably says more about this list than about your problem.\n","View all use cases",{"title":1024,"description":1025},"Case studies: AI agents and software | 9to5 software","What 9to5 software built: AI agents, AI workflows, integrations, software + hardware and technical rescue, with the decisions and results per case.\n","pages\u002Fcases","View case study",{"hero":1029},"\u002Fmedia\u002Fcases-overview\u002Fhero.webp","VpArknhRWqIpw2yFFmOEeM124IakICXwfGukBw7xgSY",1792049914255]