Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions apps/docs/components/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,31 @@ export function SerperIcon(props: SVGProps<SVGSVGElement>) {
)
}

export function SerpdiveIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg {...props} xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 1000' fill='none'>
<path
fill='#0fd1c1'
d='M816 573a236 236 0 0 0-41-59q-34-28-68 1-23 23-37 51l-26 50q-30 52-88 69-76 23-150-10-53-27-78-80-26-50-21-106 9-92 83-145 52-38 115-32 54 5 97 37l17 12q26 18 56 9l38-11c55-18 103 1 135 46l28 41q12 16 28 27l3 3v38q-16-5-30-16-26-20-43-48-13-19-28-36a79 79 0 0 0-76-22q-21 4-42 12c-18 5-37 9-56 4q-22-7-40-21-23-18-49-28-63-23-119 11-83 51-80 148c2 60 32 106 89 129q84 32 155-22 27-22 40-54 16-34 38-65 19-26 47-39 39-17 72 7 29 20 47 52l40 72 14 22q2 2 1 4l-16 42-2 1-17-27z'
/>
<path
fill='#0fd1c1'
fillRule='evenodd'
d='M540 775q19 17 31 40 10 22 27 38 15 14 33 19l10 3v2l-43 12q-14 5-24-7-19-19-33-43-12-22-31-39-24-17-53-23l-55-11q-83-22-125-97-40-72-34-154l4-68q0-17-6-35-12-29-44-32-28-2-55 11l-27 13-7 3 9-33 2-4c5-15 5-15 20-20 23-7 46-12 71-7q62 12 71 75 4 33-2 66c-5 53 0 105 23 154q26 57 80 83 32 14 67 19c22 3 44 6 63 17q15 8 28 18m137 48c-41-8-64-45-54-86q7-27 21-49l47-72q9-12 21-22c19-16 44-15 62 3q23 24 31 55 14 41 9 83l-4 21-3 5q-25 30-57 54-7 4-15 6-28 7-58 2m26-168-28 49q-12 21-14 44 0 30 29 37 23 4 44-4 32-11 40-44 6-24 1-50-3-27-15-52-18-28-40-4v1z'
/>
<path
fill='#0fd1c1'
fillRule='evenodd'
d='M569 573a96 96 0 0 1-165-51 96 96 0 0 1 119-107 95 95 0 0 1 46 158m-13-44q9-21 1-42a61 61 0 0 0-118 31c3 23 22 43 45 48 31 8 61-8 72-37M226 788c10-24 5-46-5-68l-19-44q-26-58-22-122l-2-41q0-5-3-8-6-17-23-12-18 5-31 18l-18 19-4 4-1-10 2-41q22-19 51-26 42-8 56 34 6 21 5 44-1 35 3 69 9 45 31 84c10 19 21 38 25 60q9 33-7 65l-4 7-28-25zm82-550q37-2 72-14a130 130 0 0 0 89-121v-6h40q1 18-2 38-19 77-90 113c-47 24-97 31-148 29l-74-3-21 3-10 1 19-26 12-15q4-4 9-3l70 4zm471-4 14 33q10 15 25 23 26 12 47 31l3 4 24 66-21-16q-22-20-45-38l-36-21q-27-18-38-48l-10-28q-15-42-54-62l-70-32q-27-10-50-30l-14-16 1-1 33 6q76 16 140 60c26 17 40 41 51 69m-177 78q-27-6-47-23-30-24-20-59 11-37 50-45 25-4 47 9 35 17 56 50c11 19 11 42-1 57a49 49 0 0 1-40 19q-23 0-45-8m1-35q10 5 21 7 12 3 23 3 17-3 16-21-1-10-8-17-17-18-39-29-9-5-20-5c-20 0-33 21-23 39 6 12 17 17 30 23M440 867c-23-11-45-6-65 7q-5 5-11 2l-29-12c13-19 52-43 92-38 36 4 80 40 88 73h-39l-4-4q-11-18-32-28'
/>
<path
fill='#0fd1c1'
d='M293 185q-22 5-47 3 75-61 167-82l1 1-11 18q-16 22-42 35-31 18-68 25'
/>
</svg>
)
}

export function TailscaleIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' fill='none' {...props}>
Expand Down
2 changes: 2 additions & 0 deletions apps/docs/components/ui/icon-mapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ import {
SendblueIcon,
SendgridIcon,
SentryIcon,
SerpdiveIcon,
SerperIcon,
ServiceNowIcon,
SftpIcon,
Expand Down Expand Up @@ -455,6 +456,7 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
sendblue: SendblueIcon,
sendgrid: SendgridIcon,
sentry: SentryIcon,
serpdive: SerpdiveIcon,
serper: SerperIcon,
servicenow: ServiceNowIcon,
ses: SESIcon,
Expand Down
3 changes: 2 additions & 1 deletion apps/docs/content/docs/en/integrations/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@
"sendblue",
"sendgrid",
"sentry",
"serpdive",
"serper",
"servicenow",
"ses",
Expand Down Expand Up @@ -264,4 +265,4 @@
"zoom",
"zoominfo"
]
}
}
66 changes: 66 additions & 0 deletions apps/docs/content/docs/en/integrations/serpdive.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
title: SERPdive
description: Search the web with SERPdive
---

