Search + Content
Search the web and get the full text of the top pages in one call.
`POST https://api.keirolabs.cloud/api/v2/search/content`
Cost: 1.5 credits paid · 3 free · Latency: ~3 s
Execute a search and scrape clean, markdown-formatted text from the top results in a single, unified call. The perfect foundation for RAG pipelines, LLM summarization, and AI agents. Returns enriched content with TLDR, tags, entities, and optional vector embeddings.
**When to use it.** Use Search+Content when you need the actual page text (markdown) for RAG, summarization, or AI agents. Returns clean content + TLDR + tags + optional embeddings in a single call.
**When not to.** Don't use if you only need URLs (use Search — cheaper), or if you need an LLM-synthesized answer (use Answer).
## Request
**cURL**
```bash
curl -X POST https://api.keirolabs.cloud/api/v2/search/content \
-H "Authorization: Bearer $KEIRO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "how to reverse a linked list in python", "maxResults": 4, "mode": "medium"}'
```
**Python**
```python
import os, requests
res = requests.post(
"https://api.keirolabs.cloud/api/v2/search/content",
headers={"Authorization": f"Bearer {os.environ['KEIRO_API_KEY']}"},
json={
"query": "how to reverse a linked list in python",
"maxResults": 4,
"mode": "medium"
},
)
print(res.json())
```
**Node.js**
```js
const res = await fetch("https://api.keirolabs.cloud/api/v2/search/content", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.KEIRO_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"query": "how to reverse a linked list in python",
"maxResults": 4,
"mode": "medium"
}),
});
console.log(await res.json());
```
## Parameters
| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `query` | string | yes | The search query (1-500 chars). |
| `maxResults` | integer | no | Number of pages to scrape. Default: 3. Max: 5 (server-clamped). |
| `mode` | enum | no | Extraction depth/method. Options: "medium" (full extraction + RAG enrichment, default), "deep" (renders JavaScript-heavy sites). |
| `objective` | string | no | Semantic objective extracts only text relevant to this goal, trimming noise from the page. |
| `country` | string | no | ISO-3166-1 alpha-2 country code to bias results. (Alias: location.) |
| `max_chars_source` | integer | no | Max characters extracted per source. Range: 1,000-10,000. Default: 7,000. |
| `max_chars_total` | integer | no | Max total characters across all sources. Range: 5,000-50,000. Default: 30,000. |
| `embeddings.enabled` | boolean | no | Generate vector embeddings for each content chunk. Default: false. Only honored in medium or deep mode. |
| `embeddings.dimensions` | integer | no | Matryoshka dimension truncation. Options: 384, 512, 768, 1024. Default: 768. |
| `embeddings.chunkSize` | integer | no | Characters per chunk for embedding. Range: 1500-2000. Default: 1500. Values outside this range are clamped. |
## Response
```json title="200 OK"
{
"query": "how to reverse a linked list in python",
"results": [
{
"title": "Reverse a Linked List - GeeksforGeeks",
"url": "https://www.geeksforgeeks.org/python/reverse-a-linked-list/",
"snippet": "Step-by-step guide with iterative and recursive solutions.",
"content": "Reverse a Linked List\nGiven the head of a linked list, the iterative approach uses three pointers...",
"metadata": {
"word_count": 1200
},
"enrichment": {
"tldr": "Reverse a linked list by flipping next-pointers iteratively in O(n) time and O(1) space.",
"tags": [
"python",
"linked-list",
"algorithms"
],
"entities": {
"key_entities": [
"pointer",
"head",
"next"
]
}
},
"embeddings": {
"model": "baai/bge-m3",
"dimensions": 768,
"chunkSize": 1500,
"chunkCount": 3,
"totalChunks": 3,
"chunks": [
{
"index": 0,
"embedding": [
0.0123,
-0.0456,
0.0789,
"..."
]
},
{
"index": 1,
"embedding": [
0.0234,
-0.0567,
0.089,
"..."
]
},
{
"index": 2,
"embedding": [
0.0345,
-0.0678,
0.0901,
"..."
]
}
],
"truncated": false,
"error": null
},
"error": ""
}
],
"count": 3,
"latencyMs": 2706,
"creditsCharged": 1.5,
"creditsRemaining": 1138.5
}
```
| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `results` | array | no | List of search results with extracted content. |
| `results[].title` | string | no | Page title. |
| `results[].url` | string | no | Full URL of the page. |
| `results[].content` | string | no | Clean markdown-formatted page content (main text, no nav/ads). |
| `results[].enrichment` | object | no | RAG enrichment: TLDR summary, tags, and named entities. |
| `results[].enrichment.tldr` | string | no | Auto-generated one-line summary of the page. |
| `results[].enrichment.tags` | array | no | Topic tags extracted from the content. |
| `results[].embeddings` | object | no | Vector embeddings (only if embeddings.enabled=true). |
| `results[].embeddings.chunks` | array | no | Array of { index, embedding } objects, one per chunk. |
| `results[].error` | string | no | Empty string if extraction succeeded; error message if it failed. |
| `creditsCharged` | number | no | Credits deducted (1.5 for paid tiers, 3 for free). |
| `creditsRemaining` | number | no | Your remaining credit balance. |
## Errors
| Status | Code | Cause | Fix |
| --- | --- | --- | --- |
| `400` | `VALIDATION_ERROR` | Missing query or invalid mode | Ensure query is provided and mode is "medium" or "deep". |
| `401` | `UNAUTHORIZED` | Missing or invalid API key | Check your Authorization: Bearer header. |
| `402` | `INSUFFICIENT_CREDITS` | Not enough credits | Buy more credits or upgrade your plan. |
| `429` | `RATE_LIMIT_EXCEEDED` | Too many requests | Check X-RateLimit-Remaining header. Wait for Retry-After seconds. |
| `502` | `SEARCH_UNAVAILABLE` | Extraction or search failure | Credits auto-refunded. Retry or try mode="medium" instead of "deep". |
## Rate limits
| Tier | Limit |
| --- | --- |
| Free | 10/min |
| Starter | 20/min |
| Pro | 40/min |
| Startup | 80/min |
| Enterprise | 120/min |
Over the limit you get a `429`. See [Rate limits](/rate-limits) for headers and backoff.https://api.keirolabs.cloud/api/v2/search/contentExecute a search and scrape clean, markdown-formatted text from the top results in a single, unified call. The perfect foundation for RAG pipelines, LLM summarization, and AI agents. Returns enriched content with TLDR, tags, entities, and optional vector embeddings.
When to use it. Use Search+Content when you need the actual page text (markdown) for RAG, summarization, or AI agents. Returns clean content + TLDR + tags + optional embeddings in a single call.
When not to. Don't use if you only need URLs (use Search — cheaper), or if you need an LLM-synthesized answer (use Answer).
Request
curl -X POST https://api.keirolabs.cloud/api/v2/search/content \
-H "Authorization: Bearer $KEIRO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "how to reverse a linked list in python", "maxResults": 4, "mode": "medium"}'Parameters
Prop
Type
Response
{
"query": "how to reverse a linked list in python",
"results": [
{
"title": "Reverse a Linked List - GeeksforGeeks",
"url": "https://www.geeksforgeeks.org/python/reverse-a-linked-list/",
"snippet": "Step-by-step guide with iterative and recursive solutions.",
"content": "Reverse a Linked List\nGiven the head of a linked list, the iterative approach uses three pointers...",
"metadata": {
"word_count": 1200
},
"enrichment": {
"tldr": "Reverse a linked list by flipping next-pointers iteratively in O(n) time and O(1) space.",
"tags": [
"python",
"linked-list",
"algorithms"
],
"entities": {
"key_entities": [
"pointer",
"head",
"next"
]
}
},
"embeddings": {
"model": "baai/bge-m3",
"dimensions": 768,
"chunkSize": 1500,
"chunkCount": 3,
"totalChunks": 3,
"chunks": [
{
"index": 0,
"embedding": [
0.0123,
-0.0456,
0.0789,
"..."
]
},
{
"index": 1,
"embedding": [
0.0234,
-0.0567,
0.089,
"..."
]
},
{
"index": 2,
"embedding": [
0.0345,
-0.0678,
0.0901,
"..."
]
}
],
"truncated": false,
"error": null
},
"error": ""
}
],
"count": 3,
"latencyMs": 2706,
"creditsCharged": 1.5,
"creditsRemaining": 1138.5
}Prop
Type
Errors
| Status | Code | Cause | Fix |
|---|---|---|---|
400 | VALIDATION_ERROR | Missing query or invalid mode | Ensure query is provided and mode is "medium" or "deep". |
401 | UNAUTHORIZED | Missing or invalid API key | Check your Authorization: Bearer header. |
402 | INSUFFICIENT_CREDITS | Not enough credits | Buy more credits or upgrade your plan. |
429 | RATE_LIMIT_EXCEEDED | Too many requests | Check X-RateLimit-Remaining header. Wait for Retry-After seconds. |
502 | SEARCH_UNAVAILABLE | Extraction or search failure | Credits auto-refunded. Retry or try mode="medium" instead of "deep". |
Rate limits
| Tier | Limit |
|---|---|
| Free | 10/min |
| Starter | 20/min |
| Pro | 40/min |
| Startup | 80/min |
| Enterprise | 120/min |
Over the limit you get a 429. See Rate limits for headers and backoff.
Paste one prompt into Claude Code, Cursor, Codex or Windsurf. It installs Keiro MCP, reads these docs and writes the integration against the real API.