# Search

Search the academic index with filters.

`POST /v1/search` runs a metadata search over the corpus: titles, abstracts, authors, venues. It needs the `papers&#x60; scope. Instant costs **$2*&#x2A;, standard **$5*&#x2A;, and deep **$12 per 1,000 queries**. The number of results does not change the price.

## Request [#request]

| field          | type                                     | notes                                                                                                                                                                                                                                                                                                                                          |
| -------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `query`        | `string`                                 | Natural language or keywords. 1 to 1,000 characters.                                                                                                                                                                                                                                                                                           |
| `type`         | `"instant" \| "standard" \| "deep"`      | `instant` is vector-only and fastest. `standard` (default) is hybrid keyword plus vector. `deep` searches open-access full text with citable passages.                                                                                                                                                                                         |
| `maxResults`   | `int`                                    | Default 10, max 100.                                                                                                                                                                                                                                                                                                                           |
| `filters`      | object                                   | See below.                                                                                                                                                                                                                                                                                                                                     |
| `sort`         | `"relevance" \| "recent" \| "citations"` | `relevance` (default) ranks by fit to the query, breaking near-ties toward papers cited unusually often for their age. `recent` returns the most relevant papers from the last two years, widening to four when few match, and demotes repository deposits. `citations` orders the relevant papers by citation count. Works with every `type`. |
| `includeTotal` | `boolean`                                | Best effort: include `totalEstimate` only if it is ready when results arrive. Prefer `/v1/search/total`.                                                                                                                                                                                                                                       |

### Filters [#filters]

| field             | type      | example                                         |
| ----------------- | --------- | ----------------------------------------------- |
| `publicationYear` | `string`  | `"2020"`, `">=2018"`, `"2015..2020"`            |
| `isOpenAccess`    | `boolean` | `true`                                          |
| `hasFulltext`     | `boolean` | `true` restricts to papers that `deep` can read |
| `field`           | `string`  | `"Computer Science"`                            |
| `citedByCount`    | `string`  | `">100"`                                        |

<CodeGroup>
  ```bash title="cURL"
  curl -X POST https://api.anara.com/v1/search \
    -H "Authorization: Bearer $ANARA_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"query": "CRISPR off-target detection", "maxResults": 20, "filters": {"publicationYear": ">=2021", "hasFulltext": true}}'
  ```

  ```python title="Python"
  import os
  import requests

  response = requests.post(
      "https://api.anara.com/v1/search",
      headers={"Authorization": f"Bearer {os.environ['ANARA_API_KEY']}"},
      json={"query": "CRISPR off-target detection", "maxResults": 20, "filters": {"publicationYear": ">=2021", "hasFulltext": True}},
  )
  print(response.json())
  ```

  ```ts title="TypeScript"
  const response = await fetch('https://api.anara.com/v1/search', {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.ANARA_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      query: 'CRISPR off-target detection',
      maxResults: 20,
      filters: { publicationYear: '>=2021', hasFulltext: true },
    }),
  });
  console.log(await response.json());
  ```
</CodeGroup>

## Response [#response]

```json title="Response"
{
  "papers": [
    {
      "id": "W4210000000",
      "title": "…",
      "year": 2022,
      "authors": ["…"],
      "abstract": "…",
      "citedByCount": 41,
      "openAccess": true,
      "hasFulltext": true
    }
  ],
  "totalApprox": 20,

  "charge": { "costMicroUsd": 5000, "balanceMicroUsd": 9990000 }
}
```

`totalApprox` is the number of papers in this response. It is not a count of the whole corpus.

`totalEstimate` appears only when the request sets `includeTotal` and the estimate is ready by the time results are. Search never waits for it. To always get the count, call `/v1/search/total` alongside the search.

## Total matches [#total-matches]

`POST /v1/search/total` estimates how many papers in the corpus have every word of the query in their title or abstract, under the given filters, rounded to two significant figures, like the hit count a search engine shows. Counts under 1,000 are exact. Send it in parallel with `/v1/search`, with the same `query`, `type` and `filters`, so results never wait for the count. It is free and needs the `papers` scope.

| field     | type                      | notes                                  |
| --------- | ------------------------- | -------------------------------------- |
| `query`   | `string`                  | The same query as the search.          |
| `type`    | `"instant" \| "standard"` | Default `standard`. Deep has no count. |
| `filters` | object                    | The same filters as the search.        |

The response is `{ "totalEstimate": 19000 }`. `totalEstimate` is `null` when the query has no words to count, for example only stopwords. It usually arrives in under a second.

## Deep search [#deep-search]

Use `POST /v1/search` with `"type": "deep"`, or select **Deep** under **Type** in the playground. Deep search returns citable passages from open-access full text. Deep returns `totalApprox` without a corpus estimate.

## Result count and coverage [#result-count-and-coverage]

The response contains up to `maxResults` ranked papers. Call `/v1/search/total` for the estimated match count.

Passages and hosted PDF links are returned only for open-access papers. A missing PDF link means no hosted copy is available; the API does not fall back to a publisher download.

Additional filters include `authorName`, `sourceName`, `field`, `citedByCount`, `publicationYear`, `isOpenAccess`, and `hasFulltext`. Full-text-only searches are restricted to open access.

Workspace requests are limited to 120 per minute across API keys. The signed-in playground has a separate limit of 30 per minute. A `429` response means retry after 60 seconds.

Each paper includes `venue`, `publicationDate` (the full indexed date, not just `year`), `field`, `language`, `arxivId`, `pmcid`, and `pmid` alongside `doi` when available. Missing metadata is omitted. `openAlexId` is not exposed.
