redline

Redline/Articles

Guide

How do you see what a sales agent will do to your CRM and your prospects before it goes live?

Run a sales agent against replicas of Salesforce, HubSpot, Gmail and Calendar filled with your own pipeline, and compare that with sandboxes, mocks and evals.

RedlineUpdated 20 October 202618 min read

Whiteboard sketch: a sales agent works in Salesforce, HubSpot, Gmail and Calendar copies holding company records; every step is recorded and the copies are reset between runs.
Table of contents

In short

Point the agent at replicas of the apps it sells through — Salesforce or HubSpot, the mailbox it sends from, the calendar it books into, the chat it reports in — filled with the company's own accounts, contacts, deals and threads, and record every step of the run: each model call, each tool call with its arguments and result, the cost, the failed calls, and every reply that broke a rule you wrote. Then read the state the run left behind: the deal at the stage your policy allows, the activity logged once, the email that reached the right address and no one else, the meeting on the right calendar with the right attendees.

Redline builds that environment. Its copies answer like the real APIs — the Salesforce copy serves 31 resource-and-method pairs, the HubSpot copy 190 operations, Gmail 85, Google Calendar 38, Slack 340, Microsoft Graph 1,183 — and hold records written for one company, the same facts in every app. Each run is kept as a trace you can read back. The routes teams use today, Salesforce sandboxes and scratch orgs, HubSpot test accounts and sandboxes, mocked APIs, and grading transcripts, each answer a different question, and this page compares them from each vendor's own documentation.

What a sales agent actually changes, and where

The reply is the last step of the work, not the work. A sales agent that writes "I've moved Acme Hosting to Negotiation and sent Priya the renewal quote" has told you what it meant to do: the stage changes in a deal update, the activity is a logged email, and the quote goes out in a send. Anthropic's guide to agent evals draws the same line: a transcript is "the complete record of a trial, including outputs, tool calls, reasoning, intermediate results", while "the outcome is the final state in the environment at the end of the trial" — a booking agent might say the flight is booked, but the outcome is whether a reservation exists.

For a sales agent, that means four or five separate things have to be right at once:

What the agent does Where it lands What to check after the run
Creates or updates an account, contact or lead HubSpot CRM objects, or Salesforce Account, Contact, Lead Fields, owner, no duplicate, no overwritten owner
Moves a deal HubSpot deal stage in its pipeline, or Salesforce Opportunity.StageName Stage, amount, close date, forecast the change implies
Logs the touch HubSpot calls, emails, meetings, notes, tasks, or Salesforce Task and Event Logged once, on the right record, under the right owner
Drafts or sends an email Gmail messages.send or drafts, or Microsoft Graph Right recipient, right thread, nothing internal sent outward
Books a meeting Google Calendar events, or Microsoft Graph calendar Attendees, timezone, conflicts, no invite to a stranger
Hands it to a person Slack message Right channel, enough context to act on

None of that is visible in the wording of the reply. Which is why testing a sales agent means testing the run — the calls it made, their order, and the state they left behind.

Four ways teams test a sales agent today

Each of these is a real practice with a real purpose. Read together, they show what a replica run adds and where it does not replace anything.

Salesforce sandboxes and scratch orgs

Salesforce's own description is a copy of your production environment "designed for safe development, testing, and training". Its own page sets out what each type contains, and the differences matter for anyone testing an agent:

  • Developer and Developer Pro include metadata only — no data — at 200 MB data / 5 MB files and 1 GB data / 1 GB files respectively.
  • Partial Copy adds "a sample of production data based on a custom template": 5 GB of data, refreshed no more often than every 5 days.
  • Full Copy is the most comprehensive option: metadata, full production data and all related files. The page lists it for replicating the entire org and for validating release performance, and it refreshes no more often than every 29 days.
  • Developer and Developer Pro refresh once per day.

Because Partial and Full copies carry real CRM records, Salesforce expects you to deal with the privacy consequence: "Using sandboxes with Data Mask & Seed helps accelerate development cycles and keep sensitive information protected during testing. Masking helps teams use realistic (but non-sensitive) data in environments like Partial Copy and Full sandboxes." Data Mask & Seed masks personally identifiable information in sandboxes — the treatments include anonymisation, pseudonymisation, pattern matching and deletion — and seeds selected records into Developer, Developer Pro, Partial and Full sandboxes from reusable templates.

