---
title: "Keyword Search"
method: POST
path: "/api/v3/documents/keyword-search"
tags: ["Documents"]
---

# Keyword Search

`POST /api/v3/documents/keyword-search`

## Request

- Base URL: `https://app.daloopa.com`
- URL: `https://app.daloopa.com/api/v3/documents/keyword-search`
- Auth: HTTP basic

Performs keyword search across multiple documents and returns matches without positional information for faster response times.

**Key Features:**
- Faster than batch search (no positional data retrieval)
- Each match includes a unique match_id
- Use match_id with the positional-info endpoint to get positions on demand
- Supports same filtering and search options as batch search

**Use Cases:**
- Initial search to find relevant documents quickly
- When positional information is not immediately needed
- Two-step workflow: search first, then get positions for specific matches

**Workflow:**
1. Use this endpoint to quickly find matching documents
2. Review results and identify matches of interest
3. Call the positional-info endpoint with match_id for precise locations

## Request body

- BatchSearchRequestSerializerV3Request: V3 batch-search request. Same shape as :class:`BatchSearchRequestSerializer` but nests the v3 filters serializer, which drops the deprecated ``periods`` field.
  - `keywords` string[], required: List of keywords to search for (1-10 keywords)
  - `filters` BatchSearchFiltersSerializerV3Request: V3 batch-search filters. Same shape as :class:`BatchSearchFiltersSerializer` but without the deprecated ``periods`` field (and thus no ``LegacyFieldAliasMixin``). Kept as a standalone class so it is trivial to delete once v2 is sunset.
    - `company_ids` integer[]: List of company IDs to filter by
    - `document_ids` integer[]: List of document IDs to filter by
    - `filing_types` string[]: List of filing types to filter by (e.g., '10-K', '10-Q')
    - `date_range` object: Date range filter with 'start' and 'end' keys (YYYY-MM-DD format)
    - `calendar_quarters` string[]: One or more calendar quarters in YYYYQ# format. Mutually exclusive with `fiscal_quarters`.
    - `fiscal_quarters` string[]: One or more fiscal quarters in YYYYQ# format. Translated to each company's calendar quarters before filtering, so `company_ids` is required. Mutually exclusive with `calendar_quarters`.
  - `options` BatchSearchOptionsRequest: Serializer for batch search options.
    - `size` integer: Maximum number of documents to return per page (1-100)
    - `offset` integer: Number of documents to skip for pagination (default: 0)
    - `operator` 'AND' | 'OR': * `AND` - AND * `OR` - OR
    - `fuzzy` boolean: Enable fuzzy matching (default: False). When False, only exact phrase matches are returned. When True, allows approximate matches but positional information may be unavailable.

## Response `200`

- LightweightBatchSearchResponse: Serializer for lightweight batch search responses without positional information.
  - `success` boolean, required: Whether the search was successful
  - `total_hits` integer, required: Total number of matching documents (accurate based on fuzzy setting)
  - `documents` LightweightDocumentMatch[], required: List of matching documents with match_ids for current page
    - `document_id` integer, required: Document ID
    - `company_id` integer, nullable: Company ID
    - `filing_type` string, nullable: Filing type
    - `affinitized_date` string, nullable: Affinitized date
    - `calendar_quarter` string, nullable: Calendar quarter for the document (YYYYQ#)
    - `fiscal_quarter` string, nullable: Fiscal quarter for the document (YYYYQ#)
    - `document_title` string, nullable: Document title
    - `score` number, double, required: Relevance score
    - `source_url` string: Link to the document in the viewer. This endpoint does not resolve a page, so the link opens the document at the top.
    - `matches` LightweightMatch[], required: List of matches in this document, each with its own match_id
      - `keyword` string, required: The matched keyword
      - `context` string, required: Context snippet around the match
      - `match_id` string, required: Compact match ID for fetching positional info
  - `offset` integer, required: Current pagination offset
  - `limit` integer, required: Current page size limit
  - `error` string, nullable: Error message if search failed

## Other responses

- `400`
- `401`
- `403`
- `429`
- `500`

## Changes

- **2026-11-03** `90ca7c9d6f4e`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/daloopa/apis/daloopa-api/changes/api/v3/documents/keyword-search/post.md)

---

[API](https://skmtc.dev/daloopa/apis/daloopa-api.md) - [All operations](https://skmtc.dev/daloopa/apis/daloopa-api/llms.txt) - [OpenAPI document](https://skmtc.dev/daloopa/apis/daloopa-api/revisions/90ca7c9d6f4e?raw)
