CrewAI
Installation
Section titled “Installation”pip install crewai requestsBasic tool definition
Section titled “Basic tool definition”import osimport requestsfrom crewai.tools import BaseToolfrom pydantic import BaseModel, Field
class EmailVerifyInput(BaseModel): email: str = Field(description="The email address to verify")
class VerifyEmailTool(BaseTool): name: str = "verify_email" description: str = ( "Verify if an email address is real and deliverable. " "Returns valid status, confidence score, and whether " "the address is disposable or a role address." ) args_schema: type[BaseModel] = EmailVerifyInput
def _run(self, email: str) -> dict: response = requests.post( "https://api.truval.dev/v1/email/verify", headers={ "Authorization": f"Bearer {os.environ['TRUVAL_API_KEY']}", "Content-Type": "application/json", }, json={"email": email}, ) return response.json()Building an autonomous verifier lead agent
Section titled “Building an autonomous verifier lead agent”An agent shouldn’t just run the tool; it should make decisions based on the result. Here’s how to create an agent that uses the signals to filter bad leads.
from crewai import Agent, Task, Crew
verify_tool = VerifyEmailTool()
lead_enricher = Agent( role="Lead Quality Validator", goal="Filter out bad emails before reaching out to leads. Never approve disposable or invalid emails.", backstory="You are a strict QA agent. You use verify_email. Reject if disposable or status is invalid/undeliverable. If smtp_blocked with confidence ~0.75, approve domain-level check. If status is unknown with mx_found and not smtp_blocked (often 0.50), ask for confirmation — do not auto-reject. Reject only if confidence is very low after those rules (e.g. undeliverable).", tools=[verify_tool], verbose=True,)
task = Task( description=( "You have a new lead with email: hello@mailinator.com. " "Verify this email. If it's valid with high confidence and not disposable, approve it. " "Otherwise, reject it and explain why." ), expected_output="A final decision: 'APPROVED' or 'REJECTED: [Reason]'", agent=lead_enricher,)
crew = Crew(agents=[lead_enricher], tasks=[task])result = crew.kickoff()
# The agent autonomously executes the tool, gets `disposable: true`,# and returns "REJECTED: Email is a disposable address."Environment variables
Section titled “Environment variables”export 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