E

ElevenLabs

Add human approval checkpoints to ElevenLabs voice agents. When your agent wants to take a real-world action — process a refund, book a meeting, send a follow-up — Cheqpoint pauses execution until a human approves or rejects it.

How it works

ElevenLabs voice agents can be given tools — functions they call when a conversation reaches a decision point. Add a Cheqpoint checkpoint inside any tool to require human sign-off before the action runs. The agent waits for the decision and continues automatically once approved.

Prerequisites

  • An ElevenLabs account with a configured voice agent.
  • @cheqpoint/sdk installed in your agent server.
  • A Cheqpoint Connection Key from your Developer page.

Steps

  1. Create a tool in your ElevenLabs agent (e.g. process_refund, book_callback).
  2. In your tool handler, call cheq.checkpoint() before executing the action.
  3. The agent pauses and a request appears in your Cheqpoint inbox.
  4. A reviewer approves, rejects, or modifies the action — optionally with a note back to the agent.
  5. Execution resumes with the reviewer's decision applied.

Installation

bash
npm install @cheqpoint/sdk

Setup

javascript
import { CheqpointClient, RejectedError } from "@cheqpoint/sdk";

const cheq = new CheqpointClient({
  apiKey: process.env.CHEQPOINT_CONNECTION_KEY,
});

Tool handler — refund request

javascript
// ElevenLabs calls this tool when the voice agent decides to issue a refund.
// Cheqpoint pauses it until a human approves.

async function processRefund({ orderId, amountCents, customerEmail, reason }) {
  try {
    const result = await cheq.checkpoint({
      action: "process_refund",
      summary: `Voice agent requesting refund of $${(amountCents / 100).toFixed(2)} for order ${orderId}`,
      details: { orderId, amountCents, customerEmail, reason },
      justification: `Customer called in: ${reason}`,
      riskScore: amountCents > 10000 ? 0.8 : 0.4,
    });

    // Reviewer may have modified the amount — always use modifiedDetails
    const effective = result.modifiedDetails ?? { orderId, amountCents, customerEmail };
    await stripe.refunds.create({
      amount: effective.amountCents,
      metadata: { orderId: effective.orderId },
    });

    return { success: true, refundedAmount: effective.amountCents };
  } catch (e) {
    if (e instanceof RejectedError) {
      return { success: false, reason: e.message };
    }
    throw e;
  }
}

Tool handler — book a callback

javascript
async function bookCallback({ customerName, phone, preferredTime, topic }) {
  try {
    const result = await cheq.checkpoint({
      action: "book_callback",
      summary: `Voice agent requesting callback for ${customerName} at ${preferredTime}`,
      details: { customerName, phone, preferredTime, topic },
      justification: "Customer requested a follow-up call during live conversation.",
      riskScore: 0.2,
    });

    const effective = result.modifiedDetails ?? { customerName, phone, preferredTime };
    await calendar.createEvent(effective);

    return { booked: true, time: effective.preferredTime };
  } catch (e) {
    if (e instanceof RejectedError) {
      return { booked: false, reason: e.message };
    }
    throw e;
  }
}

Sample Cheqpoint request payload

json
{
  "action": "process_refund",
  "summary": "Voice agent requesting refund of $149.00 for order ORD-8821",
  "details": {
    "orderId": "ORD-8821",
    "amountCents": 14900,
    "customerEmail": "mike.jones@example.com",
    "reason": "Item never arrived despite delivery confirmation"
  },
  "justification": "Customer called in: item never arrived despite delivery confirmation",
  "riskScore": 0.8
}

Sample Cheqpoint response (modified)

json
{
  "status": "approved",
  "modifiedDetails": {
    "orderId": "ORD-8821",
    "amountCents": 7450,
    "customerEmail": "mike.jones@example.com"
  },
  "decisionNote": "Partial refund approved — tracking shows delivered. 50% as goodwill."
}

Tips

  • Always use result.modifiedDetails ?? originalDetails — reviewers can adjust amounts, times, or any field before approving.
  • Set a higher riskScore for large refunds or irreversible actions so reviewers are prioritised accordingly.
  • Use justification to pass the customer's verbatim reason — it helps reviewers make faster decisions without needing to look up the call.
  • Combine with auto-approval rules to skip review for low-value, low-risk actions automatically.

Get your Connection Key at cheqpoint.co/signup.