> ## Documentation Index
> Fetch the complete documentation index at: https://docs.synti.co/llms.txt
> Use this file to discover all available pages before exploring further.

# API Discovery

> How the Synti agent finds a web app's backend endpoints and calls them directly instead of clicking through the UI.

Most modern web apps are single-page applications: the page you see is just a shell that fetches its data from backend endpoints in the background. Synti can watch those requests, learn the endpoints, and then call them directly — skipping the UI entirely.

This turns a slow, click-by-click task into a fast, parallel one. Where walking the interface might take five to ten seconds per item, a direct API call typically returns in around a hundred milliseconds, and many calls can run at once.

## Why it's faster

Calling the backend directly wins on every axis that matters:

* **Speed.** No page loads, no waiting for animations or spinners between items.
* **Parallelism.** Many requests can fire simultaneously instead of one click at a time.
* **Clean data.** Responses arrive as structured JSON or XML, not text scraped out of the DOM.
* **Stability.** API contracts change far less often than page layouts, so the approach keeps working after a redesign.
* **Extra fields.** Backend responses often carry useful data that the UI never renders.

## How the agent does it

The agent works through a repeatable sequence. You don't have to prompt each step — describe the outcome you want and it handles the discovery.

<Steps>
  <Step title="Explore the app">
    The agent loads the web app and interacts with it normally, triggering the requests the page makes as it renders data.
  </Step>

  <Step title="Inspect the network">
    It watches network traffic and picks out the HTTP calls that return structured data — REST or GraphQL endpoints — rather than assets or tracking pings.
  </Step>

  <Step title="Recognize the pattern">
    From those calls it extracts the URL shape, for example `/api/v1/employees/{id}/time-off`, so it can vary the parameters.
  </Step>

  <Step title="Validate with one call">
    It makes a single direct request to confirm the endpoint behaves as expected before scaling up.
  </Step>

  <Step title="Run in parallel">
    Once validated, it fetches everything at once — using `Promise.all()` for concurrency and chunking large jobs into batches to stay polite.
  </Step>

  <Step title="Collect the results">
    It formats the combined data into a table, spreadsheet, or raw dataset, whatever you asked for.
  </Step>
</Steps>

<Tip>
  The agent will often switch to this approach on its own when it detects a repetitive clicking pattern — no explicit request needed. If you want to force it, just ask it to "use the API directly" or "fetch these in parallel."
</Tip>

## Techniques it uses

Because the JavaScript runs inside the page's own origin, it inherits the browser's authentication context and sidesteps CORS restrictions entirely.

| Technique                    | What it does                                                                      |
| ---------------------------- | --------------------------------------------------------------------------------- |
| `credentials: 'include'`     | Reuses the browser's session cookies so requests are authenticated automatically. |
| `Promise.all()`              | Fires many requests concurrently instead of sequentially.                         |
| `window.__` bridge variables | Passes async results back out to the agent.                                       |
| `DOMParser`                  | Parses XML responses from enterprise systems.                                     |
| Batch chunking               | Groups work into batches of roughly 20–50 items to avoid overloading the server.  |

A typical parallel fetch looks like this:

```js theme={null}
// Fetch many records at once, reusing the logged-in session
const ids = [/* ... */];
const results = await Promise.all(
  ids.map((id) =>
    fetch(`/api/v1/employees/${id}/time-off`, { credentials: 'include' })
      .then((r) => r.json())
  )
);
window.__result = results;
```

## Supported endpoint types

* **REST** endpoints returning JSON — the most common case.
* **GraphQL**, usually a single `/graphql` endpoint. The agent inspects the query structure first so it can shape valid requests.
* **XML-returning enterprise APIs** such as BambooHR or SAP, parsed with `DOMParser`.

## Things to watch for

* **Rate limits.** High-volume jobs need batching and short delays so the server isn't flooded. The agent chunks automatically, but a strict backend may still throttle.
* **GraphQL discovery.** GraphQL hides its shape behind a single endpoint, so the agent has to observe a real query before it can craft its own.
* **XML overhead.** XML responses require an extra parsing step compared to JSON.

<Note>
  API discovery still runs through the desktop browser, so it inherits the same requirements as [Browser Automation](/browser/overview): the desktop app and an authenticated session. For patterns you rely on regularly, consider promoting the endpoint to a proper [REST API source](/sources/overview).
</Note>
