Workflow Automation vs RPA: Check the API Before You Buy a Bot
Workflow automation vs RPA: how to check if a vendor's API supports your exact operation, what bots need to run, what they cost and how to spot silent failures.
Luka Abramovic16 min read

Workflow automation vs RPA comes down to one question: does the vendor's API support your exact operation, on your plan, for the identity your automation will run as? If yes, automate through the API: the vendor maintains that contract and returns errors you can route. If no, RPA drives the screen like a person, which needs a signed-in Windows session, a user account and upkeep whenever the screen changes. Check in writing first, because "we have an API" hides gaps. In Microsoft Dynamics 365 Business Central, creating a purchase invoice through the API and posting it are separate operations.
The actual difference, and where each fits
Workflow automation works at the data layer. It reads records from one system, or is notified when they change, and tells another system to act, through a published interface the vendor documents and versions. RPA, robotic process automation, works at the presentation layer: it opens the application, finds the field a person would click and types what a person would type. Three practical differences follow.
- Identity. An API integration can usually run as an application identity with scoped permissions. Business Central lets you register an app in Microsoft Entra ID and assign it permission sets, and refuses to give an app the all-powerful SUPER set. A screen bot needs a Windows user account that signs in, because that is the only way to get a desktop to click on.
- Failure. A failed API call returns an error: a validation message, a 400 for a bad request, a 429 for exceeding a rate limit. A failed bot either can't find an element and stops, or finds the wrong one and carries on.
- Change. Vendors version their APIs and announce retirements. Nobody versions the position of a button.
Use workflow automation whenever the operations exist. RPA is the right answer when there is no programmatic interface at all (common with older desktop software and some supplier portals), when the interface leaves out your operation or puts it on a tier you won't buy, or when the job is temporary, such as a bridge until a replacement goes live. Mixing is normal: APIs wherever they exist, and a bot confined to the one screen that has none.
How to check whether an API supports your exact operation
This step decides the method, so do it before any tool demo. Budget half a day. The process owner can do steps 1 and 2. Steps 3 to 6 need someone comfortable in a developer portal.
- Write the operation as a verb, a record and an end state. Not "invoices", but "create a vendor bill with several lines, coded to a GL account and a job, and post it so it appears in the next payment run." The end state is where gaps hide.
- Find the endpoint in the API reference. Search for the record name, then check the methods (POST creates, PATCH updates, GET reads, DELETE removes) and any separate actions. In Business Central's API v2.0,
POST /companies({id})/purchaseInvoicescreates a purchase invoice, and posting it is a separate bound action,POST /companies({id})/purchaseInvoices({id})/Microsoft.NAV.post(purchaseInvoice resource type). An API that can create but not post, approve, submit or void leaves the last step on a screen. - Check every field you need to write. The resource page lists each property, and some are marked non-editable. A custom field or approval status that isn't listed can't be set through that endpoint.
- Check the permissions, often in two layers. Business Central needs both: the Entra app registration must be granted
API.ReadWrite.All, and the app must also be added on the Microsoft Entra Applications page inside Business Central with permission sets for the objects it touches (service-to-service setup). Missing either layer produces an authorization error that looks as if the API can't do the operation. - Check which plan includes API access. Find the pricing-page row for API access, integrations or developer features. If it's ambiguous, it goes in the email below.
- Test in a sandbox, then read the record back. Create one record through the API, open it on the normal screen and check it looks like one a person entered: same defaults, same validation, same reports. Note where the sandbox differs from production. Business Central sandboxes read from the primary database, while in production almost all API GET requests read from a read-only replica that can lag slightly behind writes (read scale-out). A read-after-write check that passes in the sandbox can fail intermittently in production unless it sends the
Data-Access-Intent: ReadWriteheader.
Then ask the vendor in writing. Sales calls produce "yes, we have an API". Written answers to specific questions are what you can hold a vendor to. The person who owns the vendor relationship should send this, copying whoever will build the automation:
Subject: API support for [operation] on our [plan name] plan
Hello [name],
We want to automate the following through your API rather than the user interface:
[Operation, e.g. "create a vendor bill with multiple lines, coded to a GL account
and a job, and post it so it appears in the payment run"]
Could you answer these in writing?
1. Which endpoint(s) perform this operation? Please link the API reference page.
2. Does the endpoint complete the operation, or create a draft that needs another
call or a user action (post, approve, submit) to finish?
3. Can each of these fields be set through the API: [list, including custom fields]?
4. Which scopes or permissions does the integration identity need? Can it run as an
application or service identity rather than a named user's login?
5. Is API access, and this endpoint, included in our current plan? If not, which
plan or add-on includes it, and are there per-call or per-record charges?
6. What rate limits apply to this endpoint? Is there a bulk or batch option?
7. Does the API enforce the same validation, approval workflows and audit trail as
the screen? Are records created through the API marked as such?
8. Do you provide a sandbox on the same API version as production? How does it
differ (data, limits, features)?
9. How much notice do you give before changing or retiring an API version?
10. If the API can't do this, do you support a scheduled file import (CSV or SFTP)
for it, and does the import apply the same rules?
Thank you,
[name, role, customer account number]
Read the answers to questions 2, 3 and 5 first. A "no" to any of them is the gap that pushes a process toward a bot.
Middle options people forget
Between an API integration and a bot sit interfaces that already exist but nobody thinks of as interfaces.
- The vendor's scheduled import. Many systems accept a CSV or fixed-format file on a schedule, often collected from an SFTP folder. It is a documented contract, just batched, and it suits nightly volumes. Ask for the file specification, whether a failing row is rejected alone or takes the whole file with it, and where the rejection report goes. Check every file with a row count and an amount total, the technique covered in our guide to legacy system challenges.
- Email into the system. Some products create tickets, bills or expense items from email sent to a dedicated address. Where they don't, a parsing step can turn a structured email or attachment into an API call or an import row. Use a shared mailbox, not a person's inbox.
- A read-only copy for the reads. Many "we need a bot" requests are really reads for a report or a check. A reporting replica, an OData feed or a scheduled export serves them without touching the live screen.
- The vendor's own rules. Approval workflows, assignment rules, recurring documents and bank rules are built into many products. Search the vendor's help center for the verb in your process before building anything. Rules the vendor maintains are the cheapest automation you will own.
How RPA finds things on screen, and why bots break
A bot finds each button and field with a selector: a path through the application's tree of interface elements, with attributes identifying each step. This example is from Microsoft's Power Automate selector guide:
:desktop > window[Name="Notes.txt - Notepad"][Process="Notepad"]
In plain English: on the desktop, find a window whose Name is "Notes.txt - Notepad" and whose process is Notepad. UiPath stores the same idea as an XML fragment of the element's attributes and its parents'. Either way, the bot works only while those values stay the same, and ordinary events change them:
- A title that contains data. The selector above matches one file's window, as "Invoice 10432 - Supplier Portal" matches one invoice. Match with Contains, Starts with or a regular expression instead of Equal to, or insert a variable. Power Automate supports all of these.
- Generated IDs. Some web applications build element IDs from the element's place in the page structure, so a vendor adding a panel above your field renames it, and the selector breaks on the next release.
- Position. An index attribute, "the third button in this panel", shifts when a button is added, or hidden for one user role.
- Images, resolution and scaling. Without a usable selector, bots match a captured image. Microsoft says captured images depend on the source machine's resolution and DPI scaling, and matching needs both to be the same on every machine that runs the flow (image recognition and screen resolution). Unattended runs make it worse: their remote session can default to a lower resolution than the flow was built on, hiding or moving elements. Pin it per flow with Display resolution for unattended runs, or per machine with registry values for width, height and scale (set screen resolution on unattended mode).
Two features change how a break shows up. Power Automate lets each element carry several selectors plus one image as a last fallback, so a run can succeed on its third-choice match. And as of September 2026, its self-healing feature (in preview) uses AI models to pick "the most likely intended element" when a selector fails, then continues the run (self-healing). Both trade a loud failure for a guess, so with either switched on the read-back check below matters more, not less.
What an unattended bot needs to run
An attended bot runs on someone's PC while they are signed in. An unattended bot runs on its own, and it still needs a real, interactive Windows desktop to click on. Microsoft sets out the consequences in Run unattended desktop flows:
- Nobody may be signed in. Power Automate signs in with the bot's credentials, creates a remote desktop (RDP) session, runs the flow and signs out. On Windows 10 and 11 an unattended run can't start if any user session is present, even a locked one. "Leave it logged in and lock the screen" is exactly wrong.
- The bot account needs remote desktop rights, usually membership of the machine's Remote Desktop Users group. Unattended flows can't run elevated, and someone signing in during a run can make it fail.
- Attended runs need the opposite: the connection user's Windows session already open. If that PC restarts overnight for updates, the attended bot has nowhere to run.
- Watching can break it. Minimize a remote desktop window onto a bot machine and the session stops drawing its screen, so UI actions fail. UiPath documents a registry value on the computer you connect from,
RemoteDesktop_SuppressWhenMinimizedset to 2, that keeps it drawing (minimized RDP window). Microsoft separately warns that tools which inject libraries, such as TeamViewer or Quick Assist, can freeze Power Automate for desktop (remote desktop applications). - One bot, one run at a time. A machine hosts as many unattended bots as it can open Windows sessions at once. A Windows 10 or 11 desktop normally hosts one, so two unattended processes on the same PC queue behind each other.
The account problem: MFA and service accounts
A bot can't approve a push notification or read a code from a phone, so the easy fixes are to exclude its account from multifactor authentication, set its password never to expire, or run it on a person's login. Each creates an account with broad access that no human watches. Microsoft advises against using user accounts as service accounts at all, preferring application identities with Conditional Access (governing service accounts). An API integration can follow that advice. A screen bot can't, because it needs a Windows sign-in. The safer patterns when you do run one:
- One dedicated account per bot or process, named as a bot, never used by a person, with only the application roles that process needs. Its audit trail then means something.
- Credentials in a vault, not in the flow. Power Automate's desktop flow connections can take credentials from Azure Key Vault, or CyberArk (in preview as of September 2026), so rotation happens in one place.
- A second factor that doesn't need a phone. Microsoft Entra certificate-based authentication can satisfy MFA requirements, and Power Automate supports it for unattended runs after one-off admin consent steps on the unattended page linked above.
- Conditional Access instead of a blanket exclusion. If the account must skip interactive MFA, allow it to sign in only from the bot machine's network location or device, block it everywhere else, and alert on any new sign-in location (Conditional Access overview).
- Know which connections are attended only. Power Automate's "connect with sign-in" avoids storing a password but works only for attended runs. Unattended runs with it fail (desktop flow connections).
The costs RPA carries that are easy to miss
Licensing, as of September 2026
Power Automate is a useful example because it ships with Windows. From Microsoft's license types and licensing FAQ:
- Free. Windows 11 users can build and run desktop flows attended, for personal productivity, and Windows 10 users have usage rights through a download. A work or school account on the Free license can author and run desktop flows locally, attended, with standard connectors and no sharing.
- Power Automate Premium (per user) adds one attended bot, triggering desktop flows from cloud flows, premium connectors and central monitoring. No unattended runs.
- Power Automate Process (formerly per flow) is what unattended runs need. Each license, allocated to a machine, is one unattended bot running one desktop flow at a time, so three flows in parallel take three licenses. The user whose connection runs the flow still needs Premium, and a Premium user must have registered the machine.
- Power Automate Hosted Process adds a Microsoft-hosted machine, so you don't maintain the bot's PC.
"Power Automate is free with Windows" is true for a person automating their own desk and false for a bot that runs overnight. Price Process licenses for your agreement before comparing quotes.
The other costs
A machine that stays on, patched outside run windows, with its resolution pinned. Upkeep on someone else's release calendar: every vendor interface release can break the bot, so name who fixes it and check they have capacity in month-end week. A process frozen as it is, including steps that exist only because of a tool limitation. And throughput, which is worth working through with your own numbers.
A worked example, with illustrative inputs. A bot enters 1,500 supplier invoices a month at 60 seconds each, including screen waits: 1,500 × 60 ÷ 3,600 = 25 bot-hours, which one unattended bot covers overnight. Add a close rule that everything received by the 31st is entered by the 2nd, with 600 invoices arriving in the last two days: 600 × 60 ÷ 3,600 = 10 hours, inside two eight-hour nights. If the supplier portal slows to 150 seconds per invoice at month end, those 600 need 25 hours, more than two nights hold, and you need a second Process license and machine for peak days alone. Through Business Central's API, the same volume is bounded by a rate limit that as of September 2026 allows 6,000 OData requests per user in a five-minute sliding window (operational limits). At five requests per invoice, 600 invoices is 3,000 requests.
Catching silent failures
A bot that clicks the wrong element can report success. So can one whose fallback selector or self-healing matched something close enough. The defense is to check the target system after every run, independently of what the bot says it did. The bot's builder implements this, and the process owner receives the alerts:
After each run (scheduled a few minutes after the bot finishes):
expected = rows in the source that should have been processed this run
(e.g. approved invoices in the export the bot worked from)
processed = rows the bot logged as done
present = records found in the target system by their reference
(query the API or a report for the invoice numbers in this run)
if processed < expected: alert "bot skipped (expected - processed) records"
if present < processed: alert "bot reported (processed - present) records it didn't create"
if total amount of present records in target != total of the same records in source:
alert "values differ: compare a sample field by field"
Then pick 5 records at random and compare every field the bot typed.
The first check catches a bot that stopped early. The second catches the confident wrong click, where the bot believes it saved and nothing was saved. The amount total catches a value typed into the wrong field, which counts can't see. Read back through the API or a report even when the bot writes through the screen: read access is often available where write access isn't. If the target reads from a replica, as Business Central's production API does, wait a few minutes or read with read-write intent.
Before re-running a failed bot, find out what it already created, or the re-run enters the first half of the batch again. API integrations solve the same problem with idempotent postings, covered in our ERP integration best practices. Where alerts go, and what each exception record must contain, is the exception queue design in our guide to connecting business systems.
Side by side
| Dimension | Workflow automation | RPA |
|---|---|---|
| Works through | A published API, file import or webhook | The application's screen, as a user |
| Depends on | A contract the vendor versions and announces | Selectors, window titles, resolution and scaling |
| Runs as | An application identity with scoped permissions, where supported | A Windows user account that signs in interactively |
| Runs on | The vendor's servers or an integration platform | A Windows machine with nobody signed in (unattended) |
| Failure mode | Error code and message | Element not found, or the wrong element and no error |
| Vendor interface release | Unaffected | Possible break |
| Parallel volume | Up to the vendor's rate limit | One run per bot at a time |
| Time to first result | Slower: access, permissions, sandbox | Faster: a login and a recorder |
| Effect on the process | Rules get stated | Current steps preserved |
| Ongoing cost | Low once stable | Continuing upkeep tied to vendor releases |
How to decide in one afternoon
Work through these in order and stop at the first clear answer.
- First hour: write the operation and find the endpoint. Verb, record and end state, then the API reference. No API reference at all? Skip to step 4.
- Second hour: check fields, permissions and plan, and send the vendor email above.
- If the answers are yes, use workflow automation. What remains is ownership, exceptions and recovery, not method.
- If not, check the middle options: a scheduled import, email into the system, a read-only copy for reads, the vendor's own rules.
- If only the screen is left, ask whether the gap is temporary. A system due for replacement within a year makes a bot a sensible bridge. Write the retirement date into its documentation.
- If it is permanent, look at the screen's history. A desktop application unchanged for years is a safer target than a cloud app that releases monthly. Ask the vendor for its release cadence.
- Before approving a bot, name four things: the machine and who patches it, the dedicated account and where its credentials live, who fixes it after a vendor release, and the read-back check that proves each run worked.
If you are weighing this for a specific process, bring the process written as verbs and records, the systems it touches, your plan names and any answers vendors have already given. We would start by checking each system's API reference against those exact operations, because that often settles the question before anyone discusses tools. That is where our business automation and integration work begins.