Call destinations

Call destinations

Write what happened on every call into a spreadsheet or a table you already use — automatically, as each call ends.

Set it up on an agent under Analysis → After every call, write it to…, or for the whole workspace under Settings → Organization.

Why not just give the agent a tool?

You can already give an agent a "add a row to my sheet" tool, and it isn't the same thing:

  • A tool fires only if the model decides to call it. A log has to be guaranteed.
  • A tool cannot record a call nobody answered — there was no conversation for it to act in. That's usually the row you most want.

A destination is neither of those. It runs after the call, from the call record itself, whatever happened.

Where you can write

DestinationNotes
Google SheetValues are matched to columns by header name, so inserting a column doesn't shift everything
Airtable tableValues land correctly in single-select and date fields, not just text

Only what you've connected under Workplace → Integrations is offered.

CRMs are deliberately not here. Creating a new lead for every inbound call fills your CRM with duplicates. What's actually useful is an activity logged against the contact that already exists — that's a different feature, and it's coming.

What you can write

You map your column ← our field.

Field
call.outcomeanswered, no-answer, busy or failed — the carrier's own verdict, not a flattened "failed"
call.ended_at call.attempt call.to call.from
analysis.summary analysis.sentiment analysis.dispositionfrom post-call analysis
analysis.action_items analysis.topicslists, written as comma-separated text
analysis.custom.<name>anything your agent extractsanalysis.custom.interested, analysis.custom.budget
var.<name>a context variable carried into the call
'some text'a literal, in single quotes

analysis.custom.* is usually the interesting half. Whatever you've told the agent to extract is mappable straight into your own columns.

A field with nothing in it is skipped, not blanked. If a call has no summary, that cell is left alone rather than overwritten with an empty string — we won't erase something you already had.

If you map an analysis field

Post-call analysis takes a moment to run, so the destination waits for it before writing. That means the row appears a minute or two after the call, not instantly — the editor tells you when a mapping does this.

If analysis can't complete, we write anyway after 30 minutes with those fields empty, and record why. A missing summary is better than a missing row.

Which calls

Setting
Which callsEvery call · Except campaign calls · Only campaign calls
Write when the call wasany of answered no-answer busy failed

Use Except campaign calls when a campaign already writes back to its own source and you don't want the call logged twice.

Workspace default vs per-agent

A destination set under Settings → Organization applies to every agent. An agent that defines its own uses only its own — it replaces the default rather than adding to it, so you never get a duplicate row you didn't configure.

On an agent, an inherited destination is shown greyed with a workspace default chip.

When something goes wrong

The error appears on the destination itself, with the vendor's own message — "No such column 'Call_Status__c'", "the sheet has no header row". That matters because the failure is otherwise invisible: the agent keeps answering calls perfectly and the sheet simply stops filling.

Failed writes are retried. Nothing is lost by a temporary outage at Google or Airtable.

Each call is written once per destination, even across restarts or multiple servers — so you won't get duplicate rows.

Campaign write-back is the same machinery

If you fill a campaign from a source, its write-back is a destination too — one that updates the row the contact came from rather than appending a new one. It's configured in the campaign's own importer, so it doesn't appear in these lists.

The difference is only the verb:

  • Campaign — we read the row, so we know its address and can update it
  • Agent — nothing was read (an inbound caller is in no list), so each call appends