Search API
Request parameters, domain filters, response fields, and errors for POST /v1/search.
POST https://api.lexmount.com/v1/search searches the web through the Hong Kong API.
Use an uncompressed application/json body of at most 16 KiB. Include both X-API-Key and X-Project-Id; see Quick Start for credentials.
Request body
{
"query": "PostgreSQL replication",
"limit": 20,
"timeout_ms": 10000,
"language": "en",
"region": "US",
"filters": {
"include_domains": ["postgresql.org"],
"exclude_domains": ["lists.postgresql.org"]
}
}Only query is required.
Request fields
| Field | Type | Default | Description |
|---|---|---|---|
query | string | Required | 1–512 Unicode characters; cannot be all whitespace |
limit | integer | 10 | Maximum result count, from 1 to 100 |
timeout_ms | integer | 10000 | Total processing budget, from 1000 to 60000 milliseconds |
language | string | Unspecified | BCP 47-style language tag such as en or zh-CN; at most 64 characters |
region | string | Unspecified | Two uppercase region letters such as US, GB, or CN |
filters | object | No filters | Strict result-domain filtering, described below |
Field names are case-sensitive. Unknown fields, duplicate JSON keys, null, and wrong field types return HTTP 400. Omit unused language and region fields instead of sending empty strings.
Domain filters
| Field | Type | Description |
|---|---|---|
filters.include_domains | string[] | Keep results from these domains and their subdomains; 1–20 entries when supplied |
filters.exclude_domains | string[] | Exclude results from these domains and their subdomains; 1–20 entries when supplied |
- Supply hostnames such as
example.org, without a protocol, port, path, wildcard, or IP address. - Domains are normalized for case, internationalized names, and a trailing root dot. Duplicates after normalization are rejected.
- When both lists are present, results must match the include list and not match the exclude list.
- If every included domain range is excluded, the request returns
400 invalid_filter. - Results with an unknown target domain cannot pass a domain filter. Filtering may reduce the count below
limit.
You can put site: in a query, but it does not replace strict result-domain filtering. Use filters.include_domains when the returned domain must match.
Complete cURL example
BASE_URL='https://api.lexmount.com'
API_KEY='<your-api-key>'
PROJECT_ID='<your-project-id>'
curl -sS "$BASE_URL/v1/search" \
-H 'Content-Type: application/json' \
-H "X-API-Key: $API_KEY" \
-H "X-Project-Id: $PROJECT_ID" \
--data '{
"query": "PostgreSQL replication",
"limit": 20,
"timeout_ms": 10000,
"language": "en",
"region": "US",
"filters": {
"include_domains": ["postgresql.org"],
"exclude_domains": ["lists.postgresql.org"]
}
}'Time budget and result count
timeout_ms covers processing after the body is received. Processing may finish early when enough results are available. Search completion or an exhausted budget can also produce fewer results than requested.
Language and region are search preferences, not strict per-result filters. Read the search status to determine completeness instead of only comparing returned with limit.
Response
Search returns results, status, and returned at the top level, without Web Fetch's result wrapper. Keep request_id or the X-Request-ID response header when reporting a problem.
Complete response example
The following response uses illustrative content and timing for this request:
{
"query": "PostgreSQL documentation",
"limit": 1
}{
"schema_version": "1.0",
"request_id": "019a04e0-0000-7000-8000-000000000001",
"query": "PostgreSQL documentation",
"status": "complete",
"results": [
{
"id": "web_example_1",
"kind": "web",
"position": 1,
"title": "PostgreSQL Documentation",
"url": "https://www.postgresql.org/docs/",
"canonical_url": "https://www.postgresql.org/docs/",
"url_resolved": true,
"domain": "www.postgresql.org",
"snippet": "Documentation for PostgreSQL.",
"published_at": null
}
],
"returned": 1,
"timing": {
"elapsed_ms": 1280
}
}Top-level fields
| Field | Description |
|---|---|
schema_version | Response schema version, currently 1.0 |
request_id | Correlation ID to retain for troubleshooting |
query | The search query |
status | complete, partial, empty, or unavailable |
results, returned | Final ranked results and their actual count |
timing.elapsed_ms | Server-side search processing time, not client end-to-end time |
error | Present when search is unavailable; contains code, message, and retryable |
HTTP and search status
| HTTP | status | Meaning |
|---|---|---|
| 200 | complete | Search finished with results; the count may be below limit |
| 200 | partial | Search produced a partial answer, possibly with zero results |
| 200 | empty | Search finished with no results matching the request |
| 503 | unavailable | Search could not produce an answer; inspect error |
complete neither guarantees limit results nor means that every relevant page on the web was found. Zero results with partial do not establish that no relevant pages exist.
Web results
| Field | Description |
|---|---|
id | Result identifier |
kind | Always web |
position | Rank within this response, starting at 1 |
title | Page title |
url | Link to open or pass to Web Fetch |
canonical_url | Normalized target URL, or null if unresolved |
url_resolved | Whether the target URL has been resolved |
domain | Target hostname, or null if unknown |
snippet | Search summary, not full page content |
published_at | Publication time when known, otherwise null |
Domain filters exclude results whose target domain cannot be determined. For page content, use Web Fetch.
Request errors
Requests rejected before search begins return request_id and an error object without a result list. For example:
{
"request_id": "019a04e0-0000-7000-8000-000000000002",
"error": {
"code": "invalid_query",
"message": "query must contain 1–512 Unicode characters and not be blank",
"retryable": false
}
}HTTP 400 indicates invalid parameters, 413 a body over 16 KiB, and 415 unsupported content type or encoding. Authentication and access restrictions use HTTP 401 or 403; a missing project header may return HTTP 400. Gateway errors may use a different response shape, so check the HTTP status before reading search fields.
Temporary processing failures can return HTTP 500 or 503. Retain the request ID, and use backoff when error.retryable is true. Do not repeatedly retry invalid credentials or parameters without correcting them.