import { BlockInfoCard } from "@/components/ui/block-info-card"

<BlockInfoCard
type="serpdive"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Brand Icon Falls Back To Text

BlockInfoCard resolves serpdive through the docs icon map, but this PR adds no matching map entry and passes no explicit icon. The integration page therefore renders its se text fallback instead of the new SERPdive icon.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

color="#0A0F13"
/>

{/* MANUAL-CONTENT-START:intro */}
[SERPdive](https://serpdive.com) is a web search API built for AI agents. Instead of a list of links or short snippets, one call returns the extracted, answer-ready content of each source page, cleaned and sized for a context window.

SERPdive gives your agents live web access without a scraping loop to maintain:

- **Answer-ready content**: every result carries the readable content of the page, so the agent can quote and cite facts straight from the response.
- **Two retrieval depths**: Mako returns the fact-carrying sentences of each source and is fast; Moby returns the full readable content of every page when whole-page context matters.
- **Optional written answer**: the API can also return an answer built from the sources, concise on Mako and cited on Moby.
- **Automatic localization**: the query's language decides where the search runs, so no country parameter is needed.

Quality is measured, not asserted: on a [public, replayable 1,000-question benchmark](https://github.com/edendalexis/serpdive-benchmark) judged blind by an independent model, SERPdive runs at the same speed as Tavily, feeds the LLM **20.2% fewer tokens**, and wins **60.7% of decided quality duels** against Tavily's default search.

Every account gets 1,000 free credits per month with no card.
{/* MANUAL-CONTENT-END */}


## Usage Instructions

Integrate SERPdive into the workflow. Can search the web and return the extracted, answer-ready content of each source instead of links or snippets.



## Actions

### `serpdive_search`

Search the web with SERPdive. Each result carries the extracted, answer-ready content of the page instead of a link or snippet, cleaned and sized for an LLM.

#### Input

| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `query` | string | Yes | The search query, phrased as a question or topic, in any language \(e.g., "what changed in the latest Next.js release"\). Maximum 300 characters. |
| `model` | string | No | Retrieval depth: mako \(1 credit\) returns the fact-carrying sentences of each source, moby \(1.5 credits\) returns the full readable content of every page \(e.g., "mako"\) |
| `answer` | boolean | No | Also return a written answer built from the sources: concise on mako, detailed with citations on moby. No extra credits. |
| `max_results` | number | No | Hard cap on delivered results, keeping the best-ranked ones \(1-10, e.g., 5\). Omit to get everything relevant. |
| `apiKey` | string | Yes | SERPdive API Key |

#### Output

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `query` | string | The search query that was executed |
| `results` | array | Delivered sources, best first, each carrying the extracted content of the page |
| ↳ `url` | string | Result URL, tracking parameters stripped |
| ↳ `title` | string | Page title |
| ↳ `content` | string | Extracted, answer-ready content of the page |
| ↳ `date` | string | Publication date when known, ISO YYYY-MM-DD |
| `answer` | string | Written answer built from the sources \(if requested\) |
| `extra_info` | object | Structured direct-answer block \(weather, exchange rates, live scores...\) when the query has one |
| `model` | string | The retrieval model that answered: mako or moby |
| `response_time_ms` | number | Time taken for the search request in milliseconds |


200 changes: 200 additions & 0 deletions apps/sim/blocks/blocks/serpdive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
import { SerpdiveIcon } from '@/components/icons'
import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types'
import type { SerpdiveSearchResponse } from '@/tools/serpdive/types'

export const SerpdiveBlock: BlockConfig<SerpdiveSearchResponse> = {
type: 'serpdive',
name: 'SERPdive',
description: 'Search the web with SERPdive',
authMode: AuthMode.ApiKey,
longDescription:
'Integrate SERPdive into the workflow. Can search the web and return the extracted, answer-ready content of each source instead of links or snippets.',
docsLink: 'https://docs.sim.ai/integrations/serpdive',
category: 'tools',
integrationType: IntegrationType.Search,
bgColor: '#0A0F13',
icon: SerpdiveIcon,

subBlocks: [
{
id: 'query',
title: 'Search Query',
type: 'long-input',
placeholder: 'Enter your search query',
required: true,
},
{
id: 'model',
title: 'Retrieval Depth',
type: 'dropdown',
options: [
{ label: 'Mako (fast, key sentences)', id: 'mako' },
{ label: 'Moby (full page content)', id: 'moby' },
],
value: () => 'mako',
},
{
id: 'answer',
title: 'Include Answer',
type: 'switch',
mode: 'advanced',
},
{
id: 'max_results',
title: 'Max Results',
type: 'short-input',
placeholder: '5',
mode: 'advanced',
},
{
id: 'apiKey',
title: 'API Key',
type: 'short-input',
placeholder: 'Enter your SERPdive API key',
password: true,
required: true,
},
],

tools: {
access: ['serpdive_search'],
},

inputs: {
query: { type: 'string', description: 'Search query' },
apiKey: { type: 'string', description: 'SERPdive API key' },
model: { type: 'string', description: 'Retrieval depth: mako or moby' },
answer: { type: 'boolean', description: 'Also return a written answer built from the sources' },
max_results: { type: 'number', description: 'Hard cap on delivered results (1-10)' },
},

outputs: {
query: { type: 'string', description: 'Search query used' },
results: { type: 'json', description: 'Sources with extracted page content' },
answer: { type: 'string', description: 'Written answer built from the sources' },
extra_info: {
type: 'json',
description: 'Structured direct-answer block, when the query has one',
},
model: { type: 'string', description: 'Retrieval model that answered' },
response_time_ms: { type: 'number', description: 'Request duration in milliseconds' },
},
}

export const SerpdiveBlockMeta = {
tags: ['web-scraping', 'enrichment'],
url: 'https://serpdive.com',
templates: [
{
icon: SerpdiveIcon,
title: 'SERPdive research agent',
prompt:
'Build a research agent that takes a question, runs SERPdive searches to gather live sources, and returns a written answer with the source URLs it relied on.',
modules: ['agent', 'workflows'],
category: 'productivity',
tags: ['research'],
},
{
icon: SerpdiveIcon,
title: 'SERPdive daily digest',
prompt:
'Create a scheduled daily workflow that searches SERPdive for tracked topics, summarizes the extracted content from each source, and emails a digest with links.',
modules: ['scheduled', 'agent', 'workflows'],
category: 'productivity',
tags: ['research', 'reporting'],
alsoIntegrations: ['gmail'],
},
{
icon: SerpdiveIcon,
title: 'SERPdive competitor monitor',
prompt:
'Build a scheduled weekly workflow that searches SERPdive for competitor mentions, scores each result for relevance, and appends new findings to a competitive intel table.',
modules: ['scheduled', 'tables', 'agent', 'workflows'],
category: 'marketing',
tags: ['marketing', 'monitoring'],
},
{
icon: SerpdiveIcon,
title: 'SERPdive lead enrichment',
prompt:
'Create a workflow that for each company in a table runs a SERPdive search on recent news and funding, then writes a short enriched summary back to the row.',
modules: ['tables', 'agent', 'workflows'],
category: 'sales',
tags: ['sales', 'enrichment'],
},
{
icon: SerpdiveIcon,
title: 'SERPdive fact checker',
prompt:
'Build a workflow that takes a claim, searches SERPdive with the answer option on, and returns a verdict backed by quotes from the extracted source content.',
modules: ['agent', 'workflows'],
category: 'productivity',
tags: ['research'],
},
{
icon: SerpdiveIcon,
title: 'SERPdive + Slack answer bot',
prompt:
'Build a Slack bot that answers questions about current events by searching SERPdive, replying in-thread with the answer and the source links it used.',
modules: ['agent', 'workflows'],
category: 'productivity',
tags: ['research', 'communication'],
alsoIntegrations: ['slack'],
},
{
icon: SerpdiveIcon,
title: 'SERPdive knowledge base feeder',
prompt:
'Create a workflow that searches SERPdive on a topic with full page content, then writes the extracted content of each source into a knowledge base for later retrieval.',
modules: ['agent', 'knowledge-base', 'workflows'],
category: 'productivity',
tags: ['research'],
},
{
icon: SerpdiveIcon,
title: 'SERPdive research report',
prompt:
'Build a workflow that for a chosen topic runs several SERPdive searches with full page content, synthesizes the findings, and writes a cited report file.',
modules: ['agent', 'files', 'workflows'],
category: 'productivity',
tags: ['research', 'content'],
},
],
skills: [
{
name: 'answer-with-sources',
description:
'Answer a question with SERPdive and surface the source URLs the answer was built from.',
content:
'# Answer with Sources\n\nGround an answer in live web content using SERPdive.\n\n## Steps\n1. Set the search query to the user question, phrased the way someone would search it.\n2. Turn on Include Answer so the response carries a written answer built from the sources.\n3. Use Moby retrieval depth when the question needs whole-page context, otherwise leave it on Mako.\n4. Present the answer and attach the URL of every result it drew on.\n\n## Output\nA concise answer followed by the list of source URLs that support it.',
},
{
name: 'gather-research-sources',
description:
'Run a SERPdive search and return a ranked list of sources with their extracted page content.',
content:
'# Gather Research Sources\n\nCollect sources on a topic for downstream research.\n\n## Steps\n1. Set the search query to the research topic, narrowed with the key terms that matter.\n2. Leave Include Answer off so the response is sources only.\n3. Set Max Results to bound how many sources come back, and pick Moby when full page text is needed.\n4. Review the returned results and order them by relevance to the topic.\n\n## Output\nA ranked list of sources with title, URL, and the extracted content of each page, ready to feed a summarizer or knowledge base.',
},
{
name: 'monitor-topic-mentions',
description:
'Search SERPdive for recent mentions of a brand, competitor, or topic and summarize what is new.',
content:
'# Monitor Topic Mentions\n\nTrack fresh mentions of a topic or competitor.\n\n## Steps\n1. Set the search query to the brand, competitor, or topic to monitor, adding a recency word such as the current month or "latest".\n2. Leave Include Answer off and keep Mako depth so the run stays fast and lean.\n3. Compare the returned URLs against mentions already recorded and keep only the new ones.\n4. Summarize each new mention in one line, keeping its source URL.\n\n## Output\nA list of new mentions, each with source URL and a one-line summary.',
},
{
name: 'enrich-company-record',
description:
'Search SERPdive for recent public information about a company and write a short enrichment summary.',
content:
'# Enrich Company Record\n\nAdd fresh public context to a company record.\n\n## Steps\n1. Set the search query to the company name plus what you need, for example recent funding, product launches, or leadership changes.\n2. Set Max Results to a small number so the summary stays focused.\n3. Read the extracted content of each result and pull out only facts that are stated in the sources.\n4. Write a short summary and keep the source URL for each fact.\n\n## Output\nA few sentences of enrichment with a source URL per claim, ready to write back to the record.',
},
{
name: 'verify-a-claim',
description:
'Check a specific claim against live sources with SERPdive and report whether the sources support it.',
content:
'# Verify a Claim\n\nCheck a claim against what live sources actually say.\n\n## Steps\n1. Set the search query to the claim itself, phrased neutrally rather than as a leading question.\n2. Turn on Include Answer and use Moby depth so the response carries full page context.\n3. Quote the passages in the extracted content that address the claim directly.\n4. State whether the sources support, contradict, or do not address the claim, and never assert beyond what the quotes show.\n\n## Output\nA verdict with the supporting quotes and their source URLs.',
},
],
} as const satisfies BlockMeta
5 changes: 4 additions & 1 deletion apps/sim/blocks/registry-maps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ import { SecretsManagerBlock, SecretsManagerBlockMeta } from '@/blocks/blocks/se
import { SendblueBlock, SendblueBlockMeta } from '@/blocks/blocks/sendblue'
import { SendGridBlock, SendGridBlockMeta } from '@/blocks/blocks/sendgrid'
import { SentryBlock, SentryBlockMeta } from '@/blocks/blocks/sentry'
import { SerpdiveBlock, SerpdiveBlockMeta } from '@/blocks/blocks/serpdive'
import { SerperBlock, SerperBlockMeta } from '@/blocks/blocks/serper'
import { ServiceNowBlock, ServiceNowBlockMeta } from '@/blocks/blocks/servicenow'
import { SESBlock, SESBlockMeta } from '@/blocks/blocks/ses'
Expand Down Expand Up @@ -584,6 +585,7 @@ export const BLOCK_REGISTRY: Record<string, BlockConfig> = {
sendblue: SendblueBlock,
sendgrid: SendGridBlock,
sentry: SentryBlock,
serpdive: SerpdiveBlock,
serper: SerperBlock,
servicenow: ServiceNowBlock,
ses: SESBlock,
Expand Down Expand Up @@ -869,6 +871,7 @@ export const BLOCK_META_REGISTRY: Record<string, BlockMeta> = {
sendblue: SendblueBlockMeta,
sendgrid: SendGridBlockMeta,
sentry: SentryBlockMeta,
serpdive: SerpdiveBlockMeta,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Catalog Registration Is Incomplete

This adds SERPdive to BLOCK_META_REGISTRY, but the required matching record is absent from apps/sim/lib/integrations/integrations.json. Catalog and integration-management surfaces that read that inventory will omit SERPdive even though its block is available in workflows.

serper: SerperBlockMeta,
servicenow: ServiceNowBlockMeta,
ses: SESBlockMeta,
Expand Down Expand Up @@ -919,4 +922,4 @@ export const BLOCK_META_REGISTRY: Record<string, BlockMeta> = {
zerobounce: ZeroBounceBlockMeta,
zoom: ZoomBlockMeta,
zoominfo: ZoomInfoBlockMeta,
}
}
Loading