Agent Templates
Offer Letter Routing Agent

Offer letter agents that act on-behalf-of your recruiters

Drafts the offer in PandaDoc, blocks on the hiring manager's approval in Slack, then emails the candidate their e-signature link. Every call runs as the recruiter who triggered it, never a shared HR bot.

Offer Letter Routing Agent
Sample Agent for Acme
May 22 · 10:00 AM ·
47s
Send Alex Chen the Staff Engineer offer, $180k, starting Aug 3
J
Drafting the offer in PandaDoc
Offer draft created
pandadoc_documents_create
Approval requested
slack_send_message
Manager reacted ✅
slack_get_reactions
Offer - Alex Chen - Staff Engineer
Approved in Slack (2m)
Hiring manager approved with a ✅ reaction
Document sent for e-signature via PandaDoc
Delivered
Signing link emailed to alex.chen@example.com
Rejected or timed out? Draft stays locked, candidate never contacted
Message Claude...
Trusted by teams shipping agents to production
Offer Letter Routing Agent
Sample Agent for Acme
May 22 · 10:00 AM ·
47s
Send Alex Chen the Staff Engineer offer, $180k, starting Aug 3
J
Drafting the offer in PandaDoc
Offer draft created
pandadoc_documents_create
Approval requested
slack_send_message
Manager reacted ✅
slack_get_reactions
Offer - Alex Chen - Staff Engineer
Approved in Slack (2m)
Hiring manager approved with a ✅ reaction
Document sent for e-signature via PandaDoc
Delivered
Signing link emailed to alex.chen@example.com
Rejected or timed out? Draft stays locked, candidate never contacted
Message Claude...

How agent builders go from zero to a gated offer flow in six steps

A real working agent you can deploy

This repo uses a RECRUITER_USER env var (with per-connector overrides) to simulate one recruiter. In production, pass each recruiter's real ID as the identifier on every Scalekit call, and send them an authorization link whenever their connector status is not ACTIVE.

01
Validate the offer request
validation.py
Fail-fast checks before any API call: the email must parse, the salary must normalize (180k becomes $180,000), and the start date must be a real future date. Bad input exits immediately; nothing partially executes.
validation.py
_EMAIL_RE = re.compile(r"^[^@\s]+@[^@\s]+\.[^@\s]+$")

def validate_offer_request(raw: dict) -> OfferRequest:
    errors = []

    email = (raw.get("candidate_email") or "").strip()
    if not _EMAIL_RE.match(email):
        errors.append(f"candidate_email is not a valid email address: {email!r}")

    base_salary = (raw.get("base_salary") or "").strip()
    if not _SALARY_RE.match(base_salary.replace("k", "000").replace("K", "000")):
        errors.append(
            f"base_salary must be a plain number like '180000' or '$180,000': {base_salary!r}"
        )

    start_date = (raw.get("start_date") or "").strip()
    parsed = _parse_date(start_date)
    if parsed is None:
        errors.append("start_date must be a valid date in YYYY-MM-DD format")
    elif parsed <= date.today():
        errors.append(f"start_date must be in the future: {start_date}")

    if errors:
        raise ValidationError("; ".join(errors))
    return OfferRequest(
        candidate_email=email,
        base_salary=_normalize_salary(base_salary),
        start_date=start_date,
        ...
    )
02
Authorize PandaDoc, Slack, and Gmail as the recruiter
auth.py
03
Create the offer document in PandaDoc
connectors/pandadoc.py
04
Post the approval request in Slack
connectors/slack_mcp.py
05
Block until the hiring manager reacts
approval_gate.py
06
Send for e-signature and email the candidate
run_flow.py

Agents that route real approvals, without the auth plumbing

Four things you'd otherwise build: PandaDoc OAuth, Slack auth, Gmail tokens, refresh. Handled.

1
Install
claude plugin marketplace add scalekit-inc/claude-code-authstack && claude plugin install agent-auth@scalekit-auth-stack
terminal
curl -fsSL https://raw.githubusercontent.com/scalekit-inc/codex-authstack/main/install.sh | bash
terminal
copilot plugin marketplace add scalekit-inc/github-copilot-authstack
copilot plugin install agent-auth@scalekit-auth-stack
terminal
curl -fsSL https://raw.githubusercontent.com/scalekit-inc/cursor-authstack/main/install.sh | bash
terminal
npx skills add scalekit-inc/skills --skill integrating-agent-auth
2
Clone github.com/scalekit-developers/workflow-agents-demos/tree/main/offer-letter-routing-agent and adapt it for my hiring stack.

I am building for: my recruiting team (or: an ATS product)   ← edit this line
Connectors my users need: PandaDoc, Slack, Slack MCP, Gmail   ← edit this line
Trigger: run once per offer — CLI, form, or ATS webhook. Deliver: e-signature link emailed to the candidate after manager approval.

Steps:
1. Create Scalekit AgentKit connections named pandadocmcp, slack, slackmcp, gmail. The code resolves connections by name and passes connection_name on every execute_tool call.
2. Map identifier to each recruiter's real user ID (not a shared HR bot). Per-connector *_USER overrides exist if identities differ per service.
3. If I swap a connector, mirror an existing connectors/*.py module: execute_tool(tool_name, identifier, connection_name, tool_input) → read result.data.
4. Keep the approval gate: approval_gate.wait_for_approval polls slackmcp_slack_get_reactions until ✅/❌ or timeout. REQUIRE_APPROVAL=false falls back to notify-only.
5. Point PANDADOC_TEMPLATE_UUID at our reviewed offer template (tokens: candidate_name, role_title, base_salary, start_date, company_name; recipient role defaults to "Client").
6. Run python run_flow.py with one test offer, then describe how to deploy for many recruiters.
Why choose Scalekit

Delegated identity. Not service accounts.

Credentials never touch agent code or LLM context. The agent acts as the user, not as a shared bot.
Delegated OAuth - Agent reads your calendar, your inbox — scoped to the authorizing identity, not org-wide.
Credentials outside agent runtime  -  Tokens never touch agent code or LLM context. Both failure modes covered.
Token lifecycle automatic  -  Refresh, expiry, rotation across all connectors. One SDK call. Zero management code.
200+ prebuilt connectors  -  Google, Slack, HubSpot, GitHub, Jira, Notion, Salesforce — same auth pattern everywhere.
Try other Agent Templates

Prebuilt agents you can ship today

Each one runs on delegated identity, scoped per user.

SUPPORT
Support triage agent
Read Zendesk tickets, fetch runbooks from Notion, and route to the right Slack channel with a drafted response.
SUPPORT
Support ticket automation (Google ADK)
Google ADK agent that classifies Zendesk tickets, pulls Notion context, and posts to Slack. End-to-end ticket handoff.
SUPPORT
Freshdesk CSAT follow-up agent
Google ADK agent that watches low CSAT scores in Freshdesk and drafts personalised follow-ups for support leads.
OPS
Email-to-calendar scheduling agent
Parse scheduling intent from Gmail threads and create Google Calendar events with the right attendees and timezone.
GTM
HubSpot to Slack updates agent
Watch HubSpot deal stage changes and post structured updates to the right Slack channel. Reps stop checking the CRM all day.
GTM
CRM AI agent
Log calls, update opportunity stages, and surface stalled deals across HubSpot or Salesforce. No manual data entry.

Build your own
multi-connector agent

Add connectors. Change the LLM. Same delegated auth pattern.