Tutorials
Each tutorial below walks through a real-world use case end-to-end: the services you need, the budget setup, and the step-by-step flow to get from idea to running agent. Click through the animated walkthroughs to see it in action. Each includes full code examples you can copy and adapt.
| Tutorial | Services Used | Difficulty |
|---|---|---|
| Deep Research Agent | web_search, text_generation | Beginner — 2 services, ~10 lines of code |
| Cold Outreach SDR | email.send, text_generation, web_search | Beginner — 3 services, ~20 lines of code |
| Email Triage Bot | email.read, text_generation, email.reply | Intermediate — requires OAuth (Gmail) |
| Meeting Scribe | speech.transcribe, text_generation, email.send | Intermediate — audio + LLM + email |
| Social Media Manager | web_search, text_generation, chat.send | Intermediate — requires OAuth (Slack) |
| Customer Support Agent | email.read, text_generation, ticket.create | Intermediate — email + ticketing |
| Data Pipeline Builder | web.fetch_url, data.csv_parse, text_generation, notification.webhook | Advanced — 4 services, scheduled |
| PR Review Agent | web.fetch_url, text_generation, chat.send | Advanced — code analysis + Slack posting |
Deep Research Agent
Build an agent that searches the web, summarizes findings, and delivers a structured research report.
Create the Agent
Go to /agents and create a new agent called 'Researcher'. Copy the API key.
Full Code Example
// deep-research.ts — Runs web search then summarizes
const BASE = "https://www.upivia.com/api/v1";
async function research(topic: string, agentKey: string) {
// Step 1: Search the web
const searchRes = await fetch(`${BASE}/service-requests`, {
method: "POST",
headers: {
"Authorization": `Bearer ${agentKey}`,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({
operation: "web_search.search",
payload: { query: topic },
}),
});
const searchData = await searchRes.json();
const sources = searchData.result?.results ?? [];
// Step 2: Summarize with LLM
const llmRes = await fetch(`${BASE}/service-requests`, {
method: "POST",
headers: {
"Authorization": `Bearer ${agentKey}`,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({
operation: "text_generation.generate",
payload: {
model: "openai/gpt-4o-mini",
messages: [
{ role: "system", content: "Summarize these search results into a structured research report." },
{ role: "user", content: `Topic: ${topic}\n\nSources:\n${JSON.stringify(sources, null, 2)}` },
],
},
}),
});
const llmData = await llmRes.json();
return llmData.result; // The research report
}Cold Outreach SDR
Build a sales development representative agent that researches a prospect, drafts a personalized cold email, and sends it.
Create & Configure
Create an agent called 'SDR Bot'. Enable web_search.search, text_generation.generate, and email.send. Set a $25/month cap on email.
# cold_outreach.py — Research, draft, and send
import os, uuid, requests
BASE = "https://www.upivia.com/api/v1"
KEY = os.environ["AGENT_KEY"]
HEADERS = {"Authorization": f"Bearer {KEY}", "Content-Type": "application/json"}
def dispatch(operation, payload):
r = requests.post(f"{BASE}/service-requests",
headers={**HEADERS, "Idempotency-Key": str(uuid.uuid4())},
json={"operation": operation, "payload": payload}, timeout=30)
data = r.json()
assert data["status"] == "executed", data
return data["result"]
# Step 1: Research the prospect
search = dispatch("web_search.search", {"query": f"{company} {role} recent news"})
# Step 2: Draft a personalized email
email_text = dispatch("text_generation.generate", {
"model": "openai/gpt-4o-mini",
"messages": [
{"role": "system", "content": "Write a concise cold email. Max 150 words."},
{"role": "user", "content": f"Prospect: {name}, {role} at {company}\nResearch: {search}"},
],
})
# Step 3: Send it
dispatch("email.send", {"to": prospect_email, "subject": f"Quick question about {company}", "body": email_text["content"]})Email Triage Bot
Build an agent that reads incoming emails, classifies them by urgency, drafts replies for common questions, and flags complex ones.
Connect Gmail
Go to /agents?tab=apps and connect your Gmail via Nylas OAuth.
Meeting Scribe
Build an agent that transcribes meeting audio, generates a structured summary with action items, and emails it to all attendees.
Upload Audio
Upload the meeting recording to Upivia's storage. The agent receives the file URL.
Customer Support Agent
Build an agent that reads support emails, classifies them, auto-responds to common questions, and creates tickets in Jira/Linear.
Connect Integrations
Connect Gmail (for email.read/reply) and Jira or Linear (for ticket.create/update).
Data Pipeline Builder
Build an agent that fetches CSV data, parses it, generates insights via LLM, and sends a summary webhook to your dashboard.
Enable Services
Enable web.fetch_url, data.csv_parse, text_generation.generate, and notification.webhook.
# Schedule the entire pipeline as a workflow
curl -X POST https://www.upivia.com/api/v1/scheduled-tasks \
-H "Authorization: Bearer upivia_pat_live_..." \
-H "Content-Type: application/json" \
-d '{
"agent_id": "agt_pipeline_01...",
"name": "Daily Sales Insights",
"operation": "workflow.run",
"payload": {
"workflow_id": "wf_daily_insights",
"input": { "csv_url": "https://api.example.com/sales.csv" }
},
"schedule_type": "recurring",
"cron_expr": "0 6 * * *",
"timezone": "America/New_York"
}'PR Review Agent
Build an agent that fetches a GitHub PR diff, analyzes it for bugs and security issues, and posts the review to Slack.
Set Up the Agent
Create an agent called 'PR Reviewer'. Enable web.fetch_url, text_generation.generate, and chat.send.
// pr-review.ts — Fetch, analyze, and post review
async function reviewPR(prUrl: string, agentKey: string) {
// Step 1: Fetch the PR diff
const diffRes = await fetch("/api/v1/service-requests", {
method: "POST",
headers: { "Authorization": `Bearer ${agentKey}`, "Content-Type": "application/json", "Idempotency-Key": crypto.randomUUID() },
body: JSON.stringify({ operation: "web.fetch_url", payload: { url: `${prUrl}.diff` } }),
});
const diff = (await diffRes.json()).result?.content ?? "";
// Step 2: Analyze with LLM
const reviewRes = await fetch("/api/v1/service-requests", {
method: "POST",
headers: { "Authorization": `Bearer ${agentKey}`, "Content-Type": "application/json", "Idempotency-Key": crypto.randomUUID() },
body: JSON.stringify({
operation: "text_generation.generate",
payload: {
model: "anthropic/claude-3.5-sonnet",
messages: [
{ role: "system", content: "You are a senior code reviewer. Analyze this diff for bugs, security issues, and style." },
{ role: "user", content: `PR Diff:\n\n${diff}` },
],
},
}),
});
const review = (await reviewRes.json()).result;
// Step 3: Post to Slack
await fetch("/api/v1/service-requests", {
method: "POST",
headers: { "Authorization": `Bearer ${agentKey}`, "Content-Type": "application/json", "Idempotency-Key": crypto.randomUUID() },
body: JSON.stringify({
operation: "chat.send",
payload: { channel: "#pr-reviews", text: `*PR Review: ${prUrl}*\n\n${review.content}` },
}),
});
}