What you can build

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.

TutorialServices UsedDifficulty
Deep Research Agentweb_search, text_generationBeginner — 2 services, ~10 lines of code
Cold Outreach SDRemail.send, text_generation, web_searchBeginner — 3 services, ~20 lines of code
Email Triage Botemail.read, text_generation, email.replyIntermediate — requires OAuth (Gmail)
Meeting Scribespeech.transcribe, text_generation, email.sendIntermediate — audio + LLM + email
Social Media Managerweb_search, text_generation, chat.sendIntermediate — requires OAuth (Slack)
Customer Support Agentemail.read, text_generation, ticket.createIntermediate — email + ticketing
Data Pipeline Builderweb.fetch_url, data.csv_parse, text_generation, notification.webhookAdvanced — 4 services, scheduled
PR Review Agentweb.fetch_url, text_generation, chat.sendAdvanced — code analysis + Slack posting
Beginner · web_search + text_generation

Deep Research Agent

Build an agent that searches the web, summarizes findings, and delivers a structured research report.

Tutorial1 / 4
Researcher
Status: Active
Mode: Test
Services: 0

Create the Agent

Go to /agents and create a new agent called 'Researcher'. Copy the API key.

Full Code Example

typescript
// 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
}
Beginner · email + text_generation + web_search

Cold Outreach SDR

Build a sales development representative agent that researches a prospect, drafts a personalized cold email, and sends it.

Tutorial1 / 4
SDR Bot
web_search: $10/mo
text_generation: $50/mo
email.send: $25/mo

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.

python
# 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"]})
Intermediate · email.read + text_generation + email.reply

Email Triage Bot

Build an agent that reads incoming emails, classifies them by urgency, drafts replies for common questions, and flags complex ones.

Tutorial1 / 4
Connected Apps
Gmail
Slack
Salesforce

Connect Gmail

Go to /agents?tab=apps and connect your Gmail via Nylas OAuth.

Intermediate · speech.transcribe + text_generation + email.send

Meeting Scribe

Build an agent that transcribes meeting audio, generates a structured summary with action items, and emails it to all attendees.

Tutorial1 / 4
1
Audio file uploaded
2
Presigned URL generated
3
Agent receives file_url

Upload Audio

Upload the meeting recording to Upivia's storage. The agent receives the file URL.

Intermediate · web_search + text_generation + chat.send

Social Media Manager

Build an agent that monitors industry trends, drafts social media posts, and publishes them to Slack channels for approval.

Tutorial1 / 4
Connected Apps
Slack
Gmail
Jira

Connect Slack

Install the Slack connected app at /agents?tab=apps.

Intermediate · email.read + text_generation + ticket.create

Customer Support Agent

Build an agent that reads support emails, classifies them, auto-responds to common questions, and creates tickets in Jira/Linear.

Tutorial1 / 4
Connected Apps
Gmail
Jira
Slack

Connect Integrations

Connect Gmail (for email.read/reply) and Jira or Linear (for ticket.create/update).

Advanced · web.fetch_url + data.csv_parse + text_generation + notification.webhook

Data Pipeline Builder

Build an agent that fetches CSV data, parses it, generates insights via LLM, and sends a summary webhook to your dashboard.

Tutorial1 / 4
web.fetch_url — $0.01
data.csv_parse — $0.01
text_generation.generate — $50/mo
notification.webhook — $0.01

Enable Services

Enable web.fetch_url, data.csv_parse, text_generation.generate, and notification.webhook.

bash
# 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"
  }'
Advanced · web.fetch_url + text_generation + chat.send

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.

Tutorial1 / 4
PR Reviewer
web.fetch_url: $0.01
text_generation: $50/mo
chat.send: $0.01

Set Up the Agent

Create an agent called 'PR Reviewer'. Enable web.fetch_url, text_generation.generate, and chat.send.

typescript
// 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}` },
    }),
  });
}