Service 05

RPA replacement, from screen coordinates to intent

Recorded bots break every time a vendor moves a button. This is how we migrate a bot estate onto interfaces built for machines, and how to decide which bots deserve migrating at all.

On this page
  1. What RPA replacement is
  2. Who it is for, and who it is not for
  3. The interface depth ladder
  4. What we actually build
  5. How it works technically
  6. The migration process, stage by stage
  7. What you get at handover
  8. Where these projects go wrong
  9. What it costs to run once live
  10. How to tell whether you need this
  11. How to start

What RPA replacement is

The short answer

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.

Terms used precisely on this page
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 todayWhat replaces itWhy that choice
Moves data between two systems that both expose APIsA direct integration with contract testsCheapest, most stable, and no model is involved anywhere
Reads a PDF or a scan, then types the fields inExtraction with confidence scores and a review queue, see document processingThe reading is the hard part; the typing was never the problem
Applies branching rules across three systemsAn orchestrated workflow with the rules in code, see workflow automationDeterministic branching belongs in code, where it can be tested
Reconciles two lists and flags differencesA scheduled job producing a diff and an exception queuePure comparison, no judgement, no model needed
Fills a web form from the contents of an emailParse the email to a schema, then write through the APIA model earns its place on the parse only, never on the write
Navigates a vendor portal that has no API at allA scoped browser agent using structured selectors, with a recorded contract testKeep the fragile surface as narrow as one step, not the whole flow
Drives a legacy desktop application with no interfaceKeep the bot, isolate it, wrap it in health checks and alertsSometimes the honest engineering answer is that RPA stays
The replacement decision, made per bot rather than per estate.
Some bots should be deleted, not migrated

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.

Framework

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.

01
Rung 0, documented API or database

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.

02
Rung 1, bulk export and import

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.

03
Rung 2, undocumented internal API

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.

04
Rung 3, stable element identifiers

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.

05
Rung 4, structural paths

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.

06
Rung 5, coordinates and image matching

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.

  1. The scheduler starts a run and writes a run record with a unique id before any external call happens.
  2. Inputs are resolved and hashed. If the same input hash completed within the idempotency window, the run exits rather than repeating a write.
  3. Machine-interface steps execute first, through the integration layer, on service-account credentials scoped to exactly the operations needed.
  4. 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.
  5. Model-backed steps return JSON validated against a schema, with confidence. Below threshold, the run pauses and queues for a person rather than proceeding.
  6. 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.
  7. 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.yamlyaml
# 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

  1. Estate discoveryWeek 1

    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.

  2. Triage and scoringWeek 1 to 2

    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.

  3. Credential untanglingWeek 2, runs in the background

    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.

  4. Interface archaeologyWeek 2 to 4

    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.

  5. Rebuild the first trancheWeek 4 to 9

    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.

  6. Parallel runningWeek 8 to 12

    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.

  7. Switch and decommissionWeek 10 to 14

    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.

  8. Next trancheWeek 12 onward

    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.

The handover pack
0 of 10 done
Keep the disabled bot for a month

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.

A halting bot is better than an improvising one

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.

What your current bot estate costs each year

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.

0Repair engineering per year
0Cost of stalled work per year
0Licences per year
0Estate cost per year

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 replacementWhat drives itHow it behaves over time
Compute and hostingJob runner, browser workers, queue, databaseFlat, and usually smaller than the licences it replaced
Model tokensOnly the steps that genuinely need judgement, priced per callSmall when the migration kept models off deterministic steps
Contract test maintenanceNumber of external surfaces you depend onFalls as steps climb the ladder toward documented interfaces
Break fixingCount of steps still at rungs 4 and 5Falls sharply after the first tranche, then plateaus at the residue
Vendor change responseHow often your targets ship interface changesUnchanged by you, but detected in a day rather than discovered by a user
LicencesBots still running on the old platformOnly 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.

Keep the botReplace it
Deepest rung0 to 2, on interfaces the vendor maintains4 or 5, coordinates or structural paths
Breaks per quarterRarely, and never in a surprising waySeveral times, in a different place each time
Blast radiusFailure is visible and nothing downstream depends on itThe business stops or a queue silently builds
CredentialsRuns on a service account with scoped permissionsRuns as a named person, with a verification code workaround
Target system futureBeing replaced within the year anywayStable and staying for the foreseeable
DiagnosisA failure can be explained from the logsFailures are reconstructed by rerunning and watching
OutputSomebody depends on it every dayNobody has read it in months, so delete rather than migrate
The residue is real and it is fine

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.

Cite this

ChatGPTalker, "RPA replacement, from screen coordinates to intent", chatgptalker.com/services/rpa-replacement/

Questions we get asked

Is RPA dead now that AI agents exist?
No, and anybody saying so is selling something. RPA remains the only option where a system exposes no machine interface at all, which is common in legacy desktop software. What has changed is that far fewer steps genuinely need it, so the honest position is a much smaller bot estate rather than none.
Can an AI agent just use the existing bot's screens instead?
It can, and for a fixed sequence of steps it is a poor trade. An agent driving a screen is slower, costs more per run, and fails less predictably than a direct integration. Use agents where the input is unstructured or the branching is genuinely fuzzy, and write integrations everywhere else.
How do you decide which bots to migrate first?
By interface depth and breakage rather than by volume. Each bot is scored on the deepest rung any of its steps depends on, its breaks per quarter from the run log, and whether it blocks the business. High-volume bots are often the stable ones, so migrating them first spends budget where the pain is lowest.
What happens to our existing RPA licences?
They only stop costing money when bots are decommissioned properly, which includes cancelling the licence and removing the schedule. We keep a decommission log for exactly this reason. Estates frequently carry licences for bots that were disabled years ago and never removed from the platform.
How long does a bot estate migration take?
Eight to sixteen weeks for a first tranche of three to six bots, including triage, credential work and parallel running. Later tranches are faster because the integration layer, the runner and the evidence store already exist. The credential and permission approvals are usually what determines the date, not the engineering.
Will the replacement break when the vendor changes something?
Less often, and you will find out differently. Steps on documented interfaces break only on announced deprecations. Steps still on selectors are covered by daily contract tests, so a vendor change surfaces as a failing test in the morning rather than as a user noticing that yesterday's records are missing.
Do we need to replace the whole estate at once?
No, and we would advise against it. Work in tranches of three to six bots, re-scoring the estate after each one, because the first tranche materially improves your depth estimates and repair-time figures. Some bots will move up the list, some will drop off, and a few will turn out to be deletable.

Tell us what is eating the hours.

Send the process, the volume and the tools it touches. You get a scoped plan with a build shape and a timeline, not a brochure.

Start a project