On this page
What RPA replacement is
RPA replacement is the migration of recorded automation, the kind that drives a user interface by clicking screen positions and reading pixels, onto interfaces designed for machines: APIs, file exports, database calls, and where nothing else exists, a narrowly scoped agent that works from structured selectors rather than coordinates. The goal is not smarter bots. The goal is fewer dependencies on things a vendor can change without telling you.
A recorded bot is a sequence of physical actions frozen in time. It knows that the confirm button was 40 pixels from the right edge on a 1920 pixel display in the theme that was current when somebody recorded it. Every one of those facts is a promise the vendor never made. When the promise breaks, the bot does not fail loudly, it does something else, which is worse.
Replacement work is therefore mostly archaeology and triage rather than new construction. Most of the value comes from deciding correctly which bots to move, in which order, and onto which interface. Migrating off brittle RPA bots covers the execution detail; this page covers the decisions.
- Robotic process automation
- Software that performs a task by operating an existing user interface the way a person would, through clicks, keystrokes and screen reads, rather than through a programmatic interface.
- Selector
- The instruction a bot uses to find an element on screen. Selectors range from a stable identifier the vendor promises to keep, down to an image match or a fixed coordinate.
- Bot estate
- The full population of bots an organisation runs, including the ones scheduled by a person's laptop task scheduler that no central team knows about.
- Attended automation
- A bot that requires a human session to be open and logged in while it runs. Attended bots inherit that person's permissions, their password changes and their holidays.
- Contract test
- A small test that calls an external system daily and asserts the shape of what comes back. It converts a silent vendor change into a failing build on a Tuesday morning.
- The worst stepA bot is only as stable as its deepest dependency, so triage ranks by worst step rather than by average or by volume.
- 8 to 16 weeksOur window for a first tranche of bots, with old and new running in parallel through the middle of it.
- Two clean runsMinimum parallel runs on identical inputs with matching output before a bot is switched off.
- Some bots stayWhere a legacy desktop application exposes nothing else, the honest answer is to keep the bot, isolate it, and monitor it properly.
- Service accountsRequested in week one, because approval usually takes longer than the engineering work that depends on it.
Who it is for, and who it is not for
This is for organisations with a bot estate that has become a maintenance job: bots that break several times a quarter, run under shared logins, and stop the business when they stop. It is a poor fit where the bots are stable, where the underlying vendor is about to be replaced anyway, or where the process behind the bot should simply be deleted.
| What the bot does today | What replaces it | Why that choice |
|---|---|---|
| Moves data between two systems that both expose APIs | A direct integration with contract tests | Cheapest, most stable, and no model is involved anywhere |
| Reads a PDF or a scan, then types the fields in | Extraction with confidence scores and a review queue, see document processing | The reading is the hard part; the typing was never the problem |
| Applies branching rules across three systems | An orchestrated workflow with the rules in code, see workflow automation | Deterministic branching belongs in code, where it can be tested |
| Reconciles two lists and flags differences | A scheduled job producing a diff and an exception queue | Pure comparison, no judgement, no model needed |
| Fills a web form from the contents of an email | Parse the email to a schema, then write through the API | A model earns its place on the parse only, never on the write |
| Navigates a vendor portal that has no API at all | A scoped browser agent using structured selectors, with a recorded contract test | Keep the fragile surface as narrow as one step, not the whole flow |
| Drives a legacy desktop application with no interface | Keep the bot, isolate it, wrap it in health checks and alerts | Sometimes the honest engineering answer is that RPA stays |
Every estate contains bots that produce a report nobody opens, or that exist because a person once asked for a daily email and then changed teams. Before triage, check who consumes each output. Deleting a bot is the cheapest migration available and it is usually the fastest win in the first fortnight.
The interface depth ladder
Every automated step depends on some surface of the target system, and those surfaces differ enormously in how often they change. Ranking each step by that surface is the single most useful thing we do in the first week, because it predicts breakage far better than complexity or age does.
The ChatGPTalker Interface Depth Ladder
Six rungs, from the surface a vendor contractually maintains down to the surface they change without noticing. Score each step, take the deepest number in the bot, and that is the bot's depth.
A published contract with versioning and a deprecation policy. It breaks only when someone announces that it will. This is where you want every step to end up, and where roughly half of them realistically can.
Scheduled files: CSV, fixed-width, SFTP drops. Slower and less elegant than an API, and considerably more stable than anything above it. Underrated, because it looks old fashioned in a slide and works for years without attention.
The endpoint the vendor's own front end calls, discovered from the network tab. It works, it returns clean JSON, and nobody promised you anything. Usable when wrapped in a daily contract test that tells you the morning the shape changes, and only then.
Test identifiers, form field names, ARIA roles. These survive restyling and usually survive minor releases. If a vendor gives you nothing else, ask whether they will commit to keeping the identifiers on the two screens you depend on. Sometimes they say yes.
The third cell of the fourth table inside the second panel. Any layout change breaks it, and layout changes ship silently in every release. A step at rung 4 is a maintenance subscription you did not know you bought.
Fixed screen positions, pixel comparisons, waiting on a spinner graphic. Breaks on a resolution change, a theme change, a browser update, a notification banner or a scrollbar. Everything at rung 5 migrates first, regardless of how much work it saves.
Two rules follow from the ladder and they run against instinct. Migrate by depth, not by volume, because the biggest bot in the estate is often the most stable one and moving it first spends the budget where breakage is lowest. And stop climbing when the return flattens: taking a bot from rung 5 to rung 3 removes most of the fragility, while dragging every remaining step to rung 0 usually costs more than the breakage it prevents.
What we actually build
Five components. The first is a document, and it is the one that decides whether the rest is worth building.
The estate triage
One record per bot, filled from the bot's own run log rather than from documentation: runs per month, breaks per quarter, median repair time, deepest rung, whether it blocks the business, what it is compensating for, and whether anyone still reads its output. The schema is below and it is yours whether or not you engage us further.
The integration layer
One module per target system, holding credentials, retry policy, rate limit handling and idempotency keys. This replaces the part of each bot that was actually just an API call performed with a mouse. Most steps in most estates land here, which is why the replacement usually contains less artificial intelligence than the sales conversation implied.
The scoped browser worker
For portals with no machine interface, a headless browser driver restricted to a named set of pages and actions, using element identifiers rather than coordinates, with an explicit allowed-action list. It cannot navigate outside its list. When a selector fails, it stops and raises rather than trying something adjacent, because a bot that improvises on a payment screen is a much worse outcome than a bot that halts.
The decision units
Where the old bot had a human-shaped judgement baked into brittle conditionals, a model call returns JSON against a schema with a confidence value. Document reading, message classification and fuzzy matching go here. Fixed branching does not, because rules that can be written in code should be written in code and tested there.
The runner and its evidence
Scheduling, state, retries and a full record of each run: inputs, actions attempted, responses, screenshots on failure, and the final write. Recorded bots are famously hard to debug after the fact because they leave almost nothing behind. See agent observability for what a run record needs to contain to be worth having.
How it works technically
The replacement is an orchestrated job with one adapter per surface, plus a narrow browser worker for the residue. Seven things happen on each run.
- The scheduler starts a run and writes a run record with a unique id before any external call happens.
- Inputs are resolved and hashed. If the same input hash completed within the idempotency window, the run exits rather than repeating a write.
- Machine-interface steps execute first, through the integration layer, on service-account credentials scoped to exactly the operations needed.
- Any step with no machine interface goes to the browser worker, which is handed a named page, an allowed-action list and a timeout, and nothing else.
- Model-backed steps return JSON validated against a schema, with confidence. Below threshold, the run pauses and queues for a person rather than proceeding.
- Writes go through adapters with idempotency keys, then a confirmation read compares what landed against what was intended. See idempotency in automation for why this matters more here than in most systems.
- The run closes with a status and a reason code, and the evidence record is sealed. Failures capture a screenshot and the last three actions attempted, which is what makes the difference between a five-minute diagnosis and an afternoon of guessing.
The triage record below is the artifact that drives all of it. Fill one in per bot, sort descending by score, and the migration order stops being a matter of opinion.
# bot_triage.yaml one record per bot in the estate
# Fill it from the bot's own run log, never from the process documentation.
# migrate_score = depth * 2 + breaks_per_quarter + (blocking ? 4 : 0)
# Work the estate in descending migrate_score. Anything under 6 stays where it is.
- id: BOT-014
name: "Invoice posting into the finance portal"
owner: ap_operations
runs_per_month: 3200
minutes_saved_per_run: 4
# deepest interface rung any single step depends on
# 0 api 1 bulk_export 2 undocumented_api 3 stable_dom_id 4 dom_path 5 coordinates
depth: 5
depth_evidence: "step 7 clicks a fixed x,y on the confirmation dialog"
breaks_per_quarter: 6 # counted from the run log, not from memory
minutes_to_repair_median: 45
blocking: true # does the business stop when this bot stops
attended: false # must a human be logged in for it to run
credentials:
shared_human_login: true
mfa_workaround: "code forwarded to a shared mailbox"
service_account_requested: false
machine_interface:
vendor_api: true
api_covers_steps: [1, 2, 3, 4, 6, 7]
steps_without_api: [5] # the residue is what decides the design
compensating_for: "the portal rejects bulk upload over 200 rows"
still_needed: true # is anyone reading the output of this bot
migrate_score: 20 # 5*2 + 6 + 4
decision: "migrate first, replace step 5 with a chunked file export"
The two fields people leave blank are the two that matter most. The compensating_for line asks what the bot is quietly working around, because a bot that exists to chunk uploads under a vendor row limit does not need migrating, it needs the vendor limit raised. And still_needed asks whether anybody consumes the output, which in every estate we have triaged removes at least a few records from the list entirely.
The migration process, stage by stage
- Estate discovery
Find every bot, including the ones scheduled on individual laptops that no central register knows about. Pull run logs and failure counts from the orchestrator rather than asking teams to estimate, because estimates of breakage are consistently optimistic in both directions.
- Triage and scoring
One record per bot, depth scored against the ladder, score computed, list sorted. Delete candidates get identified here and the first ones go the same week. The output is a ranked migration plan the business can argue with in specifics.
- Credential untangling
Request service accounts and scoped permissions for every target system. Start this immediately, because it routinely takes longer than the engineering. Nothing that depends on a shared human login and a forwarded verification code counts as finished.
- Interface archaeology
For each bot in the first tranche, find out what interfaces actually exist. Vendor documentation, the network tab, support tickets, the vendor's own integration partners. Half the steps we were told had no API turned out to have one that nobody in the building had asked about.
- Rebuild the first tranche
Three to six bots, highest score first. Machine-interface steps through adapters, residual steps through the scoped browser worker, judgement steps through evaluated model calls. Contract tests written at the same time as the adapter, not afterwards.
- Parallel running
Old bot and new system run on identical inputs, with outputs compared automatically rather than by eye. Only the old bot writes. Differences are triaged daily. Two clean runs with matching output is the minimum bar before anything is switched over.
- Switch and decommission
New system writes, old bot is disabled rather than deleted, and stays disabled for a month in case of a rollback. Then it is deleted properly, including its schedule, its credentials and its licence, because an estate that only ever grows was the original problem.
- Next tranche
Re-score the estate with what the first tranche taught you. Depth estimates get sharper, repair-time numbers get real, and several bots that looked marginal move up or drop off. The plan is meant to change.
Parallel running with automated output comparison is the stage teams try to shorten. It is the only stage that produces evidence, and the evidence is what lets you switch off a bot that somebody senior is frightened of switching off.
What you get at handover
The pack is yours, in your repositories, on your accounts. The triage document outlives the engagement and is the thing most clients tell us they reuse.
Disabling is reversible, deleting is not, and the month between them costs almost nothing. It also settles the argument with whoever was nervous, because by week four the rollback has not been needed and the evidence is in the run log rather than in anybody's confidence.
Where these projects go wrong
Six failure patterns, seen repeatedly, in rough order of how much time they cost.
The estate was migrated in volume order
Biggest bot first sounds like sound prioritisation and usually is not. High-volume bots tend to sit on interfaces the vendor treats as important, which makes them comparatively stable. The bot that ruins your quarter is a mid-volume one at rung 5 that breaks every third week. Rank by depth and breakage, then check volume as a tiebreak.
The bot was replaced and the process was kept
Many bots exist to work around something: a row limit, a missing field, a report that arrives in the wrong format. Migrating the bot faithfully preserves that workaround forever, in cleaner code, which makes it harder to notice. Ask what each bot is compensating for. Some of the answers are one email to a vendor away from disappearing.
Nobody found the undocumented steps
Recorded bots accumulate steps nobody remembers adding: a click on an empty area to dismiss a tooltip, a wait that exists because the page used to be slow, a dropdown selected purely to force a refresh. These never appear in the process documentation. Reconstruct from the recording and the run log, and expect the rebuild to surface at least one step whose purpose nobody can explain.
Credentials were never untangled
The estate runs on a shared human login with verification codes forwarded to a mailbox three people can read. Replacement needs service accounts with scoped permissions, and getting those approved crosses security, the vendor and procurement. Teams start the request in week six and lose a month. Start it in week one, before the first line of code.
A model was put where code belonged
The appealing story is an agent that looks at the screen and works it out. For a fixed sequence of steps, that is slower, more expensive and less predictable than an integration, and it fails in ways that are harder to explain to an auditor. Models belong where the input is unstructured or the judgement is genuinely fuzzy. Everywhere else, write the integration.
Both systems were left writing
Parallel running is correct. Parallel writing is not. If the old bot and the new system both write, state diverges within days and the comparison you were running becomes worthless because you can no longer tell which system caused which record. One writer at a time, always, with the other one reading and comparing.
When a selector fails, the tempting behaviour is to search nearby, retry a similar element, or let a model decide what to click. On a screen that can move money or change a customer record, that is the worst available option. The replacement stops, raises, and keeps the evidence. Bots that improvise produce incidents nobody can reconstruct afterwards.
What it costs to run once live
Start by costing what you already run, because most estates have never had that number calculated. The visible line is licences. The invisible ones are repair engineering, the delay while a broken bot waits for attention, and the work that piles up behind a blocking bot. The estimator uses your own figures from the triage.
Fill this from your triage records. Break counts come from the run log. This estimates the status quo, which is the number a migration business case is measured against.
With the default row, forty bots breaking twice a quarter is 320 breaks a year. At 45 minutes and 60 an hour, repair is 14,400. Stalled work at three hours and 35 an hour adds 33,600. Licences add 36,000. The stalled-work line is larger than the repair line and it is the one that never appears in any budget, because it is absorbed by people waiting rather than invoiced. Replace every number with yours.
| Cost line after replacement | What drives it | How it behaves over time |
|---|---|---|
| Compute and hosting | Job runner, browser workers, queue, database | Flat, and usually smaller than the licences it replaced |
| Model tokens | Only the steps that genuinely need judgement, priced per call | Small when the migration kept models off deterministic steps |
| Contract test maintenance | Number of external surfaces you depend on | Falls as steps climb the ladder toward documented interfaces |
| Break fixing | Count of steps still at rungs 4 and 5 | Falls sharply after the first tranche, then plateaus at the residue |
| Vendor change response | How often your targets ship interface changes | Unchanged by you, but detected in a day rather than discovered by a user |
| Licences | Bots still running on the old platform | Only falls when bots are decommissioned properly, including the licence |
How to tell whether you need this
Score your estate against the signals below rather than against a general feeling that the bots are annoying. Most estates split, with a minority of bots carrying nearly all the pain.
Every honest migration leaves a handful of steps with no machine interface, usually inside a legacy desktop application whose vendor has no incentive to help. Keeping a bot there is a legitimate engineering decision. What is not legitimate is leaving it undocumented, unmonitored and running under somebody's personal login while everyone pretends the migration finished.
How to start
Start with the triage, not with a bot. Two weeks, using your own run logs, and the output is a scored list of every bot with a recommendation against each: migrate now, migrate later, keep and monitor, or delete. Several clients have taken that document and executed it internally, which is a good outcome and one we will point at when it is the right one.
If we do build, the first tranche is three to six bots chosen by score rather than by who complained loudest, with parallel running before any switch. Expect eight to sixteen weeks including the credential work, and expect the credential work to be the part that moves the date.
ChatGPTalker, "RPA replacement, from screen coordinates to intent", chatgptalker.com/services/rpa-replacement/