> ## 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.

# Parse

> Turn a plain-language request into structured filters and criteria, without running a search. Free.

Parse runs the first stage of a search, interpretation, without running the search. Send a sentence. You get back the structured filters and criteria Avina would search with, any assumptions it made, and a request body you can send to a search endpoint unchanged.

Parse spends no credits.

```bash Request theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X POST https://api.avina.io/v1/companies/search/parse \
  -H "Authorization: Bearer $AVINA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "query": "Private dental practices in Texas hiring SDRs" }'
```

```json Response (search_request shortened) theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "object": "company_search_parse",
  "query": "Private dental practices in Texas hiring SDRs",
  "filters": {
    "all": [
      { "field": "company.industry", "operator": "in", "value": ["Dentists"] },
      { "field": "company.business_description", "operator": "matches", "value": "dental practices" },
      { "field": "company.headquarters.state", "operator": "in", "value": ["Texas"] },
      { "field": "company.type", "operator": "in", "value": ["Privately Held"] },
      { "related": { "relationship": "open_jobs", "where": { "all": [
        { "field": "title", "operator": "in", "value": ["Sales Development Representative", "SDR"] }
      ] } } }
    ]
  },
  "criteria": [],
  "unsupported_criteria": [],
  "assumptions": [],
  "errors": [],
  "search_request": {
    "filters": { "all": ["..."] },
    "criteria": null
  }
}
```

There is one Parse endpoint for each kind of search:

| Endpoint | Produces a body for |
| - | - |
| [`POST /companies/search/parse`](https://docs.data.avina.io/api-reference/parse/companies) | [`POST /companies/search`](https://docs.data.avina.io/api-reference/companies/search) |
| [`POST /people/search/parse`](https://docs.data.avina.io/api-reference/parse/people) | [`POST /people/search`](https://docs.data.avina.io/api-reference/people/search) |

## Why use it

> [card] Show your users what was understood
>
> Display the filters before the search runs, so users can correct a wrong reading before it costs anything.

> [card] Build a filter interface on plain language
>
> Let users type a sentence, then adjust the structured result with dropdowns and ranges.

> [card] Make a query repeatable
>
> Parse once, store `search_request`, and run exactly the same structured search every week.

> [card] Catch what cannot be searched
>
> Find requirements that cannot be checked before you start a search that would stop because of them.

## Reading the response

**filters** `object | null`

The parts of the query that map to structured fields. `null` when none do.

**criteria** `object[]`

The parts that will be checked against evidence, each with `text` and `kind`.

**assumptions** `object[]`

Ambiguous wording and how it was read. Each has the original `text`, the reading that was `assumed`, and `alternatives`. Assumptions do not block a search. For example, "recently funded" is read as funded within the last 90 days:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{ "text": "recently funded", "assumed": "Last funding round was within the last 90 days", "alternatives": ["Last funding round was within the last 12 months"] }
```

**unsupported\_criteria** `string[]`

Requirements no public source can confirm, quoted from the query. A search cannot run while there are any.

**errors** `object[]`

Problems validating the filters the query was read as.

**search\_request** `object | null`

A ready request body. `null` when `unsupported_criteria` or `errors` is not empty, or the query gave nothing to search on.

## From parse to search

**1. Parse the query**

Send the user's text to the parse endpoint.

**2. Check it can run**

If `search_request` is `null`, show `unsupported_criteria` and `errors` and ask the user to reword.

**3. Confirm or edit**

Show `assumptions`. Let the user edit `filters` and `criteria` if you have a UI for it.

**4. Search**

Send `search_request`, plus your own `limit` and `max_credits`, to the search endpoint.

```python parse_then_search.py theme={"theme":{"light":"github-light","dark":"github-dark"}}
import os, uuid, requests

API = "https://api.avina.io/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['AVINA_API_KEY']}"}

parsed = requests.post(
    f"{API}/companies/search/parse",
    headers=HEADERS,
    json={"query": "Private dental practices in Texas hiring SDRs"},
).json()

if parsed["search_request"] is None:
    raise SystemExit(f"Cannot search: {parsed['unsupported_criteria'] or parsed['errors']}")

for assumption in parsed["assumptions"]:
    print(f"Read '{assumption['text']}' as: {assumption['assumed']}")

search = requests.post(
    f"{API}/companies/search",
    headers={**HEADERS, "Idempotency-Key": str(uuid.uuid4())},
    json={**parsed["search_request"], "limit": 20, "max_credits": 20},  # null filters or criteria are accepted
).json()
print(search["id"])
```

## How language is read

These conventions help when you write queries or show interpretations to users.

| In the query | Read as |
| - | - |
| A role abbreviation, such as "SDRs" | The abbreviation and its expansion: `["Sales Development Representative", "SDR"]` |
| A kind of business, such as "dental practices" | An industry. When the wording is not itself an industry name, a match on the company's description is added too. |
| "hiring X" | An open job for X. No posting-date limit is added unless the query gives one. |
| "hired X" with no time frame | Someone joined as X in the last 90 days. Listed as an assumption. |
| "recently funded" | Last funding within 90 days. Listed as an assumption. |
| A region, such as "the Nordics" | A list of country codes |
| "between 50 and 200", "at least 50" | Inclusive ranges |
| "more than 50", "under 200" | Strict ranges |
| Activity on your own site, private intent, subjective quality | `unsupported_criteria` |

> [!NOTE]
>
> You do not have to call Parse before searching. Sending `query` to a search endpoint interprets it the same way, and the search's status shows the interpretation. Use Parse when you want to see or change the interpretation before any search runs.

## Next steps

> [card] [Parse a company query](https://docs.data.avina.io/api-reference/parse/companies.md)
>
> Endpoint reference.

> [card] [Filter reference](https://docs.data.avina.io/guides/structured-filters.md)
>
> The fields Parse can produce.


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