How to turn a no-API portal into a REST endpoint
Public portals that will never ship a developer API are usually scraped, badly, by code coupled to their HTML. There is a more durable method: recover the wire format the portal's own front end already speaks, and call that instead. This guide sets out the method AutomationAtlas used against a Polish court-auction portal and a US county parcel portal, the five checks worth running before trusting what comes back, and what changes when the target is old enough to have no front end worth reading.
The Bottom Line: Reverse-engineering the wire format is the more durable bet against a redesign that breaks a DOM scraper, because the JSON contract behind a front end tends to change less often than the markup in front of it. The method is only as good as its verification, so budget as much time for checking the undemonstrated paths as for building the demonstrated one. On a target old enough to have no front end worth reading there is no wire format to recover, and the method degrades to a careful parse of rendered markup, which is the case to verify hardest.
A portal with no public API is not a portal with no API. Almost every modern public listing site is a JavaScript application talking to a JSON backend, and that backend is a real interface with real parameters, real enums and real pagination. It is simply undocumented and unsupported.
The usual response is a DOM scraper: fetch the rendered page, parse the markup, extract the fields. That works until the next redesign, which is why scrapers built this way have a maintenance cost measured in redesigns rather than in years. The alternative is to find the JSON call the page itself makes, and make that call directly. This guide describes how to do that deliberately, using a worked example, and what to verify before anyone relies on the result. The worked examples come from an AutomationAtlas field test of Supergood, a platform that generates REST endpoints from a recorded browser session.
Check the ground rules before writing any code
This step comes first because it is the only one that cannot be fixed later. Read the target's robots.txt and its terms of service, and record what they say at the time of reading.
In the worked example, the target was a Polish government body's public listing of court-ordered auctions. Its robots.txt allows the public search and listing paths and disallows only logged-in account routes, which is what made the public search fair ground and the account area out of bounds.
Two things follow. A tool that generates the endpoint for you removes essentially all of the technical friction between finding data and polling it on a schedule, and none of the legal judgement. And a rule that was permissive when you read it can change, so the check belongs in the maintenance cycle rather than in the first afternoon.
Read the bundle, not the page
The rendered page is the worst place to look for a data model, because it shows only what the current view needed. The compiled JavaScript bundle carries the whole contract, including the parts no view has ever shown you.
In practice there are three places worth opening, in this order. The network tab comes first, because the request bodies from a single real search tell you which endpoint to aim at and what its parameters are called, which is what makes everything after it searchable. The server-rendered page state, which frameworks such as Nuxt and Next embed in the HTML as a JSON blob, comes second and shows the shape of the data the page was hydrated with. The compiled bundle files come last and are where the payoff is, because a validated form control has to know every value it accepts, so the bundle carries the whole enum where the network tab showed you one member of it.
Against the auction portal this produced the entire taxonomy from two recorded searches: two main categories, eight real-estate and seventeen movable sub-category codes with their Polish labels, and sixteen provinces plus an all-provinces sentinel. Both recorded searches had been real-estate searches in a single province. Everything else came out of the bundle.
When there is no bundle to read
The step above assumes a front end that carries its own data model. A classic server-rendered application does not. There is no XHR traffic to record, no hydration blob in the HTML and no enum table in a bundle, because the server decided everything before the page was sent. What is left is rendered markup, which puts you back in the position this guide opened by criticising.
That case is worth planning for rather than discovering. AutomationAtlas tested it against a public parcel-records portal that one vendor licenses to local government, and whose own site listed more than a thousand US municipalities on the same template in September 2026. The stack is ASP.NET WebForms, with hidden viewstate and event-validation fields on every page and full-page postbacks throughout.
Three things change. The unit of work becomes the navigation rather than the call, so a recorder built around XHR and fetch traffic will capture the form POSTs and miss the document GETs between them. Check what a recording actually holds before trusting anything derived from it. The hidden state fields are part of the contract rather than noise, since a postback that omits them is rejected, so they have to be read from the preceding page rather than hardcoded. And the parse becomes the fragile part, failing in ways a JSON contract cannot.
In the worked example, a table header authored with a line break inside it, Gross on one line and Area on the next, collapsed under naive text extraction into a single token. That broke the header-to-field mapping and silently dropped two area fields from the output. That is the shape to expect on this class of target: not an error, but a field that quietly stops being populated. It argues for one check beyond the five above, which is to assert on the presence and the split of every field parsed out of markup, against a record whose values you have read off the live page yourself.
Prove the parts nobody demonstrated
An integration generalised from two examples is a hypothesis until an undemonstrated path returns real data. Test the parameter combination that was never recorded, not the one that was.
| Check | What it proves | Worked example |
|---|---|---|
| Re-run the demonstrated query live | The translation is faithful, not merely replayable | Houses in one province: 200 OK, 33 matches, 20 rows, identical to the live site |
| Call an undemonstrated parameter | The schema came from the source, not from the samples | Computers, no province filter: 200 OK, 64 matches nationwide |
| Call from a fresh sandbox | The result does not depend on recording-session state | Both calls made outside the recording browser, clean on the first attempt |
| Recompute a derived number by hand | The aggregation is arithmetic, not narration | Both percentage differences, recomputed by hand from the tool's own reported averages, matched the percentages it reported to two decimal places |
| Read the sample size, not just the answer | A partial sample is not a wrong answer, but it is a different one | 33 of 33 listings on one side, 40 of 82 on the other, correctly flagged |
The second row is the one that matters most. A generated integration that only ever works on the exact parameters you demonstrated has memorised your examples rather than recovered the interface.
Expect the second capability to be harder than the first
Translating one call into one endpoint is the easy case. The work gets structurally harder the moment a second capability has to orchestrate the first, because that is where a generated integration meets the constraints of the platform running it.
In the worked example the second capability walked the existing search endpoint's pagination twice, once per region, aggregated price statistics for each, and computed the difference. Three things surfaced. The platform turned out to run every code block an integration carries but return only the last one's output, with no merge and no fallback, which is not in any visible documentation and had to be established by experiment. A debug probe left at the top of a block made the entire implementation unreachable dead code, caught by the platform's automated review rather than by AutomationAtlas. And the build notes claimed a code path had never run against live data for a reason that was demonstrably wrong, while the claim itself was still true.
The general lesson is that undocumented platform behaviour is discoverable by controlled experiment, and worth discovering before it costs a silent regression. Design the experiment to cost nothing: run it in whatever dry-run or replay mode the platform already offers, and make each throwaway call test exactly one proposition. Three such calls established the block-ordering rule in the worked example, in the order that both blocks run, that only the last one's output ships, and that a shared context object survives between them. Then absorb the constraint into a parameter rather than working around it. The fix here was an operation field defaulting to the behaviour existing callers already had, gating both blocks so exactly one does real work per call.
What to check before anyone relies on it
Treat a generated integration as code you now own, because you do.
Read the generated code rather than only its summary, since notes an agent writes about its own work are a best guess and not a specification. Confirm which calls are real: a replay against a recording is a regression test, not evidence that anything reached the network. Look for facet-count or telemetry calls that look like data requests and are not, since a call carrying a zero limit is usually asking how many results exist rather than asking for results. Check the failure shape, because an undocumented backend has undocumented error states and no contract that tells you what they are.
Then schedule the thing that actually decays. The wire format is more stable than the markup, but it is not permanent, and the check that catches a change cheaply is a scheduled call against a known query with a known answer.
Editor's Note: Two searches we recorded produced a schema covering 25 sub-category codes and 16 provinces, and on the second target a single line break inside a table header silently dropped two fields from the output. The Polish auction portal is a modern single-page app, and modern apps give up their data model almost by accident, which makes the method look easier than it is. The county parcel portal is the honest case: no XHR traffic, no embedded state, nothing to read but rendered markup. The method still works there, but the failure mode changes from a wrong answer to a missing field, and the check in the markup section above is the one that catches it. Budget for that target, not the flattering one. — Rafal Fila
Tools Mentioned
Celigo
iPaaS built for the NetSuite ecosystem with pre-built connectors
Integration PlatformsComposio
Agent-integration platform providing authenticated tool access to 1,000+ business applications
Integration PlatformsCyclr
Embedded iPaaS for SaaS vendors to ship a native integration marketplace inside their own product UI.
Integration PlatformsHubSpot Operations Hub
Automate business processes and keep your CRM data clean
Integration PlatformsRelated Guides
Workato vs Zapier in 2026: Enterprise iPaaS vs Tiered No-Code Automation
Workato and Zapier are two of the most widely shortlisted platforms for connecting ten or more business systems. Workato, founded in 2013, is a quote-priced enterprise iPaaS built on environment-promoted recipes and 1,200+ deep connectors; Zapier, founded in 2011, is a self-serve no-code platform spanning 9,000+ apps that also ships code steps, an SDK, and an MCP interface, and whose Team and Enterprise tiers add SSO, audit logs, and admin controls. This comparison covers execution architecture, connector depth, AI and MCP capabilities, published pricing, and tier-by-tier governance, verified against both vendors' official pages in July 2026.
Replacing a $40K/yr Workato Seat with Pipedream + n8n: What Broke
Anonymized retrospective of a mid-market SaaS company replacing a single $40,000/year Workato seat with a hybrid Pipedream + self-hosted n8n stack over five weeks. Direct tooling cost fell roughly 70%, but webhook delta handling, retry semantics, and observability gaps consumed most of the timeline.
Supabase vs Firebase 2026: Postgres Open-Source vs NoSQL on Google Cloud
Supabase (2020) is an open-source Postgres backend with pgvector, RLS, and self-host options from $25/month Pro. Firebase (2014, Google) is a proprietary NoSQL platform with Firestore and tight GCP integration. This 2026 comparison covers hosting, data model, AI/vector support, pricing, and vendor lock-in.
Related Rankings
Best Data Integration Platforms in 2026
A ranked list of data integration platforms in 2026. The ranking covers ELT/ETL tools, customer data platforms, and enterprise iPaaS products that move data between operational systems and analytical destinations. Entries cover managed ELT (Fivetran, Airbyte, Stitch), customer data platforms (Segment), and enterprise iPaaS (MuleSoft, Boomi, Oracle Integration Cloud, Jitterbit). Scoring reflects connector library size, ELT/ETL flexibility, reliability and SLA, pricing transparency, and real-time capability.
Best Automation Tools for Fintech and Financial Services in 2026
A ranked list of the best automation tools for fintech and financial-services organisations in 2026. This ranking evaluates platforms across SOC 2 and ISO 27001 posture, PCI DSS handling where applicable, data-residency controls, audit and governance capabilities, and the depth of integration with core banking, payments, and market-data systems. The ranking covers enterprise iPaaS (Workato, MuleSoft, Boomi), enterprise RPA (UiPath, Power Automate), self-hosted workflow automation (n8n), and enterprise data integration (Informatica). Entries are scored against the compliance, latency, and governance constraints typical of banks, lenders, payments companies, and asset managers.
Common Questions
Supabase vs Firebase: which backend is better in 2026?
Supabase is an open-source Postgres backend with pgvector, RLS, and self-host options from $25/month Pro, suited to apps needing relational data and AI/RAG. Firebase is a proprietary NoSQL backend on Google Cloud with strong mobile SDKs, suited to mobile-first realtime apps.
What is the best data integration platform in 2026?
The top data integration platforms in 2026 are [Fivetran](/tools/fivetran/) (managed ELT with 750+ connectors), [Airbyte](/tools/airbyte/) (open-source ELT with self-hosted option), and [Segment](/tools/segment/) (Twilio-owned customer data platform with real-time event streaming).
How much does Cyclr cost in 2026?
Cyclr now publishes prices as of July 2026, across three product lines: an MCP PaaS (shared infrastructure) from $999/month, a Service Embedded iPaaS from $1,495/month, and a Native Embedded iPaaS from $1,595/month (Launch), $2,595/month (Grow), and $7,195/month (Scale). Tiering is by active connectors plus an included API-call allowance. The MCP (Model Context Protocol) PaaS line is a 2026 addition. Cyclr is an embedded iPaaS for SaaS vendors building in-product integration marketplaces, positioned below Prismatic and Workato Embedded.
Is Cyclr worth it in 2026? A detailed review
Cyclr scores 7.4/10 in 2026. The Brighton, UK embedded iPaaS gives SaaS vendors a white-label integration marketplace with 600+ connectors; as of July 2026 pricing starts at $1,495-$1,595/month (the former Foundation tier is retired).