Vercel AI SDK
Installation
Section titled “Installation”npm install ai truvalBasic tool definition
Section titled “Basic tool definition”import { tool } from 'ai'import { z } from 'zod'
export const verifyEmailTool = tool({ description: 'Verify if an email address is real and deliverable. Returns valid status, confidence score, and whether the address is disposable or a role address.', parameters: z.object({ email: z.string().email().describe('The email address to verify'), }), execute: async ({ email }) => { const res = await fetch('https://api.truval.dev/v1/email/verify', { method: 'POST', headers: { Authorization: `Bearer ${process.env.TRUVAL_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ email }), }) return res.json() },})Building a resilient onboarding agent
Section titled “Building a resilient onboarding agent”An AI agent shouldn’t just fetch data; it should make decisions. Here is an example of an agent that asks for an email, validates it, handles typos, and rejects throwaway addresses.
import { generateText } from 'ai'import { openai } from '@ai-sdk/openai'import { verifyEmailTool } from '@/lib/tools'
const agent = async (userInput: string) => { const result = await generateText({ model: openai('gpt-5.4'), tools: { verifyEmail: verifyEmailTool }, maxSteps: 3, // allow the agent to call the tool and then respond system: `You are an onboarding agent trying to collect a valid email. Always verify the email. Use status, mx_found, smtp_blocked — not confidence alone. - If the tool returns a suggestion, ask "Did you mean [suggestion]?" - If disposable is true, reject and ask for a real email. - If status is invalid or undeliverable, ask for a different email. - If catch_all or status is catch_all, ask the user to confirm. - If status is unknown, mx_found is true, and smtp_blocked is false (often confidence 0.50), ask the user to confirm; do not say the email is invalid. - If smtp_blocked is true with confidence ~0.75, accept. - If confidence >= 0.9, accept and proceed.`, prompt: userInput, })
return result.text}
// User: "I'll use test@mailinator.com"// Agent runs tool -> disposable: true// Agent replies: "I cannot accept temporary email addresses. Please provide a real one."Using in a Next.js API route
Section titled “Using in a Next.js API route”import { streamText } from 'ai'import { openai } from '@ai-sdk/openai'import { verifyEmailTool } from '@/lib/tools'
export async function POST(req: Request) { const { messages } = await req.json()
const result = streamText({ model: openai('gpt-5.4'), tools: { verifyEmail: verifyEmailTool }, maxSteps: 5, messages, })
return result.toDataStreamResponse()}Environment variables
Section titled “Environment variables”TRUVAL_API_KEY=sk_live_...Get your API key at dash.truval.dev.
Public Repositories
Section titled “Public Repositories”- SDK: truval-dev/truval-sdk
- MCP Server: truval-dev/truval-mcp-server
- Agent Skills: truval-dev/truval-skills