Index 04ChangelogMMXXVI

What we
shipped.

New features, improvements, and fixes across the platform. Everything here is live in production — go try it. Sorted newest first.

202621AprWeek 17
New

Flow Functions

Let the LLM call your backend mid-conversation with a structured HTTP request shape — path, query, and body parameters, each with their own JSON Schema.

Flow functions give your agents a way to reach live data during a call: look up an order, check availability, create a ticket, verify a customer — anything where the conversation needs to talk to your systems.

The shape

Each function defines method, URL, and three independent parameter locations:

Location Supports Use
pathParams primitives /orders/{orderId} style placeholders
queryParams primitives ?source=phone&limit=10
body nested objects and arrays (depth 5) JSON request body

Parameter names are unique across all three locations, URL placeholders must match pathParams keys, and the dispatcher percent-encodes path values to prevent injection.

Where values come from

Each parameter is bound to one of three sources:

  • llm — the model extracts the value from the conversation
  • call_context — server injects from the active call (caller identity, variables). Never shown to the LLM. onNull: reject hides the function for that call; fallback_to_llm exposes it.
  • static — fixed value baked in. Never shown to the LLM.

This lets you keep sensitive identifiers server-side while still giving the LLM everything it needs to decide when and how to call the function.

Execution

Functions run server-side. Headers are encrypted at rest with AES-256-GCM. Timeouts are configurable (100–30000ms, default 5000). If the function has transitionTo, the agent transitions even when the HTTP call fails — the LLM sees the error in the new node's context.

See the flow functions docs for the full request shape, binding modes, and validation rules.

Improved

Smarter LLM parameter handling

Models that don't support custom temperature (GPT-5 family) now have that field stripped automatically — no more silent ignores.

Some reasoning models reject a caller-specified temperature and use their own defaults. Talkif now strips the field before the flow definition reaches the bot, so you can see at a glance which models accept which parameters.

What's affected

gpt-5, gpt-5-mini, gpt-5-chat-latest, gpt-5.1-chat-latest, and gpt-5.2-chat-latest do not accept custom temperature. If you set one on a flow using these models, the value is removed when the flow is saved or returned to the editor.

How to tell

The model list response now includes an llmCapabilities.temperature boolean per model. The in-app model picker surfaces this directly.

Why

Before, the bot would receive a temperature value, silently drop it to call the model, and you'd never know whether your setting had any effect. Now the flow definition reflects what will actually run.

Improved

Phone numbers follow the latest version by default

Publishing a new flow version automatically serves calls on connected phones — no more manual reassignment, and pinned phones stay pinned correctly.

Phone-to-flow version behavior is now predictable:

  • Default (unpinned): The phone follows the latest published version. Publishing a new version immediately starts serving it on all connected phones.
  • Pinned: You can pin a phone to a specific version. When that version is republished, pinned phones are auto-bumped to the new version in the same transaction — preserving the intent that this phone stays in sync with this particular flow.

Previously, a phone could silently become pinned to whatever the current version happened to be at connection time. That surprise is gone — pinning is now opt-in and explicit.

Fixed

Function vs. action distinction

Only `end_call` is a builtin function. `tts_say`, `play_audio`, `wait`, `webhook`, and `forward_call` are pre/post actions — attempting to publish them as functions is rejected.

The difference matters:

Category Invoked by Example
Builtin function LLM decides during a turn end_call
Pre/post action Runs automatically on agent entry or exit tts_say, play_audio, wait, webhook, forward_call
Flow function LLM decides, executes server-side HTTP Custom HTTP endpoints

Publishing a flow that declares tts_say or forward_call as a function is rejected with unknown_builtin. Move them to preActions or postActions with the appropriate config ({ text } for tts_say, { phoneNumber } for forward_call).

The action nodes and flow functions docs have been updated to reflect the correct shape.

202611MarWeek 11
New

Public REST API

Full programmatic access to calls, contacts, flows, campaigns, analytics, and more — with scoped API keys and granular permissions.

202610MarWeek 11
New

Payment Method Health Tracking

Your payment methods now show real-time health status — know instantly if a card is declined, expired, or blocked.

Every payment method on your account now carries a status that updates automatically based on charge outcomes.

Statuses

Status Meaning
Active Last charge succeeded
Declined Card was declined (insufficient funds, etc.)
Expired Card expiration date has passed
Blocked Permanently unusable (lost, stolen, or flagged)

Status resets to Active on any successful charge. When a charge fails, the specific Stripe decline code is stored so you know exactly what went wrong.

Auto-recharge will not attempt charges against Expired or Blocked methods. If your default card enters one of these states, add a replacement before your balance runs low.