Salesforce also ships its own way to test agents, and it is sandbox-bound: "Agent testing is available only in sandboxes", with a Testing Center in the UI, Agentforce DX for the CLI, and a Testing API. The same page notes that running tests "doesn't consume Einstein Requests or Flex Credits, but Data 360 queries that run during tests still consume Data 360 credits, and tests can modify data."

Scratch orgs are the other route: "a source-driven and disposable deployment of Salesforce code and metadata". They are empty by default — the documentation lists what you do not get, including sample data, custom objects and fields, profiles and permission sets, dashboards and reports, and workflows — until you configure the org's shape, and it is explicit that you should deploy "synthetic or dummy data for testing" and "don't add personal data to scratch orgs". They expire: a maximum 30-day lifespan, a duration you choose from 1 to 30 days, default 7, and after expiry you cannot restore them.

That is a good place to prove your Salesforce-side wiring, fields, validation rules and agent configuration. What it is not is the whole case. The sandbox is your org, not your prospect's world: the deal exists, but the email thread behind it, the calendar, the chat, the payment, and the app that sends the sequence live elsewhere. The refresh intervals decide how many different starting states you can prepare per week, and a refresh restores the copy's state, not one scenario's. And the unit of record is the Salesforce test, not the agent's own run.

HubSpot test accounts and sandboxes

HubSpot separates two things. A developer test account is a free HubSpot account "with access to a 90-day trial of many enterprise features", and you can create up to 10 per standard account; "test accounts cannot sync data with other accounts", and they "expire after 90 days if no API calls are made to the account". Its documented limits include that in Marketing Hub "you can only send marketing emails to addresses of users who you've added to your developer test account", and a workflow cap of 100,000 record enrolments per day.

A standard sandbox account requires an Enterprise subscription and, per HubSpot's knowledge base, "these sandboxes copy the structure of your standard account". Sandbox creation can copy up to 5,000 of your most recently updated contacts with up to 100 of their associated deals, companies and tickets each, or you can import records later. Its limits are the interesting part for agent testing:

  • "Contact, company, deal, ticket, and custom object IDs will have different IDs between sandbox and production accounts."
  • Integrations "in your production account won't be connected automatically to the standard sandbox account", and HubSpot recommends connecting the sandbox version of an integration "to prevent disruptions to your CRM data".
  • Emails from a standard sandbox "will not send" to contacts that are not sandbox users; you can send one-to-one and marketing emails only to contacts that share the same email address as existing sandbox users.
  • "You can only enroll 100,000 records per day in all workflows for the entire sandbox account."
  • Sandbox creation "may take a few hours".

The email limit is the fair reading of both sides of this route. It means an agent working in a HubSpot sandbox cannot email a real prospect list, which is exactly the protection you want. It also means you never watch the send path happen against a realistic list — the send is refused rather than addressed and delivered — so the HubSpot side of the run stops at the CRM boundary.

Mocked CRM APIs

A mock is a server you write, or record, that answers in place of the vendor. WireMock's own documentation describes the two mechanisms teams use: record-and-playback, where "recorded stubs will start being served immediately after recording is stopped"; and scenarios, where "a scenario is essentially a state machine whose states can be arbitrarily assigned", with state you can fetch, set and reset.

This is the cheapest way to test your own code: the adapter that builds a HubSpot batch-upsert body, the retry wrapper around a Gmail send, the branch when Salesforce answers 400 with a query error. It runs in CI in seconds, with no accounts and no keys.

What it cannot do is tell you whether the agent's work was correct. The stage transition it "performs" changes no pipeline, so a forecast report cannot contradict it. The account it updates has no history, so "did we already email this company in March?" has no answer. And each answer is only as accurate as the stub someone wrote — nothing checks it against the vendor's published schema.

Grading transcripts and simulated prospects

Transcript grading scores what a run did, and Anthropic's guide is the clearest public description of the practice. For conversational agents — which it puts in the same family as support and sales agents, because they "maintain state, use tools, and take actions mid-conversation" — it recommends "verifiable end-state outcomes and rubrics that capture both task completion and interaction quality", and notes that they "often require a second LLM to simulate the user", as in the τ-Bench and τ2-Bench simulations where one model plays a user persona.

