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

# Build with AI

> Give a coding agent everything it needs to integrate the Avina Data API correctly on the first try.

These docs are written to be read by coding agents as well as people. Paste the brief below into Claude Code, Cursor, Codex or any other agent, and it has what it needs to build a working integration in your codebase.

## Copy the integration brief

The brief tells the agent what to build, where to find the API's exact definition, and how to handle three things that are easy to get wrong: retries, polling and spend.

```text Integration brief theme={"theme":{"light":"github-light","dark":"github-dark"}}
You are integrating the Avina Data API into this codebase.

GOAL
Add a server-side function that starts a company search from a natural-language
query, waits for it to finish, and returns the matching companies with their
evidence. Done means: the function returns an array of companies for the query
"Privately held dental practices in Texas hiring SDRs" with limit 5, and a test
or script proves it.

BEFORE YOU WRITE CODE
1. Read this project's language, framework, HTTP client and conventions, and
   follow them. Do not add a new HTTP library if one is already in use.
2. Read the docs you need, as Markdown:
   - https://docs.data.avina.io/quickstart.md
   - https://docs.data.avina.io/concepts/search-lifecycle.md
   - https://docs.data.avina.io/guides/poll-and-paginate.md
   - https://docs.data.avina.io/guides/errors-and-retries.md
   - https://docs.data.avina.io/api-reference/openapi.md  (full OpenAPI 3.1 spec)
   The index of every page is https://docs.data.avina.io/llms.txt

API FACTS
- Base URL: https://api.avina.io/v1
- Auth: "Authorization: Bearer <key>". Read the key from the AVINA_API_KEY
  environment variable. Never hardcode it, log it, or send it to a browser.
- Start:   POST /companies/search   body: { "query": string, "limit": 1-500 }
           Returns 202 with { id, status, status_url, results_url }.
- Status:  GET  /companies/search/{id}/status
- Results: GET  /companies/search/{id}/results?after=<next_cursor>&limit=1-100
- Cancel:  POST /companies/search/{id}/cancel
- People search has the same shape under /people/search.

RULES
- Searches are asynchronous. Poll status with backoff (start at 2 seconds, cap
  at 10) until status is "completed", "failed" or "cancelled".
- After a terminal status, page through results until has_more is false.
  Always pass the previous next_cursor as "after".
- Send an Idempotency-Key header on every POST that starts a search, and reuse
  the same key when you retry that request. Without it, a retry starts and
  charges for a second search.
- Starting a search spends credits (1 credit = $1). Set "max_credits" on every
  search you start. Reading status and results is free.
- A client timeout does not stop a search. To stop one, call cancel.
- Errors have the shape { "error": { code, message, request_id, details } }.
  Branch on error.code. Retry 429 (after Retry-After) and 5xx. Also retry a 409
  on a start request that reuses the same key and body: the first attempt is
  still being handled. Do not retry other 4xx errors.
- "completed" means the run finished, not that the list is exhaustive.
  Check stop_reason.

DO NOT
- Do not start a real search in a loop, in tests that run on every commit, or
  with a large limit while developing. Use limit 5 and max_credits 5.
- Do not invent fields, endpoints or SDK packages. If something is not in the
  docs above, say so instead of guessing.

HUMAN SETUP REQUIRED
- The Data API is in beta. A person must request access first:
  https://docs.data.avina.io/get-access
- A workspace admin must create the API key in the Avina dashboard under
  Settings > API Keys and add credits. Ask the user for AVINA_API_KEY to be set
  in the environment; do not ask them to paste it into chat.
```

> [!TIP]
>
> Change the `GOAL` section to describe what you actually want, such as a people search, a contact lookup with personas, or a filter builder on top of [Parse](https://docs.data.avina.io/capabilities/parse.md). Leave the rules as they are.

## What still needs a person

An agent can write and test the integration. These steps need a person:

| Step | Who | Where |
| - | - | - |
| Request beta access | You | [Request access](https://docs.data.avina.io/get-access.md) |
| Create the API key | Workspace admin | Avina dashboard, **Settings → API Keys** |
| Add credits | Workspace admin | Avina dashboard |
| Put `AVINA_API_KEY` in your server's environment | You | Your secret manager or `.env` file |
| Approve real searches that spend credits | You | Review the `limit` and `max_credits` the agent uses |

## Machine-readable docs

Every page on this site is available in formats agents can read directly.

> [card] [llms.txt](https://docs.data.avina.io/llms.txt)
>
> An index of every page with a one-line description. Start here to find the right page.

> [card] Any page as Markdown
>
> Add `.md` to any page URL, for example `/quickstart.md`. The **Copy page** button does the same.

> [card] [OpenAPI specification](https://docs.data.avina.io/api-reference/openapi.md)
>
> The full contract in OpenAPI 3.1. Generate a client or load it as a tool definition.

> [card] [llms-full.txt](https://docs.data.avina.io/llms-full.txt)
>
> The whole site in one file. Useful for bulk indexing; prefer single pages for a focused task.

## Use the API as an agent tool

You can give an AI agent the Data API as a tool it calls directly. There are two common ways to set that up.

> [tab] One blocking tool
>
> Wrap start, poll and read in one function and give it to the agent as a single tool. The agent calls `find_companies(query, limit)` and gets companies back. This is the simpler option, and a good default for searches with a small `limit`.
>
> ```python find_companies.py theme={"theme":{"light":"github-light","dark":"github-dark"}}
> import os, time, uuid, requests
>
> API = "https://api.avina.io/v1"
> HEADERS = {"Authorization": f"Bearer {os.environ['AVINA_API_KEY']}"}
>
> def find_companies(query: str, limit: int = 10, max_credits: float = 10) -> list[dict]:
>     """Find companies matching a plain-language description. Returns verified matches with evidence."""
>     search = requests.post(
>         f"{API}/companies/search",
>         headers={**HEADERS, "Idempotency-Key": str(uuid.uuid4())},
>         json={"query": query, "limit": limit, "max_credits": max_credits},
>     )
>     search.raise_for_status()
>     search = search.json()
>
>     delay = 2
>     while search["status"] in ("queued", "running"):
>         time.sleep(delay)
>         delay = min(delay * 1.5, 10)
>         response = requests.get(search["status_url"], headers=HEADERS)
>         response.raise_for_status()
>         search = response.json()
>
>     companies, after = [], None
>     while True:
>         response = requests.get(
>             search["results_url"], headers=HEADERS, params={"after": after, "limit": 100}
>         )
>         response.raise_for_status()
>         page = response.json()
>         companies += page["data"]
>         after = page["next_cursor"]
>         if not page["has_more"]:
>             return companies
> ```

> [tab] Three small tools
>
> Give the agent `start_search`, `get_search` and `get_results` as separate tools. The agent starts a search, does other work, and checks back. This suits large searches, and it lets the agent read early results while the search is still running.
>
> Give the agent these rules in the tool descriptions:
>
> * `start_search` spends credits. Call it once per distinct request and keep the returned `id`.
> * `get_search` and `get_results` are free. Call them as often as needed.
> * Pass the last `next_cursor` to `get_results` to read only new results.

> [!NOTE]
>
> Reading these docs gives an agent no access to your account. It can only act on your workspace once you give it an API key.

## Next steps

> [card] [Quickstart](https://docs.data.avina.io/quickstart.md)
>
> The same integration, step by step, for people.

> [card] [Errors and retries](https://docs.data.avina.io/guides/errors-and-retries.md)
>
> Safe retries and error handling, in detail.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.