Building agents for clients? Run approvals on RobotRock
Freelance agent developers: skip bespoke approval UIs and Slack hacks. Ship faster, hand off cleanly, and give every client a production inbox their whole team can use.
Published June 25, 2026
The part clients never put in the brief
A company hires you to build an AI agent — support triage, sales outreach, content pipeline, internal ops. The fun work is prompts, tools, and orchestration. Then reality shows up: someone on their team has to approve drafts, reject bad outputs, and leave an audit trail. That means an inbox, forms, notifications, roles, and a UI their marketing lead can actually use.
Suddenly you are not just an agent developer. You are building a mini-product on the side — often unpaid, often scoped as "just wire up Slack." Slack threads do not scale, email links get lost, and custom admin pages rot the moment you move to the next contract.
RobotRock is infrastructure for that missing layer: human approvals your client can run without you in the loop forever.
What freelancers usually build (and regret)
- A Slack bot per project — fast to demo, painful to maintain. No structured forms, no audit trail, messages scroll away, and non-technical approvers hate it.
- A bespoke approval page — you own every bug, every auth edge case, every mobile layout complaint long after handoff.
- Hard-coded email flows — approve links with opaque tokens, no central inbox, no assignment to the right team.
- Nothing at all — agent runs fully autonomous until something goes wrong; then the client pulls the plug and blames the agent, not the missing gate.
Each path either eats your margin or erodes client trust. RobotRock replaces all of them with one integration and a product your client can log into on day one.
Why RobotRock fits freelance agent work
Ship the agent, not an approval product
One SDK call — or a Trigger.dev triggerAndWait()— creates a task in your client's inbox with rich context, action buttons, and optional forms. You do not scaffold Next.js pages, design form validation, or host approval APIs. Your estimate stays about the agent; human-in-the-loop is a line item you can deliver confidently.
import { createClient } from "robotrock";
// One client project — inbox bucket keeps their tasks separate
const acmeAgent = createClient({
app: "acme-support-agent",
});
export async function draftSupportReply(ticket: Ticket) {
const draft = await generateReply(ticket);
const result = await acmeAgent.sendToHuman({
type: "support-reply",
name: `Approve reply — ${ticket.customerName}`,
description: "Review before this sends to the customer.",
assignTo: { groups: ["support-leads"] },
context: {
data: {
ticketId: ticket.id,
customerMessage: ticket.body,
draftReply: draft,
},
ui: {
customerMessage: { "ui:widget": "markdown" },
draftReply: { "ui:widget": "markdown" },
},
},
actions: [
{ id: "approve", title: "Send reply" },
{
id: "edit",
title: "Request changes",
schema: {
type: "object",
required: ["feedback"],
properties: {
feedback: { type: "string", title: "What should change?" },
},
},
},
],
});
if (result.actionId === "approve") {
await sendEmail(ticket, draft);
}
}A real handoff, not a README paragraph
When the project ends, the client keeps using RobotRock. They invite their team, set up groups like finance or support-leads, configure notifications, and handle approvals without paging you. You document the API key and app slug — not a deployment pipeline for custom admin software.
Your client's team actually uses it
Approvers are not developers. RobotRock gives them an inbox with readable context (markdown, tables, currency widgets), clear action cards, assignment filters, and share links for external reviewers. That matters when you are selling to a COO, not a CTO — read the human-in-the-loop article for why that UX wins inside companies.
Separate projects without separate products
Use the app field (or named API keys) to bucket tasks per client or per agent — acme-support-agent, contoso-sales-bot. Your client filters their inbox by app; you keep integrations tidy across multiple contracts.
Durable waits that match how agents run
Agents pause for hours, not milliseconds. RobotRock integrates with Trigger.dev wait tokens, Vercel Workflow, webhooks, and the Vercel AI SDK — so human gates survive retries, deploys, and long review cycles without you holding HTTP connections open.
// trigger/acme-support.ts — re-export once per project
export { sendToHumanTask } from "robotrock/trigger";
// Your agent task — durable wait, zero custom approval backend
import { task } from "@trigger.dev/sdk";
import { sendToHumanTask } from "./acme-support";
export const handleTicket = task({
id: "acme-handle-ticket",
maxDuration: 3600,
run: async (payload) => {
const draft = await generateReply(payload);
const waitResult = await sendToHumanTask.triggerAndWait({
app: "acme-support-agent",
type: "support-reply",
name: `Approve reply — ${payload.customerName}`,
context: { data: { draftReply: draft } },
actions: [
{ id: "approve", title: "Send reply" },
{ id: "reject", title: "Do not send" },
],
});
if (!waitResult.ok) throw waitResult.error;
return waitResult.output;
},
});Audit and compliance included
Clients ask "who approved this email?" sooner than you think. Every handled task records who acted, when, and what they submitted. You do not bolt on logging for each project — it is part of the platform, which makes enterprise-minded clients much easier to close.
Advantages for your business
- Faster proposals— "Includes a production approval inbox for your team" beats "we'll figure out notifications later."
- Clear scope boundaries — approval UI, assignment, and audit are RobotRock's job. You scope agent logic, integrations, and prompts — not a second product.
- Less post-launch support — fewer "the approve button broke" tickets when you did not build the button in the first place.
- Look professional on demos — show a polished inbox with real context widgets during the sales call instead of a Slack screenshot or localhost admin page.
- Start free, scale with the client — prototype on the free tier during discovery; the client upgrades their workspace as usage grows. You are not hosting approval infra on your own VPS bill.
- Integrate the way you already work — npm SDK, Trigger.dev tasks, AI SDK tools, MCP server, and an agent skill for Cursor or Claude Code. Less doc-diving, more shipping.
A practical handoff pattern
This workflow works well across freelance engagements:
- Client creates a RobotRock workspace (or invites you to theirs). They own billing and team access long term.
- You create a named API key per agent or per environment — e.g.
acme-support-prod. Store it in their Trigger.dev / Vercel project, not yours. - Pick an app slug for inbox grouping and set
assignToto groups they configure (finance, legal, support). - Demo with real tasks — send a sample approval during the kickoff so stakeholders see exactly what they will use in production.
- Document two things — which actions your agent expects back, and which inbox app/type to filter on. Link to docs.robotrock.io for their ops team.
- Hand off — revoke your access when the contract ends; their team keeps running approvals without you.
For agents that call humans mid-run via tools, use createSendToHumanTool with mode: "trigger" inside a Trigger worker so waits outlive serverless timeouts. See the waitpoint tokens guide for the mechanics.
Where to start
If you are scoping your next client agent, add human-in-the-loop on RobotRock from day one — not as phase two. Install the SDK, send one test task to your own inbox, and show the client that screen before you write another thousand lines of agent code.
Start for free, read the documentation, or install the RobotRock agent skill so your coding assistant already knows the integration patterns. Build the agent once; let RobotRock carry the approval layer on every project after that.