Four warnings in the same document apply directly here. Trials should be isolated "by starting from a clean environment", because "unnecessary shared state between runs (leftover files, cached data, resource exhaustion) can cause correlated failures due to infrastructure flakiness rather than agent performance", and "shared state can also artificially inflate performance". Grading a fixed sequence of tool calls is brittle, so "it's often better to grade what the agent produced, not the path it took". Partial credit matters — an agent that qualifies the lead and then fails the update is better than one that fails at once. And pass^k, the probability that all k trials succeed, "especially matters for customer-facing agents where users expect reliable behavior every time": at a 75% per-trial success rate, three trials all pass about 42% of the time. The guidance for where to start is 20-50 tasks drawn from real failures.

An eval suite is the right way to judge decisions across many runs. What it cannot do is conjure the environment: a graded transcript of a deal update sent to a stub shows that the agent decided to move the deal, not that the pipeline state allowed it and ended correct.

The mailbox and the calendar have no test mode

The CRM is not the whole run, and the other half is harder to sandbox. Gmail has no separate test environment. Google's scope documentation puts gmail.send among the sensitive scopes, and the scopes that read and manage mail — gmail.modify, gmail.compose, gmail.readonly, gmail.metadata — among the restricted ones: restricted scopes "require restricted scope OAuth App Verification", and "if you store restricted scope data on servers (or transmit), then you must go through a security assessment". So the staging mailbox is either a real mailbox holding real prospect mail, or a hand-made account with none of your threads in it. The calendar, similarly, is either the sales team's own working calendars or an empty one.

What running the agent against replicas looks like

Redline serves copies of the provider APIs, built to answer like the real ones from each provider's published spec, with a watcher that reports when that spec or its documentation pages change; only the data is fake. Every company gets its own copy of every app, so the records in them belong to that company alone.

The copies a sales agent touches, and what the repo's own test suites report:

Copy What it serves What the repo reports
Salesforce 31 resource and method pairs: versions, resources, limits, record counts, describe global, sObject describe and create, records by ID and by external ID, updated/deleted, SOQL query, SOSL search, composite, sObject tree and collections; objects Account, Contact, Lead, Opportunity, Case, Task, Event, User 31/31 operations pass, 12/12 checks, 31/31 behaviour checks, jsforce client 20/20; recorded unauthenticated answers identical to the real API (68 of the 450, 0 different)
HubSpot 190 operations: contacts, companies, deals, tickets, line items, products, calls, emails, meetings, notes and tasks with batch and search, associations v3/v4, properties, pipelines, owners, OAuth token endpoints 190/190 operations pass, 46/46 behaviour checks, the official @hubspot/api-client 17/17; recorded unauthenticated answers identical (382 of the 450, 0 different)
Gmail 85 operations, including send, drafts, threads, labels, filters and settings 85/85 operations pass, 21/21 behaviour checks
Google Calendar 38 operations, including events, ACLs and sync 38/38 operations pass
Slack 340 methods 374/374 checks
Microsoft 365 (Outlook, Teams) 1,183 Graph endpoints, for teams whose mail and chat are Microsoft's —
LinkedIn 60 endpoints, for agents that work in social selling The repo notes this copy's recorded-answer comparison at 36 identical and 96 different, so its answers deserve more care than the CRM copies'

Agents sign in on the copy's own sign-in page rather than the vendor's: the HubSpot copy serves the OAuth authorize and token endpoints, with its account chooser labelled "Agent Sandbox", and a private-app token sits in the seed for agents that use one. Nothing reaches a real org, and no prospect is in the database.

The records are the company's own, and made up

The data agent writes a company's records as files in the company folder, one folder per app and one file per record kind, in exactly the format that app's API returns: accounts, contacts, leads, deals and their stages, logged calls, emails and meetings, owners and pipelines. Volumes are parameters rather than guesses. A shared world file keeps the facts the apps must agree on, so the deal the email refers to is the deal in the CRM, the account owner is a user who exists in both the CRM and the chat tool, and the meeting attendee is the person who wrote the thread. Everything is made-up: people and companies on .example domains, never a real person or a real company presented as the business or the prospect.

The state is there to act on, and you can put it back

A stage change in the copy moves the pipeline; an update keeps its history; a sent email sits in the thread. POST /_twin/reset returns a copy to its seed and GET /_twin/coverage says which operations it serves, so the same case runs again from the same starting state — the isolated trial Anthropic asks for, per scenario rather than per refresh interval. The HubSpot copy can also enable rate limits and expire a token, so the agent's behaviour under a 429 or a stale token is something you can watch instead of assume. Because each company has its own copy, one team's runs cannot inflate another's results.

Every step is recorded as the agent's run

