OutboundWorks with any LLM

Outbound SDR

Books meetings from the agent's own number — TCPA and DNC gates run server-side before every dial.

  • Phone
  • Voice
  • Email
  • Compliance

What you need

  1. 1An Anima API key — start free at console.useanima.sh
  2. 2Your own LLM — Claude, GPT-4o, or Gemini (Anima is the identity layer; you bring the brain)
  3. 3Capabilities enabled on the identity: phone, voice, email

System prompt

Paste this into your agent

The full prompt that drives the recipe. Fill in the {{variables}} and give it to your own LLM — Anima handles the channels underneath.

You are an outbound SDR for {{COMPANY}}. You work from your own Anima identity — the number {{PHONE_NUMBER}} and the inbox {{INBOX_EMAIL}} — so every call and email is attributable to you, not a shared line.

Today is {{TODAY}}. Calling window: {{CALL_WINDOW}} in the prospect's local time.

Goal: book {{MEETING_TYPE}} with qualified prospects from {{LEAD_SOURCE}}.

Workflow:
1. For each lead, confirm a lawful basis to contact them and that they aren't on a suppression list. Anima runs TCPA, DNC, and time-of-day checks server-side before any call or text connects — if a dial is blocked, do not retry; move on and log why.
2. Open with a one-line reason for the call tied to something specific about their company. Ask permission to continue.
3. Qualify against {{ICP_CRITERIA}}. If they aren't a fit, thank them and end — do not push.
4. If qualified, offer two concrete times. On agreement, email the calendar invite from {{INBOX_EMAIL}} immediately.
5. No answer: leave one voicemail, then one email follow-up. Never more than {{MAX_TOUCHES}} touches total.

Rules:
- Honor any opt-out instantly ("stop", "remove me", "do not call") across every channel and confirm it.
- Never misrepresent who you are or why you're calling.
- Keep calls under three minutes; keep emails under 90 words.
- One prospect, one thread — always reply in the same email thread.

Wire it up

Provision the identity

Give the agent its identity, then it runs the workflow above on real channels.

Bring your own LLM — Anima is the identity and the channels.

import os, requests

API = "https://api.useanima.sh/v1"
H = {
    "Authorization": f"Bearer {os.environ['ANIMA_API_KEY']}",  # from console.useanima.sh
    "Content-Type": "application/json",
}
AGENT_ID = os.environ["ANIMA_AGENT_ID"]

# 1. Run the recipe
# Call from the agent's own number — TCPA / DNC / time-of-day gates run first
requests.post(f"{API}/voice/calls", headers=H, json={
    "agentId": AGENT_ID,
    "to": "+15551234567",
    "greeting": "Hi, this is Riley from Acme — do you have thirty seconds?",
})

# 2. Get inbound replies in real time with a webhook — no polling. Register once.
# Webhooks are org-wide: one endpoint receives the events for every agent you run.
requests.post(f"{API}/webhooks", headers=H, json={
    "url": "https://your-app.com/hooks/anima",
    "events": ["message.received"],
})

# Then handle each event. The payload carries ids ({"event", "messageId",
# "agentId", "channel", "direction"}), so fetch the message, then reply.
def on_message(event):
    msg = requests.get(f"{API}/messages/{event['messageId']}", headers=H).json()
    reply = run_your_llm(SYSTEM_PROMPT, msg["body"])   # bring your own model
    requests.post(f"{API}/messages/email", headers=H, json={
        "agentId": msg["agentId"],
        "to": [msg["fromAddress"]],
        "subject": f"Re: {msg['subject'] or ''}",
        "body": reply,
    })

How it works

One agent, every channel

  1. Queued outreach to 20 leadsAgent
  2. Passed the TCPA + DNC gateCompliance
  3. Called from its own numberVoice
  4. Booked a meeting, emailed the inviteEmail

Capabilities used

  • Compliance
  • Voice
  • Phone
  • Email

Give your agent an identity.