---
title: "Search Rfps"
method: POST
path: "/api/internal/rfps/search"
tags: ["RFPs"]
---

# Search Rfps

`POST /api/internal/rfps/search`

Search RFPs.

The ``query`` field accepts a websearch-style query string evaluated against
the RFP search vector (title + description, english config, stemming on).
See RFPSearchFilters docstring for syntax.

All filters are optional. Empty body returns paginated RFPs sorted by the
default order (``due_date_asc``). At ~2.4M rows the RFP table is small
enough that fully unbounded queries are fine; this differs from the PO
endpoint, which requires at least one bounding filter.

## Request body

- RFPSearchFilters — Search filters for RFPs. The ``query`` field accepts a websearch-style query string evaluated against the ``search_vector`` column (covers title + description, tokenized with the ``english`` config — stemming enabled, stop words filtered). Query syntax: bare words: "content filter" AND of both words quoted phrase: '"content filtering"' exact phrase match OR: "filter OR cybersecurity" literal OR keyword exclude: "filter -demo" prefix - to exclude combined: '"content filter" -demo -test' Stemming means ``filter`` matches ``filter``, ``filters``, ``filtering``, ``filtered``. Unlike the PO endpoint (which uses ``simple`` config), word boundaries here are at the tokenizer level — phrase syntax handles exact matching when needed. At least one of ``institution_ids`` or ``query`` must be supplied — the endpoint rejects requests with both empty.
  - `query` string, nullable
  - `status` 'active' | 'expired' | 'no_due_date'
  - `due_after` string, date, nullable
  - `due_before` string, date, nullable
  - `institution_ids` string[], nullable
  - `states` string[], nullable
  - `source_tables` string[], nullable
  - `sort` 'due_date_asc' | 'due_date_desc' | 'updated_desc' | 'relevance'
  - `offset` integer
  - `limit` integer

## Response `200`

Successful Response

- PaginatedResponseRFPResponse
  - `results` RFPResponse[], required
    - `id` integer, required
    - `rfp_id` string, nullable
    - `title` string, nullable
    - `description` string, nullable
    - `agency` string, nullable
    - `due_date` string, date, nullable
    - `rfp_url` string, nullable
    - `source_url` string, nullable
    - `created_at` string, date-time, nullable
    - `updated_at` string, date-time, nullable
    - `institution_id` string, nullable
    - `institution_name` string, nullable
    - `institution_state` string, nullable
    - `institution_type` string, nullable
    - `status` 'active' | 'expired' | 'no_due_date'
    - `days_until_due` integer, nullable
    - `relevance` number, nullable
  - `total` integer, required
  - `offset` integer, required
  - `limit` integer, required

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.net/nationgraph/apis/nationgraph-api.md) · [All operations](https://skmtc.net/nationgraph/apis/nationgraph-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/nationgraph/nationgraph-api/revisions/85804e68d86d/schema)