You can also now assign custom labels to payment methods (e.g., "Corporate Visa", "Marketing Budget") to stay organized across multiple cards.

New

Charge History

A detailed breakdown of every billable event on your account — not just credit movements, but what consumed them.

The billing section now includes a full charge history alongside the existing transaction log.

While transactions track credit movements (purchases, refunds, expirations), charges track the individual billable events that consume those credits.

Charge types

  • Call Usage — telephony, STT, TTS, and LLM costs per call
  • Phone Purchase — one-time number acquisition
  • Phone Rental — monthly number rental
  • Call Analysis — post-call AI analysis
  • Recording Storage — storage costs, billed when recordings expire or are deleted
  • Adjustment — manual credits or debits
  • Reservation — pre-authorized holds during active calls

Each charge includes a status lifecycle (Pending → Completed/Failed/Refunded), cost line items, and context about the associated entity (phone number, flow, or contact). Click any charge to see the full breakdown.

202628FebWeek 09
New

GDPR Data Export

Export all your account data in one click — contacts, calls, flows, billing history, and more.

You can now export a complete copy of your account data directly from Settings > Data Export.

The export includes 12 data categories: account info, users, contacts, calls, flows, phone numbers, VoIP providers, call schedules, campaigns, charges, balance transactions, and notifications.

How it works

  1. Request an export from Settings
  2. Confirm via email (security verification)
  3. A background job collects and packages your data
  4. Download link arrives by email — valid for 24 hours

The export is a structured JSON file, machine-readable and portable. Sensitive fields like passwords and MFA secrets are excluded automatically.

Limits

  • One active export at a time
  • 24-hour cooldown between exports
  • Download available for 24 hours after generation

This fulfills GDPR Article 20 (right to data portability). Full details on our Privacy Policy.

202627FebWeek 09
New

Dynamic Prompt Resolution

Every call now gets a personalized prompt assembled at call time — no latency tradeoff for personalization.

Every prompt in Talkif is a Handlebars template. When a call starts, the platform resolves that template against real data: who the contact is, why they're being called, what business is calling, and what time it is in their timezone.

Four namespaces are available at resolution time:

  • contact.* — name, email, company, timezone, language, notes, interests, tags, custom fields
  • call.* — direction (inbound/outbound), caller and callee numbers
  • account.* — your business name and identifier
  • system.* — current date, time, and timezone

A template looks like this:

handlebarsYou are calling on behalf of {{default account.name "our office"}}
to confirm an upcoming appointment.
 
Address the contact as {{default contact.firstName "there"}}.
 
{{#if contact.email}}
  Offer to send a confirmation email to {{contact.email}}.
{{/if}}
 
{{#if (includes contact.tags "vip")}}
  This is a high-priority contact. Be especially attentive.
{{/if}}

The engine supports conditionals, comparisons (eq, ne, gt, lt), regex matching, array operations, fallback defaults, and existence checks. Template resolution runs in microseconds — the agent picks up, greets the caller by name, and references their specific context in under one second.

New

AI-Assisted Prompt Authoring

The Prompt Library now includes an AI assistant that knows your contact schema, available Handlebars helpers, and account-specific custom variables.

Writing Handlebars templates from scratch isn't always intuitive — especially when you have dozens of available variables and helpers.

The Prompt Library now includes an AI assistant that knows your schema. Describe what you want in plain language. It generates a complete, valid template using only variables that actually exist in your account.

The assistant enforces proper Handlebars syntax, avoids literal dialogue scripts, and supports multi-turn refinement. You stay in control of the final template — the AI just gets you there faster.

textYou: "I need a prompt for appointment reminders that 
      checks if they're a VIP and mentions their timezone"
 
Assistant generates:
  {{#if (includes contact.tags "vip")}}
    This is a priority client. Be especially accommodating.
  {{/if}}
  Their local time is based on {{default contact.timezone "UTC"}}.

No more guessing which variables exist or getting the syntax wrong.

New

Campaign Contact Snapshots

Contact data is now frozen at campaign enrollment time. No more mid-campaign data drift.

When you run an outbound campaign, contact data is now captured at enrollment time and frozen for the duration of the campaign.

If a contact's name, company, or notes change between scheduling and dialing, the call still uses the original data. Retries and rescheduled attempts stay consistent — the agent references the same context across every attempt.

This prevents a class of bugs where mid-campaign CRM updates cause the agent to reference stale or conflicting information. The prompt your agent receives on retry #3 is identical to what it received on attempt #1.

Older entries available on requestRSS · talkif.ai/changelog.rss