The agent sends its run to the company's Redline project with the @redlineai/sdk, whose tracing API is Langfuse's JS SDK: observe() wraps a model call or a tool as a span, and propagateAttributes({ sessionId }) keeps one prospect's conversation together. The console shows each model call's request, the tools it called, the reply, tokens and cost per run. Rules are separate and written by you: on the site's own description of the monitor, "Write what your agent must not do. Each run is read against it, and every reply that breaks it is kept with its words and the reason." So "never move a deal to Closed Won", "never change an account owner" and "no second email to a prospect who has not replied" become records attached to runs, not a note in a prompt you hope holds.

How the routes compare

Route What the agent acts on Whose records What you keep afterwards Where it stops short
Salesforce sandbox A copy of your org's metadata, plus data on Partial or Full Copy Production, or production masked with Data Mask & Seed Salesforce-side test evidence; deployment One app; refresh every 5 or 29 days; the run is not the unit of record
Salesforce scratch org An empty org shaped by a definition file Synthetic or dummy data only Reproducible, CI-friendly configuration No sample data by default; 30-day maximum; personal data is not allowed in it
HubSpot test account or sandbox A standalone account, or a copy of your account's structure Up to 5,000 recent contacts, or none HubSpot-side change evidence One app; emails send only to sandbox users; IDs differ from production; test accounts expire after 90 idle days
Mocked CRM APIs Responses you wrote or recorded Stubs A fast, deterministic suite No state to be wrong, no history, accuracy unverified
Transcript evals A recorded or freshly run agent, wherever it ran Wherever the run happened Scores, regressions, graded traces Cannot show what the environment would have done
Replicas with the company's records Stateful copies of the CRMs, mail, calendar and chat Records written for that company Every step, cost, failures, rule breaks, and a resettable state Not the vendors; made-up data; some behaviour unverified

What the replicas do not do

Fair limits, from the copies' own READMEs and the repo's notes:

  • They are not the vendors. No email leaves the copy, no prospect is contacted, no invitation reaches a real calendar, no payment moves. Keep a Salesforce sandbox for validating Salesforce-side configuration, and HubSpot's test accounts for app and integration work.
  • Some answers are not verified against signed-in traffic. The Salesforce copy's standard picklist values in a new org (Opportunity.StageName, Lead.Status and others) are the copy's own choices, because the saved pages do not list them; the "Resources by Version" answer is the documented example's list of 47 resources, while a real org's list depends on its features. HubSpot's labels, groups and field types for default properties the reference pages do not describe are likewise the copy's own.
  • Not every app a sales team uses is replicated. There is no copy of a sequencing tool, a dialer or a meeting-scheduler link, so those calls are outside the run. The copies cover Salesforce and HubSpot for the CRM, Gmail and Microsoft Graph for mail, Google Calendar and Graph for meetings, Slack for chat, and LinkedIn for social selling.
  • It is not production data. The records are made up for the company. If one real case matters — the account with the odd renewal clause, the prospect who replied twice — write that record into the company folder by hand rather than exporting production records.

A week's worth of steps

  1. List the write actions, not the prompts. Every field the agent may set, every stage it may move, every send, invite and log, and the API each one lands in.
  2. Write the cases from real failures. Anthropic's starting point is 20-50 tasks drawn from real failures; for sales, that means the deals your team already knows are hard.
  3. Fill the company's records. Give the data agent the business, the domain and the apps; the world file keeps the account, owner, deal and thread consistent across the CRM, mail, calendar and chat.
  4. Write the rules before you run. "Never move a deal to Closed Won", "never overwrite an owner", "one activity per touch, never two", "no follow-up in a thread where the prospect has not replied", "book only in the prospect's business hours".
  5. Run each case from a reset copy, with the SDK instrumenting the agent, and keep the trace.
  6. Grade the state first, then the transcript. Stage, amount, activity count, recipient, attendee list; a rubric for tone and grounding; a turn limit.
  7. Re-run the set on every prompt or model change. The point of a recorded run is that last week's result is comparable with this week's.

Related reading on this site: how to test a support agent before it touches customers goes through the same comparison for a help desk; how to test a payment agent covers money movement and idempotency; how to test an AI agent for security before deployment covers the pre-release method; and approval gates and scoped credentials covers the controls that stop an agent writing outside its remit.

Common questions

Can we point the agent at a Salesforce sandbox instead?

