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
- Compliance
What you need
- 1An Anima API key — start free at console.useanima.sh
- 2Your own LLM — Claude, GPT-4o, or Gemini (Anima is the identity layer; you bring the brain)
- 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
- Queued outreach to 20 leadsAgent
- Passed the TCPA + DNC gateCompliance
- Called from its own numberVoice
- Booked a meeting, emailed the inviteEmail
Capabilities used
- Compliance
- Voice
- Phone