---
title: "Count matching raw blocks (mass-unlock cost estimate)"
method: POST
path: "/search/raw/count"
tags: ["Raw Search"]
---

# Count matching raw blocks (mass-unlock cost estimate)

`POST /search/raw/count`

Return how many raw blocks match the given filters, i.e. the maximum number of parts (1 point each) a mass unlock would consume. Uses the **same** payload as `/search/raw` so the count matches exactly what search and unlock traverse.

This is intended to be called on demand (e.g. when opening the mass-unlock dialog), NOT on every search: the count is heavier than a page fetch and is cached.

- `exact=true`: `total` is the exact count.
- `exact=false`: `total` is an upper bound (`q_exact` and/or `dedup` shrink the real set).
- `capped=true`: the count hit its upper limit, so `total` is a lower bound.

**Rate limit:** shares the raw search limit, including its concurrent-request slot: a count fans out over every shard of the raw index, so it is billed against the same budget as `/search/raw` rather than the wider generic search limit.

## Query parameters

- `dedup` boolean — Mark the count as an upper bound because the deduplicated view folds identical content (block_fp64) app-side.

## Request body

- RawSearchRequest
  - `q` string, nullable — Optional full text query to match within raw blocks. Quotes are ignored for the length check. When omitted or empty, you must provide at least one filter among container_id, exts, categories, file_name.
  - `container_id` integer, nullable — Restrict the search to a specific container id.
  - `exts` string[], nullable — List of file extensions to include (case-insensitive, without leading dot).
  - `exts_not` string[], nullable — List of file extensions to exclude (case-insensitive, without leading dot).
  - `categories` string[], nullable — Filter results by raw file category. Applied after the search query.
  - `categories_not` string[], nullable — Exclude these raw file categories. Applied after the search query.
  - `file_name` string[], nullable — Case-insensitive wildcards that must match the entry name (OR by default, AND if force_and=true).
  - `file_name_not` string[], nullable — Case-insensitive wildcards that must NOT match the entry name.
  - `folder_name` string[], nullable — Case-insensitive match on the folder holding the block (OR by default, AND if force_and=true). By default the value must appear anywhere in the folder path; with folder_name_exact=true it must be a whole folder at any depth. Leading and trailing slashes are ignored.
  - `folder_name_not` string[], nullable — Folders to exclude, same matching rules as folder_name. Not a standalone selector: a search using only folder_name_not is rejected, provide q or another positive filter.
  - `force_and` boolean, nullable — When true, require all file_name values to match, and all folder_name values to match (AND instead of OR within each list).
  - `file_name_exact` boolean, nullable — When true, file_name / file_name_not match the entry name exactly (case-insensitive) instead of as a 'contains' wildcard.
  - `folder_name_exact` boolean, nullable — When true, folder_name / folder_name_not must match a whole folder at any depth: 'data' matches 'a/b/data' but not 'a/b/database'. A value containing slashes matches a whole run of folders ('b/data' matches 'a/b/data/c'). Without it the value is matched as a substring of the folder path.
  - `q_exact` boolean, nullable — When true, the q term must match on word boundaries: '4.4.4.4' will not match '4.4.4.400'. Applied as a content post-filter (no effect without q).
  - `exclude_terms` string[], nullable — Content terms to exclude: any block whose content contains one of these (substring, case-insensitive) is removed from the results. Min 4 characters per term, max 20 terms. Not a standalone selector: a search using only exclude_terms is rejected, provide q or another positive filter.
  - `ingested_at_min` string, date-time, nullable — Filter results ingested on or after this datetime (inclusive).
  - `ingested_at_max` string, date-time, nullable — Filter results ingested on or before this datetime (inclusive).

## Response `200`

Count computed successfully.

- RawCountResponse
  - `total` integer, required — Number of matching raw blocks for the same filters as /search/raw. This is the maximum number of parts (and, at 1 point per part, the maximum points) a mass unlock would consume. It counts all matches, including any the caller already unlocked (those are not re-charged), so treat it as an upper bound on cost.
  - `exact` boolean, required — True when total is the exact match count. False when it is only an upper bound: q_exact (word-boundary post-filter) or dedup (app-side fold) shrink the real set.
  - `capped` boolean — True if the count reached its upper limit; total is then a lower bound ("at least").
  - `blacklisted_value` string, nullable — If a filter value matched a blacklist entry, the matched value (total is 0).

## Other responses

- `400` — Invalid query (too short, too long, or empty with no filters).
- `401` — Authentication required, or invalid/expired API key.
- `403` — Raw search not available on your plan, account banned, or pending email verification.
- `422` — Validation Error
- `429` — Rate limit exceeded. See Retry-After / X-RateLimit-* headers.
- `503` — Raw search under maintenance, or public API temporarily disabled.

---

[API](https://skmtc.dev/leakradar/apis/leakradar-io-api.md) · [All operations](https://skmtc.dev/leakradar/apis/leakradar-io-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/leakradar/leakradar-io-api/revisions/82a99c608e1a/schema)