Partly, and for some checks it is the right place. Salesforce's own agent testing runs only in sandboxes, with a Testing Center, Agentforce DX and a Testing API, and the sandbox is where your fields, validation rules and flows are. What it does not give you is the rest of the case: the prospect's email thread, the calendar, the chat, a reset per scenario, and the agent's own run as the record. It also decides how many starting states you get: a Partial Copy refreshes every 5 days and a Full Copy every 29, against a copy whose data is either production (masked with Data Mask & Seed) or, in Developer and Developer Pro, absent.

Does a HubSpot test account keep the agent away from real prospects?

On the sending side, yes: emails from a standard sandbox only send to contacts that share an email address with existing sandbox users, and a developer test account only sends marketing email to addresses of users you added to it. That protection is also the limitation — the send is refused rather than addressed and delivered, so the agent's list-building and follow-up behaviour is never exercised against a realistic set of contacts. Two other details matter for repeat tests: contact, company, deal and ticket IDs differ between sandbox and production, and a developer test account expires after 90 days without API calls.

Aren't mocked APIs enough if we grade the agent's own calls?

No, because the calls are not the work. Anthropic's distinction is that the transcript is the record and "the outcome is the final state in the environment at the end of the trial". With a mock, the deal stage is whatever the stub says it is, so "did the agent move the pipeline correctly" has no answer, and there is no history to contradict a claim that the account was already contacted. Mocks stay the cheapest way to test your adapter code and to run fast in CI.

Do we still need eval suites once the agent runs against replicas?

Yes. Evals are how you score decisions across many runs, catch regressions after a prompt or model change, and read the transcripts when a case fails. The replica changes what the score refers to: a state check against a copy that actually moved is a claim about a pipeline, not about a response body. Anthropic's warning about shared state is easier to honour here too, since POST /_twin/reset puts a copy back to its seed between cases, and each company has its own copy.

What about the sequencing tool the agent sends through?

If the agent starts a sequence or logs a call through a sales-engagement tool, a dialer, or a meeting-scheduler link, that call is outside the copies: Redline replicas Salesforce, HubSpot, Gmail, Microsoft Graph, Google Calendar, Slack, LinkedIn and others, but not those apps. The run then covers the CRM writes, the mail, the calendar and the chat, and the sequencer's behaviour is something you test there or leave out and say so.

Sources

  • Salesforce, What is a Salesforce Sandbox? — the four sandbox types and what each contains, storage per type, refresh intervals (1 day, 5 days, 29 days), Partial Copy templates, Full Copy as the option for replicating the whole org and validating release performance, Data Mask & Seed for masking and seeding.
  • Salesforce, Data Masking & Seeding Tools — masking PII by sensitivity with treatments including anonymisation, pseudonymisation, pattern matching and deletion; seeding templates; seeding into Developer, Developer Pro, Partial and Full sandboxes.
  • Salesforce Developers, Scratch Orgs — source-driven disposable orgs, what is not included by default, the advice to deploy synthetic or dummy data and not add personal data, the 30-day maximum lifespan and default of 7 days.
  • Salesforce Developers, Get Started with Testing Agents — Testing Center, Agentforce DX and Testing API; agent testing available only in sandboxes; tests can modify data.
  • Salesforce, Your Complete Guide to AI Agent Testing — sandboxes as the place agents are tested, and the Agentforce Testing Center.
  • HubSpot, HubSpot Account Types — up to 10 developer test accounts, the 90-day trial of enterprise features, sending limits, no syncing between accounts, expiry after 90 days without API calls, and standard sandbox accounts on Enterprise.
  • HubSpot Knowledge Base, Create a sandbox and deploy changes to production — what a sandbox copies, the 5,000-contact option, ID differences, integrations not connected automatically, email sending limited to sandbox users, the 100,000 workflow enrolment cap, and creation time.
  • WireMock, Record and playback — recorded stubs served immediately after recording stops.
  • WireMock, Stateful behaviour — scenarios as state machines with assignable, resettable states.
  • Anthropic, Demystifying evals for AI agents — transcript and outcome defined, conversational agents' end-state outcomes plus rubrics and simulated users, τ-Bench and τ2-Bench, isolated trials and shared state, grading what the agent produced rather than the path, partial credit, pass^k and the 42% three-trial figure, 20-50 tasks from real failures.
  • Google, Choose Gmail API scopes — sensitive and restricted scopes, restricted-scope verification, and the security assessment for storing or transmitting restricted-scope data.

Replicas of Slack, Gmail, Jira and more, filled with your company's data, to test your agent before production.

Run a simulation