feat(wiza): add Wiza integration for B2B prospect enrichment and search (#4662)

* feat(wiza): add Wiza integration for B2B prospect enrichment and search

* fix(wiza): coerce reveal id to string, skip empty filters in prospect search

* fix(wiza): throw on invalid JSON in advanced filter fields instead of silently dropping
This commit is contained in:
Waleed
2026-05-19 12:06:19 -07:00
committed by GitHub
parent ef14b2b580
commit b98164fd3d
18 changed files with 1700 additions and 2 deletions
+11
View File
@@ -6950,3 +6950,14 @@ export function SnowflakeIcon(props: SVGProps<SVGSVGElement>) {
</svg>
)
}
export function WizaIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg {...props} viewBox='0 0 51 49' fill='none' xmlns='http://www.w3.org/2000/svg'>
<path
fill='#FFFFFF'
d='m50.3 33.6-9.3-3.5c-2.9-10.4-9.6-20.8-17.1-29.4-1.4-1.5-4.4-0.7-4.2 1.9 0.4 6-0.4 13.3-4.4 20.5-0.9 1.6 1.4 3.3 2.9 1.6 3.2-3.3 5.3-9.1 6.3-15.2 3.9 5.4 9.2 13.8 11.2 22.9 0.2 0.9 0.8 1.6 1.6 1.9l6.2 2.3c-4.1 3.3-9.6 6-17.7 6-7.1 0-13.2-2.3-18.5-6l3.6-2.5c3.5 2 7.5 3.5 12.5 3.6 2.5 0 5-0.2 7.3-0.9 2-0.5 1.6-3.2-0.3-3-4 0.5-10.3 0.3-17.1-4.3-0.8-0.5-1.9-0.6-2.7-0.2l-9.2 4.3c-1.4 0.6-2.1 3.1-0.5 4.3 4.7 3.8 12.4 10.1 24.2 10.1 11.9 0 20.4-4.3 25.8-10.1 1.2-1.2 1.2-3.5-0.6-4.3z'
/>
</svg>
)
}
+2
View File
@@ -197,6 +197,7 @@ import {
WebflowIcon,
WhatsAppIcon,
WikipediaIcon,
WizaIcon,
WordpressIcon,
WorkdayIcon,
xIcon,
@@ -426,6 +427,7 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
webflow: WebflowIcon,
whatsapp: WhatsAppIcon,
wikipedia: WikipediaIcon,
wiza: WizaIcon,
wordpress: WordpressIcon,
workday: WorkdayIcon,
x: xIcon,
@@ -56,7 +56,7 @@ Read content from a Google Docs document
### `google_docs_write`
Write or update content in a Google Docs document
Append content to a Google Docs document. Content is inserted literally; Markdown is not interpreted. For formatted output from Markdown, use the Create operation with the markdown toggle enabled.
#### Input
@@ -88,6 +88,7 @@ Create a new Google Docs document
| `content` | string | No | The content of the document to create |
| `folderSelector` | string | No | Google Drive folder ID to create the document in \(e.g., 1ABCxyz...\) |
| `folderId` | string | No | The ID of the folder to create the document in \(internal use\) |
| `markdown` | boolean | No | When true, content is interpreted as Markdown and converted to formatted Google Docs content \(headings, bold/italic, lists, tables, links, code blocks, blockquotes\). Default: false \(content inserted as plain text\). |
#### Output
@@ -197,6 +197,7 @@
"webflow",
"whatsapp",
"wikipedia",
"wiza",
"wordpress",
"workday",
"x",
+251
View File
@@ -0,0 +1,251 @@
---
title: Wiza
description: Find, enrich, and verify B2B contact data with Wiza
---
import { BlockInfoCard } from "@/components/ui/block-info-card"
<BlockInfoCard
type="wiza"
color="#9284BC"
/>
{/* MANUAL-CONTENT-START:intro */}
[Wiza](https://wiza.co/) is a B2B contact data platform that finds and verifies emails and phone numbers for sales, recruiting, and marketing teams. Wiza pairs a global prospect database with real-time enrichment, so the data you act on stays accurate and deliverable.
With Wiza, you can:
- **Search a global prospect database**: Find people using person, company, and financial filters
- **Enrich companies**: Resolve firmographic data from a name, domain, or LinkedIn URL
- **Reveal individual contacts**: Get verified work emails, personal emails, and mobile phone numbers
- **Track credit usage**: Check remaining email, phone, export, and API credits at any time
In Sim, the Wiza integration lets your agents drive prospecting and enrichment workflows end-to-end:
- **Prospect Search**: Use `wiza_prospect_search` to discover prospects matching detailed filters.
- **Company Enrichment**: Use `wiza_company_enrichment` to enrich a company from name, domain, LinkedIn ID, or LinkedIn slug.
- **Start Individual Reveal**: Use `wiza_start_individual_reveal` to begin enrichment for a contact via LinkedIn URL, name + company, or email — with configurable enrichment depth (`none`, `partial`, `phone`, `full`).
- **Get Individual Reveal**: Use `wiza_get_individual_reveal` to poll a reveal and retrieve verified emails, phones, and full company context.
- **Get Credits**: Use `wiza_get_credits` to monitor remaining credit balances before scaling up runs.
Individual reveals are asynchronous: start a reveal, then poll `wiza_get_individual_reveal` until `is_complete` is `true`. Combine these tools to build agents that source, enrich, and qualify leads on demand — without leaving your workflow.
{/* MANUAL-CONTENT-END */}
## Usage Instructions
{/* MANUAL-CONTENT-START:usage */}
### Wiza API Key Setup
Wiza authenticates via API key. To get yours:
1. Log in to your [Wiza account](https://app.wiza.co/).
2. Open **Settings → API** and generate a new API key (or copy an existing one).
3. In Sim, open the Wiza block and paste the key into the **Wiza API Key** field.
The same key is used for every Wiza operation. Wiza enforces a rate limit of 30 requests per minute (43,200 per day) per key.
### Individual Reveals Are Asynchronous
`wiza_start_individual_reveal` returns immediately with a reveal `id` and a `status` of `queued` or `resolving`. To retrieve the enriched contact data, call `wiza_get_individual_reveal` with that `id` and check `is_complete`. Possible statuses are `queued`, `resolving`, `finished`, and `failed`.
For real-time delivery without polling, pass a `callback_url` when starting the reveal — Wiza will POST the completed payload to that URL.
### Enrichment Levels and Credits
When starting an individual reveal, choose the enrichment level that matches the data you need:
- **`none`** — Identity only, no contact info (no credit spend)
- **`partial`** — Verified work email (email credits)
- **`phone`** — Mobile phone (phone credits)
- **`full`** — Email + phone (email + phone credits)
Use `wiza_get_credits` to monitor remaining email, phone, export, and API credits before running large batches.
{/* MANUAL-CONTENT-END */}
Integrates Wiza into the workflow. Search prospects, enrich companies, reveal verified emails and phone numbers for individuals, and check your account credit balance.
## Tools
### `wiza_prospect_search`
Search Wiza
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Wiza API key |
| `size` | number | No | Number of sample profiles to return \(0-30, default 0\) |
| `filters` | object | No | Full filters object \(overrides individual filter params if provided\) |
| `first_name` | array | No | Exact first names to match \(e.g., \["John", "Jane"\]\) |
| `last_name` | array | No | Exact last names to match |
| `job_title` | array | No | Job titles to include/exclude \(e.g., \[\{"v":"CEO","s":"i"\},\{"v":"CTO","s":"e"\}\]\) |
| `job_title_level` | array | No | Seniority levels \(e.g., \["cxo", "director", "manager"\]\) |
| `job_role` | array | No | Job role categories \(e.g., \["sales", "engineering", "marketing"\]\) |
| `job_sub_role` | array | No | Detailed role categories \(e.g., \["software", "product"\]\) |
| `location` | array | No | Person's location filters \(city/state/country with include/exclude\) |
| `skill` | array | No | Professional skills \(e.g., \["python", "marketing"\]\) |
| `school` | array | No | Educational institutions |
| `major` | array | No | Field of study |
| `linkedin_slug` | array | No | LinkedIn profile slugs |
| `job_company` | array | No | Current company filters \(include/exclude\) |
| `past_company` | array | No | Past company filters |
| `company_location` | array | No | Company HQ location filters |
| `company_industry` | array | No | Company industry filters \(include/exclude\) |
| `company_size` | array | No | Company headcount brackets \(e.g., \["1-10", "11-50", "51-200"\]\) |
| `company_type` | array | No | Company type \(e.g., \["private", "public", "educational"\]\) |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `total` | number | Total number of matching prospects |
| `profiles` | array | Sample profiles matching the filter criteria |
### `wiza_company_enrichment`
Enrich a company by name, domain, LinkedIn ID, or LinkedIn slug with detailed firmographic data
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Wiza API key |
| `company_name` | string | No | Company name \(e.g., "Wiza"\) |
| `company_domain` | string | No | Company domain \(e.g., "wiza.co"\) |
| `company_linkedin_id` | string | No | Company LinkedIn ID |
| `company_linkedin_slug` | string | No | Company LinkedIn slug from the URL |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `company_name` | string | Company name |
| `company_domain` | string | Company domain |
| `domain` | string | Domain |
| `company_industry` | string | Industry |
| `company_size` | number | Employee count |
| `company_size_range` | string | Headcount range |
| `company_founded` | number | Year founded |
| `company_revenue_range` | string | Revenue range |
| `company_funding` | string | Total funding |
| `company_type` | string | Company type |
| `company_description` | string | Description |
| `company_ticker` | string | Stock ticker |
| `company_last_funding_round` | string | Last funding round |
| `company_last_funding_amount` | string | Last funding amount |
| `company_last_funding_at` | string | Last funding date |
| `company_location` | string | Full location string |
| `company_twitter` | string | Twitter URL |
| `company_facebook` | string | Facebook URL |
| `company_linkedin` | string | LinkedIn URL |
| `company_linkedin_id` | string | LinkedIn ID |
| `company_street` | string | Street address |
| `company_locality` | string | City |
| `company_region` | string | State/region |
| `company_postal_code` | string | Postal code |
| `company_country` | string | Country |
| `credits` | json | Remaining API credits |
### `wiza_start_individual_reveal`
Start an individual reveal to enrich a contact via LinkedIn URL, name+company, or email
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Wiza API key |
| `enrichment_level` | string | Yes | Enrichment depth: none, partial, phone, or full |
| `profile_url` | string | No | LinkedIn profile URL \(e.g., https://linkedin.com/in/johndoe\) |
| `full_name` | string | No | Full name \(used with company or domain\) |
| `company` | string | No | Company name \(used with full_name\) |
| `domain` | string | No | Company domain \(used with full_name\) |
| `email` | string | No | Email address \(use alone or with other identifiers\) |
| `accept_work` | boolean | No | Whether to accept work emails \(email_options\) |
| `accept_personal` | boolean | No | Whether to accept personal emails \(email_options\) |
| `callback_url` | string | No | Optional URL to receive a callback with the reveal update |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `id` | number | Individual reveal ID \(use with Get Individual Reveal\) |
| `status` | string | Reveal status: queued, resolving, finished, or failed |
| `is_complete` | boolean | Whether the reveal has completed |
### `wiza_get_individual_reveal`
Retrieve the status and enriched data for an individual reveal by ID
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Wiza API key |
| `id` | string | Yes | Individual reveal ID returned from Start Individual Reveal |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `id` | number | Reveal ID |
| `status` | string | queued \| resolving \| finished \| failed |
| `is_complete` | boolean | Whether the reveal has completed |
| `name` | string | Full name |
| `company` | string | Company name |
| `enrichment_level` | string | Enrichment level used |
| `linkedin_profile_url` | string | LinkedIn URL |
| `title` | string | Job title |
| `location` | string | Location |
| `email` | string | Primary email |
| `email_type` | string | Email type |
| `email_status` | string | valid \| risky \| unfound |
| `emails` | array | All emails found |
| `mobile_phone` | string | Mobile phone |
| `phone_number` | string | Direct/office phone |
| `phone_status` | string | found \| unfound |
| `phones` | array | All phones found |
| `company_size` | number | Employee count |
| `company_size_range` | string | Headcount range |
| `company_type` | string | Company type |
| `company_domain` | string | Company domain |
| `company_locality` | string | City |
| `company_region` | string | State/region |
| `company_country` | string | Country |
| `company_street` | string | Street |
| `company_postal_code` | string | Postal code |
| `company_founded` | number | Year founded |
| `company_funding` | string | Funding total |
| `company_revenue` | string | Revenue |
| `company_industry` | string | Industry |
| `company_subindustry` | string | Subindustry |
| `company_linkedin` | string | Company LinkedIn URL |
| `company_location` | string | Full company location |
| `company_description` | string | Company description |
| `credits` | json | Remaining credits balance |
### `wiza_get_credits`
Retrieve the remaining credits on your Wiza account
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Wiza API key |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `email_credits` | json | Remaining email credits \(number or "unlimited"\) |
| `phone_credits` | json | Remaining phone credits \(number or "unlimited"\) |
| `export_credits` | number | Remaining export credits |
| `api_credits` | number | Remaining API credits |
@@ -197,6 +197,7 @@ import {
WebflowIcon,
WhatsAppIcon,
WikipediaIcon,
WizaIcon,
WordpressIcon,
WorkdayIcon,
xIcon,
@@ -403,6 +404,7 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
webflow: WebflowIcon,
whatsapp: WhatsAppIcon,
wikipedia: WikipediaIcon,
wiza: WizaIcon,
wordpress: WordpressIcon,
workday: WorkdayIcon,
x: xIcon,
@@ -5202,7 +5202,7 @@
},
{
"name": "Write to Document",
"description": "Write or update content in a Google Docs document"
"description": "Append content to a Google Docs document. Content is inserted literally; Markdown is not interpreted. For formatted output from Markdown, use the Create operation with the markdown toggle enabled."
},
{
"name": "Create Document",
@@ -14212,6 +14212,45 @@
"integrationTypes": ["search", "documents"],
"tags": ["knowledge-base", "web-scraping"]
},
{
"type": "wiza",
"slug": "wiza",
"name": "Wiza",
"description": "Find, enrich, and verify B2B contact data with Wiza",
"longDescription": "Integrates Wiza into the workflow. Search prospects, enrich companies, reveal verified emails and phone numbers for individuals, and check your account credit balance.",
"bgColor": "#9284BC",
"iconName": "WizaIcon",
"docsUrl": "https://docs.sim.ai/tools/wiza",
"operations": [
{
"name": "Prospect Search",
"description": "Search Wiza"
},
{
"name": "Company Enrichment",
"description": "Enrich a company by name, domain, LinkedIn ID, or LinkedIn slug with detailed firmographic data"
},
{
"name": "Start Individual Reveal",
"description": "Start an individual reveal to enrich a contact via LinkedIn URL, name+company, or email"
},
{
"name": "Get Individual Reveal",
"description": "Retrieve the status and enriched data for an individual reveal by ID"
},
{
"name": "Get Credits",
"description": "Retrieve the remaining credits on your Wiza account"
}
],
"operationCount": 5,
"triggers": [],
"triggerCount": 0,
"authType": "api-key",
"category": "tools",
"integrationTypes": ["sales"],
"tags": ["enrichment", "sales-engagement"]
},
{
"type": "wordpress",
"slug": "wordpress",
+427
View File
@@ -0,0 +1,427 @@
import { WizaIcon } from '@/components/icons'
import type { BlockConfig } from '@/blocks/types'
import { AuthMode, IntegrationType } from '@/blocks/types'
import type { WizaResponse } from '@/tools/wiza/types'
export const WizaBlock: BlockConfig<WizaResponse> = {
type: 'wiza',
name: 'Wiza',
description: 'Find, enrich, and verify B2B contact data with Wiza',
authMode: AuthMode.ApiKey,
longDescription:
'Integrates Wiza into the workflow. Search prospects, enrich companies, reveal verified emails and phone numbers for individuals, and check your account credit balance.',
docsLink: 'https://docs.sim.ai/tools/wiza',
category: 'tools',
integrationType: IntegrationType.Sales,
tags: ['enrichment', 'sales-engagement'],
bgColor: '#9284BC',
icon: WizaIcon,
subBlocks: [
{
id: 'operation',
title: 'Operation',
type: 'dropdown',
options: [
{ label: 'Prospect Search', id: 'prospect_search' },
{ label: 'Company Enrichment', id: 'company_enrichment' },
{ label: 'Start Individual Reveal', id: 'start_individual_reveal' },
{ label: 'Get Individual Reveal', id: 'get_individual_reveal' },
{ label: 'Get Credits', id: 'get_credits' },
],
value: () => 'prospect_search',
},
{
id: 'apiKey',
title: 'Wiza API Key',
type: 'short-input',
placeholder: 'Enter your Wiza API key',
password: true,
required: true,
},
// Prospect Search
{
id: 'size',
title: 'Sample Size',
type: 'short-input',
placeholder: '0-30 (default 0, returns total only)',
condition: { field: 'operation', value: 'prospect_search' },
},
{
id: 'job_title',
title: 'Job Titles',
type: 'code',
placeholder: '[{"v":"CEO","s":"i"},{"v":"Founder","s":"i"}]',
condition: { field: 'operation', value: 'prospect_search' },
mode: 'advanced',
},
{
id: 'job_title_level',
title: 'Job Title Levels',
type: 'code',
placeholder: '["cxo", "director", "manager"]',
condition: { field: 'operation', value: 'prospect_search' },
mode: 'advanced',
},
{
id: 'job_role',
title: 'Job Roles',
type: 'code',
placeholder: '["sales", "engineering", "marketing"]',
condition: { field: 'operation', value: 'prospect_search' },
mode: 'advanced',
},
{
id: 'job_sub_role',
title: 'Job Sub-Roles',
type: 'code',
placeholder: '["software", "product"]',
condition: { field: 'operation', value: 'prospect_search' },
mode: 'advanced',
},
{
id: 'first_name',
title: 'First Names',
type: 'code',
placeholder: '["John", "Jane"]',
condition: { field: 'operation', value: 'prospect_search' },
mode: 'advanced',
},
{
id: 'last_name',
title: 'Last Names',
type: 'code',
placeholder: '["Smith", "Doe"]',
condition: { field: 'operation', value: 'prospect_search' },
mode: 'advanced',
},
{
id: 'location',
title: 'Person Locations',
type: 'code',
placeholder: '[{"v":{"country":"united states"},"b":"city","s":"i"}]',
condition: { field: 'operation', value: 'prospect_search' },
mode: 'advanced',
},
{
id: 'skill',
title: 'Skills',
type: 'code',
placeholder: '["python", "marketing"]',
condition: { field: 'operation', value: 'prospect_search' },
mode: 'advanced',
},
{
id: 'school',
title: 'Schools',
type: 'code',
placeholder: '["stanford university"]',
condition: { field: 'operation', value: 'prospect_search' },
mode: 'advanced',
},
{
id: 'major',
title: 'Majors',
type: 'code',
placeholder: '["computer science"]',
condition: { field: 'operation', value: 'prospect_search' },
mode: 'advanced',
},
{
id: 'linkedin_slug',
title: 'LinkedIn Slugs',
type: 'code',
placeholder: '["john-doe-123"]',
condition: { field: 'operation', value: 'prospect_search' },
mode: 'advanced',
},
{
id: 'job_company',
title: 'Current Companies',
type: 'code',
placeholder: '[{"v":"wiza","s":"i"}]',
condition: { field: 'operation', value: 'prospect_search' },
mode: 'advanced',
},
{
id: 'past_company',
title: 'Past Companies',
type: 'code',
placeholder: '[{"v":"google","s":"i"}]',
condition: { field: 'operation', value: 'prospect_search' },
mode: 'advanced',
},
{
id: 'company_location',
title: 'Company Locations',
type: 'code',
placeholder: '[{"v":{"country":"canada"},"b":"country","s":"i"}]',
condition: { field: 'operation', value: 'prospect_search' },
mode: 'advanced',
},
{
id: 'company_industry',
title: 'Company Industries',
type: 'code',
placeholder: '[{"v":"computer software","s":"i"}]',
condition: { field: 'operation', value: 'prospect_search' },
mode: 'advanced',
},
{
id: 'company_size',
title: 'Company Sizes',
type: 'code',
placeholder: '["11-50", "51-200"]',
condition: { field: 'operation', value: 'prospect_search' },
mode: 'advanced',
},
{
id: 'company_type',
title: 'Company Types',
type: 'code',
placeholder: '["private", "public"]',
condition: { field: 'operation', value: 'prospect_search' },
mode: 'advanced',
},
{
id: 'filters',
title: 'Full Filters Object (overrides above)',
type: 'code',
placeholder: '{"job_title":[{"v":"CEO","s":"i"}], "company_size":["11-50"]}',
condition: { field: 'operation', value: 'prospect_search' },
mode: 'advanced',
},
// Company Enrichment
{
id: 'company_name',
title: 'Company Name',
type: 'short-input',
placeholder: 'Wiza',
condition: { field: 'operation', value: 'company_enrichment' },
},
{
id: 'company_domain',
title: 'Company Domain',
type: 'short-input',
placeholder: 'wiza.co',
condition: { field: 'operation', value: 'company_enrichment' },
},
{
id: 'company_linkedin_id',
title: 'Company LinkedIn ID',
type: 'short-input',
placeholder: '11272782',
condition: { field: 'operation', value: 'company_enrichment' },
mode: 'advanced',
},
{
id: 'company_linkedin_slug',
title: 'Company LinkedIn Slug',
type: 'short-input',
placeholder: 'wizaco',
condition: { field: 'operation', value: 'company_enrichment' },
mode: 'advanced',
},
// Start Individual Reveal
{
id: 'enrichment_level',
title: 'Enrichment Level',
type: 'dropdown',
options: [
{ label: 'None', id: 'none' },
{ label: 'Partial', id: 'partial' },
{ label: 'Phone', id: 'phone' },
{ label: 'Full', id: 'full' },
],
value: () => 'full',
condition: { field: 'operation', value: 'start_individual_reveal' },
required: { field: 'operation', value: 'start_individual_reveal' },
},
{
id: 'profile_url',
title: 'LinkedIn Profile URL',
type: 'short-input',
placeholder: 'https://linkedin.com/in/johndoe',
condition: { field: 'operation', value: 'start_individual_reveal' },
},
{
id: 'full_name',
title: 'Full Name',
type: 'short-input',
placeholder: 'John Doe',
condition: { field: 'operation', value: 'start_individual_reveal' },
},
{
id: 'company',
title: 'Company',
type: 'short-input',
placeholder: 'Wiza',
condition: { field: 'operation', value: 'start_individual_reveal' },
},
{
id: 'domain',
title: 'Company Domain',
type: 'short-input',
placeholder: 'wiza.co',
condition: { field: 'operation', value: 'start_individual_reveal' },
},
{
id: 'email',
title: 'Email',
type: 'short-input',
placeholder: 'john@wiza.co',
condition: { field: 'operation', value: 'start_individual_reveal' },
},
{
id: 'accept_work',
title: 'Accept Work Emails',
type: 'switch',
condition: { field: 'operation', value: 'start_individual_reveal' },
mode: 'advanced',
},
{
id: 'accept_personal',
title: 'Accept Personal Emails',
type: 'switch',
condition: { field: 'operation', value: 'start_individual_reveal' },
mode: 'advanced',
},
{
id: 'callback_url',
title: 'Callback URL',
type: 'short-input',
placeholder: 'https://example.com/wiza-callback',
condition: { field: 'operation', value: 'start_individual_reveal' },
mode: 'advanced',
},
// Get Individual Reveal
{
id: 'id',
title: 'Reveal ID',
type: 'short-input',
placeholder: 'Reveal ID returned from Start Individual Reveal',
condition: { field: 'operation', value: 'get_individual_reveal' },
required: { field: 'operation', value: 'get_individual_reveal' },
},
],
tools: {
access: [
'wiza_prospect_search',
'wiza_company_enrichment',
'wiza_start_individual_reveal',
'wiza_get_individual_reveal',
'wiza_get_credits',
],
config: {
tool: (params) => {
switch (params.operation) {
case 'prospect_search':
return 'wiza_prospect_search'
case 'company_enrichment':
return 'wiza_company_enrichment'
case 'start_individual_reveal':
return 'wiza_start_individual_reveal'
case 'get_individual_reveal':
return 'wiza_get_individual_reveal'
case 'get_credits':
return 'wiza_get_credits'
default:
throw new Error(`Invalid Wiza operation: ${params.operation}`)
}
},
params: (params) => {
const parsed: Record<string, unknown> = { ...params }
const parseJsonField = (field: string) => {
const value = parsed[field]
if (typeof value === 'string' && value.trim() !== '') {
try {
parsed[field] = JSON.parse(value)
} catch (err) {
throw new Error(
`Invalid JSON in Wiza "${field}" filter: ${err instanceof Error ? err.message : String(err)}`
)
}
}
}
for (const field of [
'filters',
'first_name',
'last_name',
'job_title',
'job_title_level',
'job_role',
'job_sub_role',
'location',
'skill',
'school',
'major',
'linkedin_slug',
'job_company',
'past_company',
'company_location',
'company_industry',
'company_size',
'company_type',
]) {
parseJsonField(field)
}
if (typeof parsed.size === 'string' && parsed.size.trim() !== '') {
const n = Number(parsed.size)
if (!Number.isNaN(n)) parsed.size = n
}
return parsed
},
},
},
inputs: {
apiKey: { type: 'string', description: 'Wiza API key' },
operation: { type: 'string', description: 'Operation to perform' },
size: { type: 'number', description: 'Sample size for prospect search (0-30)' },
filters: { type: 'json', description: 'Full filters object for prospect search' },
first_name: { type: 'json', description: 'First name filter array' },
last_name: { type: 'json', description: 'Last name filter array' },
job_title: { type: 'json', description: 'Job title filter array' },
job_title_level: { type: 'json', description: 'Job title level filter' },
job_role: { type: 'json', description: 'Job role filter' },
job_sub_role: { type: 'json', description: 'Job sub-role filter' },
location: { type: 'json', description: 'Person location filter' },
skill: { type: 'json', description: 'Skill filter' },
school: { type: 'json', description: 'School filter' },
major: { type: 'json', description: 'Major filter' },
linkedin_slug: { type: 'json', description: 'LinkedIn slug filter' },
job_company: { type: 'json', description: 'Current company filter' },
past_company: { type: 'json', description: 'Past company filter' },
company_location: { type: 'json', description: 'Company location filter' },
company_industry: { type: 'json', description: 'Company industry filter' },
company_size: { type: 'json', description: 'Company size filter' },
company_type: { type: 'json', description: 'Company type filter' },
company_name: { type: 'string', description: 'Company name' },
company_domain: { type: 'string', description: 'Company domain' },
company_linkedin_id: { type: 'string', description: 'Company LinkedIn ID' },
company_linkedin_slug: { type: 'string', description: 'Company LinkedIn slug' },
enrichment_level: { type: 'string', description: 'Enrichment level for individual reveal' },
profile_url: { type: 'string', description: 'LinkedIn profile URL' },
full_name: { type: 'string', description: 'Full name' },
company: { type: 'string', description: 'Company' },
domain: { type: 'string', description: 'Domain' },
email: { type: 'string', description: 'Email address' },
accept_work: { type: 'boolean', description: 'Whether to accept work emails' },
accept_personal: { type: 'boolean', description: 'Whether to accept personal emails' },
callback_url: { type: 'string', description: 'Callback URL' },
id: { type: 'string', description: 'Individual reveal ID' },
},
outputs: {
success: { type: 'boolean', description: 'Whether the operation was successful' },
output: { type: 'json', description: 'Output data from the Wiza operation' },
},
}
+2
View File
@@ -225,6 +225,7 @@ import { WebflowBlock } from '@/blocks/blocks/webflow'
import { WebhookRequestBlock } from '@/blocks/blocks/webhook_request'
import { WhatsAppBlock } from '@/blocks/blocks/whatsapp'
import { WikipediaBlock } from '@/blocks/blocks/wikipedia'
import { WizaBlock } from '@/blocks/blocks/wiza'
import { WordPressBlock } from '@/blocks/blocks/wordpress'
import { WorkdayBlock } from '@/blocks/blocks/workday'
import { WorkflowBlock } from '@/blocks/blocks/workflow'
@@ -488,6 +489,7 @@ export const registry: Record<string, BlockConfig> = {
webhook_request: WebhookRequestBlock,
whatsapp: WhatsAppBlock,
wikipedia: WikipediaBlock,
wiza: WizaBlock,
wordpress: WordPressBlock,
workday: WorkdayBlock,
workflow: WorkflowBlock,
+11
View File
@@ -6950,3 +6950,14 @@ export function SnowflakeIcon(props: SVGProps<SVGSVGElement>) {
</svg>
)
}
export function WizaIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg {...props} viewBox='0 0 51 49' fill='none' xmlns='http://www.w3.org/2000/svg'>
<path
fill='#FFFFFF'
d='m50.3 33.6-9.3-3.5c-2.9-10.4-9.6-20.8-17.1-29.4-1.4-1.5-4.4-0.7-4.2 1.9 0.4 6-0.4 13.3-4.4 20.5-0.9 1.6 1.4 3.3 2.9 1.6 3.2-3.3 5.3-9.1 6.3-15.2 3.9 5.4 9.2 13.8 11.2 22.9 0.2 0.9 0.8 1.6 1.6 1.9l6.2 2.3c-4.1 3.3-9.6 6-17.7 6-7.1 0-13.2-2.3-18.5-6l3.6-2.5c3.5 2 7.5 3.5 12.5 3.6 2.5 0 5-0.2 7.3-0.9 2-0.5 1.6-3.2-0.3-3-4 0.5-10.3 0.3-17.1-4.3-0.8-0.5-1.9-0.6-2.7-0.2l-9.2 4.3c-1.4 0.6-2.1 3.1-0.5 4.3 4.7 3.8 12.4 10.1 24.2 10.1 11.9 0 20.4-4.3 25.8-10.1 1.2-1.2 1.2-3.5-0.6-4.3z'
/>
</svg>
)
}
+12
View File
@@ -2937,6 +2937,13 @@ import {
wikipediaRandomPageTool,
wikipediaSearchTool,
} from '@/tools/wikipedia'
import {
wizaCompanyEnrichmentTool,
wizaGetCreditsTool,
wizaGetIndividualRevealTool,
wizaProspectSearchTool,
wizaStartIndividualRevealTool,
} from '@/tools/wiza'
import {
wordpressCreateCategoryTool,
wordpressCreateCommentTool,
@@ -5228,6 +5235,11 @@ export const tools: Record<string, ToolConfig> = {
wikipedia_search: wikipediaSearchTool,
wikipedia_content: wikipediaPageContentTool,
wikipedia_random: wikipediaRandomPageTool,
wiza_company_enrichment: wizaCompanyEnrichmentTool,
wiza_get_credits: wizaGetCreditsTool,
wiza_get_individual_reveal: wizaGetIndividualRevealTool,
wiza_prospect_search: wizaProspectSearchTool,
wiza_start_individual_reveal: wizaStartIndividualRevealTool,
wordpress_create_post: wordpressCreatePostTool,
wordpress_update_post: wordpressUpdatePostTool,
wordpress_delete_post: wordpressDeletePostTool,
+142
View File
@@ -0,0 +1,142 @@
import type { ToolConfig } from '@/tools/types'
import type { WizaCompanyEnrichmentParams, WizaCompanyEnrichmentResponse } from '@/tools/wiza/types'
export const wizaCompanyEnrichmentTool: ToolConfig<
WizaCompanyEnrichmentParams,
WizaCompanyEnrichmentResponse
> = {
id: 'wiza_company_enrichment',
name: 'Wiza Company Enrichment',
description:
'Enrich a company by name, domain, LinkedIn ID, or LinkedIn slug with detailed firmographic data',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Wiza API key',
},
company_name: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Company name (e.g., "Wiza")',
},
company_domain: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Company domain (e.g., "wiza.co")',
},
company_linkedin_id: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Company LinkedIn ID',
},
company_linkedin_slug: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Company LinkedIn slug from the URL',
},
},
request: {
url: 'https://wiza.co/api/company_enrichments',
method: 'POST',
headers: (params: WizaCompanyEnrichmentParams) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
body: (params: WizaCompanyEnrichmentParams) => {
const body: Record<string, unknown> = {}
if (params.company_name) body.company_name = params.company_name
if (params.company_domain) body.company_domain = params.company_domain
if (params.company_linkedin_id) body.company_linkedin_id = params.company_linkedin_id
if (params.company_linkedin_slug) body.company_linkedin_slug = params.company_linkedin_slug
return body
},
},
transformResponse: async (response: Response) => {
if (!response.ok) {
const errorText = await response.text()
throw new Error(`Wiza API error: ${response.status} - ${errorText}`)
}
const json = await response.json()
const d = json.data ?? {}
return {
success: true,
output: {
company_name: d.company_name ?? null,
company_domain: d.company_domain ?? null,
domain: d.domain ?? null,
company_industry: d.company_industry ?? null,
company_size: d.company_size ?? null,
company_size_range: d.company_size_range ?? null,
company_founded: d.company_founded ?? null,
company_revenue_range: d.company_revenue_range ?? null,
company_funding: d.company_funding ?? null,
company_type: d.company_type ?? null,
company_description: d.company_description ?? null,
company_ticker: d.company_ticker ?? null,
company_last_funding_round: d.company_last_funding_round ?? null,
company_last_funding_amount: d.company_last_funding_amount ?? null,
company_last_funding_at: d.company_last_funding_at ?? null,
company_location: d.company_location ?? null,
company_twitter: d.company_twitter ?? null,
company_facebook: d.company_facebook ?? null,
company_linkedin: d.company_linkedin ?? null,
company_linkedin_id: d.company_linkedin_id ?? null,
company_street: d.company_street ?? null,
company_locality: d.company_locality ?? null,
company_region: d.company_region ?? null,
company_postal_code: d.company_postal_code ?? null,
company_country: d.company_country ?? null,
credits: d.credits ?? null,
},
}
},
outputs: {
company_name: { type: 'string', description: 'Company name', optional: true },
company_domain: { type: 'string', description: 'Company domain', optional: true },
domain: { type: 'string', description: 'Domain', optional: true },
company_industry: { type: 'string', description: 'Industry', optional: true },
company_size: { type: 'number', description: 'Employee count', optional: true },
company_size_range: { type: 'string', description: 'Headcount range', optional: true },
company_founded: { type: 'number', description: 'Year founded', optional: true },
company_revenue_range: { type: 'string', description: 'Revenue range', optional: true },
company_funding: { type: 'string', description: 'Total funding', optional: true },
company_type: { type: 'string', description: 'Company type', optional: true },
company_description: { type: 'string', description: 'Description', optional: true },
company_ticker: { type: 'string', description: 'Stock ticker', optional: true },
company_last_funding_round: {
type: 'string',
description: 'Last funding round',
optional: true,
},
company_last_funding_amount: {
type: 'string',
description: 'Last funding amount',
optional: true,
},
company_last_funding_at: { type: 'string', description: 'Last funding date', optional: true },
company_location: { type: 'string', description: 'Full location string', optional: true },
company_twitter: { type: 'string', description: 'Twitter URL', optional: true },
company_facebook: { type: 'string', description: 'Facebook URL', optional: true },
company_linkedin: { type: 'string', description: 'LinkedIn URL', optional: true },
company_linkedin_id: { type: 'string', description: 'LinkedIn ID', optional: true },
company_street: { type: 'string', description: 'Street address', optional: true },
company_locality: { type: 'string', description: 'City', optional: true },
company_region: { type: 'string', description: 'State/region', optional: true },
company_postal_code: { type: 'string', description: 'Postal code', optional: true },
company_country: { type: 'string', description: 'Country', optional: true },
credits: { type: 'json', description: 'Remaining API credits', optional: true },
},
}
+62
View File
@@ -0,0 +1,62 @@
import type { ToolConfig } from '@/tools/types'
import type { WizaGetCreditsParams, WizaGetCreditsResponse } from '@/tools/wiza/types'
export const wizaGetCreditsTool: ToolConfig<WizaGetCreditsParams, WizaGetCreditsResponse> = {
id: 'wiza_get_credits',
name: 'Wiza Get Credits',
description: 'Retrieve the remaining credits on your Wiza account',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Wiza API key',
},
},
request: {
url: 'https://wiza.co/api/meta/credits',
method: 'GET',
headers: (params: WizaGetCreditsParams) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
if (!response.ok) {
const errorText = await response.text()
throw new Error(`Wiza API error: ${response.status} - ${errorText}`)
}
const data = await response.json()
const credits = data.credits ?? {}
return {
success: true,
output: {
email_credits: credits.email_credits ?? null,
phone_credits: credits.phone_credits ?? null,
export_credits: credits.export_credits ?? null,
api_credits: credits.api_credits ?? null,
},
}
},
outputs: {
email_credits: {
type: 'json',
description: 'Remaining email credits (number or "unlimited")',
optional: true,
},
phone_credits: {
type: 'json',
description: 'Remaining phone credits (number or "unlimited")',
optional: true,
},
export_credits: { type: 'number', description: 'Remaining export credits', optional: true },
api_credits: { type: 'number', description: 'Remaining API credits', optional: true },
},
}
@@ -0,0 +1,163 @@
import type { ToolConfig } from '@/tools/types'
import type {
WizaGetIndividualRevealParams,
WizaGetIndividualRevealResponse,
} from '@/tools/wiza/types'
export const wizaGetIndividualRevealTool: ToolConfig<
WizaGetIndividualRevealParams,
WizaGetIndividualRevealResponse
> = {
id: 'wiza_get_individual_reveal',
name: 'Wiza Get Individual Reveal',
description: 'Retrieve the status and enriched data for an individual reveal by ID',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Wiza API key',
},
id: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Individual reveal ID returned from Start Individual Reveal',
},
},
request: {
url: (params: WizaGetIndividualRevealParams) =>
`https://wiza.co/api/individual_reveals/${encodeURIComponent(String(params.id).trim())}`,
method: 'GET',
headers: (params: WizaGetIndividualRevealParams) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
if (!response.ok) {
const errorText = await response.text()
throw new Error(`Wiza API error: ${response.status} - ${errorText}`)
}
const json = await response.json()
const d = json.data ?? {}
const emails = Array.isArray(d.emails) ? d.emails : []
const phones = Array.isArray(d.phones) ? d.phones : []
return {
success: true,
output: {
id: d.id ?? null,
status: d.status ?? null,
is_complete: d.is_complete ?? null,
name: d.name ?? null,
company: d.company ?? null,
enrichment_level: d.enrichment_level ?? null,
linkedin_profile_url: d.linkedin_profile_url ?? null,
title: d.title ?? null,
location: d.location ?? null,
email: d.email ?? null,
email_type: d.email_type ?? null,
email_status: d.email_status ?? null,
emails: emails.map((e: Record<string, unknown>) => ({
email: (e.email as string) ?? null,
email_type: (e.email_type as string) ?? null,
email_status: (e.email_status as string) ?? null,
})),
mobile_phone: d.mobile_phone ?? null,
phone_number: d.phone_number ?? null,
phone_status: d.phone_status ?? null,
phones: phones.map((p: Record<string, unknown>) => ({
number: (p.number as string) ?? null,
pretty_number: (p.pretty_number as string) ?? null,
type: (p.type as string) ?? null,
})),
company_size: d.company_size ?? null,
company_size_range: d.company_size_range ?? null,
company_type: d.company_type ?? null,
company_domain: d.company_domain ?? null,
company_locality: d.company_locality ?? null,
company_region: d.company_region ?? null,
company_country: d.company_country ?? null,
company_street: d.company_street ?? null,
company_postal_code: d.company_postal_code ?? null,
company_founded: d.company_founded ?? null,
company_funding: d.company_funding ?? null,
company_revenue: d.company_revenue ?? null,
company_industry: d.company_industry ?? null,
company_subindustry: d.company_subindustry ?? null,
company_linkedin: d.company_linkedin ?? null,
company_location: d.company_location ?? null,
company_description: d.company_description ?? null,
credits: d.credits ?? null,
},
}
},
outputs: {
id: { type: 'number', description: 'Reveal ID' },
status: { type: 'string', description: 'queued | resolving | finished | failed' },
is_complete: { type: 'boolean', description: 'Whether the reveal has completed' },
name: { type: 'string', description: 'Full name', optional: true },
company: { type: 'string', description: 'Company name', optional: true },
enrichment_level: { type: 'string', description: 'Enrichment level used', optional: true },
linkedin_profile_url: { type: 'string', description: 'LinkedIn URL', optional: true },
title: { type: 'string', description: 'Job title', optional: true },
location: { type: 'string', description: 'Location', optional: true },
email: { type: 'string', description: 'Primary email', optional: true },
email_type: { type: 'string', description: 'Email type', optional: true },
email_status: { type: 'string', description: 'valid | risky | unfound', optional: true },
emails: {
type: 'array',
description: 'All emails found',
optional: true,
items: {
type: 'object',
properties: {
email: { type: 'string' },
email_type: { type: 'string' },
email_status: { type: 'string' },
},
},
},
mobile_phone: { type: 'string', description: 'Mobile phone', optional: true },
phone_number: { type: 'string', description: 'Direct/office phone', optional: true },
phone_status: { type: 'string', description: 'found | unfound', optional: true },
phones: {
type: 'array',
description: 'All phones found',
optional: true,
items: {
type: 'object',
properties: {
number: { type: 'string' },
pretty_number: { type: 'string' },
type: { type: 'string' },
},
},
},
company_size: { type: 'number', description: 'Employee count', optional: true },
company_size_range: { type: 'string', description: 'Headcount range', optional: true },
company_type: { type: 'string', description: 'Company type', optional: true },
company_domain: { type: 'string', description: 'Company domain', optional: true },
company_locality: { type: 'string', description: 'City', optional: true },
company_region: { type: 'string', description: 'State/region', optional: true },
company_country: { type: 'string', description: 'Country', optional: true },
company_street: { type: 'string', description: 'Street', optional: true },
company_postal_code: { type: 'string', description: 'Postal code', optional: true },
company_founded: { type: 'number', description: 'Year founded', optional: true },
company_funding: { type: 'string', description: 'Funding total', optional: true },
company_revenue: { type: 'string', description: 'Revenue', optional: true },
company_industry: { type: 'string', description: 'Industry', optional: true },
company_subindustry: { type: 'string', description: 'Subindustry', optional: true },
company_linkedin: { type: 'string', description: 'Company LinkedIn URL', optional: true },
company_location: { type: 'string', description: 'Full company location', optional: true },
company_description: { type: 'string', description: 'Company description', optional: true },
credits: { type: 'json', description: 'Remaining credits balance', optional: true },
},
}
+6
View File
@@ -0,0 +1,6 @@
export { wizaCompanyEnrichmentTool } from './company_enrichment'
export { wizaGetCreditsTool } from './get_credits'
export { wizaGetIndividualRevealTool } from './get_individual_reveal'
export { wizaProspectSearchTool } from './prospect_search'
export { wizaStartIndividualRevealTool } from './start_individual_reveal'
export type * from './types'
+246
View File
@@ -0,0 +1,246 @@
import type { ToolConfig } from '@/tools/types'
import type { WizaProspectSearchParams, WizaProspectSearchResponse } from '@/tools/wiza/types'
export const wizaProspectSearchTool: ToolConfig<
WizaProspectSearchParams,
WizaProspectSearchResponse
> = {
id: 'wiza_prospect_search',
name: 'Wiza Prospect Search',
description: "Search Wiza's database of prospects using person, company, and financial filters",
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Wiza API key',
},
size: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Number of sample profiles to return (0-30, default 0)',
},
filters: {
type: 'object',
required: false,
visibility: 'user-or-llm',
description: 'Full filters object (overrides individual filter params if provided)',
},
first_name: {
type: 'array',
required: false,
visibility: 'user-or-llm',
description: 'Exact first names to match (e.g., ["John", "Jane"])',
},
last_name: {
type: 'array',
required: false,
visibility: 'user-or-llm',
description: 'Exact last names to match',
},
job_title: {
type: 'array',
required: false,
visibility: 'user-or-llm',
description:
'Job titles to include/exclude (e.g., [{"v":"CEO","s":"i"},{"v":"CTO","s":"e"}])',
},
job_title_level: {
type: 'array',
required: false,
visibility: 'user-or-llm',
description: 'Seniority levels (e.g., ["cxo", "director", "manager"])',
},
job_role: {
type: 'array',
required: false,
visibility: 'user-or-llm',
description: 'Job role categories (e.g., ["sales", "engineering", "marketing"])',
},
job_sub_role: {
type: 'array',
required: false,
visibility: 'user-or-llm',
description: 'Detailed role categories (e.g., ["software", "product"])',
},
location: {
type: 'array',
required: false,
visibility: 'user-or-llm',
description: "Person's location filters (city/state/country with include/exclude)",
},
skill: {
type: 'array',
required: false,
visibility: 'user-or-llm',
description: 'Professional skills (e.g., ["python", "marketing"])',
},
school: {
type: 'array',
required: false,
visibility: 'user-or-llm',
description: 'Educational institutions',
},
major: {
type: 'array',
required: false,
visibility: 'user-or-llm',
description: 'Field of study',
},
linkedin_slug: {
type: 'array',
required: false,
visibility: 'user-or-llm',
description: 'LinkedIn profile slugs',
},
job_company: {
type: 'array',
required: false,
visibility: 'user-or-llm',
description: 'Current company filters (include/exclude)',
},
past_company: {
type: 'array',
required: false,
visibility: 'user-or-llm',
description: 'Past company filters',
},
company_location: {
type: 'array',
required: false,
visibility: 'user-or-llm',
description: 'Company HQ location filters',
},
company_industry: {
type: 'array',
required: false,
visibility: 'user-or-llm',
description: 'Company industry filters (include/exclude)',
},
company_size: {
type: 'array',
required: false,
visibility: 'user-or-llm',
description: 'Company headcount brackets (e.g., ["1-10", "11-50", "51-200"])',
},
company_type: {
type: 'array',
required: false,
visibility: 'user-or-llm',
description: 'Company type (e.g., ["private", "public", "educational"])',
},
},
request: {
url: 'https://wiza.co/api/prospects/search',
method: 'POST',
headers: (params: WizaProspectSearchParams) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
body: (params: WizaProspectSearchParams) => {
const body: Record<string, unknown> = {}
if (typeof params.size === 'number') {
body.size = Math.max(0, Math.min(params.size, 30))
}
if (
params.filters &&
typeof params.filters === 'object' &&
!Array.isArray(params.filters) &&
Object.keys(params.filters).length > 0
) {
body.filters = params.filters
return body
}
const filters: Record<string, unknown> = {}
const arrayKeys: Array<keyof WizaProspectSearchParams> = [
'first_name',
'last_name',
'job_title',
'job_title_level',
'job_role',
'job_sub_role',
'location',
'skill',
'school',
'major',
'linkedin_slug',
'job_company',
'past_company',
'company_location',
'company_industry',
'company_size',
'company_type',
]
for (const key of arrayKeys) {
const value = params[key]
if (Array.isArray(value) && value.length > 0) {
filters[key as string] = value
}
}
if (Object.keys(filters).length > 0) {
body.filters = filters
}
return body
},
},
transformResponse: async (response: Response) => {
if (!response.ok) {
const errorText = await response.text()
throw new Error(`Wiza API error: ${response.status} - ${errorText}`)
}
const data = await response.json()
const payload = data.data ?? {}
const profiles = Array.isArray(payload.profiles) ? payload.profiles : []
return {
success: true,
output: {
total: payload.total ?? 0,
profiles: profiles.map((p: Record<string, unknown>) => ({
full_name: (p.full_name as string) ?? null,
linkedin_url: (p.linkedin_url as string) ?? null,
industry: (p.industry as string) ?? null,
job_title: (p.job_title as string) ?? null,
job_title_role: (p.job_title_role as string) ?? null,
job_title_sub_role: (p.job_title_sub_role as string) ?? null,
job_company_name: (p.job_company_name as string) ?? null,
job_company_website: (p.job_company_website as string) ?? null,
location_name: (p.location_name as string) ?? null,
})),
},
}
},
outputs: {
total: { type: 'number', description: 'Total number of matching prospects' },
profiles: {
type: 'array',
description: 'Sample profiles matching the filter criteria',
items: {
type: 'object',
properties: {
full_name: { type: 'string' },
linkedin_url: { type: 'string' },
industry: { type: 'string' },
job_title: { type: 'string' },
job_title_role: { type: 'string' },
job_title_sub_role: { type: 'string' },
job_company_name: { type: 'string' },
job_company_website: { type: 'string' },
location_name: { type: 'string' },
},
},
},
},
}
@@ -0,0 +1,142 @@
import type { ToolConfig } from '@/tools/types'
import type {
WizaStartIndividualRevealParams,
WizaStartIndividualRevealResponse,
} from '@/tools/wiza/types'
export const wizaStartIndividualRevealTool: ToolConfig<
WizaStartIndividualRevealParams,
WizaStartIndividualRevealResponse
> = {
id: 'wiza_start_individual_reveal',
name: 'Wiza Start Individual Reveal',
description:
'Start an individual reveal to enrich a contact via LinkedIn URL, name+company, or email',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Wiza API key',
},
enrichment_level: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Enrichment depth: none, partial, phone, or full',
},
profile_url: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'LinkedIn profile URL (e.g., https://linkedin.com/in/johndoe)',
},
full_name: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Full name (used with company or domain)',
},
company: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Company name (used with full_name)',
},
domain: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Company domain (used with full_name)',
},
email: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Email address (use alone or with other identifiers)',
},
accept_work: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Whether to accept work emails (email_options)',
},
accept_personal: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Whether to accept personal emails (email_options)',
},
callback_url: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Optional URL to receive a callback with the reveal update',
},
},
request: {
url: 'https://wiza.co/api/individual_reveals',
method: 'POST',
headers: (params: WizaStartIndividualRevealParams) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
body: (params: WizaStartIndividualRevealParams) => {
const individual: Record<string, unknown> = {}
if (params.profile_url) individual.profile_url = params.profile_url
if (params.full_name) individual.full_name = params.full_name
if (params.company) individual.company = params.company
if (params.domain) individual.domain = params.domain
if (params.email) individual.email = params.email
const body: Record<string, unknown> = {
individual_reveal: individual,
enrichment_level: params.enrichment_level,
}
if (params.accept_work !== undefined || params.accept_personal !== undefined) {
const emailOptions: Record<string, unknown> = {}
if (params.accept_work !== undefined) emailOptions.accept_work = params.accept_work
if (params.accept_personal !== undefined) {
emailOptions.accept_personal = params.accept_personal
}
body.email_options = emailOptions
}
if (params.callback_url) body.callback_url = params.callback_url
return body
},
},
transformResponse: async (response: Response) => {
if (!response.ok) {
const errorText = await response.text()
throw new Error(`Wiza API error: ${response.status} - ${errorText}`)
}
const json = await response.json()
const d = json.data ?? {}
return {
success: true,
output: {
id: d.id ?? null,
status: d.status ?? null,
is_complete: d.is_complete ?? null,
},
}
},
outputs: {
id: { type: 'number', description: 'Individual reveal ID (use with Get Individual Reveal)' },
status: {
type: 'string',
description: 'Reveal status: queued, resolving, finished, or failed',
},
is_complete: { type: 'boolean', description: 'Whether the reveal has completed' },
},
}
+178
View File
@@ -0,0 +1,178 @@
import type { ToolResponse } from '@/tools/types'
export interface WizaGetCreditsParams {
apiKey: string
}
export interface WizaGetCreditsResponse extends ToolResponse {
output: {
email_credits: number | string | null
phone_credits: number | string | null
export_credits: number | null
api_credits: number | null
}
}
export interface WizaProspectSearchParams {
apiKey: string
size?: number
filters?: Record<string, unknown>
first_name?: string[]
last_name?: string[]
job_title?: unknown[]
job_title_level?: string[]
job_role?: string[]
job_sub_role?: string[]
location?: unknown[]
skill?: string[]
school?: string[]
major?: string[]
linkedin_slug?: string[]
job_company?: unknown[]
past_company?: unknown[]
company_location?: unknown[]
company_industry?: unknown[]
company_size?: string[]
company_type?: string[]
}
interface WizaProspectProfile {
full_name: string | null
linkedin_url: string | null
industry: string | null
job_title: string | null
job_title_role: string | null
job_title_sub_role: string | null
job_company_name: string | null
job_company_website: string | null
location_name: string | null
}
export interface WizaProspectSearchResponse extends ToolResponse {
output: {
total: number
profiles: WizaProspectProfile[]
}
}
export interface WizaCompanyEnrichmentParams {
apiKey: string
company_name?: string
company_domain?: string
company_linkedin_id?: string
company_linkedin_slug?: string
}
export interface WizaCompanyEnrichmentResponse extends ToolResponse {
output: {
company_name: string | null
company_domain: string | null
domain: string | null
company_industry: string | null
company_size: number | null
company_size_range: string | null
company_founded: number | null
company_revenue_range: string | null
company_funding: string | null
company_type: string | null
company_description: string | null
company_ticker: string | null
company_last_funding_round: string | null
company_last_funding_amount: string | null
company_last_funding_at: string | null
company_location: string | null
company_twitter: string | null
company_facebook: string | null
company_linkedin: string | null
company_linkedin_id: string | null
company_street: string | null
company_locality: string | null
company_region: string | null
company_postal_code: string | null
company_country: string | null
credits: Record<string, unknown> | null
}
}
export interface WizaStartIndividualRevealParams {
apiKey: string
enrichment_level: 'none' | 'partial' | 'phone' | 'full'
profile_url?: string
full_name?: string
company?: string
domain?: string
email?: string
accept_work?: boolean
accept_personal?: boolean
callback_url?: string
}
interface WizaIndividualRevealData {
id: number | null
status: string | null
is_complete: boolean | null
name: string | null
company: string | null
enrichment_level: string | null
linkedin_profile_url: string | null
title: string | null
location: string | null
email: string | null
email_type: string | null
email_status: string | null
emails: Array<{
email: string | null
email_type: string | null
email_status: string | null
}>
mobile_phone: string | null
phone_number: string | null
phone_status: string | null
phones: Array<{
number: string | null
pretty_number: string | null
type: string | null
}>
company_size: number | null
company_size_range: string | null
company_type: string | null
company_domain: string | null
company_locality: string | null
company_region: string | null
company_country: string | null
company_street: string | null
company_postal_code: string | null
company_founded: number | null
company_funding: string | null
company_revenue: string | null
company_industry: string | null
company_subindustry: string | null
company_linkedin: string | null
company_location: string | null
company_description: string | null
credits: Record<string, unknown> | null
}
export interface WizaStartIndividualRevealResponse extends ToolResponse {
output: {
id: number | null
status: string | null
is_complete: boolean | null
}
}
export interface WizaGetIndividualRevealParams {
apiKey: string
id: string
}
export interface WizaGetIndividualRevealResponse extends ToolResponse {
output: WizaIndividualRevealData
}
export type WizaResponse =
| WizaGetCreditsResponse
| WizaProspectSearchResponse
| WizaCompanyEnrichmentResponse
| WizaStartIndividualRevealResponse
| WizaGetIndividualRevealResponse