# Manage agents Source: https://help.avoca.ai/agents/overview Find call and message agents and update their customer-facing behavior. Open **Settings → Agents** to view the agents available to your team. Agents are separated into **Calls** and **Messages** because voice and messaging channels use different configuration. The agents and editing tabs you see depend on your team's products, agent type, and permissions. ## Configure a call agent Select an agent on the **Calls** tab. Its editor can include: * **Voice Settings:** Voice, customer-facing agent name, new-customer greeting, existing-customer greeting, and internal name and description * **Agent Settings:** The agent's operational behavior and enabled capabilities * **Agent Logic:** Additional logic, when configured for the team * **Agent Flowchart:** A visual representation of the agent flow, when available Voice Settings can also show whether the agent inherits the team's Knowledge Base or uses an explicit override. Prefer the shared Knowledge Base when the information applies across agents; use an override only when that agent needs different instructions. ## Configure a message agent Select an agent on the **Messages** tab. Depending on the agent type, its editor can include: * **Agent Settings** for escalation, links, follow-up behavior, and channel-specific options * **Objective** for the goal, prompt, assistant name, first message, and available tools * **Setup Instructions** for channel installation or behavior Message-agent types can include Outbound, Speed-to-Lead, Call Follow-up, Webchat, Google Local Services Ads, Yelp, New Customer Sign-Up, and Genesys SMS. Some campaign agents expose only the settings relevant to their objective. ### Choose escalation reasons deliberately Under **Agent Settings → Escalation Settings**, enable only the reasons that a team member is prepared to own. Common reasons are disabled until you select them, and workflow editors can expose the same choices for workflow-specific behavior. Two available reasons need special operational handling: * **The customer asks to stop receiving messages:** an exact `STOP` is handled as an automatic text opt-out. Other wording, such as “take me off the list,” escalates only when this reason is enabled; the receiving team member must complete the opt-out. * **The customer asks to be contacted again at a later time:** enable this when a person should take over requests such as “call me next week.” This escalation does not schedule an automatic future follow-up. After enabling a reason, confirm the customer-facing escalation message, the internal alert recipients, and who resolves the conversation. Test one matching phrase and one phrase that should remain with the AI. ### Configure Call Follow-up messages and attribution For a **Call Follow-up** agent, expand **First Message → Advanced settings** to choose how the first text is written: * Leave **Contextual first message** off to send the configured first-message template. * Turn it on to generate a short opener from the broad service issue stated in the call transcript. The configured template remains the fallback when the transcript is unavailable, generation fails, or the generated message does not pass the safety checks. The same advanced area can include **Attribute follow-up bookings to the original call**. This setting changes ServiceTitan reporting for a job booked in the follow-up text conversation: * **Off (default):** use the dedicated **AI Text Rehash** campaign and do not attach the original call. * **On:** retain the original call's ServiceTitan campaign and call reference. Changing the first-message mode changes live customer copy. Changing call attribution changes which campaign and call receive credit for later text bookings. Test the message and verify a controlled ServiceTitan booking before relying on either setting in production. ### Enterprise-managed message agents A message agent based on an enterprise template shows a notice that later template updates can modify the agent. The team editor exposes only **Objective** because **Agent Settings** and **Setup Instructions** are managed by the enterprise template. When an enterprise template is pushed or re-pushed to a team, the managed agent is enabled with AI responses on. The phone number remains a team-specific binding and must still be reviewed separately. Before an enterprise push, confirm the target teams, customer-facing objective, escalation behavior, tools, and phone-number readiness; then test one conversation on each affected use case. An enterprise template push can adopt an existing team-owned agent and immediately make the resulting managed agent live with AI responses enabled. Treat adoption and re-push actions as production changes. ### Replace a Yelp objective across an enterprise When the enterprise has the required feature and you have permission to manage enterprise agent settings, open the enterprise workspace and go to **Agents → Messages**. The **Yelp objective** section can replace the channel objective for selected teams in one action. 1. Review the team selector. Teams without a Yelp agent and teams managed by a template are labeled and skipped. 2. Select only the intended writable teams. 3. Paste the complete replacement objective and compare the **will be updated** and **skipped** counts with your intended scope. 4. Choose **Apply to *n* teams**, review the confirmation, and replace the objective. 5. Open each updated team's Yelp agent and run an approved conversation test. This action changes only the Yelp objective. Each team's universal messaging prompt continues to apply before it. The enterprise page does not keep objective version history, so record the current objective outside the form before replacing it. Replacing an enterprise Yelp objective overwrites live customer-facing instructions on every selected writable team and cannot be undone from that page. Treat the team count, objective text, and confirmation as a production change. ## Make a safe change 1. Open the correct team and agent. 2. Record the behavior you expect to change. 3. Update the smallest relevant setting. 4. Save the change. 5. Test a realistic customer scenario before relying on it in production. Greetings, booking behavior, transfer rules, and message objectives are customer-facing. Review the result as a complete conversation, not only as an isolated field. # Build Custom Analytics Source: https://help.avoca.ai/analytics/custom-analytics Create, validate, save, organize, and export custom charts with the Avo-guided analytics builder. Open **Analytics → Custom Analytics** to review saved views. Select the option to create a view to open the guided builder. Custom Analytics is feature-gated. The available datasets, fields, chart types, and actions depend on your team and role. ## Ask a complete business question Include: * The measure you want to count, sum, average, or calculate * The time range * The grouping, such as day, call reason, source, assistant, or service area * Filters that define the population * The intended chart type when it matters For example: > Show inbound booked calls by week for the last 90 days, split by service area. Avo turns the request into a draft. Review the draft fields rather than assuming the chart matches the wording. ## Review the chart specification Check: * **Dataset:** the product data used for the chart * **Measure:** the value being calculated * **Grouping:** the categories or time grain on the axes * **Filters:** the population included or excluded * **Date range:** the current preview range and the saved default * **Visualization:** line, bar, pie, aggregate table, stat card, call list, or another supported type * **Sort and limits:** especially for ranked tables and categorical charts Line charts need a time-based x-axis. Pie charts should use one meaningful category with a limited number of segments. A stat card should answer one ungrouped headline question. ## Refine with Avo Use follow-up instructions such as: * “Make this a line chart by week.” * “Only include inbound calls.” * “Split it by call reason.” * “Exclude silent and spam calls.” * “Rename the chart to Weekly booked calls.” The builder sends the current draft with each refinement, so a follow-up edits the active chart instead of starting an unrelated one. ## Build a list of individual calls Ask Avo for a **call list** when the question is “which calls?” rather than “how many?” For example: > List the unbooked inbound calls from yesterday with customer name, phone number, call reason, and duration. A call list shows one row per call instead of an aggregate. The call start time is always the first column. Ask Avo to add or change up to eight other columns, such as customer name, customer phone, call reason, duration, booking outcome, AI or human handler, transfer destination, team call reason, or available Oversight tags and evals. Use filters and the date picker to define the population. By default, a list shows the 25 most recent matching calls; ask Avo for a different row limit or sort when needed, up to 100 calls. In the dashboard, select anywhere on a row to open that call in a new tab. An enterprise call list opens each call in its owning team. If more calls match than the saved row limit, the preview says that additional calls matched the range. Call lists are available only for call analytics. Avo creates the list and changes its columns; the standard measure and grouping controls are for aggregate charts. ## Validate before saving 1. Choose a short period with known activity. 2. Compare the result with the closest standard report or metric drill-down. 3. Confirm the dataset, measure, filters, and timezone. 4. Inspect a table version or, for a call list, open representative call rows. 5. Check empty categories, null values, and unexpected totals. 6. Restore the intended saved date range. A visually plausible chart can still answer the wrong question. Validate the population and calculation, not only the trend shape. ## Save and organize views Give every saved view: * A specific title * A description that states the business question * The important population or exclusions * A sensible default date range From the saved-view library, you can open a view, change its preview date range, edit its title or description, edit it in the builder, reorder supported views, or delete it. Deleting a team-owned view removes it from the Custom Analytics library. Confirm that it is not used in a recurring review before deleting it. ## Export a report When PDF export is available: 1. Select the saved charts to include. 2. Choose the report date range. 3. Review the preview and chart titles. 4. Export the PDF. The export has a maximum number of charts. Use a focused set that tells one story rather than combining unrelated views. When a call list appears in a PDF, scheduled email report, or CSV output, it is rendered as a plain table. Dashboard call links are not included in those exported rows, and the saved row limit still applies. ## Troubleshoot a chart * **No data:** widen the date range, remove one filter at a time, and confirm the selected dataset is available. * **Unexpected total:** compare the measure and denominator with [Analytics → Metrics](/analytics/metrics). * **Too many categories:** add a filter, choose a higher-level grouping, or apply a supported limit. * **A call list is too short:** ask Avo to increase its row limit, up to 100, and confirm whether the preview says more calls matched. * **A call list opens the wrong population:** review its filters and date range; its columns describe each call but do not define which calls are included. * **A line chart will not render:** use a date grouping on the x-axis. * **A saved view changed:** confirm the preview date range and whether the view was edited in the builder. Record the saved-view title, team, date range, and the specific value that differs when escalating. # Run A/B experiments Source: https://help.avoca.ai/analytics/experiments Create controlled assistant variants, split live traffic, interpret experiment metrics, and stop safely. Open **Analytics → A/B Test** to create and run experiments across voice-assistant configurations. This page appears only for teams and roles with configuration access. Starting an experiment sends live calls to every configured variant. Validate each assistant configuration and the assistant's default configuration before you start. ## Plan the experiment Define these before creating anything: * One behavior you want to change * A hypothesis with an expected direction and business reason * A primary success metric and any guardrail metrics * The voice assistant that will receive the experiment * A saved assistant configuration for every variant * A traffic allocation and planned duration * The default assistant configuration to use if the experiment is stopped Use variants that differ only in the behavior being tested. If a prompt, voice, transfer rule, and booking policy all change at once, the result will not explain which change mattered. ## Create an experiment 1. Choose **New Experiment**. 2. Enter a descriptive name and hypothesis. 3. Select the voice assistant. If the team has one assistant, it is selected automatically. 4. Enter a planned duration in days. 5. Configure at least two variants. Give each one a distinct name, traffic percentage, and assistant configuration belonging to the selected assistant. 6. If assistant overrides appear, optionally set a first-message or TTS-voice override for a supported variant. 7. Select up to 10 primary metrics. The available metric catalog depends on your team's features. 8. Confirm that all traffic percentages add up to 100% and choose **Create Experiment**. The new experiment is **Not Started** and does not receive traffic yet. The selected voice assistant is fixed as soon as the experiment is created. Common outcome metrics can include booking, contained-booking, transfer, lead-booking, and average-call-duration measures. Use each metric's description in the dashboard; a similar name does not guarantee the same population or preferred direction. ## Edit before starting While an experiment is **Not Started**, you can edit its name, hypothesis, planned duration, variant names, traffic splits, assistant configurations, supported overrides, and metrics. You cannot change its voice assistant. Before choosing **Start Experiment**: 1. Open every referenced assistant configuration and test a representative call. 2. Confirm the intended control configuration. 3. Confirm that splits total 100% and every variant has a configuration. 4. Recheck which configuration is currently the voice assistant's default. 5. Verify the metric set and record the launch decision outside the experiment if your team requires an approval trail. Starting begins live allocation immediately. Once live, the experiment structure is locked. ## Monitor a live experiment The detail page shows status, processed exposures, total exposures, days running, and results for each group. Results update once daily, so calls can appear before their metric results do. For each metric, review: * The control baseline and each variant's mean * Actual exposures by group, not only the configured split * Absolute change from control * The p-value and **Significant** or **Not Yet Significant** label * Whether higher, lower, or neither direction is considered better * The linked calls for each variant The star marks the best observed value in that row; it does not by itself prove that the variant is a winner. Average Call Duration is treated as neutral because longer or shorter is not universally better. The dashboard gives rough call-volume guidance for booking-rate changes: a smaller percentage-point improvement generally needs far more calls per variant. Avoid decisions based on the first few exposures, an unbalanced sample, or a positive metric with a harmful guardrail. You can add metrics to a live experiment, up to the limit, but cannot remove a metric that was already attached while the experiment is live. Variant configurations, names, and traffic splits are also locked. ## Stop and roll back safely Choose **Stop Experiment** when a guardrail degrades, a variant is defective, or the planned decision point is reached. Enter a required stop reason and confirm **Stop Serving Experiment**. Stopping does two things: * It stops the experiment from serving new traffic. * New calls fall back to the voice assistant's current default configuration. Stopping does **not** deploy the control or the best-looking variant. Verify the default configuration before stopping, especially if someone changed it after the experiment began. A stopped experiment cannot be resumed from the dashboard. If the page displays a synchronization warning after stopping, preserve the warning and contact your Avoca support channel. Confirm the experiment status and test a new call against the default configuration before considering the rollback complete. ## Decide what to ship 1. Wait for the daily result update and enough exposures for the expected effect size. 2. Check exposure balance and open calls from each variant. 3. Review every primary and guardrail metric, including directionality. 4. Treat **Not Yet Significant** as inconclusive, not as a loss. 5. Record the decision and stop reason. 6. Stop the experiment. 7. Separately make the chosen assistant configuration the default, then test it. Keeping the stop and deployment steps separate prevents an experiment result from silently changing the production default. # Review Google Ads Reporting Source: https://help.avoca.ai/analytics/google-ads-reporting Compare account- and campaign-level Google Local Services Ads performance for a selected date range. Open **Google Ads Reporting** in the main sidebar. This page appears only when reporting is enabled for your team and your role can view messages. Google Ads Reporting summarizes connected Google Local Services Ads accounts. It is separate from Avoca's conversation reporting and does not configure how the message agent responds. ## Review account performance 1. Select the date range in the upper-right corner. 2. Find the correct connected business account. 3. Review its totals for **Impressions**, **Clicks**, **Conversions**, **All Conversions**, and **Cost**. 4. Compare the account totals with the campaign table beneath them. Currency is shown using the connected account's currency. Conversion totals can include fractional values when Google Ads attribution reports them that way. ## Review campaign performance The campaign table breaks the same period down by campaign and shows: * Campaign name and status * Impressions and clicks * Conversions and all conversions * Cost Use the same date range when comparing this page with Google Ads or another report. Differences in attribution windows, time zones, conversion definitions, or account scope can make similar-looking totals differ. ## Troubleshoot missing data * **No connected account:** coordinate the Google LSA account connection with Avoca. * **A connected account could not be loaded:** note the account and error shown on the page, then contact Avoca Support. * **No campaign activity:** confirm the date range and campaign status in the source account. * **Only some accounts failed:** the page reports those accounts separately; data from the accounts that loaded successfully remains visible. For conversation handling, AI settings, escalation recipients, and opt-outs, see [Google Local Services Ads](/integrations/google-lsa). # Understand call metrics Source: https://help.avoca.ai/analytics/metrics Read the call and Call Flows metrics, compare populations correctly, and use drill-downs to validate a number. Open **Analytics → Metrics** to review the definitions available to your team. On a Calls or Call Flows page, use a metric card's information control to see its current calculation and definitions. The dashboard can show a different set of metric cards by team, role, product surface, or rollout. Use the definition shown with the metric you are viewing. ## Start with the population Before comparing rates, identify the denominator: * **Total Calls:** every call in the selected date range and filters * **True Interactions:** Total Calls minus silent, spam, telemarketing, and test calls * **Leads:** calls where the customer had something new to book * **Contained Calls:** calls Avoca booked or completed without an external transfer, including calls booked before a later transfer * **Contained Leads:** bookable calls Avoca handled without an external transfer, including calls booked before a later transfer Two cards can both say “booking rate” while answering different questions. ## Booking metrics | Metric | What it answers | | - | - | | **Raw Booking Rate** | What share of all calls ended with a booking? | | **Contained Raw Booking Rate** | What share of contained calls did Avoca book? | | **Lead Booking Rate** | What share of bookable leads booked on the first call, including bookings completed by a human after transfer? | | **Contained Lead Booking Rate** | What share of contained leads did Avoca book, excluding leads transferred without an Avoca booking? | | **Fully Recovered Booking Rate** | What share of leads eventually booked on the call, after transfer, or through eligible follow-up? | | **Contained Fully Recovered Booking Rate** | What share of contained leads Avoca booked on the call or recovered later, excluding bookings completed after transfer? | “Contained” narrows the customer journey. “Fully recovered” widens the time horizon. Do not compare those variants without explaining both differences. For call classification, an offered slot alone is not a confirmed booking. The agent must state a concrete new appointment day, time, or window, and the customer must accept it afterward. Silence, a disconnected call before acceptance, a vague promise to find the first available technician, or acknowledgement of an existing appointment does not qualify. If a total looks unexpected, inspect the transcript for both the agent's offer and the customer's later acceptance. ## Transfer and containment metrics * **Containment Rate:** calls Avoca booked or handled without an external transfer divided by Total Calls * **External Transfer Rate:** calls transferred to your team divided by Total Calls * **Avoca Internal Transfer Rate:** contained calls where an Avoca human agent stepped in, divided by the eligible contained population * **All Transfer Rate:** calls where Avoca AI initiated an internal or external transfer, divided by Total Calls An internal handoff to an Avoca human and an external transfer to your team answer different operational questions. ## Volume and quality metrics Common count cards include: * Total Calls * Total Contained Calls * Leads * Contained Leads * Booked Calls * Contained Booked Calls * Transferred Calls * True Interactions * Silent/Spam Calls * Unbooked Calls * Emergency Handled Calls * Recovered Calls The **Silent/Spam Rate** compares non-actionable silent, spam, telemarketing, or test calls with the full call population. **Bookable Opportunities** compares Leads with True Interactions. ## Duration, repeat, and operating metrics Depending on the surface, you may also see: * Total Duration * Average Call Duration * Average Booked Call Duration * Average Unbooked Call Duration * Average Time to Availability * Repeat Calls within seven days * Pre-call Transfers and Pre-call Transfer Rate * Estimated Call Spend * Calls with Tasks Rate Estimated spend uses configured per-minute assumptions and is not an invoice. ## Use a metric drill-down When a metric supports it: 1. Apply the date range and page filters. 2. Open the metric's details. 3. Review the numerator, denominator, and excluded records. 4. Open the matching-call drill-down. 5. Inspect representative rows and their call detail. 6. Return to the card without changing filters. Some Sankey-derived contained populations cannot be represented exactly by a Calls-page filter. The dashboard says when an exact drill-down is unavailable. ## Compare two reports safely Match all of these: * Team * Date range and timezone * Inbound, outbound, or all-call scope * Service areas * Assistants * Call reasons and bookability buckets * Transfer and handling filters * Whether silent/spam calls are included * Whether recovered bookings are included Write comparisons as a complete sentence: “Contained Lead Booking Rate for inbound Responder calls in July,” not simply “booking rate.” ## When a number looks wrong 1. Clear saved or inherited filters. 2. Confirm the page and metric use the same data model; Call Flows and legacy Calls are separate surfaces. 3. Check the definition and denominator. 4. Open matching records where available. 5. Allow for recent call processing or CRM attribution. 6. Compare the same calls, not only the headline total. 7. Preserve the metric name, URL, team, filters, date range, and example call IDs when contacting Support. # Use Oversight Source: https://help.avoca.ai/analytics/oversight Define call annotations and evals, validate them safely, monitor results, and backfill historical calls. Open **Analytics → Oversight** to manage the call-analysis signals available to your team. Oversight is available only when it is enabled and your role can view it. Oversight has five team-level pages: * **Dashboard:** monitor annotation volume and eval failures * **Annotations:** extract structured signals from call transcripts * **Evals:** test whether an applicable call met a pass/fail standard * **Playground:** try temporary definitions against a small call sample * **Backfill:** recalculate selected persisted definitions on historical calls ## Read the Dashboard The Dashboard defaults to the last 30 days. Change the date range to review: * **Analyzed calls:** calls with analysis available in the period * **Calls with annotations:** the count and share with at least one annotation value * **Eval failures:** failed eval results in the period * **Most common annotations:** values, counts, and shares by annotation * **Top eval failures:** failed count, failure rate, and applicable-call count An eval's failure rate uses applicable calls, not every analyzed call. Compare the **Applicable** count before ranking two evals by failure rate. ## Configure annotations An annotation extracts a reusable value from a transcript. In **Annotations**, choose an available template or create a custom annotation, then configure: * **Name** and **Description** * **Type:** Simple, Multiple choice, or Text * **Options** for a Multiple choice annotation * **Prompt** that describes the extraction logic * **Voice agent scope** when that control is available * **Active** and **Visible** Use **Simple** for a yes/no signal, **Multiple choice** for a controlled set of categories, and **Text** only when a free-form answer is necessary. ### Review Avoca-managed annotations When Avoca maintains shared annotations for your team's responder vertical, the **Annotations** page shows a separate **Avoca-managed annotations** section. These annotations run like other active annotations, but their name, prompt, options, Active state, and Visible state are read-only on the team page. The section can group annotations under: * Your team's current vertical * **Other verticals** for annotations installed while the team used a different vertical * **All teams** for globally managed annotations An annotation under **Other verticals** can continue running until Avoca removes it. Do not treat that grouping as proof that the annotation is inactive. Open the annotation to review its definition, then contact Avoca Support when a managed annotation appears under the wrong vertical, should be retired, or does not match the team's current call-analysis needs. ## Configure evals and alerts An eval returns pass or fail only when the call is applicable. In **Evals**, configure: * A clear name and description * An **Applicability prompt** that says when the standard should be tested * An **Evaluation prompt** with the pass/fail criteria * A voice-agent scope when available * Active and Visible settings Keep applicability narrow. A call that should not be judged must be excluded by the applicability prompt rather than treated as a failure. To receive email notifications for an eval, open its alert control and set: * A failure-rate threshold from 1% to 100% * A 1-, 6-, 12-, or 24-hour window * The minimum number of applicable calls required before alerting * One or more recipient email addresses Use a minimum volume large enough to prevent a single call from creating a noisy alert. You can disable an alert without removing it, or remove the alert rule when it is no longer needed. ## Understand Active, Visible, and scope **Active** and **Visible** do different jobs: * An inactive definition remains saved but does not run on calls. * A hidden definition can still run, but its result does not appear in the dashboard call UI. New custom definitions start inactive and hidden. Validate them before enabling either control. Custom and code-backed definitions can offer **All voice agents** or one voice agent. Shared templates apply across assistants and do not expose a voice-agent scope. Some definitions are managed at the enterprise level; those are read-only on the team page and must be changed by the appropriate enterprise owner. Avoca-managed annotations are also read-only and must be changed or removed by Avoca. ## Test in Playground first Playground creates a temporary working session from the current annotation and eval library. Changes made there do not update the persisted definitions or production call results. 1. Open **Playground**. 2. Choose **Last 5**, **Last 10**, or **Last 25**, or paste up to 25 call UUIDs. 3. Add the annotations and evals you want to test. 4. Refine their temporary prompts or options. 5. Choose **Run playground**. 6. Review evaluated and skipped calls, token usage, transcripts, extracted values, explanations, quotes, pass/fail results, and evidence. Use examples that include expected positives, expected negatives, and calls where an eval should be not applicable. Copy a proven change back into the saved definition only after reviewing the individual-call evidence. ## Backfill historical calls Backfill queues background work for eligible analyzed calls. It changes historical Oversight results, so test the definition in Playground first. 1. Open **Backfill**. 2. Select the first and last calendar day. The range is interpreted in the team's timezone. 3. Select only the persisted annotations and active evals that need recalculation. 4. Review the day count and selected definitions. 5. Choose **Run backfill**, then confirm. The dashboard queues one job per eligible call. Successful results replace or create the historical value for each selected definition. If a selected definition fails to evaluate, its existing value is preserved; changing a voice-agent scope can also clear a stale selected result from calls that no longer match that scope. A queued backfill has no cancel control on the team page. Start with a narrow date range, do not submit the same backfill twice, and wait for processing before judging the Dashboard totals. ## Make changes safely * Set a definition inactive before retiring it; hiding it alone does not stop evaluation. * Prefer inactive and hidden over deletion while you confirm that no workflow depends on the result. * Deleting a team-created annotation or eval cannot be undone. * Backfill only the definitions whose logic or scope changed. * Do not use Backfill merely to refresh the Dashboard; change the date range or reload the page instead. * Review alert recipients and thresholds after changing an eval's applicability. Dashboard totals can lag while live analysis or a backfill is still processing. Inspect a few underlying calls before concluding that a definition or historical run is incorrect. # Use Analytics Source: https://help.avoca.ai/analytics/overview Find product performance, understand metric definitions, and keep report comparisons consistent. Open **Analytics** in the main sidebar to reach reporting for your enabled Avoca products. Analytics is visible only when reporting is enabled for your team and your role has permission. Individual tabs can also require a product, integration, or additional access. ## Start from Overview The **Overview** page links to the product analytics your team can access: * **Responder:** inbound call performance and outcomes * **Outbound:** campaign reach, engagement, and bookings * **Speed-to-Lead:** source quality, response, and conversion Simple Scheduler analytics is available from **Products → Simple Scheduler → Overview** when that product is enabled. Portfolio members can use the [Portfolio dashboard](/analytics/portfolio-dashboard) to compare Responder performance across the enterprises and brands in their portfolio scope. Leadership and cross-product sections appear when enabled for the portfolio. ## Use the Analytics tabs Depending on your team's configuration, Analytics can include: * **[Portfolio dashboard](/analytics/portfolio-dashboard):** cross-enterprise and cross-brand Responder KPIs for members with Portfolio **View KPIs** access, with leadership and product analytics sections when enabled * **[Metrics](/analytics/metrics):** definitions for call and call-flow metrics, including their calculation and drill-down population * **[Custom Analytics](/analytics/custom-analytics):** saved views and a guided builder for team-specific questions * **[Revenue](/analytics/revenue):** ServiceTitan revenue, Avoca attribution, job trends, and campaign performance when the required data is available * **[Oversight](/analytics/oversight):** annotations, evals, alerts, Playground validation, and historical backfills for teams with Oversight access * **[A/B Test](/analytics/experiments):** create, configure, run, monitor, and stop live voice-assistant experiments for teams with configuration access * **[Survey Analytics](/analytics/survey-analytics):** post-call survey volume, satisfaction, resolution, feedback, and participation when enabled If a tab is missing, confirm the selected team, product access, and your role before assuming that data is unavailable. A/B experiments can change how live calls are handled, and Oversight backfills can replace selected historical results. Review the dedicated guide and validate the configuration before starting either action. ## Compare reports correctly 1. Select the correct team. 2. Apply the same date and time range to both reports. 3. Match service-area, campaign, source, channel, and call filters. 4. Open **Metrics** to confirm the numerator, denominator, and excluded records. 5. Use a metric's drill-down to inspect the records behind the value. 6. Export data only after the filters match the question you are answering. Rates with similar names can use different populations. For example, a booking rate based on all actionable calls is not directly comparable to a rate based only on contained, bookable calls. ## Build a custom view When **Custom Analytics** is available: 1. Open **Custom Analytics** and select the option to create a view. 2. Describe the business question in plain language. 3. Review the proposed metric, grouping, filters, chart, and time range. 4. Validate the preview against a known product report or drill-down. 5. Name and save the view. 6. Return to the library to edit its title or description and arrange saved views. Add a description that states the business question and important filters. A clear saved-view name alone rarely explains why two similar charts differ. # Use the Portfolio dashboard Source: https://help.avoca.ai/analytics/portfolio-dashboard Compare Responder KPIs and, when enabled, product performance across portfolio enterprises and brands. The Portfolio dashboard rolls up reporting across the enterprises and brands in a portfolio. Select the portfolio workspace, then open **Analytics → Dashboard**. Portfolio access must be enabled, and your portfolio membership needs **View KPIs** permission. The dashboard includes only the enterprises and brands within your membership scope. The dashboard experience depends on the rollout enabled for your portfolio: * **Portfolio KPIs:** the standard view shows Responder metrics, a team KPI summary grouped by enterprise, and Responder charts. * **Enterprise Dashboard:** the leadership view adds an executive Responder overview with call flow, performance comparisons, trends, capacity impact, unbooked reasons, and minutes by brand. * **Enterprise Dashboard with product analytics:** the expanded leadership view also adds a product rollout tracker, Responder configuration checks, **Speed-to-Lead**, and **Outbound**. If the page loads Responder results but does not show **Overview**, **Speed-to-Lead**, or **Outbound** tabs, your portfolio is using the standard view. This is a rollout difference, not a **View KPIs** permission error. ## Set the reporting population The dashboard initially shows the most recent 7-day period and all brands and customer types available to you. Before comparing results: 1. Set the date range. 2. Open **Filters** and choose the brands to include. Brands are grouped by enterprise; teams connected directly to the portfolio appear under **Direct Teams**. 3. Select one or more customer types: **New**, **Existing**, or **Unknown**. 4. Choose **Apply**. Use **Reset** to restore all available brands and customer types. On the leadership view, the page title states how many brands and enterprise groups are included. Use **Refresh dashboard** when you need to reload the current population. Match the date range, brands, and customer types before comparing the Portfolio dashboard with a team or enterprise report. Similar metric names can represent a different filtered population. ## Read Portfolio KPIs The standard **Portfolio KPIs** view presents Responder performance for the selected population. It includes: * Lead Booking Rate, Adjusted Raw Booking Rate, and Raw Booking Rate * Avoca Containment Rate, Bookable Opportunities, and Silent/Spam Rate * Call counts, transfer and containment counts, and total duration * **Team KPI Summary**, grouped by enterprise, with per-brand call, booking, rescheduling, transfer, and containment results * Responder charts for the selected date range and filters Adjusted Raw Booking Rate uses booked calls divided by true interactions. The standard Portfolio view does not include the leadership call-flow, capacity-impact, minutes-by-brand, or cross-product sections. ## Read the leadership Overview When the leadership dashboard is enabled, **Overview** rolls up Responder activity for the selected population. It includes: * Total calls, true interactions, jobs booked, bookable calls, and Avoca-handled minutes * Raw Booking Rate, Lead Booking Rate, and Transfer Rate * A **Responder Call Flow** that can group calls by requested service or show **Contained View** and **AI Bookable Lead View** paths through call handling, lead, transfer, direct-booking, and follow-up-booking outcomes * **Responder Performance** comparisons for the portfolio overall, by region, or by brand, including call-volume share, bookable leads, lead booking rate, transfer rate, bookability coverage, diagnostic flags, jobs booked, fully recovered contained lead booking rate, and directly attributable revenue * **Product Activity** rollout comparisons when product analytics is enabled * A day-by-day, week-by-week, or month-by-month **Booking Performance Trend** for Raw Booking Rate and Fully Recovered Contained Lead Booking Rate, depending on the selected date range * **# Calls Unbooked Due to Time Concern**, a requested-service breakdown, capacity-adjusted booking rate, potential uplift, and the leading classified unbooked reasons, with portfolio, region, and brand views * Responder minutes by brand * **Agent Best Practices** checks when product analytics is enabled When product analytics is enabled, **Product Rollout Tracker** reports Responder, Speed-to-Lead, Outbound, Coach, QA, and Direct Mail. The **Overall** and **By Region** views count brands marked live; **By Brand** shows **Live**, **Configured**, or **Not Live**, plus the official go-live date when available. When no go-live date exists, the row can show the first observed activity date instead. **Unavailable** means rollout evidence was not returned for that product and brand, not that the product is off. **Agent Best Practices** compares canonical Responder configuration checks across the selected brands. Use **Overall**, **By Region**, and **By Brand** to change the aggregation. The current checks can include human callbacks, Dropped Responder, first- and second-line disclosure, and priority overbooking. Enabled or **Yes** values appear in green; disabled or **No** values appear in red. **Disclosure in First or Second Line?** reports whether either of the first two spoken lines identifies the assistant as AI, automated, digital, or virtual. A dash means the check is unavailable for that brand; it is not a failed check. ### Read the Responder Call Flow Use the tabs above the Sankey diagram to change how the selected call population is organized: * **Requested Service** groups the service the caller asked about into **Sales & Estimates**, **Repair & Diagnostics**, **Maintenance & Inspections**, **General Service**, **Appointment & Account**, **Other Requests**, or **No Service Type Captured**, then separates each group into **Booked**, **Unbooked**, and **Not Bookable / Unknown**. These are requested-service categories, not CRM job types. * **Call Outcome** opens the existing call-outcome flow. Its view toggle changes between **Contained View** and **AI Bookable Lead View**. Within **Call Outcome**: * **Contained View** first groups call-flow paths with no transfer under **Contained** and every transferred call under **Transferred**, including calls that booked and also transferred. Each branch then separates AI-bookable leads from calls that were not AI-bookable and shows the applicable booking outcome. * **AI Bookable Lead View** first separates AI-bookable leads from calls that were not AI-bookable. Use it to compare booking outcomes across AI-bookable demand whether Avoca contained or transferred the call. In either view, **Non-Actionable** includes silent, spam, and excused calls. For contained leads, **Booked as Follow-up** represents a later booking identified by available recovery data; **Not Booked** is the remaining contained, unbooked population. Transferred lead outcomes appear separately as **Transferred Booked** and **Transferred Unbooked**. The Sankey's **Contained** branch is visualization-specific. The broader **Contained Calls** metric elsewhere in Analytics also includes calls that booked before a later transfer, so do not compare that metric directly with the Sankey branch count. Hover over a call-flow label to read its definition and count. Switch views to answer a different population question; the total selected calls do not change. ### Keep the Responder populations distinct | Metric | Portfolio calculation | | - | - | | **Raw Booking Rate** | Booked calls divided by all inbound calls, including non-actionable calls. | | **Lead Booking Rate** | Booked calls divided by bookable calls. | | **Transfer Rate** | Calls transferred to a team divided by true interactions. | | **Adjusted Raw Booking Rate** | Booked calls divided by true interactions. | | **Capacity-Adjusted Rate** | Booked calls divided by true interactions after removing classified **Time Concern** losses, up to the available unbooked population. | | **Fully Recovered Contained Lead Booking Rate** | Direct bookings plus later recovered bookings divided by contained leads, when recovered-booking data is complete. | The capacity-adjusted rate is a scenario for isolating appointment-time losses, not a forecast that every removed call would have booked. **Time Concern Calls by Requested Service** uses the same requested-service categories as the Sankey and shows each category's share and count within time-concern calls. The categories add to 100% of the classified breakdown. **No Service Type Captured** means the call ended before the caller named a service; it is not a CRM job-type value. Responder Performance can flag **Transfer-first** when at least half of calls transferred, **Low lead volume** when there are fewer than 30 bookable leads, and **Low classification coverage** when more than 15% of calls were never classified as bookable or not. Treat these as data-quality or volatility warnings, not performance verdicts. Directly attributable revenue includes completed jobs linked to Avoca bookings. **Unavailable** means the selected brands do not have complete revenue or recovered-booking data for that metric; do not substitute a zero. ## Compare Speed-to-Lead When product analytics is enabled for the leadership dashboard, open **Speed-to-Lead** to review: * Total leads, jobs booked, and conversion rate * Leads called and call pickup rate * Leads texted and text reply rate * Performance for the portfolio overall, by enterprise, or by brand * Call and text engagement side by side * **Speed-to-Lead Performance by Lead Source**, including total leads, campaigns launched, jobs booked, booked-job revenue, conversion rate, and text reply rate Conversion rate is booked jobs divided by total leads. Call pickup rate is picked-up calls divided by leads called. Keep those denominators aligned when comparing the portfolio total with an individual brand. If no eligible Speed-to-Lead data exists for the selected portfolio population, the tab shows that data is unavailable. Use **Export CSV** in the lead-source section when you need the source-level rows. A source can be a native channel or a mapped lead source. If the page says that one or more brands could not be loaded, the source table and its totals are incomplete for the selected portfolio. ## Compare Outbound When product analytics is enabled for the leadership dashboard, open **Outbound** to review: * Campaign audience, jobs booked, and booking rate * Calls placed and texts sent * Text conversations, replies, and response rate * Performance for the portfolio overall, by enterprise, or by brand * The relative mix of audience, call, text, and booking activity Outbound booking rate is booked jobs divided by audience members. Text response rate is replies divided by text conversations. The **completed in the last 24 hours** details on the call and text cards use that stated 24-hour window; do not treat them as totals for a longer selected date range. If no eligible Outbound data exists for the selected portfolio population, the tab shows that data is unavailable. ## Export the dashboard Select **Export dashboard**, choose **Last 3 months**, **Last 6 months**, **Last 12 months**, or **Last 24 months**, and then select **Export**. The XLSX export uses the currently selected brands and customer types. The export's reporting-history choice sets its time horizon. It is separate from the on-page date-range picker. ## Troubleshoot missing or unexpected results 1. Confirm that you selected the intended portfolio workspace. 2. Confirm that your membership has **View KPIs** and includes the expected enterprise or brand scope. 3. Open **Filters** and restore the expected brands and customer types. 4. Confirm the date range and refresh the dashboard. 5. If leadership sections or product tabs are absent but Responder results load, contact Avoca Support to confirm which Portfolio dashboard rollout is enabled for your organization. 6. Treat **No activity** as no recorded usage in the selected population, not proof that a product is disabled. 7. If an enabled product tab says data is unavailable, verify that included brands recorded eligible activity during the selected period. 8. When contacting Support, include the portfolio, date range, brand and customer-type filters, metric name, dashboard title, visible tabs, and whether you used the page or an export. # Review Revenue Analytics Source: https://help.avoca.ai/analytics/revenue Understand ServiceTitan revenue, Avoca attribution, job trends, and campaign performance. Open **Analytics → Revenue** to review job and revenue performance for the selected team. Revenue Analytics appears only when enabled and depends on ServiceTitan data. The page is read-only. Changing its date range does not modify jobs, invoices, or attribution records. ## Set the reporting period Revenue Analytics opens to the most recent 30 days. Choose a different date range to update every card, chart, and campaign row on the page. The trend is grouped daily for ranges of seven days or fewer and weekly for longer ranges. Recent or partially synced periods can change as ServiceTitan data arrives. ## Read Performance The **Performance** cards include: * **Total Revenue:** ServiceTitan revenue represented in the selected period * **Completed Jobs:** completed jobs in the period * **New Customers:** customers counted as new in the period * **Avg Revenue/Job:** completed-job revenue divided by completed jobs; \$0 and low-revenue completed jobs remain in the denominator * **Opportunity Job Avg.:** revenue from ServiceTitan job opportunities divided by the opportunity-job count * **Completion Rate:** completed jobs divided by total jobs An opportunity job is a completed job that is not marked No Charge, or a No Charge job whose invoice subtotal meets its job type's sold threshold. The average-revenue cards use job completion date for the date filter, which can differ from booking or creation date. ## Understand Avoca Revenue Attribution The second card group attributes direct and follow-on revenue to Avoca channels: * **Inbound Calls** * **Outbound Calls** * **Simple Scheduler** * **Texting**, including supported SMS and web messaging channels **Direct** revenue comes from a job booked through that Avoca channel. **Indirect** revenue comes from eligible follow-up work for the same customer after the channel-booked visit, within the follow-on window configured for the team and without an intervening inbound call. **Total Avoca Revenue** combines direct and indirect revenue across channels. When the same job could be attributed to multiple channels, it is counted once using this priority: Inbound Calls, Outbound Calls, Simple Scheduler, then Texting. Hover the information control on a card to see its direct and indirect job counts and the exact follow-on window applied to your team. Attributed revenue is an operational analytics measure, not a replacement for ServiceTitan invoices, accounting reports, or your financial ledger. ## Review trends and campaigns The **Jobs & Revenue Trends** chart combines: * Completed and canceled job counts * Completed revenue * Total Avoca-attributed revenue * Channel-level attributed revenue in the point details Use **Campaign Performance** to compare new customers, completed jobs, revenue, and average revenue per job by category. Select a category to expand its individual campaigns. Before comparing two campaigns, use the same date range and check whether one includes a different mix of completed, No Charge, maintenance, estimate, or opportunity jobs. ## Resolve incomplete data The page shows **Sync Data Incomplete** when: * ServiceTitan is not connected * ServiceTitan sync is disabled * Synced data starts after the beginning of the selected range * No ServiceTitan revenue data has arrived yet Use the earliest-data date in the warning to choose a fully covered period. If values are still missing, verify the ServiceTitan connection and sync status, then compare a known completed job's completion date, total, campaign, and category in ServiceTitan. If the Revenue tab itself is missing, confirm the selected team and ask a team administrator whether Revenue Analytics is enabled. # Review Survey Analytics Source: https://help.avoca.ai/analytics/survey-analytics Measure post-call survey volume, satisfaction, resolution, feedback, and participation. Open **Analytics → Survey Analytics** to review post-call customer survey responses. This page appears only when Survey Analytics is enabled for the team. ## Filter the full report The page opens to the most recent 30 days. The following controls update the summary, charts, and response list together: * **Date range** * **Assistant / Config**, when attributed configuration data exists * **Experiment Variant**, when experiment attribution exists * **Refresh** to request the latest available results The filter button shows how many assistant/config and variant values are selected. Choose **Clear all** in the filter panel to return to all available values. An unattributed bucket can appear when a survey cannot be matched to a saved assistant configuration or experiment variant. Do not assume those responses belong to the current default configuration. ## Read the summary * **Total Surveys:** submitted surveys in the current report filters * **Avg CSAT:** mean customer satisfaction score on the 1–5 scale * **Resolution Rate:** share of answered surveys marked resolved * **With Feedback:** surveys that include free-text feedback * **Adoption Rate:** total matched surveys divided by total inbound calls in the range Adoption Rate is an approximation of participation. It is not a true offered-versus-accepted rate, because the denominator is inbound calls rather than only customers who were offered and could complete the survey. ## Use the charts The report includes: * **Survey Volume:** submissions per day * **Average CSAT:** daily mean satisfaction * **Resolution Rate:** daily share marked resolved * **CSAT Distribution:** response count for each score from 1 to 5 Compare volume with the rates. A sharp CSAT or resolution change based on very few surveys may not represent the full call population. ## Inspect individual responses The response table shows date and time, caller, CSAT, resolved status, feedback, and a link to the original call when available. Its row-level controls filter only the loaded response table: * One or more CSAT scores * Resolved or Unresolved * **With feedback** These table controls do not recalculate the summary or charts. Use the date, assistant/config, and experiment-variant controls at the top of the page when you need the entire report to change. If the server limits a large response list, the table explains that it is showing the latest responses. The summary and charts still represent the full filtered range. Narrow the date range to inspect older rows. ## Download survey data Choose **Download CSV** to export the current date, assistant/config, and experiment-variant filters. The export is not limited to the response-table preview, but very large exports can still be capped. If the CSV ends with a truncation notice, narrow the range or filters and export again. Treat caller identifiers and free-text feedback as customer data. Store exports only in an approved location and share them only with people who need access. ## Investigate unexpected results 1. Confirm the team, date range, and top-level filters. 2. Compare Total Surveys with inbound-call volume and the Adoption Rate caveat. 3. Open several original calls and verify that the survey answers match the displayed response. 4. Check whether responses are unattributed to a configuration or variant. 5. If only the table looks different, clear its CSAT, resolution, and feedback filters. 6. Refresh after allowing time for recent calls and survey submissions to process. Missing CSAT, resolution, feedback, or call links can mean the customer did not answer that part of the survey or that the survey could not be matched to a call; it does not automatically indicate a reporting error. # Get funnel analytics Source: https://help.avoca.ai/api-reference/analytics-v1/get-funnel-analytics /api-reference/openapi.json get /api/v1/teams/{teamId}/analytics/funnel Funnel metrics with drop-off data. Requires the `read:scheduler_analytics` permission. # Get funnel analytics (cross-team) Source: https://help.avoca.ai/api-reference/analytics-v1/get-funnel-analytics-cross-team /api-reference/openapi.json get /api/v1/analytics/funnel Aggregated funnel data across all teams accessible to a multi-team key, with an optional `team_id` filter. Requires the `read:scheduler_analytics` permission. # Get issue-type distribution Source: https://help.avoca.ai/api-reference/analytics-v1/get-issue-type-distribution /api-reference/openapi.json get /api/v1/teams/{teamId}/analytics/issue-types Distribution of issue types selected in the scheduler. Same query parameters as funnel. Requires the `read:scheduler_analytics` permission. # Get service-area distribution Source: https://help.avoca.ai/api-reference/analytics-v1/get-service-area-distribution /api-reference/openapi.json get /api/v1/teams/{teamId}/analytics/service-areas Distribution of service-area lookups. Same query parameters as funnel. Requires the `read:scheduler_analytics` permission. # Get UTM attribution Source: https://help.avoca.ai/api-reference/analytics-v1/get-utm-attribution /api-reference/openapi.json get /api/v1/teams/{teamId}/analytics/utm UTM attribution data. Same query parameters as funnel. Requires the `read:scheduler_analytics` permission. # Import audiences Source: https://help.avoca.ai/api-reference/audience-imports Create an outbound audience from JSON contacts without uploading a spreadsheet. Send a complete contact list to Avoca, then select **Existing Audience** when creating a campaign in the dashboard. Importing contacts does not create, launch, or extend a campaign. No CRM customer or lead record is required. ## 1. Create an API key In the dashboard, open your team and go to **Integrations → API Keys**. Select **Create API Key** and enable **Import audiences** (`write:audiences`) and **Read audiences** (`read:audiences`). Copy the key when it is shown; the full key is displayed only once. Creating team API keys requires a team admin account and enterprise access. If you cannot access this page, ask your team admin to set up the key. See [Authentication & Permissions](/api-reference/authentication) for other key types. Your numeric team ID is the number after `/team/` in the dashboard URL. The team in an API request must be within the key's team, enterprise, or portfolio scope. ## 2. Send your contacts `POST /api/v1/teams/{teamId}/audiences` These endpoints use **`https://api.prod.avoca.ai`**. In the example below, replace `YOUR_TEAM_ID`, `YOUR_API_KEY`, and the sample contact with your values. Include each contact's actual ZIP if your team has service areas configured. Use a new `Idempotency-Key` for each new list. To retry the same import, keep the key and body unchanged. Keys can contain letters, numbers, dots, underscores, colons, and hyphens, up to 200 characters. ```bash theme={null} export TEAM_ID="YOUR_TEAM_ID" export AVOCA_API_KEY="YOUR_API_KEY" curl -X POST "https://api.prod.avoca.ai/api/v1/teams/$TEAM_ID/audiences" \ -H "Authorization: Bearer $AVOCA_API_KEY" \ -H "Idempotency-Key: september-generator-list-1" \ -H "Content-Type: application/json" \ -d '{ "name": "September generator leads", "exclude_recently_contacted_days": 45, "members": [{ "customer_name": "Example Customer", "customer_phone": "+12025550123", "customer_email": "customer@example.com", "customer_address_street": "123 Example Street", "customer_address_city": "Washington", "customer_address_state": "DC", "customer_address_zip": "20001", "business_unit": "Generators" }] }' ``` ## 3. Check the result **Success — HTTP 201:** ```json theme={null} { "data": { "audience_id": 123, "name": "September generator leads", "member_count": 1, "duplicates_skipped": 0, "excluded_count": 0 } } ``` Import applies the same initial eligibility filter as spreadsheet uploads: team exclusions, the recent-contact window, and configured service-area ZIPs. If your team has service areas, include a matching ZIP for each contact. `excluded_count` reports unique contacts removed by that filter; `member_count` is the number saved. A fully excluded list has zero members. ## 4. Use the audience in a campaign When the import succeeds, open outbound campaign creation in the dashboard. Choose **Existing Audience** and select the audience by the name you submitted. Review the saved contacts, current exclusions, and outreach settings, then launch through the dashboard when ready. The API import itself does not send messages or make calls. ## Contact fields | Field | Required | Limit | | - | - | - | | `name` | Yes | 1–200 characters | | `exclude_recently_contacted_days` | No | Integer 0–365; defaults to 45. Use 0 to disable the recent-contact window. | | `members` | Yes | 1–1,000 contacts; maximum request body 1 MiB | | `members[].customer_name` | Yes | 1–200 characters | | `members[].customer_phone` | Yes | Valid +1 E.164 number, such as `+12025550123` | | `members[].customer_email` | No | Valid email, up to 254 characters | | `members[].customer_address_street` | No | Up to 300 characters | | `members[].customer_address_unit` | No | Up to 100 characters | | `members[].customer_address_city` | No | Up to 100 characters | | `members[].customer_address_state` | No | Up to 100 characters | | `members[].customer_address_zip` | No | Up to 20 characters | | `members[].business_unit` | No | Up to 200 characters | Optional contact fields may be omitted, empty, or null. Unknown fields are rejected. Each contact takes one phone number. If a phone appears more than once, the first contact wins and the remaining rows count toward `duplicates_skipped`. Any invalid row rejects the entire request; no partial audience is created. ## Retry behavior Retry a timeout or server error with the **same key and request body**. Within 24 hours, successful retries return the original audience and set `X-Idempotency-Replayed: true`. Reusing the key with a different body returns 409\. Keys are scoped to the team, so rotating an API key does not duplicate a completed import. After 24 hours, a retry can create a new audience. Each new import creates a separate audience. This API does not update an existing list or change recipients of an existing campaign. Lists over 1,000 contacts should use the existing spreadsheet import flow. ## Retrieve an audience `GET /api/v1/teams/{teamId}/audiences/{audienceId}` Use the returned `audience_id` to retrieve the name, current member count, and archive status. This also works for spreadsheet audiences. The key needs `read:audiences`. ```bash theme={null} export AUDIENCE_ID="ID_FROM_IMPORT_RESPONSE" curl "https://api.prod.avoca.ai/api/v1/teams/$TEAM_ID/audiences/$AUDIENCE_ID" \ -H "Authorization: Bearer $AVOCA_API_KEY" ``` ```json theme={null} { "data": { "audience_id": 123, "name": "September generator leads", "member_count": 1, "is_archived": false } } ``` ## Errors | Status | Meaning | | - | - | | 400 | Invalid input or missing/invalid `Idempotency-Key`; row errors include the field path | | 401 | Missing, invalid, revoked, or unsupported API key | | 403 | Missing audience permission or team outside the key's scope | | 404 | Audience not found in the team's imported audiences | | 409 | Idempotency key already used for a different request | | 500 | Import failed; retry with the same key and body | # Authentication & Permissions Source: https://help.avoca.ai/api-reference/authentication API key types, team scoping, and permission scopes ## API Keys [Avoca MCP](/api-reference/mcp) uses your Avoca sign-in and app authorization. Enterprise API keys described below do not authenticate that connection. All Enterprise API requests are authenticated with an API key in the `Authorization` header: ```bash theme={null} Authorization: Bearer YOUR_API_KEY ``` Keys follow the format `avoca_<64 hex characters>` — the `avoca_` prefix followed by a cryptographically random hex token. Keys are stored hashed; treat them like passwords and never commit them to source control. ### Obtaining API Keys API keys are managed in the Avoca dashboard: * **Team-level keys:** `Integrations → API Keys` on your team (`/team/[teamId]/integrations/api-keys`) * **Enterprise-level keys:** `Settings → API Keys` on your enterprise (`/enterprise/[slug]/settings/api-keys`) Creating team-level API keys requires a team admin account and enterprise access. ## Key Types | Type | Access | Team scoping | | - | - | - | | `enterprise` | Single team | Locked to one team; no `x-team-id` header needed | | `enterprise_all_teams` | All teams in the enterprise | v0 endpoints require `x-team-id` header or `team_id` query param (except `GET /api/teams`); v1 endpoints take the team ID in the URL path | | `portfolio_all_teams` | All teams in a portfolio (can span enterprises) | Same scoping rules as `enterprise_all_teams`; not valid for enterprise-scoped routes like `/api/v1/enterprise/...` | ```bash theme={null} # Single-team key curl -H "Authorization: Bearer $API_KEY" \ "https://enterprise-api.avoca.ai/api/calls" # Multi-team key on a v0 endpoint (requires x-team-id) curl -H "Authorization: Bearer $API_KEY" -H "x-team-id: 808" \ "https://enterprise-api.avoca.ai/api/calls" # Multi-team key on a v1 endpoint (team in path) curl -H "Authorization: Bearer $API_KEY" \ "https://enterprise-api.avoca.ai/api/v1/teams/808/sessions" ``` ## Permissions Each key is configured with permission scopes controlling which endpoints it can call. Calling an endpoint without the required permission returns `403 Forbidden`. | Permission | Grants access to | | - | - | | `read:calls` | Call records, metadata, recordings, and pre-call transfers | | `read:transcripts` | Call transcripts | | `read:leads` | Unified leads (v0) and the canonical leads feed (v1) | | `read:teams` | Listing accessible teams (multi-team keys) | | `read:coach` | Coach call evaluations, scores, and rubrics | | `read:scheduler_analytics` | Simple Scheduler analytics, sessions, bookings, booking requests, and scheduler configs | | `read:outbound` | Outbound texting feeds (campaign texts and subscription events) | | `read:audiences` | Imported audience details and member counts | | `write:audiences` | Import contact audiences for selection in the dashboard | | `read:support_tickets` | Enterprise support tickets; available only to `enterprise_all_teams` keys | ## Multi-team Behavior * Cross-team v1 endpoints (`/api/v1/sessions`, `/api/v1/bookings`, `/api/v1/analytics/funnel`) aggregate across all teams the key can access, with an optional `team_id` query filter. * Enterprise-scoped routes (`/api/v1/enterprise/:enterpriseId/...`) require an `enterprise_all_teams` key whose enterprise matches the path. The support-ticket feed additionally requires `read:support_tickets`. * Designated internal QA/test teams are excluded from multi-team aggregations by default; pass `include_test_teams=true` to include them. Explicitly team-addressed requests are never filtered. # Get a call Source: https://help.avoca.ai/api-reference/calls/get-a-call /api-reference/openapi.json get /api/calls/{id} Get a specific call by ID. Requires the `read:calls` permission. # Get a call transcript Source: https://help.avoca.ai/api-reference/calls/get-a-call-transcript /api-reference/openapi.json get /api/calls/{id}/transcript Get the transcript for a specific call. Requires the `read:transcripts` permission. # Get capacity-adjusted booking rates Source: https://help.avoca.ai/api-reference/calls/get-capacity-adjusted-booking-rates /api-reference/openapi.json get /api/v1/teams/{teamId}/call-analytics/capacity-adjusted-booking Requires read:calls and capacity-adjusted booking enabled for the requested team. Uses the default call-type scope and excludes standard non-actionable reasons. Time Concern uses the recorded unbooked classification, including subsequently recovered calls; rates can exceed 100%. Maximum 31 days and 10 requests per minute. See the capacity-adjusted booking guide for formulas and exports. # Get latest call by phone number Source: https://help.avoca.ai/api-reference/calls/get-latest-call-by-phone-number /api-reference/openapi.json get /api/calls/latest-by-phone Get the most recent call for a phone number. Requires the `read:calls` permission. # List calls Source: https://help.avoca.ai/api-reference/calls/list-calls /api-reference/openapi.json get /api/calls List calls for the authenticated team. The exact columns returned are governed by the team's configured column allowlist. Requires the `read:calls` permission. # List pre-call transfers Source: https://help.avoca.ai/api-reference/calls/list-pre-call-transfers /api-reference/openapi.json get /api/calls/pre-call-transfers List inbound calls that were forwarded to a configured destination *before* the AI agent picked up, based on the team's pre-call transfer rules. These calls have `duration_seconds: 0` because the AI never engaged. Returns a fixed shape and does not honor the team's column allowlist. Requires the `read:calls` permission. # Stream a call recording Source: https://help.avoca.ai/api-reference/calls/stream-a-call-recording /api-reference/openapi.json get /api/calls/{id}/recording Stream or download the recording for a call visible to the target team. Uses the same v0 team-scoping rules as the call endpoints and requires the `read:calls` permission. # Capacity-adjusted booking rates Source: https://help.avoca.ai/api-reference/capacity-adjusted-booking Exclude appointment-time losses from recovered booking-rate denominators in Call Analytics, CSV exports, and the API. Capacity-adjusted booking rates show booking performance after removing bookable calls classified as **Unbooked – Time Concern** from the denominator. These optional metrics must be enabled for your team or enterprise. Contact your Avoca team if they are unavailable. ## Understand the two rates Both metrics keep the same numerator: **Booked Calls + Recovered Calls**. Booked Calls includes bookings completed after a transfer. Recovered Calls includes qualifying follow-up bookings and manual recovery marks. | Metric | Calculation | | - | - | | **Capacity Adj. Fully Recovered Booking Rate** | `(Booked Calls + Recovered Calls) / (Contained Leads + Transferred Leads − Unbooked–Time Concern) × 100` | | **Capacity Adj. Raw Recovered Booking Rate** | `(Booked Calls + Recovered Calls) / (Total Calls − Unbooked–Time Concern) × 100` | Transferred leads include leads dropped during a transfer where that classification is enabled. Time Concern counts only unbooked leads, including transferred leads whose final transfer outcome was unbooked. Already-booked calls and non-leads are not removed. For example, with **100 total calls**, **80 leads**, **40 booked calls**, **8 recovered calls**, and **20 unbooked Time Concern calls**: * Fully recovered: `(40 + 8) / (80 − 20) = 80%`. * Raw recovered: `(40 + 8) / (100 − 20) = 60%`. If the adjusted denominator is zero, the dashboard shows **—**, the API returns **null**, and the CSV cell is blank. Time Concern uses the recorded unbooked call classification. A call subsequently recovered can still have that classification: it remains in the recovered numerator and the Time Concern exclusion. In that case, the adjusted rate can exceed 100%. These metrics are an adjustment scenario, not an actual conversion rate or a forecast. ## Add the metrics to your dashboard 1. Open **Channels → Calls**, or your enterprise **Calls** page. 2. Set the date range and call filters. 3. Open **Customize Metrics** and select either or both capacity-adjusted rates. 4. Save your selection. Hover over a metric's information icon to see the counts and subtraction used in its calculation. Choose **Export capacity metrics** beside the customization control to download one CSV row containing the displayed counts and both rates. It uses the same date range and call filters as those cards. This is a metrics summary; the existing per-call export remains separate. ## Retrieve JSON or CSV from the API Use a key with **`read:calls`** permission and access to the requested team: `GET https://api.prod.avoca.ai/api/v1/teams/{teamId}/call-analytics/capacity-adjusted-booking` Supply `dateFrom` and `dateTo` as ISO timestamps with a time-zone offset. A request can span at most **31 days**. This endpoint uses the team's default call-type scope and excludes the standard non-actionable call reasons. Additional dashboard filters are not supported by this endpoint; use the dashboard export for a filtered view. ```bash theme={null} curl --get "https://api.prod.avoca.ai/api/v1/teams/$TEAM_ID/call-analytics/capacity-adjusted-booking" \ --header "Authorization: Bearer $AVOCA_API_KEY" \ --data-urlencode 'dateFrom=2026-08-01T00:00:00Z' \ --data-urlencode 'dateTo=2026-08-31T23:59:59Z' ``` ```json theme={null} { "data": { "totalCalls": 100, "bookableCalls": 80, "bookedCalls": 40, "recoveredCalls": 8, "unbookedTimeConcernCalls": 20, "fullyRecoveredBookingRate": 80, "rawRecoveredBookingRate": 60 } } ``` Add `--data-urlencode 'format=csv'` to download the same result as CSV. The column names match the JSON fields above. Rates are percentages, so `80` means **80%**. For a period longer than 31 days, request non-overlapping ranges, sum the count fields, and recompute the rates using those sums. Do not average percentages. Use inclusive timestamp boundaries that do not overlap between requests. The endpoint returns **404** when the feature is disabled, **400** for an invalid date range, and **401/403** for missing authentication or insufficient access. Requests are limited to **10 per minute**; wait before retrying a **429** response. An unavailable aggregate returns **503**; retry later rather than interpreting it as zero. These rates use call outcomes. They do not use the number of days until an appointment was available. See [soonest availability reporting](/api-reference/soonest-availability) for that separate measure. # Get a coach call evaluation Source: https://help.avoca.ai/api-reference/coach/get-a-coach-call-evaluation /api-reference/openapi.json get /api/coach/{id} Get a single evaluated coach call by its numeric ID. Requires the `read:coach` permission. # Get a coach call transcript Source: https://help.avoca.ai/api-reference/coach/get-a-coach-call-transcript /api-reference/openapi.json get /api/coach/{id}/transcript Get the diarized transcript for a coach (QA) call — including CSR / human-handled calls, which have no AI transcript at `GET /api/calls/{id}/transcript`. The response shape and line grammar match that endpoint, so one parser handles both; the speaker labels are `agent` / `customer` here rather than `bot` / `user`, because these calls are handled by people. A turn reads `unknown` when the call has not been speaker-labelled, or when the speaker is neither the agent nor the customer — typically IVR or hold-music audio, which is deliberately not attributed to the caller. Use `has_transcript` on the coach call to tell which calls have one. Requires the `read:transcripts` permission. # List coach call evaluations Source: https://help.avoca.ai/api-reference/coach/list-coach-call-evaluations /api-reference/openapi.json get /api/coach List evaluated coach (QA) calls for the team, newest first. Each row includes the score, awarded/max points, per-item evaluation answers, and the `rubric_id` for joining to `GET /api/coach/rubrics`. Linked Avoca calls include canonical transfer status from the Calls system; unlinked and non-Avoca Coach calls report it as null. The response automatically includes `soonest_slot_at` and `soonest_slot_days_out` from linked Avoca availability lookups, with null values when unavailable; no Data Configuration selection is required. See [Report on soonest availability](/api-reference/soonest-availability) for request examples, CSV export steps, and averaging guidance. Requires the `read:coach` permission. # List coach rubrics Source: https://help.avoca.ai/api-reference/coach/list-coach-rubrics /api-reference/openapi.json get /api/coach/rubrics Reference endpoint: lists the team's enabled rubrics. Items provide the key → name mapping for the `evaluation_answers` keys returned on coach calls. Requires the `read:coach` permission. # API Overview Source: https://help.avoca.ai/api-reference/introduction Introduction to the Avoca Enterprise API ## Overview The Avoca Enterprise API gives enterprise customers and partners programmatic, read-only access to Avoca data: call records, recordings and transcripts, unified leads, coach (QA) evaluations, Simple Scheduler sessions and analytics, outbound texting activity, and enterprise support tickets. For pushing data **into** Avoca (lead intake) and receiving real-time notifications **from** Avoca (event webhooks), see [Webhooks & Lead Intake](/api-reference/webhooks/event-webhooks). To create an outbound audience from your own contacts, follow [Import audiences](/api-reference/audience-imports). The guide covers API-key setup, a complete request, and selecting the saved audience in a campaign. ## Base URL All Enterprise API requests are made to: ``` https://enterprise-api.avoca.ai ``` Audience imports and capacity-adjusted booking metrics use **`https://api.prod.avoca.ai`**. See the [audience import guide](/api-reference/audience-imports) and [capacity-adjusted booking guide](/api-reference/capacity-adjusted-booking) for their endpoint paths. Endpoint paths in this reference include the `/api` prefix (for example `https://enterprise-api.avoca.ai/api/calls`). ## Authentication Every request requires an API key sent as a Bearer token: ```bash theme={null} Authorization: Bearer YOUR_API_KEY ``` API keys use the format `avoca_<64 hex characters>`. Multi-team (`enterprise_all_teams`) keys must also identify the target team on v0 endpoints via the `x-team-id` header or `team_id` query parameter — v1 endpoints embed the team ID in the URL path instead. See [Authentication](/api-reference/authentication) for key types, permissions, and how to obtain keys. ## API Versions | Version | Style | Recommendation | | - | - | - | | **v1** (`/api/v1/...`) | RESTful resources, team ID in the URL path, cursor pagination | Recommended for new integrations | | **v0** (`/api/...`) | Flat endpoints, team resolved from the API key or `x-team-id` header | Continues to work unchanged | For Simple Scheduler integrations, use the v1 sessions, bookings, and analytics endpoints. The v0 Scheduler Analytics endpoints remain available for existing integrations but are deprecated for new implementations. ## Pagination Two pagination styles are used: * **Offset pagination** (most v0 endpoints): `limit` and `offset` query parameters. Responses include a `pagination` object with `limit`, `offset`, and `has_more`. * **Cursor (keyset) pagination** (v1 sessions, bookings, leads, and outbound feeds): pass the `cursor` value from a response's `pagination.cursor` back as the `cursor` query parameter to fetch the next page. On the last page `has_more` is `false` and `cursor` is `null`. ## Response Format Successful responses return JSON with a `data` field, plus `pagination` and/or `meta` where applicable: ```json theme={null} { "data": [ ... ], "pagination": { "cursor": "eyJ0Ijoi...", "has_more": true, "limit": 50 }, "meta": { "team_id": 808 } } ``` ## Errors Errors use a consistent shape with an `error` field and, on newer endpoints, a human-readable `message`: ```json theme={null} { "error": "Forbidden", "message": "This API key does not have the 'read:scheduler_analytics' permission" } ``` | Code | Description | | - | - | | 200 | Success | | 400 | Bad Request — invalid parameters | | 401 | Unauthorized — missing or invalid API key | | 403 | Forbidden — API key lacks the required permission or team access | | 404 | Not Found — resource does not exist | | 500 | Internal Server Error | ## Rate Limiting Rate limiting is not currently enforced on the Enterprise API. This may change in future versions; build clients to tolerate `429` responses. ## Support * **Email**: [support@avoca.ai](mailto:support@avoca.ai) * **Dashboard**: [dashboard.avoca.ai](https://dashboard.avoca.ai) # List leads (all brands) Source: https://help.avoca.ai/api-reference/leads/list-leads-all-brands /api-reference/openapi.json get /api/v1/enterprise/{enterpriseId}/leads The canonical leads feed across every team (brand) in the enterprise. Requires an `enterprise_all_teams` key whose enterprise matches the path — single-team and portfolio keys receive 403. Every row carries `team_id`. Same query parameters as the single-team feed. Requires the `read:leads` permission. # List leads (single team) Source: https://help.avoca.ai/api-reference/leads/list-leads-single-team /api-reference/openapi.json get /api/v1/teams/{teamId}/leads The canonical leads feed for one team: the historical/pull counterpart to the `lead.*` event webhooks, including the raw third-party payload. Keyset cursor-paginated ascending by `(created_at, id)`. Leads from registered test phone numbers are excluded by default (`include_test_numbers=true` opts in). Requires the `read:leads` permission. # List unified leads (v0) Source: https://help.avoca.ai/api-reference/leads/list-unified-leads-v0 /api-reference/openapi.json get /api/leads Channel-touchpoint aggregation of leads across calls, the scheduling widget, web chat, text, and Google LSA. This is **not** the canonical leads record and does not include the raw third-party payload — for that, use the v1 leads feed (`GET /api/v1/teams/{teamId}/leads`). Requires the `read:leads` permission. # Connect your AI agent to Avoca MCP Source: https://help.avoca.ai/api-reference/mcp Read calls, transcripts, and call metrics through MCP using your existing Avoca sign-in. Connect your AI agent to Avoca MCP to retrieve call records and metrics. Your agent handles analysis and presentation. These tools read existing data; they do not start an Avo conversation or run an Avo model. Customer data MCP requires activation by Avoca. If the server reports that it is not enabled, contact your Avoca representative. Your existing dashboard data permissions apply; a workspace Avo flag is not required by this connection. ## Connect your app 1. In an MCP client that supports remote **Streamable HTTP** servers and OAuth, add this server URL: ```text theme={null} https://api.prod.avoca.ai/api/mcp ``` 2. Follow the client's sign-in prompt. Sign in to Avoca using your usual dashboard method, including Google when available for your account. 3. Review the app name, return address, and requested **Read Avoca data** access. Choose **Allow access** to connect or **Deny** to cancel. 4. Ask your agent to list your team workspaces, then retrieve data from the workspace you select. Example app requesting read-only Avoca data access The connection follows your current permissions across teams and enterprises. Call transcripts may contain personal information. Only approve apps you trust with the data they can read. Signing in does not add workspace membership or grant additional permissions. You do not need to copy a dashboard token or create an Enterprise API key. Your dashboard sign-in stays the same; the connected app receives a separate credential for this MCP. The connection is separate from Avoca's internal staff MCP. For custom MCP clients, the OAuth scope is `avoca:read`. Send one refresh request at a time and save the replacement refresh token before refreshing again. Reusing a refresh token, including simultaneous requests or retries after an uncertain response, revokes the connection and requires reauthorization. ## Select your data | Tool | Purpose | | - | - | | `list_workspaces` | List team workspaces from your dashboard selector. Supply an `enterprise_id` to list accessible teams within that enterprise. | | `list_calls` | Retrieve a filtered page of visible call summaries for one team. | | `get_call` | Read one call's existing summary and outcome. | | `get_call_transcript` | Read a page of that call's transcript, with a continuation cursor for longer calls. | | `get_call_metrics` | Read standard dashboard call metrics from ClickHouse for a team or enterprise. | Call lists, details, and transcripts require `team_id` and the team's **Calls** permission. Details and transcripts also require `call_id`. Enterprise membership alone does not grant permission to read an individual team's call records. Metrics take `workspace_type` (`team` or `enterprise`), `workspace_id`, `date_from`, and `date_to`. Team metrics require the team's **Calls** permission; enterprise metrics require the enterprise **Calls** permission and are limited to 50 accessible teams. The start timestamp is inclusive and the end timestamp is exclusive; timestamps are not rounded to calendar days. The response includes `source: "clickhouse"`, the requested dates, `team_count`, and a `metrics` array. Each metric contains `metric_id`, `name`, `unit`, and `value`. Available metrics are Total Calls, Total Duration (seconds), Leads, Booked Calls, Unbooked Calls, Transferred Calls, Contained Booked Calls, and Contained Leads. They reuse the dashboard's standard metric definitions and the Custom Analytics visible-call population, including human-handled and unprocessed calls. A Calls page with additional filters can show different totals. Lead, booking, and transfer metrics overlap; do not add them to calculate total calls. Recent changes can take time to reach ClickHouse. Metrics are unavailable through MCP for workspaces whose call classifications are not yet supported by the ClickHouse analytics compiler. If any accessible team in an enterprise is unsupported, the whole enterprise query fails; it does not return a partial total. Use dashboard analytics or select a supported team in that case. You can also use the numeric workspace ID from a dashboard URL: * Team: `https://dashboard.avoca.ai/team/TEAM_ID` * Enterprise: `https://dashboard.avoca.ai/enterprise/ENTERPRISE_ID` Workspace discovery is bounded and may omit workspaces available through other access paths. A parent enterprise ID in a team result does not imply enterprise membership. If a workspace is missing, provide its known dashboard ID; permissions are checked when data is requested. ## Keep requests focused * Call lists and metrics require ISO timestamps with a timezone offset and a date range of at most **31 days**. For example, `2026-09-01T00:00:00Z` to `2026-09-08T00:00:00Z`. * Call lists return **20 records by default**, up to **100**. Filter with `is_booked`, `is_bookable`, `is_transferred`, `call_reasons`, or `call_outcomes`. * Pass `next_cursor` back as `cursor` to continue a call list, keeping the same team, dates, and filters. Stop when `has_more` is false. The tools never download every page automatically. * Transcripts return up to **8,000 characters by default**, with a maximum of **20,000**. Pass `transcript.nextCursor` as `cursor` while `transcript.hasMore` is true. * Workspace discovery uses `offset` and `limit`, returning `pageInfo.nextOffset` while more results are available. * Prefer metrics for aggregate questions. Fetch individual transcripts only when needed. A failed metrics query is reported as unavailable, not as a zero count. Example request to your agent: “For this team, find up to 20 transferred calls from September 1–7, then retrieve the transcript for the call I select.” The MCP cannot modify records, approve actions, or retrieve arbitrary database queries. It returns structured data that your agent can use to build its own tables or charts. ## Disconnect an app Open [Connected apps](https://dashboard.avoca.ai/auth/mcp) while signed in to Avoca, then choose **Disconnect** beside the app. Removing the server from your MCP client alone may leave its authorization active. Disconnecting stops new MCP requests and leaves your dashboard sign-in active. Connections expire after 30 days; reconnect through the sign-in and approval flow. Connected apps with a Disconnect button ## Troubleshooting * **Sign-in keeps failing:** Restart the connection in your MCP client. Use the Avoca account with access to the intended workspace. * **Data access is denied:** Verify your team or enterprise membership and the applicable Calls permission. Access to enterprise metrics does not necessarily include individual team records. * **Metrics unavailable:** Use dashboard analytics if your workspace is not yet supported. For a timeout or query limit, narrow the date range or select one team. Failed or incomplete queries never return a zero count as a substitute. * **Invalid query:** Check the date range, workspace ID, and cursor. Enterprise metrics support at most 50 accessible teams; use individual team metrics for larger enterprises. * **Too many concurrent requests:** Reduce parallel reads and retry after the delay indicated by the server. * **The app requires a client secret:** This integration supports public OAuth clients with PKCE. Use a client that supports that flow. # List campaign texts Source: https://help.avoca.ai/api-reference/outbound-texting/list-campaign-texts /api-reference/openapi.json get /api/v1/teams/{teamId}/outbound/campaign-texts One row per initial outbound campaign text message, including the customer's first reply. Designed for partners ingesting Avoca outbound activity into a BI warehouse. Always scoped to the team in the URL path. Requires the `read:outbound` permission. # List outbound customer events Source: https://help.avoca.ai/api-reference/outbound-texting/list-outbound-customer-events /api-reference/openapi.json get /api/v1/teams/{teamId}/outbound/events Customer events over time (multiple rows per customer): outbound messages and subscription (opt-in/opt-out) changes. Subscription events reflect each phone's *current* state, timestamped by its last change — at most one subscription event per phone. Requires the `read:outbound` permission. # Get scheduler analytics Source: https://help.avoca.ai/api-reference/scheduler-analytics-v0/get-scheduler-analytics /api-reference/openapi.json get /api/scheduler-analytics Detailed Simple Scheduler analytics. Select which metric blocks to include with the `metrics` parameter: `funnel`, `bookings`, `chart`, `utm`, `google_ads`, `service_areas`, `issue_types`, `customer_events`. Requires the `read:scheduler_analytics` permission. # Get scheduler analytics summary Source: https://help.avoca.ai/api-reference/scheduler-analytics-v0/get-scheduler-analytics-summary /api-reference/openapi.json get /api/scheduler-analytics/summary Summary Simple Scheduler stats for today, this week, and this month. Requires the `read:scheduler_analytics` permission. # List Simple Scheduler booking requests Source: https://help.avoca.ai/api-reference/scheduler-analytics-v0/list-simple-scheduler-booking-requests /api-reference/openapi.json get /api/simple_scheduler_booking_requests Booking requests submitted through Simple Scheduler. Supports offset pagination (`offset` + `limit`, returns `meta.total`) or cursor pagination (`cursor` = `created_at` from a previous page; response includes `next_cursor` and `has_more`). Requires the `read:scheduler_analytics` permission. # List Simple Scheduler configs Source: https://help.avoca.ai/api-reference/scheduler-analytics-v0/list-simple-scheduler-configs /api-reference/openapi.json get /api/simple_scheduler_config Scheduler configurations for the team. Team is resolved from `x-team-id` or the optional `team_id` query parameter (multi-team keys must have access to that team). Requires the `read:scheduler_analytics` permission. # ServiceTitan Integration Source: https://help.avoca.ai/api-reference/service-titan Documentation of Avoca's ServiceTitan API workflows and required scopes. # ServiceTitan API Workflow Documentation ## Overview and Integration Goal Avoca orchestrates **post-call workflows, AI responder experiences, scheduling, dispatch, marketing audiences, and messaging** by sitting directly on top of ServiceTitan’s APIs. Every major Avoca feature—voice QA, AI booking, Simple Scheduler, dispatch boards, outbound campaigns, texting, and task automation—either reads live ST data or pushes updates back through v2 endpoints. **Integration goals** * Deliver AI-assisted booking, reschedule, and cancellation flows that write directly to ST jobs, appointments, campaigns, tags, and notes. * Provide real-time customer, membership, and service-history context to agents and automations during voice or text conversations. * Sync Telecom calls, job/technician KPIs, and marketing audiences into Avoca’s analytics layer while feeding ST with reclassification decisions, tasks, and notes. * Keep dispatch capacity, zones, technician rosters, and service areas aligned so Avoca scheduling mirrors ST availability. * Maintain compliant credential storage (within a managed secrets platform) and scoped API usage for each tenant. ## Key Integration Use Cases & Workflows | # | Use Case | Description | Data Flow | Required ST API Endpoint and Data Fields | Necessary API Scopes (Read/Write) | | - | - | - | - | - | - | | **1** | Booking, rescheduling, or cancelling a job | AI or CSR workflows create jobs, reschedule appointments, cancel/hold jobs, assign campaigns/tags, and append summaries. | Avoca ⇌ ST | `POST /jpm/v2/tenant/{tenant}/jobs`, `PATCH /jpm/v2/tenant/{tenant}/appointments/{id}/reschedule`, `PUT /jpm/v2/tenant/{tenant}/jobs/{id}/cancel`, `POST /crm/v2/tenant/{tenant}/bookings`, `GET /dispatch/v2/tenant/{tenant}/capacity`, `GET /jpm/v2/tenant/{tenant}/job-types`, `GET /settings/v2/tenant/{tenant}/business-units` | **READ:** CRM, JPM, Dispatch, Marketing, Settings
**WRITE:** JPM (jobs/appointments), CRM (bookings) | | **2** | Customer & membership intelligence during calls/texts | Lookups by phone/address determine customer identity, locations, contacts, membership eligibility, tags, and guardrails. | ST → Avoca | `GET /crm/v2/tenant/{tenant}/customers`, `/locations`, `/locations/{id}/contacts`, `GET /memberships/v2/tenant/{tenant}/customer-memberships`, `GET /settings/v2/tenant/{tenant}/tag-types`, `GET /jpm/v2/tenant/{tenant}/jobs` | **READ:** CRM, Memberships, JPM, Settings | | **3** | Simple Scheduler & booking windows | Avoca reads ACP capacity, arrival windows, shifts, and booking windows before generating ST bookings/jobs. | ST → Avoca then Avoca ⇌ ST when booking | `POST /dispatch/v2/tenant/{tenant}/capacity`, `GET /dispatch/v2/tenant/{tenant}/arrival-windows`, `/technician-shifts`, `/non-job-appointments`, `/zones` (final bookings reuse row 1 APIs) | **READ:** Dispatch, Settings
**WRITE:** CRM/JPM for final booking | | **4** | Dispatch board & technician (un)assignment | Ops users unassign business units, auto-assign responders, and sync on-call rosters. | Avoca ⇌ ST | `GET /settings/v2/tenant/{tenant}/technicians`, `GET /jpm/v2/tenant/{tenant}/appointments`, `POST /dispatch/v2/tenant/{tenant}/appointmentassignments/assignTechnicians`, `/unassignTechnicians`, `GET /dispatch/v2/tenant/{tenant}/appointment-assignments` | **READ:** Dispatch, JPM, Settings
**WRITE:** Dispatch | | **5** | Telecom ingestion & QA analytics | Coach, CSR QA, and cron jobs pull Telecom calls/recordings for evaluation. | ST → Avoca | `GET /telecom/v3/tenant/{tenant}/calls`, `/calls/{id}`, `/calls/{id}/recording` | **READ:** Telecom | | **6** | Call reclassification & compliance updates | Avoca writes new call reasons and memos via Telecom APIs after QA or AI review. | Avoca ⇌ ST | `GET /jbce/v2/tenant/{tenant}/call-reasons`, `PUT /telecom/v2/tenant/{tenant}/calls/{id}` | **READ:** JBCE, Telecom
**WRITE:** Telecom | | **7** | Technician performance & revenue analytics | Jobs/appointments/invoices/estimates sync for dashboards; technician metadata powers UI. | ST → Avoca | `GET /jpm/v2/tenant/{tenant}/jobs`, `/appointments`, `GET /accounting/v2/tenant/{tenant}/invoices`, `GET /estimates/v2/tenant/{tenant}/estimates`, `GET /dispatch/v2/tenant/{tenant}/appointment-assignments`, `GET /settings/v2/tenant/{tenant}/technicians` | **READ:** JPM, Accounting, Dispatch, Settings | | **8** | Audience building & outbound campaign enrichment | Recurring services, memberships, customers, campaigns, and jobs feed Avoca audiences and outbound workflows. | ST → Avoca (read) then Avoca ⇌ ST for overrides | `GET /crm/v2/tenant/{tenant}/customers`, `/locations`, `GET /memberships/v2/tenant/{tenant}/memberships`, `/membership-types`, `/recurring-service-types`, `GET /marketing/v2/tenant/{tenant}/campaigns`, `GET /jpm/v2/tenant/{tenant}/jobs`, `GET /crm/v2/tenant/{tenant}/bookings` | **READ:** CRM, Memberships, Marketing, JPM
**WRITE:** None unless a new booking/job is created | | **9** | Messaging, notes, and ST Task automation | Text threads write ST job/customer notes; workflows create ST tasks and fetch metadata. | Avoca ⇌ ST | `POST /jpm/v2/tenant/{tenant}/jobs/{id}/notes`, `POST /crm/v2/tenant/{tenant}/customers/{id}/notes`, `POST /taskmanagement/v2/tenant/{tenant}/tasks`, `GET /taskmanagement/v2/tenant/{tenant}/client-side-data` | **READ:** CRM, Task Management
**WRITE:** JPM (job notes), CRM (customer notes), Task Management | | **10** | Service areas, zones, and technician data | Zones, business units, and technician rosters sync for service areas and on-call rotations. | ST → Avoca | `GET /dispatch/v2/tenant/{tenant}/zones`, `GET /settings/v2/tenant/{tenant}/business-units`, `GET /settings/v2/tenant/{tenant}/technicians` | **READ:** Dispatch, Settings | ## ServiceTitan API Scopes & Data Objects ### Essential READ scopes | Scope | Purpose | Activity Examples | | - | - | - | | **CRM / READ** | Caller identification, contact lookup, bookings. | `/customers`, `/locations/{id}/contacts`, `/bookings/{id}` | | **Dispatch / READ** | Capacity, windows, shifts, zones. | `/capacity`, `/arrival-windows`, `/technician-shifts`, `/zones` | | **JPM / READ** | Jobs, job types, cancel/hold reasons. | `/appointments`, `/jobs`, `/job-types` | | **Memberships / READ** | Memberships, recurring services. | `/memberships`, `/recurring-service-events` | | **Marketing / READ** | Campaigns, ST audience exports. | `/campaigns`, `/audience-lists` | | **Telecom / READ** | Call/recording ingestion. | `/calls`, `/calls/{id}/recording` | | **Settings / READ** | Business units, technicians, tags, booking tags. | `/business-units`, `/technicians`, `/tag-types` | | **Task Mgmt / READ** | Metadata for composing tasks. | `/client-side-data` | | **Accounting / READ** | Invoices for revenue & cancellation guardrails. | `/invoices` | ### Essential WRITE scopes | Scope | Purpose | Activity Examples | | - | - | - | | **JPM / WRITE** | Job creation, reschedule, cancel, notes, tags. | `POST /jobs`, `PATCH /appointments/{id}/reschedule` | | **CRM / WRITE** | Customer/location upserts, notes. | `POST /customers`, `/locations`, `/customers/{id}/notes` | | **Dispatch / WRITE** | Assign/unassign technicians. | `/appointmentassignments/assignTechnicians` | | **Bookings / WRITE** | Provider-based bookings. | `POST /crm/bookings` | | **Telecom / WRITE** | Reclassification & memos. | `PUT /telecom/calls/{id}` | | **Task Mgmt / WRITE** | Create tasks. | `POST /taskmanagement/tasks` | | **Settings / WRITE** | Admin-created tag types. | `POST /settings/tag-types` | ## ServiceTitan Best Practices | Question | Answer | Additional Context | | - | - | - | | Key rotation frequency | Rotate when ServiceTitan issues new credentials, after suspected exposure, or according to the applicable credential policy. | Stored only in a managed secrets vault. | | Hard-coded keys? | No. | Never in source control. | | Credential storage | Managed secrets platform (US East). | Access via backend-only service accounts. | | Purging keys on churn | ServiceTitan app removal or removing secrets from vault; credentials become invalid immediately. | Part of formal offboarding. | | Purging customer data | Depends on the Avoca product, record type, and customer agreement. | Contact Avoca Support for a scoped retention or deletion request. | # Get a booking Source: https://help.avoca.ai/api-reference/sessions-&-bookings/get-a-booking /api-reference/openapi.json get /api/v1/teams/{teamId}/bookings/{bookingId} Get a single booking by session ID. Returns 404 if the session exists but is not booked. Requires the `read:scheduler_analytics` permission. # Get a session Source: https://help.avoca.ai/api-reference/sessions-&-bookings/get-a-session /api-reference/openapi.json get /api/v1/teams/{teamId}/sessions/{sessionId} Get a single session by ID. Requires the `read:scheduler_analytics` permission. # List bookings Source: https://help.avoca.ai/api-reference/sessions-&-bookings/list-bookings /api-reference/openapi.json get /api/v1/teams/{teamId}/bookings List bookings for a team — sessions with status `booked`. Same query parameters as sessions, minus `status`. Requires the `read:scheduler_analytics` permission. When `start_date` is omitted, the window defaults to the 90 days before `end_date` (or now); the effective window is echoed in `meta.start_date` / `meta.end_date`. # List bookings (cross-team) Source: https://help.avoca.ai/api-reference/sessions-&-bookings/list-bookings-cross-team /api-reference/openapi.json get /api/v1/bookings Bookings across all teams accessible to a multi-team key. Requires the `read:scheduler_analytics` permission. When `start_date` is omitted, the window defaults to the 90 days before `end_date` (or now); the effective window is echoed in `meta.start_date` / `meta.end_date`. # List schedulers Source: https://help.avoca.ai/api-reference/sessions-&-bookings/list-schedulers /api-reference/openapi.json get /api/v1/teams/{teamId}/schedulers List scheduler configs for a team. Requires the `read:scheduler_analytics` permission. # List sessions Source: https://help.avoca.ai/api-reference/sessions-&-bookings/list-sessions /api-reference/openapi.json get /api/v1/teams/{teamId}/sessions List scheduling-widget sessions for a team — a customer's journey from starting a booking to completing it or dropping off. Requires the `read:scheduler_analytics` permission. When `start_date` is omitted, the window defaults to the 90 days before `end_date` (or now); the effective window is echoed in `meta.start_date` / `meta.end_date`. # List sessions (cross-team) Source: https://help.avoca.ai/api-reference/sessions-&-bookings/list-sessions-cross-team /api-reference/openapi.json get /api/v1/sessions Sessions across all teams accessible to a multi-team key. Supports the same query parameters as the team-scoped endpoint, plus an optional `team_id` filter. Requires the `read:scheduler_analytics` permission. When `start_date` is omitted, the window defaults to the 90 days before `end_date` (or now); the effective window is echoed in `meta.start_date` / `meta.end_date`. # Report on soonest availability Source: https://help.avoca.ai/api-reference/soonest-availability Review earliest appointment availability in the dashboard, retrieve it from the Coach API, and download it in Coach CSV exports. Soonest availability measures how far out the earliest appointment slot returned to the Avoca agent was. Use it to compare booking outcomes across different waits and calculate average availability for a reporting period. These values come from recorded availability lookups. They describe what the agent could offer, not necessarily the slot spoken aloud or the appointment ultimately booked. They are different from **Time to Availability (seconds)**, which measures seconds from call start to the first successful availability result. ## Review availability in the dashboard When enabled for your team, open **Channels → Calls** in the Avoca Calls workspace and find **Soonest availability offered** below the call analytics. 1. Set the page's date range. 2. Review booking outcomes grouped by how many days out availability was, including calls with **No availability**. 3. Choose **Service types**, **Appointment types**, or **Job types**. The table includes median and 90th-percentile days out, same-or-next-day availability, and booking rate. 4. Select a breakdown row to see its individual calls, earliest slots, days out, and outcomes. Select **View call** to inspect a call. The card uses the page's date range; other Calls filters do not filter this card. Use its breakdown rows to inspect a subset. If the card is not available, contact your Avoca team about access. ## Retrieve the fields from the Coach API Use an API key with **`read:coach`** permission and call **`GET /api/coach`**. Both availability fields are included automatically; no Data Configuration selection is required for this endpoint. | API field | Coach CSV column | Meaning | | - | - | - | | `soonest_slot_at` | **Soonest Slot Offered (UTC)** | Earliest appointment slot returned across the linked Avoca call's availability lookups, as a UTC timestamp, or the lookup-time fallback for undated immediate availability described below. | | `soonest_slot_days_out` | **Soonest Slot Days Out** | Calendar days between the lookup that returned that slot and the slot itself, in the linked call's team time zone. `0` means same-day availability. | An availability lookup can return an immediate window without a dated appointment slot, such as **By Request Only**. For that result, Avoca uses the lookup's timestamp as the availability timestamp and counts it as **0 days out**. If that is the earliest result for the call, the API and CSV contain this fallback. Treat it as an immediate-availability indicator, not a confirmed appointment start time. These fields alone do not distinguish this fallback from a dated same-day slot. A multi-team key must identify the team with **`x-team-id`**. A single-team key is already scoped to its team. See [Authentication and permissions](/api-reference/authentication). Replace the placeholders below with your API key and an accessible team ID, and set your reporting dates. The example dates are in UTC. ```bash theme={null} curl --get 'https://enterprise-api.avoca.ai/api/coach' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'x-team-id: YOUR_TEAM_ID' \ --data-urlencode 'start_date=2026-09-01T00:00:00Z' \ --data-urlencode 'end_date=2026-09-07T23:59:59.999Z' \ --data-urlencode 'limit=100' \ --data-urlencode 'offset=0' ``` The response includes the following fields alongside the other Coach data. This example shows only the availability fields: ```json theme={null} { "data": [ { "soonest_slot_at": "2026-09-03T14:00:00.000Z", "soonest_slot_days_out": 2 } ], "pagination": { "limit": 100, "offset": 0, "has_more": false } } ``` If `pagination.has_more` is `true`, increase `offset` by `limit` and request the next page with the same dates. Continue until `has_more` is `false` before calculating a reporting-period average. The endpoint returns evaluated, unarchived Coach calls in the requested call-date range. Changing the API's `timezone` display parameter does not change `soonest_slot_days_out`, which uses the linked call's team time zone. ## Download a Coach CSV 1. Select your team and open **Products → Coach → Overview**. 2. Set the date range and any filters for the calls you want to export. 3. Select the download icon labeled **Export Data** beside the date controls. Confirm the date range, then select **Start Export**. 4. When the export is ready, use the email notification or reopen **Export Data → Recent Exports** and select **Download CSV**. The CSV includes **Soonest Slot Offered (UTC)** and **Soonest Slot Days Out** automatically. You do not need to select **Include transcripts** or **Include rubric details** to receive them. ## Calculate average availability in days Average the non-null `soonest_slot_days_out` values from the API, or the numeric values in the CSV's **Soonest Slot Days Out** column. Include zeros and exclude nulls or blank cells. For example, values of `0`, `2`, `4`, and `null` have an average of **2 days**: `(0 + 2 + 4) / 3`. Combine all calls across API pages before averaging. If no calls have a numeric value, report the average as unavailable. ## Interpret missing values and differences * **`null` in the API or a blank CSV cell** means availability is unavailable for that Coach record. This can happen when there is no linked Avoca call, no recorded supported availability lookup, or no slot was returned. It does not mean zero days or prove that no appointments were available. * **No availability in the dashboard** counts calls whose recorded lookups never returned a slot. A blank Coach export cell alone cannot identify that group. * **Dashboard and Coach totals can differ.** The dashboard examines availability lookups for AI calls in its selected call-date range, while the Coach API and export select evaluated Coach records. Match the population and dates before comparing results. The dashboard's median and 90th percentile are also different statistics from an arithmetic average. For booking rates that exclude appointment-time losses, see [capacity-adjusted booking rates](/api-reference/capacity-adjusted-booking). For more on exporting and reviewing Coach records, see [Coach overview](/coach/overview). # List enterprise support tickets Source: https://help.avoca.ai/api-reference/support-tickets/list-enterprise-support-tickets /api-reference/openapi.json get /api/v1/enterprise/{enterpriseId}/support-tickets List support tickets across the enterprise's accessible teams, ordered by creation time. Reporter identities, Zendesk tags, and internal agent links are intentionally omitted. Requires an `enterprise_all_teams` key with the `read:support_tickets` permission; single-team and portfolio keys receive 403. # List teams Source: https://help.avoca.ai/api-reference/teams/list-teams /api-reference/openapi.json get /api/v1/teams List all teams accessible with this API key. Requires the `read:teams` permission. Internal QA/test teams are excluded by default; pass `include_test_teams=true` to include them. # List teams (v0) Source: https://help.avoca.ai/api-reference/teams/list-teams-v0 /api-reference/openapi.json get /api/teams List the teams the API key can access. For multi-team keys, all accessible teams; for single-team keys, the one team. Requires the `read:teams` permission. # Event Payloads Source: https://help.avoca.ai/api-reference/webhooks/event-payloads Payload schemas for each webhook event type All webhook payloads share a common envelope: ```json theme={null} { "event": "lead.created", "eventId": "5e0f2a9c-6d3a-4a6e-9d1e-3f8a2b7c4d5e", "deliveredAt": "2026-05-01T16:04:22.117Z", "teamId": 808 } ``` `deliveredAt` is regenerated on each retry attempt; `eventId` is stable across retries — use it for idempotency. ## voice\_call.completed Fires after a call ends and has been classified. `transcript` and `recordingUrl` are included only when enabled on the webhook configuration. ```json theme={null} { "event": "voice_call.completed", "eventId": "…", "deliveredAt": "…", "teamId": 808, "call": { "id": "1f0e8a2b-…", "timestamp": "2026-05-01T16:00:12.000Z", "callerId": "+19175551234", "phoneNumber": "+19175551234", "receivingPhoneNumber": "+19175550100", "originalDialedNumber": null, "callerFirstName": "John", "callerLastName": "Doe", "bookingOutcome": "booked", "declineReason": null, "agentHandledBy": "chloe", "aiOrHuman": "ai", "callType": "Inbound", "callReason": "Service request", "callOutcome": "Appointment booked", "callEndedReason": "customer-ended-call", "durationSeconds": 245, "isBooked": true, "isBookable": true, "isTransferred": false, "forwardedPhoneNumber": null, "serviceTitanJobId": 456789, "customerId": "1048291", "isEmergency": false, "transcript": "…", "recordingUrl": "https://…" } } ``` Key fields: * `receivingPhoneNumber` — Avoca number that directly received the call. * `originalDialedNumber` — inbound destination from linked ServiceTitan records for the original call. Transferred legs use their linked original call regardless of the leg's own direction. Returns `null` when the original call is outbound, records are unsupported or missing, or destinations conflict. Earlier forwarding hops may not be preserved. This is a snapshot when the payload is built; a later Calls API read may have data synced afterward. See [Report on dialed numbers](/integrations/webhooks-and-api-keys#report-on-dialed-numbers). * `bookingOutcome` — `booked` | `declined` | `transferred` | `unknown` * `agentHandledBy` — `chloe` (AI) | `human` | `unknown` * `isEmergency` — emergency classification from the AI or booking-window flag * `serviceTitanJobId` / `customerId` — CRM linkage when a booking was made ## lead.created Fires when a new lead is recorded. Includes the raw inbound webhook body (when the lead arrived via webhook intake) under `rawWebhook`. ```json theme={null} { "event": "lead.created", "eventId": "…", "deliveredAt": "…", "teamId": 808, "lead": { "id": 12345, "source": "Angi", "customerName": "John Doe", "phoneNumber": "+11234567890", "email": "john@example.com", "address": "123 Main St, Austin, TX 78701", "externalId": "abc-123", "createdAt": "2026-01-15T10:30:00Z" }, "rawWebhook": { "...": "original third-party payload" } } ``` ## lead.booking\_created Fires when a booking is created for a lead — once per distinct CRM job. Multiple appointments booked in one conversation emit multiple events. For native-channel bookings (Google LSA, Yelp, web chat), `campaign` is `null`. ```json theme={null} { "event": "lead.booking_created", "eventId": "…", "deliveredAt": "…", "teamId": 808, "lead": { "id": 12345, "source": "Angi", "customerName": "John Doe", "phoneNumber": "+11234567890", "email": null, "address": null, "externalId": "abc-123", "createdAt": "2026-01-15T10:30:00Z" }, "booking": { "crmJobId": "98765", "bookedAt": "2026-01-15T10:35:00Z", "bookedBy": "ai", "serviceType": "HVAC Repair", "businessUnitId": 42, "serviceAreaId": 7, "crmCustomerId": "1048291" }, "campaign": { "id": 314, "name": "Speed to Lead — Angi", "workflowType": "SPEED_TO_LEAD" } } ``` * `booking.bookedBy` — `ai` | `human` | `self_service` | `unknown` * `booking.crmJobId` can be `null` when the event fires before the CRM job ID is recorded ## lead.completed Fires once per lead when it reaches the true end of its lifecycle — either its campaign finished, or it terminated at intake without ever entering a campaign. ```json theme={null} { "event": "lead.completed", "eventId": "…", "deliveredAt": "…", "teamId": 808, "lead": { "id": 12345, "source": "Angi", "customerName": "John Doe", "phoneNumber": "+11234567890", "email": null, "address": null, "externalId": "abc-123", "createdAt": "2026-01-15T10:30:00Z" }, "completion": { "outcome": "booked", "completedAt": "2026-01-15T11:40:00Z", "crmJobId": "98765", "bookingsCount": 1, "errorMessage": null, "notEnrolledReason": null } } ``` * `outcome` — `booked` | `unbooked` | `opted_out` | `failed` * `bookingsCount` — currently reports 0 or 1; derive exact counts from `lead.booking_created` events * `errorMessage` — set only when `outcome` is `failed` * `notEnrolledReason` — set only when the lead never entered a campaign ## customer.communication\_preference\_changed Fires when a customer opts out (STOP) or back in (START) of SMS. Currently SMS-only; `email` and `voice` channels are reserved for future use. ```json theme={null} { "event": "customer.communication_preference_changed", "eventId": "…", "deliveredAt": "…", "teamId": 808, "change": { "channel": "sms", "status": "opted_out", "phoneNumber": "+19175551234", "email": null, "customerId": "1048291", "source": "inbound_sms", "occurredAt": "2026-05-02T09:11:05.882Z", "category": "STOP" } } ``` # Event Webhooks Source: https://help.avoca.ai/api-reference/webhooks/event-webhooks Receive real-time notifications when calls complete, leads are created, bookings happen, and customers change subscription preferences ## Overview Avoca can push events to your systems in real time via HTTPS webhooks. Webhook configurations are managed per team (or enterprise-wide) and deliver signed JSON payloads to an endpoint you control. Event webhooks are the push counterpart to the [v1 leads feed](/api-reference/introduction) — consumers can join the webhook stream to pulled lead records on `id` / `external_id`. ## Event Types | Event | Fires when | | - | - | | `voice_call.completed` | A call ends and has been classified and saved | | `lead.created` | A new lead is recorded (from any intake source) | | `lead.booking_created` | A booking is created for a lead — one event per distinct CRM job | | `lead.completed` | A lead reaches the true end of its lifecycle (booked, unbooked, opted out, or failed) | | `customer.communication_preference_changed` | A customer opts in or out of SMS (STOP/START) | See [Event Payloads](/api-reference/webhooks/event-payloads) for the full schema of each event. ## Configuration Webhook configurations are managed from the Avoca dashboard (or via the team-scoped configuration API): * **Name** — a label for the configuration * **Endpoint URL** — your HTTPS endpoint (max 2048 chars; `https://` required) * **Events** — which event types to subscribe to (at least one) * **Custom headers** — optional name/value pairs sent on every delivery; individual headers can be marked *encrypted* (stored AES-GCM encrypted, never returned in plaintext) * **Include transcript / recording URL** — opt-in flags controlling optional fields on `voice_call.completed` payloads * **Lead source filter** — optionally restrict `lead.*` events to specific lead sources You can create a configuration in a disabled state with no endpoint to obtain the signing secret first, then enable it once your receiver is deployed. Each configuration also supports a **test event** so you can verify your receiver end to end. ## Verifying Signatures Every delivery is signed with the configuration's webhook secret using HMAC-SHA256: | Header | Contents | | - | - | | `X-Webhook-Signature` | `sha256=` | | `X-Webhook-Timestamp` | ISO 8601 timestamp of this delivery attempt | | `X-Avoca-Event` | The event type (e.g. `lead.created`) | | `X-Avoca-Event-Id` | Delivery ID (UUID) — stable across retries of the same event | | `X-Avoca-Delivery` | Same as the event ID | Compute the HMAC of the raw request body with your webhook secret and compare against `X-Webhook-Signature` using a constant-time comparison. The timestamp and signature are regenerated on each retry attempt, so also check `X-Webhook-Timestamp` freshness to reject replays. ```javascript theme={null} import crypto from 'node:crypto'; function verify(req, secret) { const expected = 'sha256=' + crypto .createHmac('sha256', secret) .update(req.rawBody) .digest('hex'); return crypto.timingSafeEqual( Buffer.from(expected), Buffer.from(req.headers['x-webhook-signature'] ?? '') ); } ``` ## Delivery & Retries * Deliveries are `POST` requests with `Content-Type: application/json` and a **10-second timeout**. * Failed deliveries are retried **5 times with exponential backoff**. `4xx` responses are treated as non-retriable (a misconfigured endpoint won't be hammered); `5xx` and network errors are retried. * Use `X-Avoca-Event-Id` for idempotency — it is stable across retries of the same event. * **Auto-pause:** after 50 consecutive failures a configuration is automatically disabled (`disabled_reason: auto_paused_consecutive_failures`). Any successful (2xx) delivery resets the counter. Re-enable from the dashboard once your endpoint is healthy. * Delivery logs are retained for 90 days. ## Respond Quickly Return a `2xx` as soon as you have durably received the event, and process asynchronously. Anything slower than 10 seconds counts as a failed attempt. # Speed-to-Lead Intake Webhook Source: https://help.avoca.ai/api-reference/webhooks/lead-intake Push leads into Avoca from any source for instant AI outreach ## Overview The Speed-to-Lead intake webhook is the endpoint partners and lead providers POST leads to. Each accepted lead is recorded, matched against your configured field mappings, and queued for outbound AI outreach according to your team's scheduling rules. ``` POST https://app.avoca.ai/api/outbound/speed-to-lead/ingest ``` **If you were given a dedicated source URL** when your integration was set up, post there instead: ``` POST https://app.avoca.ai/api/outbound/speed-to-lead/ingest/ ``` A dedicated source URL identifies both your team and which lead source the payload came from — you don't need to send a `lead_source` field, and it's not possible to misattribute leads to the wrong source. If you operate at the portfolio or enterprise level, the [routing rules below](#portfolio-and-enterprise-routing) don't apply on this URL either, since the team is already fixed by the key. Ask your Avoca contact whether a dedicated source URL exists for your integration; if not, use the shared endpoint above. ## Authentication Avoca issues your API key already in its full, final form, including the `avoca_` prefix (e.g. `avoca_3f1a9c2e6b7d4e2a9c3f8d5b1a2e4f6c...`), when you (or the Avoca team) generate it in the dashboard. Copy it exactly as given; there's nothing to prepend or assemble yourself. Set it as an environment variable and authenticate with either header: ```bash theme={null} Authorization: Bearer $AVOCA_API_KEY # or X-API-Key: $AVOCA_API_KEY ``` ### Rate limits Avoca does not currently enforce rate limits on this endpoint. There is no documented or guaranteed limit, so if you anticipate very high-volume or bursty delivery, check with your Avoca contact first. ## Request Send any JSON object. Field names are resolved through your team's configured **field mappings**, so you can point most lead sources at Avoca without reshaping their payloads. Standard target fields include: | Field | Type | Required | Description | | - | - | - | - | | `customer_name` (or `first_name` / `last_name`) | string | **Yes** (by default) | Customer name. Send either the combined name or both parts: Avoca joins `first_name` + `last_name` when `customer_name` isn't mapped. Required by default; some accounts (e.g. a missed-call or abandoned-lead feed with only a phone number) have this made optional on request. Ask your Avoca contact if you need this. | | `phone_number` | string | **Yes** | Customer phone. Any common US format is accepted (`(555) 123-4567`, `555-123-4567`, `5551234567`, `+15551234567`) and normalized to `+1XXXXXXXXXX`. Must resolve to a 10-digit US number (11 digits accepted with a leading `1`); anything else is rejected, see [Errors](#errors). International numbers are not currently supported. | | `email` | string | No | Customer email. Not validated as a well-formed email address; any string is accepted and stored as-is. | | `address` / `street` / `city` / `state` / `zip` / `country` | string | No | Location. `country` defaults to `USA` when omitted. | | `service_type` | string | No | Requested service | | `lead_source` | string | No | Source label, mapped to a configured Avoca lead source. Omitted payloads fall back to `API Webhook` (or `API ()` when `utm_source` is present). | | `external_id` | string | No, but strongly recommended | Your reference ID. Any string, including a UUID, is accepted; there's no required format. Combined with the phone number, this is the identity Avoca uses to recognize a repeat delivery as the *same* lead rather than a new one, see [Duplicate and repeat deliveries](#duplicate-and-repeat-deliveries). Echoed on webhooks and the leads feed. | | `notes` | string | No | Free-form notes; can be configured to combine multiple payload fields into one JSON object | | `bypass_deduplication` | boolean | No | Set to `true` to have this delivery treated as a brand-new lead even when the same `phone_number` + `external_id` already exists, see [Duplicate and repeat deliveries](#duplicate-and-repeat-deliveries). Read from the top level of your payload as-is (not through field mappings). Omit it for normal deliveries. | | `appointment_datetime` | string (ISO 8601, e.g. `2026-09-10T15:00:00-04:00`) | No | Requested appointment time, if any. A `LLL d yyyy h:mm a` format (e.g. `Sep 10 2026 3:00 PM`) is also accepted as a fallback, but ISO 8601 is the only supported contract, so don't rely on the fallback. | | `utm_source` / `utm_medium` / `utm_campaign` / `utm_term` / `utm_content` | string | No | Attribution | Each mapping is a first-match-wins alias list (e.g. `phone_number` ← `phone`, `Phone`, `contact.phone`), configured per team by the Avoca team. Fields outside this table are not lost: the complete raw JSON body you send is always stored on the lead and available in the [v1 leads feed](#tracking-leads-downstream) and on outbound lead events, whether or not a field mapping exists for it. Mapping only controls what gets used *operationally* (matching, dedupe, display), not what's retained. ```bash theme={null} curl -X POST https://app.avoca.ai/api/outbound/speed-to-lead/ingest \ -H "Authorization: Bearer $AVOCA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "John Doe", "phone": "(555) 123-4567", "email": "john@example.com", "source": "Website Form", "service": "HVAC Repair", "external_id": "form-8812" }' ``` ## Response ### Success (`201 Created`) A `201` is returned whenever the request was authenticated and well-formed, **whether or not a lead was actually recorded or will be contacted.** Always check `data.lead_id` and `skipped` rather than treating `201` alone as "a new lead now exists." ```json theme={null} { "success": true, "message": "Lead created successfully", "data": { "lead_id": 12345 }, "request_id": "3f1a9c2e-6b7d-4e2a-9c3f-8d5b1a2e4f6c" } ``` `request_id` is a UUID generated fresh per request. The example above is illustrative, not a real value to match against. | Field | Type | Always present | Description | | - | - | - | - | | `success` | boolean | Yes | `true` for every `201` response. | | `message` | string | Yes | Human-readable summary. See the `message` values in the table below. Not a stable machine-readable field; parse `skipped` / `data.lead_id` instead. | | `data.lead_id` | integer | No | The lead's id. **Absent** only when the resolved lead source is disabled (see below); that is the one case where a `201` means nothing was stored. | | `skipped` | boolean | No | `true` when the lead will **not** receive AI outreach. Omitted entirely (not `false`) on the normal path. | | `skip_reason` | string | No | Present only alongside `skipped: true`, see [Skip and ignore reasons](#skip-and-ignore-reasons). | | `request_id` | string (UUID) | Yes | Correlates this request with Avoca-side logs if you need to escalate an issue. | #### What each outcome looks like | Scenario | `data.lead_id` | `skipped` | `skip_reason` | `message` | | - | :-: | :-: | - | - | | New lead, will be contacted | present | n/a | n/a | `"Lead created successfully"` | | Repeat delivery (same phone + `external_id` as an existing lead) | present (existing lead's id) | n/a | n/a | `"Duplicate lead merged into existing lead"` | | Repeat delivery with `bypass_deduplication: true` | present (a new lead's id) | n/a | n/a | `"Lead created successfully"` | | Appointment time is already in the past | present | `true` | `"past_appointment"` | `"Lead is ignored: past_appointment"` | | Suppressed by cooldown | present | `true` | free-text, contains `"cooldown"` (see below) | `"Lead is ignored: "` | | Resolved lead source is disabled | **absent** | `true` | `"lead_source_disabled"` | `"Lead source is disconnected; lead was not logged"` | ### Duplicate and repeat deliveries Avoca treats `team + phone_number + external_id` as the identity of a lead. Re-sending a payload with the **same** phone number and `external_id` does not create a second lead or error. It updates the existing lead's name, email, address, and notes in place, and the response reports `"Duplicate lead merged into existing lead"` with the original `lead_id`. This is safe to rely on for retries. It does **not** apply to correcting a phone number: changing the phone number changes the identity, so it always creates a new, separate lead rather than updating the old one. **Always send `external_id` when you have one.** When it's omitted, identity collapses to `team + phone_number` alone. Two genuinely different leads for the same phone number (e.g. two different service requests) will merge into one lead rather than creating two, since Avoca can't otherwise tell them apart. `external_id` is the only thing that disambiguates repeat callers. **Forcing a repeat to be treated as new.** Send `bypass_deduplication: true` at the top level of the payload and Avoca skips the identity match and the cooldown window for that one delivery, creating and contacting a new lead even though the same `phone_number` + `external_id` already exists. This is intended for testing your integration by replaying the same lead. Do not send it on production retries: a retry carrying it creates a duplicate lead that will be contacted again. Two deliveries for the same identity arriving at (or near) the exact same instant are not fully guarded: this endpoint checks for an existing lead and creates a new one as separate steps, so a race between two concurrent requests can, in rare cases, surface as a `500` on one of them rather than both cleanly merging. If you see an occasional `500` on what should be a duplicate, a brief retry will resolve it: the underlying lookup succeeds on the next attempt. ### Skip and ignore reasons `skip_reason` is not yet a fixed enum. Treat it as one of these categories rather than matching on exact text (only `past_appointment` and `lead_source_disabled` are stable literal strings today; the cooldown reason is a generated sentence): | Category | `skip_reason` shape | Meaning | | - | - | - | | Lead source disabled | exact string `lead_source_disabled` | The lead source this payload resolved to has been disconnected. **No lead was stored at all**, this is the only case where `data.lead_id` is absent on a `201`. | | Past appointment | exact string `past_appointment` | The mapped `appointment_datetime` was already in the past (only evaluated when your team has this check enabled). The lead is stored but not queued for outreach. | | Cooldown | free text containing `cooldown` (e.g. `"cooldown time is … for lead source …"`) | A recent lead for the same phone number is still inside the source's configured cooldown window. The lead is stored but not queued for outreach. | One outreach-affecting state is **not** visible in this response at all: if the resolved lead source has AI outreach turned off (distinct from being disabled: the source still accepts and stores leads normally), that decision is made asynchronously after this request already returned `201` with a normal, non-skipped response. To detect it, check `is_ignored` / `ignored_reason` on the lead via the [leads feed](#tracking-leads-downstream) after the fact, rather than the synchronous ingest response. The `lead.created` webhook event does **not** carry these fields (it fires at insert time, before this state is known), so the leads feed is the only place to observe it. ### Errors | Status | Body shape | Meaning | | - | - | - | | 400 | `{ "success": false, "error": string, "request_id": string }`. A payload-shape error also includes `"errors": [{ "field": string, "message": string, "code": string }]`. | Invalid payload shape, failed routing rule, or a missing `customer_name` / missing-or-unparseable `phone_number` | | 401 | `{ "success": false, "error": string, "request_id": string }` | Missing or invalid API key | | 405 | `{ "success": false, "error": string, "request_id": string }` | Method other than `POST` | | 500 | Usually `{ "success": false, "error": string, "request_id": string }`. A failure specifically inside lead processing (after payload validation) instead returns `{ "success": false, "message": string, "request_id": string }`. Check for whichever key is present rather than assuming one. | Unexpected server-side failure processing the request | There is no `409` response. A payload that matches an existing lead's identity is merged, not rejected (see [Duplicate and repeat deliveries](#duplicate-and-repeat-deliveries)). ```json theme={null} { "success": false, "error": "Payload validation failed", "errors": [ { "field": "phone_number", "message": "phone_number is required", "code": "MISSING_REQUIRED" } ], "request_id": "7c2e4a1b-9d3f-4a6c-8e1b-2f5d9a7c3e6b" } ``` ```json theme={null} { "success": false, "error": "Payload validation failed", "errors": [ { "field": "phone_number", "message": "Invalid phone number length: 7 digits (expected 10 or 11)", "code": "INVALID_FORMAT" } ], "request_id": "1e9b3c5a-4f7d-4e2a-9b1c-6a8d3f5e7c2b" } ``` ```json theme={null} { "success": false, "error": "Invalid API key", "request_id": "9a3f6c1e-2b5d-4a8c-9e3f-1c6a4b8d2f7e" } ``` ## Examples `customer_name` and `phone_number` are required by default. ```bash theme={null} curl -X POST https://app.avoca.ai/api/outbound/speed-to-lead/ingest \ -H "Authorization: Bearer $AVOCA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "John Doe", "phone": "5551234567" }' ``` ```json theme={null} { "success": true, "message": "Lead created successfully", "data": { "lead_id": 12345 }, "request_id": "4d8e2a6c-1f3b-4a9d-8c2e-5b7f1a3d9e6c" } ``` No `lead_source` was sent, so this lead is filed under the `API Webhook` fallback source. Some accounts (e.g. a missed-call or abandoned-lead feed that never has a name to send) have `customer_name` configured as optional. Ask your Avoca contact if this applies to you before omitting it. For every other account, this payload gets a `400`. ```bash theme={null} curl -X POST https://app.avoca.ai/api/outbound/speed-to-lead/ingest \ -H "Authorization: Bearer $AVOCA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "phone": "5551234567" }' ``` ```json theme={null} { "success": true, "message": "Lead created successfully", "data": { "lead_id": 12345 }, "request_id": "7f2c9e6a-4b1d-4e3c-8a5f-1d6b2e9c7f3a" } ``` Any fields you send beyond the ones Avoca recognizes are not rejected and not dropped. The full payload is always retained. ```bash theme={null} curl -X POST https://app.avoca.ai/api/outbound/speed-to-lead/ingest \ -H "Authorization: Bearer $AVOCA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "John Doe", "phone": "(555) 123-4567", "source": "Website Form", "external_id": "form-8812", "internal_crm_stage": "MQL", "assigned_rep_id": "rep-4471", "custom_scoring": { "intent": 0.82, "fit": 0.61 } }' ``` `internal_crm_stage`, `assigned_rep_id`, and `custom_scoring` have no configured field mapping, so they don't affect matching, dedupe, or how the lead displays in Avoca. They're still stored verbatim on the lead's raw payload and available through the [v1 leads feed](#tracking-leads-downstream) and on outbound lead events. ```json theme={null} { "success": true, "message": "Lead is ignored: cooldown time is 2026-09-03T14:00:00.000Z for lead source Website Form. Lead was created at 2026-09-03T10:12:00.000Z.", "skipped": true, "skip_reason": "cooldown time is 2026-09-03T14:00:00.000Z for lead source Website Form. Lead was created at 2026-09-03T10:12:00.000Z.", "data": { "lead_id": 12346 }, "request_id": "8f2c4e6a-3d9b-4a1c-9e6f-2b5d8a3c1f7e" } ``` The lead is still stored (`data.lead_id` present); it just won't be queued for outreach. See [Skip and ignore reasons](#skip-and-ignore-reasons). ```json theme={null} { "success": true, "message": "Lead source is disconnected; lead was not logged", "skipped": true, "skip_reason": "lead_source_disabled", "data": {}, "request_id": "6a1d3f5c-8e2b-4a7d-9c1f-3e6a8b2d4f9c" } ``` `data.lead_id` is absent. This is the one outcome where nothing was actually created, despite the `201` status. Sending the same `phone_number` + `external_id` a second time (e.g. a retry, or the provider re-sending an updated record) updates the existing lead rather than creating a new one: ```json theme={null} { "success": true, "message": "Duplicate lead merged into existing lead", "data": { "lead_id": 12345 }, "request_id": "2c5e7a9d-4f1b-4a3c-8e5d-1a4c7f2b9e6a" } ``` `lead_id` matches the original lead. Name, email, address, and notes are updated from this request's payload; the phone number and `external_id` themselves are not changed by a resend. ## Scheduling Behavior When the AI calls the lead is governed by your team's configured scheduling mode: * `always`: call as soon as the lead arrives * `business_hours`: call immediately during business hours; queue otherwise * `after_hours`: only outside business hours * `custom`: custom windows configured with the Avoca team ## Portfolio and Enterprise Routing A single API key can post leads for **multiple teams** (every brand in an enterprise, or every team in a portfolio) through this one endpoint, instead of needing a separate key per team. This applies to both `enterprise_all_teams` keys and `portfolio_all_teams` keys (the key type issued at the portfolio level) identically. **If you operate at the portfolio or enterprise level, ask your Avoca contact whether routing is configured for your key before assuming a routing field is optional.** Your key's **anchor team** is the one specific team it is directly tied to in Avoca (for a portfolio key, the team the key was generated from; for an enterprise key, whichever member team it was issued against). What happens if you omit the routing field depends entirely on whether routing is configured at all: it does **not** uniformly fall back to the anchor team. See below for the full breakdown. There is no platform-wide `team_id` field name; which JSON field carries the target team, and how its value maps to a team, is configured once by the Avoca team on your anchor team's Speed-to-Lead settings (`routing_rules`), in one of two modes: | Mode | How the payload's routing field is interpreted | Example | | - | - | - | | `team_id` | The field's value **is** the numeric team id directly. | Field configured as `team_id`, a value of `` routes to that team. | | `custom_field` (default) | The field's value is an arbitrary string (e.g. a brand or location code) that is looked up against a configured value → team id mapping. | Field configured as `brand`, value `"acme-hvac"` is mapped to a specific team on the Avoca side. | ```bash theme={null} curl -X POST https://app.avoca.ai/api/outbound/speed-to-lead/ingest \ -H "Authorization: Bearer $AVOCA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "John Doe", "phone": "(555) 123-4567", "team_id": "", "source": "Website Form", "external_id": "form-8812" }' ``` Replace `` with the numeric id of the team this lead belongs to. Assumes your routing field was configured as `team_id` in `team_id` mode. The value is validated as a positive integer and must belong to a team inside your portfolio or enterprise. A team id outside it is rejected with `400` **unless** a fallback default team is configured for your key, in which case (same as `custom_field` mode below) the lead is routed to that fallback team instead and the request succeeds with `201`. ```bash theme={null} curl -X POST https://app.avoca.ai/api/outbound/speed-to-lead/ingest \ -H "Authorization: Bearer $AVOCA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "John Doe", "phone": "(555) 123-4567", "brand": "acme-hvac", "source": "Website Form", "external_id": "form-8812" }' ``` Assumes your routing field was configured as `brand`, mapped to a specific team on the Avoca side. Ask your Avoca contact to confirm the exact field name and its value-to-team mappings for your account. What happens when the routing field is missing, invalid, or doesn't match a configured mapping depends on your configuration: * **No routing configured at all:** every lead is accepted and lands on the anchor team, silently, with no error. If you're only seeing one team's leads and expected several, this is the first thing to check. * **Routing is configured, but this request's value is missing, empty, or doesn't match any rule:** these are treated identically. Rejected with `400` by default (`Routing field value "…" did not match any configured rule`, or the equivalent missing-field message), unless a fallback default team was configured, in which case the lead routes there instead. It does **not** fall back to the anchor team. * **Value resolves to a team outside your portfolio/enterprise:** rejected with `400` unless a fallback default team is configured, in which case it routes to the fallback instead (same as the unmatched case above), applying in both `team_id` and `custom_field` modes. The one boundary that is never configurable: a fallback team itself must be inside your portfolio/enterprise, or the request is rejected regardless. Ask your Avoca contact to confirm whether routing is configured for your key, which field name and mode it uses, and whether a fallback team is set. **Working at the portfolio level:** routing setup for `portfolio_all_teams` keys is currently done directly on the anchor team's own Speed-to-Lead settings in the Avoca dashboard; there is not yet a dedicated portfolio-wide configuration screen (enterprises have one, portfolios don't yet). Your Avoca contact will need to know which team is your anchor team to make this change. ## Tracking Leads Downstream * Subscribe to [`lead.created`, `lead.booking_created`, and `lead.completed` webhooks](/api-reference/webhooks/event-webhooks) for real-time lifecycle updates. * Pull historical records (including your original raw payload) from the v1 leads feed: `GET /api/v1/teams/{teamId}/leads`. Join on `external_id` or the returned `lead_id`. # Speed-to-Lead Pause Webhook Source: https://help.avoca.ai/api-reference/webhooks/lead-pause Pause AI outreach for a specific lead that booked or closed outside Avoca ## Overview The Speed-to-Lead pause webhook lets you stop AI outreach for a specific lead you previously sent through the [intake webhook](/api-reference/webhooks/lead-intake) — for example, the lead booked or was closed out in your own system. It targets one lead's active campaign enrollment; it does not touch any other lead. Two endpoints, mirroring the intake webhook's own pattern: ``` POST https://api.prod.avoca.ai/api/outbound/speed-to-lead/pause POST https://api.prod.avoca.ai/api/outbound/speed-to-lead/pause/ ``` If you were given a dedicated source URL when your integration was set up, use that (the URL identifies your team; `team_id` isn't needed in the body). Otherwise use the bare endpoint and include `team_id`. ## Authentication Same as the intake webhook — authenticate with either header: ```bash theme={null} Authorization: Bearer $AVOCA_API_KEY # or X-API-Key: $AVOCA_API_KEY ``` See [Authentication](/api-reference/webhooks/lead-intake#authentication) for how your key is issued. There is no documented rate limit on this endpoint. ## Request | Field | Type | Required | Description | | - | - | - | - | | `phone_number` | string | **Yes** | The lead's phone number. Any common US format is accepted. Must be the same lead you're targeting — see [Identity and matching](#identity-and-matching). | | `external_id` | string | **Yes** | Your reference id for this lead, exactly as originally sent to the intake webhook. | | `team_id` | integer | Only on the bare endpoint | The numeric id of the team this lead belongs to. Not accepted on the source-key endpoint — sending it there has no effect, since the URL already identifies the team. | ```bash theme={null} # Using your dedicated source URL curl -X POST https://api.prod.avoca.ai/api/outbound/speed-to-lead/pause/ \ -H "Authorization: Bearer $AVOCA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "phone_number": "(555) 123-4567", "external_id": "form-8812" }' ``` ```bash theme={null} # Using the bare endpoint (portfolio/enterprise callers naming their own team) curl -X POST https://api.prod.avoca.ai/api/outbound/speed-to-lead/pause \ -H "Authorization: Bearer $AVOCA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "team_id": 123, "phone_number": "(555) 123-4567", "external_id": "form-8812" }' ``` ## Response ### Success (`200 OK`) ```json theme={null} { "success": true, "data": { "paused": true, "workflow_campaign_audience_ids": [900] }, "request_id": "3f1a9c2e-6b7d-4e2a-9c3f-8d5b1a2e4f6c" } ``` | Field | Type | Always present | Description | | - | - | - | - | | `success` | boolean | Yes | `true` for every `200` response. | | `data.paused` | boolean | Yes | `true` if an active enrollment was found and paused; `false` if the lead exists but had nothing active to pause (already paused, already completed, or never enrolled). Always present, even on `false`. | | `data.workflow_campaign_audience_ids` | integer\[] | Yes | Internal enrollment ids that were paused. Empty array (not omitted) when `paused` is `false`. Informational only — there's no corresponding "resume by id" call. | | `request_id` | string (UUID) | Yes | Correlates this request with Avoca-side logs if you need to escalate an issue. | ```json theme={null} { "success": true, "data": { "paused": false, "workflow_campaign_audience_ids": [] }, "request_id": "7c2e4a1b-9d3f-4a6c-8e1b-2f5d9a7c3e6b" } ``` This is not an error. It means the lead exists but has no active enrollment right now — it may already be paused, already finished its campaign, or was never enrolled in the first place. ### Errors | Status | Body shape | Meaning | | - | - | - | | 400 | `{ "success": false, "error": string, "request_id": string }` | Missing/invalid `phone_number` or `external_id`; an unparseable `phone_number`; missing or invalid `team_id` on the bare endpoint; or an unrecognized source key on the source-key endpoint | | 401 | `{ "success": false, "error": string, "request_id": string }` | Missing or invalid API key | | 403 | `{ "success": false, "error": string, "request_id": string }` | `team_id` in the body is outside the scope your API key is allowed to act on | | 404 | `{ "success": false, "error": "Lead not found", "request_id": string }` | No lead matches `phone_number` + `external_id` for the resolved team | | 500 | `{ "success": false, "error": string, "request_id": string }` | Unexpected server-side failure | ## Identity and Matching This endpoint targets the exact same lead identity the intake webhook uses to [merge repeat deliveries](/api-reference/webhooks/lead-intake#duplicate-and-repeat-deliveries): `team + phone_number + external_id`. There's no fuzzy or partial lookup — send the same `phone_number` and `external_id` you originally sent for this lead. A different `external_id` for the same phone number is a different, unrelated lead as far as Avoca is concerned, and this call won't affect it. ## No Resume Endpoint Pausing here is one-directional. To re-enable outreach for the same inquiry, re-POST it to the [intake webhook](/api-reference/webhooks/lead-intake) with `bypass_deduplication: true` — this forces a fresh enrollment even though the phone number and `external_id` are unchanged. A genuinely new inquiry (a new `external_id`) was never affected by this pause and enrolls normally on its own. # Build your Brand Kit Source: https://help.avoca.ai/business-info/brand-kit Add the approved logos, colors, and images that supported Avoca creative tools can reuse. Open **Settings → Business Info → Brand Kit** to manage your team's reusable brand assets. The Brand Kit has four sections: * **Logos** for brand marks that supported content tools can place in a creative * **Colors** for the approved color palette * **Images** for photos and graphics * **Brand profile**, which currently shows a coming-soon state and has no editable guidance fields ## Add a logo or image 1. Open **Logos** or **Images**. 2. Choose **Add logo** or **Add image**. 3. Select a PNG, JPG, or SVG file. 4. Add a recognizable **Name**. 5. Add a **Usage note** that tells the AI when the asset is appropriate, such as `White lockup — use on navy or photos.` 6. Save the asset. Use the Logos section for actual brand marks and Images for supporting photography or graphics. A specific usage note is more useful than a generic description. Add only approved, current assets. Clear names such as “Primary horizontal logo” and “Technician team photo” make the library easier to review. ## Add a color 1. Open **Colors** and choose **Add color**. 2. Enter a six-digit hexadecimal value, such as `#16294A`. 3. Add an optional label such as `Primary navy`. 4. Choose **Add color**. Edit an asset to update its name, usage note, or color value. To replace an uploaded image file, remove the existing asset and add the new file. ## Remove an asset Use the delete action on an asset card, then confirm **Remove**. The asset will no longer be available to the AI, but creatives that were already generated or sent are not changed. Removing an asset is not a way to retract previously generated content. Handle any already-published creative in the system where it was published. ## Keep the library healthy * Remove superseded logo versions after the replacement is available. * Keep light, dark, and alternate marks clearly labeled. * Use exact brand color values rather than visually similar approximations. * Do not upload customer data, credentials, private documents, or images your business is not authorized to use. * Review the Brand Kit after a rebrand before generating new content. # Manage Capacity Planning Source: https://help.avoca.ai/business-info/capacity-planning Review availability, organize business units, apply capacity rules, test examples, and schedule capacity reports. Open **Settings → Business Info → Capacity Planning**. The tile appears only when Capacity Planning is enabled and your role has access to it. Several controls on these pages apply only when the team's **Capacity Source** is set to **Avoca Capacity**. The dashboard shows a banner when another source is active. ## Understand the tabs * **Capacity** shows technician capacity by date and window. Use its filters to review the relevant business-unit group and inspect the calculation before making a manual adjustment. * **Mission Control** shows quota fill and availability and lets authorized controllers add or edit quota caps and overbook allowances when that rollout is enabled for the team. * **Test** saves representative job type, business unit, service area, and tag combinations and previews the slots a customer would see now. * **Business Unit Groups** organizes CRM business units and sets the group's base capacity. * **Rulesets** applies percentage adjustments to capacity when configured conditions match. * **Drive Time** adds supported travel-time behavior when enabled. * **Tag Skills** connects job tags to technician skill logic. * **Notifications** chooses the team timezone and report-delivery hours. * **Settings** contains the capacity-source and calculation options available to your team. Capacity **Rulesets** are active capacity controls. They are unrelated to the deprecated Rulesets tab under Fees. ## Build the Drive Time ZIP matrix When Drive Time is enabled, open **Drive Time → ZIP matrix**. The matrix stores pre-computed drive times between the team's service-area ZIP codes so supported capacity checks do not need to start from an empty cache. Every pair is measured using the next Tuesday at 9:00 AM in the team's timezone, with traffic-aware duration when Google provides it, so values in the matrix use one comparable departure basis. 1. Confirm that the service area contains at least two valid five-digit ZIP codes. 2. Select **Build Matrix**. 3. Review **Matrix coverage**, **Fetched now**, **Already cached**, **Unroutable**, and **Missing** while the build runs. 4. Expand the unroutable-pair details when any pair could not be filled. 5. Filter the matrix by origin or destination ZIP and review important routes. Building fetches only missing pairs and leaves existing cached times unchanged. The build dialog identifies the standardized departure used for that pass. If a build stops, progress is saved; select **Continue** to retry the remaining pairs instead of starting over. If older pairs were measured on a different basis, building only the missing pairs does not refresh them. Review the matrix before changing a drive-time cutoff; traffic-aware values can be higher than a free-flow estimate and therefore make an existing cutoff more restrictive. Nothing is stored for an unroutable pair. If bookings depend on that route, verify both ZIP codes and then set a reviewed drive time manually in the matrix table. Do not treat an incomplete matrix as complete merely because some pairs are cached. **Clear matrix** deletes every cached drive-time pair for the team. Live capacity falls back to on-demand Google lookups until the matrix is rebuilt. Clear it only when you intend to rebuild the complete matrix and have reviewed the effect on live booking. When Drive Time and its rollout are enabled, the same customer ZIP is enforced when Responder offers slots and when Avoca commits a primary booking or reschedule. This prevents the final technician selection from bypassing a drive-time cutoff that removed a technician from the offered availability. Human-in-the-loop submissions and Simple Scheduler bookings do not use this commit-time Drive Time check. If a slot disappears at confirmation, verify the customer ZIP, technician home or configured origin ZIP, cutoff, matrix value, and whether the final booking path supports Drive Time. Do not assume that seeing a slot earlier guarantees that the same technician remains eligible at commit time. ### Trace a Drive Time decision For supported ServiceTitan and Avoca Capacity booking calls, open the booking-information result in the call details and select **How did we calculate these availabilities?** The **Drive Time Capacity** stage shows technicians removed from a window, the inbound and outbound drive-time tests, and the applicable cutoffs. When the availability pipeline ran and recorded a trace, this inspection action also appears on a failed or zero-slot booking-information result. Use it to find the stage that removed availability before widening capacity or changing a cutoff. If no trace was recorded, the action does not appear. When a preceding or next ServiceTitan job determined a drive-time leg, the trace links to that job and shows when the preceding appointment ends or the next appointment starts. Avoca considers job appointments that start on the same local calendar day as the candidate window, using the team's timezone. A job from a different local day is not used as the preceding or next anchor for that window. Use the linked jobs and displayed times before changing a cutoff. Confirm the job ZIP codes, appointment times, team timezone, and customer ZIP. A missing same-day anchor can cause the configured shop or technician-home behavior to apply instead. Diagnostic traces are retained for 30 days; older calls can show that no trace was recorded. ## Read the Capacity view Each capacity cell compares available capacity with total capacity for a business-unit group and arrival window. Filter by job type, service area, date, and timezone before interpreting it. Open a cell to review: * The technicians contributing to the window * Base or shift-derived capacity * Booked work * Ruleset adjustments * Existing manual adjustments Use the timezone selector when the business operates in multiple regions. ## Build business-unit groups Group business units that draw from the same technician pool. For example, HVAC Service, HVAC Maintenance, and HVAC Install can share a group when the same technicians cover all three. Do not group units only because their names are similar. Confirm the real staffing pool and booking behavior first. ## Configure rulesets A ruleset can target a combination of: * Arrival windows * Weekdays * Business units * Job types * Technicians Set the multiplier to the intended share of normal capacity. For example, `0` closes the matching capacity and `0.5` limits it to half. When several rulesets match the same slot, Avoca uses the most restrictive result. Start with a small number of rules whose purpose and owner are clear. ## Manage quotas in Mission Control Use **Mission Control** when you need a capacity ceiling for a business-unit and priority combination or for a job type. Quotas use the same live technician pool as Capacity Planning. 1. Match the timezone and week to the Capacity page you are comparing. 2. Choose **Business Unit / Priority** or **Job Type Quotas**. 3. Use **Week** to scan daily fill, then open a day for the full matrix. 4. Select the pencil on a row to add or edit a quota. 5. Choose the priorities and arrival windows the quota covers. 6. Enter the cap in jobs or hours. The editor previews the equivalent share of the live pool and the projected fill. 7. Choose the inclusive **Starts on** and **Ends on** dates, or turn on **Perpetual** when the quota should have no end date. 8. Select **Schedule** to review every temporary and perpetual quota on that row across the calendar, then save. The jobs display converts technician hours using the current **hours per job** value. Changing that display value does not change the underlying technician-hour calculation. A row can contain multiple quotas for different priority and arrival-window combinations; choose the intended entry before editing or deleting it. A temporary quota can pause a perpetual quota for the same priority and arrival-window scope. The perpetual quota resumes after the temporary quota's inclusive end date. If you delete the temporary quota, choose whether to re-establish the paused perpetual quota immediately or leave its scheduled resume date in place. If the dates and scope overlap another quota, the save confirmation lists the affected temporary or perpetual entries. Continuing replaces or removes those entries and cannot be undone from the confirmation. Review the quota type, dates, allocation, priorities, and arrival windows before choosing **Overwrite and save** or **Remove and save**. In call-taker view, green and amber cells can be expanded for details. A red configured quota is already full or over capacity and cannot be expanded from that view; no-quota cells keep a dashed border so they are not mistaken for configured quota rules. Quota rules can be scoped by the Mission Control business-unit or job-type target, priorities, and arrival windows. They cannot currently be scoped by service area, skill, or tag. A zero quota closes the matching capacity. Before saving, confirm the row, priorities, arrival windows, start and end dates or **Perpetual** setting, and projected fill. After saving, reopen the selected day and confirm the quota appears only in the intended matrix cells. **Test** can verify the business-unit or job-type result, but it cannot select a priority or arrival window; verify those dimensions in **Mission Control**. ## Configure Settings Review the calculation defaults that apply to the team, such as: * Availability threshold or buffer behavior * Whether non-managed technicians contribute * Whether on-call technician shifts contribute * Zone and business-unit restrictions * Whether business-unit groups take priority When on-call shifts should supply after-hours capacity, keep the source schedules current and confirm that **Include On-Call Technician Shifts** is enabled. ## Recommended setup order 1. Confirm the intended Capacity Source in **Settings**. 2. Create and review **Business Unit Groups**. 3. Configure technician and tag-skill inputs used by the calculation. 4. Add the minimum necessary capacity rulesets and leave speculative rules disabled. 5. Save common scenarios in **Test** and compare the returned availability with the expected result. 6. Review **Capacity** for the next several operating days. 7. Configure report times in **Notifications** and verify recipients' Capacity Report Email preference under **Employee Contacts**. ## Make manual adjustments carefully Before changing a capacity cell, open its details and understand the base capacity, booked work, rule adjustments, and any existing manual adjustment. Record why the change is needed and avoid using a manual adjustment to hide a broken CRM mapping or ruleset. Capacity controls the appointment windows Avoca can offer. Test one combination that should be available and one that should be unavailable after every material change. If the Capacity page appears empty, check the selected date and filters, CRM technician and appointment data, business-unit grouping, active capacity source, and enabled rulesets before adding capacity manually. ## Know the current limits * Avoca Capacity uses arrival windows rather than free-form business hours. Represent bookable time with the intended arrival windows. * ServiceTitan does not expose every capacity ruleset through the integration. Recreate required rules deliberately in Avoca instead of assuming they synchronized. * Manual capacity adjustments do not repair stale technician shifts, missing mappings, or an incorrect capacity source. # Manage catalog data and service areas Source: https://help.avoca.ai/business-info/catalog-and-service-areas Sync CRM job types, business units, and tags, then define the postal-code areas your team serves. Open **Settings → Business Info** to manage the CRM catalog records Avoca can use and the geographic areas your team serves. The connected CRM remains the source of truth for its catalog. Use Avoca to import the records you need and configure how Avoca may use them; do not create a duplicate just because a CRM record has not been synced yet. ## Job Types Open **Job Types** to review the types of work available from the connected CRM. * ServiceTitan teams see the ServiceTitan job-type editor. * AccuLynx teams see the corresponding Trade Types editor. * If neither supported connection is present, the page links back to **Integrations**. For ServiceTitan: 1. Choose **Sync from ST** to find job types that have not been imported into Avoca. 2. Review the unsynced list and import only the job types Avoca needs. 3. Add or generate a clear definition when the CRM name alone is ambiguous. 4. Review the available **Book**, **Reschedule**, and **Cancel** controls for each type. 5. Review any feature-gated controls, such as hiding an appointment, masking its date, or priority behavior, only if they appear for your team. 6. Test a representative booking after changing a customer-facing capability. Use the search box to narrow the list before selecting rows. For Job Types and Business Units, select the intended rows and choose **Bulk edit** to turn **Book**, **Reschedule**, **Cancel**, or all three actions on or off together. The selection can include rows outside the current search results, so confirm the selected count before applying the change. Bulk edits save immediately across every selected record. Turning an action off can remove live booking, rescheduling, or cancellation paths for several services at once. Record the current state, use the narrowest selection, and test the affected combinations after the update. The ServiceTitan priority badge is read-only and reflects the priority currently returned by ServiceTitan. Avoca-specific priority controls can also appear when priority overbooking is enabled; do not change them simply to match the badge. ### Configure AccuLynx trade types For AccuLynx, open **Trade Types** after the API credentials are connected. For each trade: 1. Add keywords, synonyms, or a short description that helps Avoca classify the caller's request. 2. Set **Duration (hours)** to the amount of calendar time that trade should block. 3. Save, then test availability and a controlled booking for that trade. The duration accepts positive values in quarter-hour increments. If a trade has no saved duration, Avoca uses the team's configured default or four hours when no team default is available. The customer still sees the configured arrival window; the trade duration controls capacity and the appointment's calendar end time from the selected window start. A duration that is shorter than the work can make a representative appear free too soon; a duration that is too long can hide valid availability. Keep the value aligned with the trade used for the offered slot and confirm the booked AccuLynx calendar block. ## Business Units Open **Business Units** to review ServiceTitan business units and the actions Avoca may perform for each one. 1. Choose **Sync from ST** and import the required unsynced units. 2. Give each imported unit a useful definition. 3. Review **Book**, **Reschedule**, and **Cancel** independently. 4. If **Mask Appointment Date** appears, enable it only when the agent should withhold the appointment date or time for that unit. Business Units requires a ServiceTitan connection. If the page is empty, verify the integration before adding records elsewhere. ### Understand Knowledge Base locks For ServiceTitan Job Types and Business Units, the Knowledge Base sets the team-wide cancellation and rescheduling policy. When the matching Knowledge Base section transfers the request, takes a message, or otherwise does not allow the action, the catalog row shows **Cancel** or **Reschedule** as locked off with a link to **Edit in Knowledge Base**. The lock changes the effective action without deleting the saved row-level setting. Allow the action in the Knowledge Base first, then return to the catalog to review which individual Job Types and Business Units are enabled. The row-level **All** control changes only the actions that are not locked by the Knowledge Base. A saved catalog toggle cannot override a team-wide Knowledge Base handling rule. ## Tags Open **Tags** to import and configure ServiceTitan tags. * **Include in Job Tags** controls whether the tag is available in supported job-tag behavior. * Additional **Reschedule**, **Cancel**, or **Hide Appointment** controls appear only when the corresponding feature is enabled. * **Enable All** turns on every available tag toggle for every imported tag. Review the entire list before using this bulk action. Prefer importing selected tags. Removing all synced records or enabling every tag can affect several products at once. ## Service Areas Open **Service Areas** to group the ZIP or postal codes your team serves. ### Add an area manually 1. Choose **New Service Area**. 2. Give the area a clear operational name. 3. Add comma-separated ZIP or postal codes, or use **Import from CSV** on the area card. 4. If a timezone selector is available, choose a timezone or leave it set to inherit the team's timezone. 5. Choose **Save Changes**. Wildcard patterns are supported. For example, `*` matches all codes, `90*` matches US ZIP codes from 90000 through 90999, and `M5V*` matches Canadian postal codes beginning with M5V. Use the narrowest pattern that represents the actual service boundary. ### Import ServiceTitan zones For ServiceTitan teams, you can import a zone as a new service area or add its valid ZIP codes to an existing area. You can also associate one or more ServiceTitan zones with an area. After saving the associations: * **ST Sync** runs the same zone-to-ZIP update used by nightly sync. * **Sync nightly** keeps associated areas updated automatically. * **Allow sync to remove zips** also removes codes that no longer exist in the associated ServiceTitan zones. Leave **Allow sync to remove zips** off until you have verified the zone associations. Turning it on can shrink a live service area during the next sync. Use **Export to CSV** when you need a reviewable copy of the current service areas. Deleting a service area also deletes all booking windows associated with it after you save, and the action cannot be undone. Review those booking windows before typing `DELETE` to confirm removal. ## Validate a catalog or geography change 1. Confirm that the intended record exists in the CRM and is imported into Avoca. 2. Review its definition and enabled actions. 3. Check the relevant Booking Windows, Capacity, campaign, or Responder configuration. 4. Test one customer who should qualify and one who should not. 5. Confirm the resulting booking or routing in the CRM. If a CRM record disappears or changes name, correct it in the CRM first, then sync again. If a service area is unexpectedly empty, review manual removals, wildcard syntax, zone associations, and the setting that permits nightly sync to remove ZIP codes. # Complete business compliance Source: https://help.avoca.ai/business-info/compliance Provide the business, representative, policy, and opt-in evidence carriers require for messaging and voice registration. Open **Settings → Business Info → Compliance**. Complete all five sections so Avoca can use the information when registering your business for supported messaging and voice traffic. Use exact legal information. Carrier verification can be delayed or rejected when names, addresses, registration numbers, policies, or opt-in evidence do not match. ## 1. Business Information Enter the legal business details shown in the form, including: * legal business name and an optional public DBA * an HTTPS business website * legal structure and A2P company type * industry * business registration number, such as an EIN * stock exchange and ticker when the selected company type requires them Use the legal name and registration number exactly as they appear on government records. ## 2. Business Address Enter the primary physical business address. The form supports US and Canadian addresses and requires the appropriate state or province and postal code. Do not enter a temporary address solely to complete the form. The address should correspond to the registered business. ## 3. Authorized Representative Enter the first and last name, business email, direct phone number with country code, job position, and business title of the person authorized to represent the company. That person may need to respond if Twilio or a carrier sends a verification email or text. Use an actively monitored business email and phone number. ## 4. Policy URLs Add public HTTPS links to your **Terms & Conditions** and **Privacy Policy**. 1. Confirm both pages are published and accessible without signing in. 2. Confirm the terms include the applicable SMS and calling consent language. 3. Confirm the privacy policy explains how phone numbers and messaging data are used. 4. Choose **Verify & Save** to run the displayed checks. **Save Only** stores the URLs without completing verification. The section is counted as complete only after its status is **Verified**. A status of **Pending**, **Needs review**, or **Failed** requires follow-up. ## 5. Opt-in Screenshots Upload up to five screenshots that show how a customer consents to receive SMS messages. Include the consent language and enough surrounding context to make the opt-in flow understandable. Choose **Analyze & Save** to run the displayed compliance checks. **Save Only** stores the screenshots without making the section verified. Do not upload passwords, API keys, identity documents, or unrelated customer data. Capture only the opt-in experience needed for review and redact unrelated personal information. ## Use the templates carefully The page includes copyable examples for a privacy policy, terms and conditions, opt-in language, and an A2P message flow. Replace every placeholder and have your legal or compliance owner review the final text before publishing it. The templates are general examples, not legal advice. The **Opt-in Screenshots** section also shows a read-only **Example of a compliant opt-in** built from the business name and policy URLs already entered on the page. Select **Download** to save the example as a PNG for your web developer. Use it as a layout and disclosure reference; adapt the live website form to the business's actual customer-care and marketing use cases, then upload screenshots of that real opt-in flow for verification. ## Read progress and verification states The progress bar counts a section only when its required data is complete. Policy and opt-in sections also need successful verification. Open any incomplete or failed pill to review its details, make the smallest correction, and verify again. If verification continues to fail, confirm that the pages are public, use HTTPS, contain the required disclosures, and match the uploaded evidence. Then contact Avoca Support with the verification summary; do not send representative details or registration documents through an unapproved channel. # Configure fees and holidays Source: https://help.avoca.ai/business-info/fees-and-holidays Add booking exceptions, fee conditions, holiday fee overrides, and promotions without using deprecated fee rulesets. Fees and holidays are separate settings that work together: a holiday changes booking behavior for a date, while a fee controls what Avoca communicates or applies when its conditions match. ## Add a holiday Open **Settings → Business Info → Booking Windows → Holidays**. 1. Select the year you want to review. 2. Choose **Add Holiday**, or **Import** to select supported public holidays. 3. Enter the holiday name and date. 4. Choose the booking behavior: **No Booking**, **Regular Booking**, or **Emergency Only Booking**. 5. Set transfer behavior when that option is available. 6. If the holiday applies only to certain work, scope it to the intended service and appointment types. 7. Save the holiday and leave it enabled only when it should affect live availability. The holiday list shows whether each entry is enabled, its booking mode, what it applies to, and transfer behavior. Use the year controls to review future dates before the seasonal schedule starts. Add Holiday dialog with booking and transfer configuration ## Configure a fee Open **Settings → Business Info → Fees → Fees**, then choose **Add Fee** or open an existing fee. 1. Give the fee a clear internal name and customer-facing amount or wording. 2. Add or edit the fee's **Applications** or conditions. 3. Select only the conditions required for that fee. 4. Save and confirm the Applications count on the fee list. Available conditions can include call time, days of the week, booking windows, job types, and—when enabled—driving distance. Every condition on one application must be satisfied for that application to match. An omitted condition does not restrict the fee. The separate **Rulesets** tab under Fees is deprecated and disabled. Configure fee conditions directly on each fee; do not build a new workflow around the old fee-ruleset page. Capacity Planning also has a tab named **Rulesets**. Those rules adjust capacity and are unrelated to fees. ## Add holiday fee behavior Use the currency action on a holiday or the **Holiday Fees** tab to map a normal fee to the fee that should apply on that holiday. Review the base fee and override fee carefully; a holiday override can change the fee without changing the normal fee. A holiday fee **replaces** the matching base fee for that date; it is not added on top of it. If no holiday override is assigned, the base fee remains in effect. Edit Holiday dialog with an emergency-only booking mode and fee overrides Use **Promotions** for supported promotional fee behavior. Keep promotion dates and eligibility narrower than the underlying fee so the normal fee remains the fallback. ## Verify the result Test at least these cases before relying on the configuration: * A normal day that should use the base fee * A matching holiday date * A service or appointment type inside the holiday scope * A service or appointment type outside the scope * A fee condition that should match and one that should not Fees and Holidays are permission-gated. If either tile or tab is missing, ask a team admin to confirm that Scheduling or Fees is enabled and that your role has access. # Manage members, employee contacts, and SSO Source: https://help.avoca.ai/business-info/members-and-sso Control dashboard access, operational contact records, and SAML Single Sign-On from Business Info. Open **Settings → Business Info → Members**. Depending on your team's configuration, the page has **Team Members**, **Employee Contacts**, and **Single Sign-On** tabs. Members requires the Members feature and the appropriate settings permission. Single Sign-On appears only for teams with SSO configuration enabled. ## Team Members: dashboard access Use **Team Members** for people who need to sign in to Avoca. To add someone: 1. Enter their work email address in the invite form. 2. Select the least-privileged role that covers their work. 3. Review any available custom permissions. 4. Send the invite. 5. Use the **Invited** tab to resend or revoke a pending invitation. Admins with the required permissions can change another member's role, review or edit permissions, update their display name, and remove them. You cannot change your own role or remove yourself from this page. If ServiceTitan agent mapping is available, link the dashboard member to the correct ServiceTitan agent. Do not use that mapping as a substitute for an Employee Contact record. To configure defaults across an enterprise or team, preserve individual exceptions, or reset a member to inherited permissions, see [Set enterprise and team role defaults](/business-info/role-permission-defaults). For the starting Coach permission matrix and scorecard troubleshooting, see [Invite managers and agents to Coach](/coach/access). ## Employee Contacts: routing and delivery **Employee Contacts** are operational records. A contact can receive calls, texts, emails, reports, on-call broadcasts, or other notifications without needing dashboard access. For each employee, verify: * Name, email, and phone number * Active status * Department and service-area assignments * On-call and backup status * Relevant email, text, and call preferences * Home ZIP when distance-based on-call routing is used * CRM employee or technician mapping, when available In the employee editor, use **Service Areas** to control which area-matched Responder emails the contact receives. Leaving the area list empty makes the contact eligible for all configured areas. **Catch-all (unmatched area only)** is different: it sends only when a call matches no service area. Turning catch-all on overrides and disables the individual area choices; saving in that state clears the contact's saved area links. Do not turn on catch-all as a shortcut for “all service areas.” It excludes calls that match a configured area. Use an empty area selection for all areas, or select the exact areas the employee owns. You can add contacts manually, sync available ServiceTitan technicians, and use the CSV tools shown on the page. Deactivate a former employee instead of repurposing their record; historical activity can continue to reference it. Team Members and Employee Contacts are different. Inviting a dashboard user does not automatically make them an alert or on-call recipient, and creating an Employee Contact does not grant dashboard access. ## Single Sign-On The **Single Sign-On** tab configures SAML SSO through Avoca's identity service. Coordinate the setup with your identity-provider administrator and Avoca before enforcing it. A safe rollout is: 1. Configure the SAML connection using the values shown in Avoca and your identity provider. 2. Add the work email domain that should use the connection. 3. Complete any requested domain-verification step and confirm the domain shows as verified. 4. Enable SSO without making it the only sign-in method. 5. Test with a non-admin user in a private browser session. 6. Only then enable **SSO-only** if your organization requires it. When SSO-only is enabled for a matching domain, email-code and password sign-in are blocked for those users. Keep a tested recovery plan and do not remove the final working administrator until the new configuration is verified. # Set up the On-Call Calendar Source: https://help.avoca.ai/business-info/on-call-calendar Configure emergency recipients, coverage schedules, broadcast history, and on-call routing. Open **Settings → Business Info → On-Call Calendar**. The feature must be enabled for the team, and your role needs the dedicated **View On-Call Calendar** permission. When **View On-Call Calendar** has no explicit enterprise, team, or individual setting, it follows the member's Scheduling access. An explicit setting controls it separately. Review the resolved permission when editing [role defaults or individual permissions](/business-info/role-permission-defaults). ## Understand the tabs * **Recipients:** departments and Employee Contacts eligible for on-call work * **Schedule:** manual shifts and supported ServiceTitan shift sync * **Emergency Hours:** designated emergency windows when that behavior is enabled * **Broadcasted Messages:** sent notifications and confirmation state * **Configuration:** routing, delivery channels, notification triggers, backup timing, and message behavior ## 1. Prepare recipients Start on **Recipients**: 1. Create or review the departments used for emergency routing. 2. Open **Employee Contacts** and verify each on-call employee's phone, email, department, active status, and delivery preferences. 3. Add a Home ZIP if your team uses distance-based routing. The page warns when a scheduled employee has no department. Fix that warning before relying on department-based routing. ## 2. Build the schedule Use **Schedule** to assign eligible Employee Contacts to the appropriate on-call coverage periods and departments. Check for gaps and overlaps, and confirm that the intended person is active before saving. Schedules depend on Employee Contacts, not dashboard Team Members. Adding a user to Avoca does not put them on the on-call schedule. For an on-call recipient, confirm the employee's on-call notification preference is enabled. Phone-call delivery also requires the employee's **Receive Call** preference. ### Assign roles deliberately * **Technician:** receives the emergency job notification during the scheduled shift and can confirm receipt; assignment behavior depends on the team's CRM configuration * **Manager:** receives emergency-call notifications for oversight during the manager's scheduled coverage * **Backup:** receives an escalation when the primary technician does not confirm within the configured delay The notification-hours filter is evaluated when each alert is sent for managers, technicians, and backups. Technician matching and assignment can still depend on the appointment time and assignment mode. Use a controlled test to validate both decisions. ### Prepare the ServPro customer-to-technician handoff For ServPro teams using the Cotality DASH booking workflow, Avoca can enable an opt-in two-way group text after a confirmed booking. The thread introduces the customer to the one eligible technician active on the on-call schedule at that moment so they can coordinate next steps directly. It runs at any hour and does not replace the internal post-job notification thread. Before Avoca enables this rollout for a team: 1. Maintain continuous technician coverage with no gaps or overlaps in the applicable on-call department. 2. Give each eligible technician a name and a valid US or Canadian mobile number. On legacy calendar configurations, also enable the technician's **Receive Text** preference. 3. Confirm that the customer and technician are allowed to see each other's phone numbers in the group thread. 4. Provide an approved HTTPS self-help resource for each applicable ServPro Division when the introduction should include one. 5. Run a controlled DASH booking and confirm the intended technician, introduction, and optional resource link. The introduction is suppressed when no eligible technician is active, when more than one eligible technician is active in the configured scope, or when the customer phone number is not a valid US or Canadian number. A missing Division resource does not suppress the introduction; Avoca sends it without the resource paragraph. Delivery is best-effort and a text failure does not reverse or block the DASH booking. This group thread exposes the customer's and technician's phone numbers to each other. Use an approved business mobile number for the technician, verify the team's communication policy, and correct coverage gaps or overlaps before relying on the handoff. Replies are direct coordination between the participants and should not be expected to appear in Avoca. Avoca manages the tenant-level rollout, Division resources, and optional department scope. When a dedicated group-text department is configured, its technicians can be excluded from the separate automated outbound on-call dial set. Contact Avoca Support to review or change that configuration; it is not controlled by the team-level **On-Call Calendar** page. ### Sync ServiceTitan on-call shifts When ServiceTitan sync is available: 1. Open **Schedule** and choose **Sync from ServiceTitan**. 2. Select all eligible technicians or a reviewed subset. 3. Set the lookahead window from 1 to 60 days; the default is 7. 4. Choose whether shifts should sync periodically. 5. Run **Sync now** and review the created schedules. Avoca pulls supported ServiceTitan OnCall technician shifts. Manual Avoca schedules are left in place. Changes and deletions in the synced ServiceTitan range are reflected by later syncs. Syncing is not a substitute for reviewing coverage. Confirm departments, roles, dates, and timezones after every material ServiceTitan schedule change. ## 3. Define Emergency Hours **Emergency Hours** appears when designated emergency windows or the emergency-hours notification filter is enabled. Enable the applicable days, set one start and end time for each, and save. An overnight period is supported when the end time is earlier than the start time. Do not use identical start and end times; the page treats that row as invalid. ## 4. Review Broadcasted Messages Use **Broadcasted Messages** to audit emergency broadcasts, recipients, and confirmation state. This is a history view: new entries appear when on-call notification fires for an emergency call. If a person did not receive a message, verify their Employee Contact details, department, schedule, delivery preferences, and the active configuration before sending another notification. ## 5. Configure routing and message behavior Use **Configuration** for the options enabled for your team, such as: * Whether on-call notifications are enabled * Business-hours, after-hours, or emergency-hours notification filtering * Text and phone-call delivery by role * Which job situations notify technicians, managers, and backups, including cancelled appointments (technicians who are on call when the appointment starts; managers who are on call when the cancellation call happens) * Backup escalation timing * Emergency message templates and recording-link behavior * Technician assignment strategy * Override and distance-based routing behavior Available controls vary by rollout. Follow the descriptions in the dashboard and change one behavior at a time. For **Notify on-call recipients during**, choose **No filter**, **Business hours only**, **After hours only**, or **Emergency hours only** when those options are available. Every recipient is checked against the current moment when the alert is sent, not the appointment start time. Delayed technician or backup attempts are checked again when their alert is due, so an escalation can be skipped if the configured hours boundary has passed. For a new configuration, manager text notifications for emergency bookings, emergency calls without a booking, regular booked and unbooked jobs, non-service calls, and same-day dispatch start enabled. Manager phone delivery starts off. Technician text delivery starts enabled, but the **emergency without a booking** event starts off while the emergency-booked event starts on. Existing teams keep their saved settings. Review every role, channel, and event toggle before the first save. Defaults are a starting point for a new team, not evidence that recipients, schedules, or escalation ownership are ready. ### Limit manager escalation by department Under **On-Call Escalation (Multi-Cycle)**, **Escalate to manager when unconfirmed** can notify an on-call manager after the configured primary and backup attempts go unconfirmed. Turn on **Filter manager escalation by department** only when on-call departments are enabled and every relevant manager is attached to the departments they cover. With the filter on, Avoca notifies only on-call managers attached to the call's department. If the call has no department, or no scheduled manager matches it, Avoca skips the manager escalation instead of notifying an unrelated manager. Leave the filter off when the team uses a shared manager pool across departments. ### Choose how multiple on-call technicians are assigned When **Use On-Call Calendar** returns more than one eligible technician for the same department, choose one tie-breaking method under **Tech Assignment**: * **Round-robin assign among on-call techs:** rotates new jobs through the matching technicians for that department. When departments are not used, Avoca rotates through the team's matching on-call pool. * **Route to nearest on-call tech by ZIP:** assigns the matching technician whose Home ZIP is closest to the customer's ZIP. Keep every eligible technician's Home ZIP current under **Employee Contacts**. The two controls are mutually exclusive. Turning on one turns off the other. Round-robin applies to the **On-Call Calendar** strategy; it does not change the **Use Capacity** strategy. New configurations default to round-robin. Existing teams retain their saved behavior until an administrator enables it. When neither method is enabled, or the selected method cannot resolve a technician, Avoca falls back to the first eligible technician in alphabetical order. On-call changes can affect live emergency routing immediately. Verify the team's timezone, departments, schedule, and message template, then run an approved test before the next on-call period. ## Test the complete escalation 1. Create a short approved test shift with a technician and backup. 2. Confirm the employee phone and notification preferences. 3. Place an after-hours call that meets the emergency criteria. 4. Confirm the intended text or phone call arrives. 5. Open the confirmation link when testing acknowledgement. 6. Verify the primary assignment or CRM result. 7. When safe, test the backup delay with the primary test recipient not confirming. 8. Review the event under **Broadcasted Messages**. Remove temporary shifts and test CRM records after validation. # Business Info overview Source: https://help.avoca.ai/business-info/overview Use the Business Info hub to manage the business data, people, schedules, and operating rules Avoca relies on. Open **Settings → Business Info** in the Avoca dashboard. The page is a hub of tiles rather than one long settings form. The tiles you see depend on your team's enabled products and your permissions. A saved URL does not bypass those requirements. Business Info settings tiles for knowledge, booking, CRM data, alerts, members, and capacity ## Choose the right source of truth | Tile | Use it for | | - | - | | **Knowledge Base** | Business hours, policies, services, memberships, emergency guidance, and other facts Avoca's assistants use with customers. | | **Brand Kit** | Approved logos, colors, and images used by supported creative tools. | | **Job Types**, **Business Units**, and **Tags** | Review and configure the CRM catalog records Avoca can use. Business Units and Tags are shown for ServiceTitan teams. | | **Service Areas** | Define the ZIP or postal-code patterns the team serves. | | **Booking Windows** | Map service and appointment types and define when appointments can be offered. The **Holidays** tab adds exceptions. | | **Fees** | Define customer-facing fees, the conditions on each fee, holiday overrides, and promotions. | | **Members** | Manage dashboard access, employee contacts, and Single Sign-On when enabled. | | **Team Alerts** | Route internal operational alerts to selected recipients. | | **On-Call Calendar** | Maintain emergency recipients, schedules, broadcast history, and on-call behavior. | | **Skills** | Review technician eligibility and the skills read from ServiceTitan when the Skills product is enabled. | | **Capacity Planning** | Review and configure the capacity Avoca uses to decide which appointment windows are available. | | **Compliance** | Manage available messaging compliance and opt-in settings. | | **Brand Onboarding** | Review the business, messaging, and voice registration work used by supported phone channels. | The CRM remains the source of truth for its catalog and customer records. The Business Info pages control how Avoca interprets or uses those records. If a job type, business unit, tag, or technician is missing, correct or sync the CRM record before creating a duplicate in Avoca. ## Make a safe change 1. Confirm the team name in the dashboard. 2. Open the relevant Business Info tile. 3. Record the current setting before changing live booking, routing, fee, or notification behavior. 4. Save the smallest required change. 5. Test the affected scenario in the appropriate Avoca testing surface. 6. Check the resulting call, message, booking, or alert. Business Info is shared by several Avoca products. A change to hours, service areas, catalog mappings, fees, or capacity can affect live customer conversations immediately. ## If a tile is missing Confirm that you selected the right team, that the product is enabled, and that your role has the relevant view or edit permission. Ask a team admin or Avoca Support for access rather than using another team's configuration as a workaround. # Set enterprise and team role defaults Source: https://help.avoca.ai/business-info/role-permission-defaults Set starting permissions for Admins, Members, and Agents, customize exceptions, and reset users to inherited defaults. Use role defaults when people with the same team role should start with the same permissions. Set a shared starting point across an enterprise, then customize a team or an individual member when needed. These are overridable defaults for **Admin**, **Member**, and **Agent** team roles. Enterprise workspace permissions and access granted through portfolio membership are managed separately. Products and features must still be enabled for the team. ## Understand which settings apply Permissions inherit in this order, with more specific saved settings taking precedence: | Level | Applies to | | - | - | | Avoca role defaults | The starting permissions for each role | | Enterprise defaults | That team role across the enterprise's teams | | Team defaults | That role on one team | | Individual overrides | One team member | For example, an enterprise can turn **View Calls** off for Members, and a team can turn it on for its Members. A member on that team inherits access unless their individual permissions explicitly turn it off. Changing a default affects existing members who inherit that permission as well as future members. Existing saved individual customizations remain in place. Some members may have a complete set of saved permissions from earlier edits; changing defaults will not replace those saved values. ## Set defaults for an enterprise You need an enterprise **Admin** role with **Manage Members** permission and access to the enterprise's Members page. 1. Select the enterprise workspace and open **Members**. 2. Select **Team role defaults**. 3. Choose **Admin**, **Member**, or **Agent**. 4. Change the permissions that should apply to that role across the enterprise's teams. 5. Review the changes and select **Save Changes**. Team and individual overrides continue to take precedence over these defaults. ## Customize defaults for one team You need **Edit Permissions** and access to the team's Members page. You can edit defaults for roles at or below your own: Admins can edit all three roles, Members can edit Member and Agent defaults, and Agents can edit Agent defaults when granted **Edit Permissions**. 1. Select the team and open **Settings → Business Info → Members → Team Members**. 2. Select **Role defaults** and choose a role. 3. Change the permissions that should differ for this team. 4. Select **Save Changes**. Permissions without a custom setting continue to inherit the enterprise's defaults, or Avoca's role defaults when no enterprise setting applies. In the editor, **Custom** marks an explicit choice at the level you are editing; **Inherited** marks a value supplied by its defaults. To remove all custom settings for the selected role at that level, select **Use inherited defaults**, review the resulting permissions, and select **Save Changes**. At the team level this restores enterprise or Avoca defaults; at the enterprise level it restores Avoca defaults. Select **Cancel** to discard the draft. ## Customize or reset an individual member Use individual overrides for exceptions to the team's role defaults. An authorized member can open **Edit Permissions** for another member at or below their own role. Permissions can also be customized while preparing an invitation. To return an existing member to their current role defaults: 1. Open **Team Members** and select **Edit Permissions** for that person. 2. Select **Reset to role defaults**. 3. Review the resulting permissions. This clears all of that member's individual overrides, so access can increase or decrease. 4. Select **Save Changes** to apply the reset, or **Cancel** to keep the existing settings. After a saved reset, the member follows the current team and enterprise defaults. Future default changes continue to apply to permissions without individual overrides. ## Check the result Ask the affected member to refresh the dashboard and confirm the pages and actions they need. Viewing a page and editing its settings can require separate permissions. * **A default change did not affect someone:** check their individual overrides and any team defaults that take precedence. Reset only if they should follow the role defaults. * **The defaults button or a role is unavailable:** confirm the selected workspace, your permission-management access, and your role. The available controls depend on your access. * **Saving reports that role defaults changed:** another administrator saved changes after you opened the editor. Reopen it, review the latest defaults, and apply your changes again. * **A page is still unavailable:** check the team's products and features as well as permissions. See [Understand access and feature visibility](/getting-started/access-and-visibility). For invitations and SSO, see [Manage members, employee contacts, and SSO](/business-info/members-and-sso). For the starting Coach permissions, see [Invite managers and agents to Coach](/coach/access). # Review technician skills Source: https://help.avoca.ai/business-info/skills Use the Skills pages to audit ServiceTitan technician eligibility by job type, business unit, and skill. Open **Settings → Business Info → Skills**. This tile appears only when Skills is enabled and your role has access. Technician skills are read directly from ServiceTitan. ServiceTitan is the source of truth; the legacy sync and manual skill-management controls shown on these pages are not required for current capacity and backend behavior. ## Review technicians The **Technicians** tab lists each technician's business unit and skills. Use the filters to answer different questions: * **Filter by Job Type** shows technicians who hold every skill required by that job type. A job type with no required skills is shown as open to all technicians. * **Filter by Business Unit** narrows the list to one or more units and can surface technicians with no assigned unit. * **Filter by Skills** finds technicians who have all selected skills and can surface technicians with no skills. When a job type is selected, the page separates technicians who can run the job from those who cannot and lists the missing skills for each ineligible technician. ## Correct missing or incorrect skills 1. Confirm the technician, business unit, and required job type in ServiceTitan. 2. Correct the skill assignment in ServiceTitan. 3. Return to Avoca and reload the Skills page. 4. Select the job type again and confirm that the technician moves to the expected eligibility group. 5. Re-test the related capacity or dispatching scenario. Do not use **All Skills** edits as the source of truth for current capacity decisions. That tab maintains a legacy Avoca copy, and the page explicitly notes that its changes do not affect capacity or other backend features. Avoid using the legacy periodic-sync, request-sync, duplicate-removal, or manual assignment controls as a substitute for correcting ServiceTitan. They can make the page appear different without fixing the data current product logic reads. If a technician remains missing after the CRM record is correct, verify that you selected the correct Avoca team and ServiceTitan tenant, then contact Avoca Support with the technician and job-type identifiers. Do not include CRM credentials. # Configure Team Alerts Source: https://help.avoca.ai/business-info/team-alerts Send internal operational alerts to the right recipients, optionally by service area and Microsoft Teams. Open **Settings → Business Info → Team Alerts**. This page is available when Team Alerts is enabled and your role can view workflows. Team Alerts are internal operational alerts. They are not the same as: * **Settings → Notifications**, which controls operational email behavior for calls and texts * **Outbound → Customer Notifications**, which sends customer-facing SMS from eligible ServiceTitan events * The **Notifications** tabs under the main Messages channel, Google LSA, and Yelp, which are legacy read-only summaries. Configure their recipients in Team Alerts. ## Configure an alert 1. Find the relevant section and alert card. 2. Turn on the alert. 3. Open its editor and choose the recipients. 4. Apply the available workflow type, lead source, or service-area conditions. 5. Save and confirm the card summary reflects the intended rule. Sections can include **Outbound**, **Speed-to-Lead**, **Dropped Responder**, **Web Chat**, **Google LSA**, **Yelp**, and **Call Volume**. A section can be unavailable when its underlying product is not enabled. ## Use service-area-specific recipients Turn on **Enable service areas** only when different locations need different recipients. With it off, the configured recipients apply across service areas. With it on, review every active area so a newly added location does not inherit the wrong coverage. Some Speed-to-Lead rules can automatically apply to newly created lead sources. Use that option only when the same recipient policy should cover future sources. ## Microsoft Teams delivery If Microsoft Teams delivery is enabled for the team, the page can show a Teams webhook setting for a section. Treat the webhook as a secret, use the intended channel, and send a controlled test after saving. Team Alerts uses Employee Contacts and other available recipient records. If someone is missing, first confirm that their contact is active and has a valid email address. ## Troubleshoot a missing alert Check, in order: 1. The alert and its product section are available and enabled. 2. The event matches all saved conditions. 3. The lead source, workflow type, and service area are correct. 4. The recipient is active and has valid contact information. 5. The alert was not expected from a different notification system. # Review booked calls Source: https://help.avoca.ai/calls/booked-calls Find calls that resulted in a booking, inspect the call details, and export a date range. Open **Channels → Booked Calls** to focus on calls that resulted in a booking. This page appears only when it is enabled for your team. ## Find and inspect a booking 1. Set the date range in the upper-right corner. 2. Browse the rows and use pagination to move through the selected period. The table shows date, customer name, phone number, street address, and ZIP code. 3. Select a row to open the full call details. 4. Review the recording, transcript, outcome, and booking information available for that call. Use **Export CSV** to download all booked calls in the selected date range. The export uses the current team and dates, so confirm both before sharing it. **Booked Calls** is a focused operational list. Use [Calls](/calls/review-calls) or [Call Flows](/calls/call-flows) when you need all calls, additional filters, or funnel analysis. # Understand Call Flows Source: https://help.avoca.ai/calls/call-flows Use the newer call workspace to see who handled a call, how it routed, and whether it booked. **Call Flows** is the newer call workspace. Its purpose is to show every call across your enabled phone channels—who handled it, how it routed, and whether it booked. Open the newer call workspace: * If **Channels** contains two items named **Calls**, select the one marked **NEW**. * If your rollout labels the newer item **Call Flows**, select **Channels → Call Flows**. The correct workspace opens the **Call Flows** page at a `/call-flows` dashboard path. The unbadged **Calls** item and **Calls → Avoca Calls** open the legacy workspace. ## Choose a call view The current Call Flows tabs are: * **All Calls:** the full call-flow dataset available to the team * **Responder:** calls associated with Responder * **Outbound AI:** calls associated with Outbound AI The tabs apply a product scope; page filters narrow that scoped population further. ## Analyze call traffic Use the date range and available filters to narrow the table. Current Call Flows data can support filters and columns such as: * Direction and call type * Assistant or agent * Handled By * Transfer destination * Call reason and bookability outcome * Service area * Customer and phone details * Duration and date Metrics and the flow visualization summarize how calls moved through handlers and outcomes. The available cards are restricted to metrics that can be calculated safely from Call Flows data. Select a Sankey path or metric card only when you want to narrow the call population. Clear the resulting selection before comparing it with an unfiltered table total. Select a call to inspect details such as: * Recording, summary, and transcript * Handler chain and routing steps * Disposition, classification, and booking outcome * Customer and call metadata * Relevant CRM or Avoca reasons The handler chain is especially useful when a call moves between an AI agent, a transfer destination, and another phone-system handler. ## Read handler and transfer fields * **Assistant** identifies the Avoca assistant associated with the call. * **Handled By** summarizes the participant that handled the relevant leg. * **Transfer Destination** identifies the configured external destination when one exists. * **Call Reason** uses the call-flow classification returned for the record. One call can contain several participants or legs. Use the detail view when a table row's final handler does not explain the complete journey. ## Export a result set 1. Set the date range. 2. Apply all required filters. 3. Review the resulting call count. 4. Use the CSV export action. Some teams may also have recording export. Availability depends on call data and user access. ## Call Flows and legacy Avoca Calls The newer **Calls** item and the legacy **Calls → Avoca Calls** page may both appear. They use different analytics data models. Use Call Flows for cross-channel routing, participant, and handler analysis. Use Avoca Calls when you need a legacy field or workflow that has not moved to Call Flows. Legacy-only controls can include experiment, Oversight, processing, note, task, or support fields. Do not expect a filter or saved total from one workspace to reproduce exactly in the other. When sharing a call internally, include the call ID and say whether you found it in Call Flows or Avoca Calls. This makes the same record easier to locate. ## Troubleshoot a missing call 1. Confirm whether the call should be in Call Flows or legacy Avoca Calls. 2. Clear filters and widen the date range. 3. Check the All Calls, Responder, and Outbound AI tabs. 4. Search with the call ID when available. 5. Allow recently completed calls time to process. 6. Record the team, workspace, call ID, time, and active filters before contacting Support. # Review Avoca calls Source: https://help.avoca.ai/calls/review-calls Filter, inspect, and export calls handled through Avoca's call experiences. Open **Channels → Calls** to review the legacy **Avoca Calls** workspace. Some teams also have **Call Flows**, a newer view focused on every handler and routing step. The two experiences can coexist. Use the call page available to your team. Fields and filters can differ between Avoca Calls and Call Flows; one view is not always a complete replacement for the other. ## Find a call 1. Select the relevant date range. 2. Apply the available outcome, agent, reason, or processing filters. 3. Search using a supported customer or call identifier. 4. Adjust visible columns if you need a different table view. 5. Select a row to open the call details. Summary cards and flow visualizations can help narrow a large result set before reviewing individual calls. When enabled, **Soonest availability offered** shows appointment availability alongside booking outcomes, with breakdowns and individual call drilldowns. See [Report on soonest availability](/api-reference/soonest-availability) for dashboard instructions and the corresponding Coach API and CSV fields. When you filter by **Business Hours**, Avoca uses the structured **Business Hours** schedule in the Knowledge Base and the team's timezone. The **View / Edit Company Hours** dialog contains legacy hours that are used only when Knowledge Base business hours are not set. Update the Knowledge Base schedule for the current source of truth, then re-run the filter. ## Review the call details Available details can include: * Audio recording and transcript * Call summary * Disposition and call classification * Booking or bookability outcome * Customer and call metadata * Avoca and CRM reasons * Handler or routing history * Tasks, support activity, notes, evaluations, or revenue data when enabled Listen to the recording when exact wording, timing, audio quality, or transfer behavior matters. A summary is useful for orientation but is not a substitute for the source call. ## Review pre-call transferred calls When enabled for your team, open **Channels → Calls → Pre-call Transferred Calls** to review calls that were forwarded before the normal agent conversation. The metric cards show total transferred calls and the count and percentage attributed to each rule type for the selected date range. Select a rule-type card to filter the table, or select **Total Calls** to clear that filter. Use the available controls to: * Change the date range * Search by caller phone number * Filter by one or more rule types * Refresh the results Each row shows the date and time, caller phone number, matched rule type, and the **Forwarded To** destination. Use that value to confirm that the expected receiving number was selected; it does not by itself prove that the destination answered. Select **Manage Rules** to open **Pre-call Transfer Rules** when you have access to that configuration. Keep this call page focused on outcomes: review and edit rule definitions on the rules page rather than inferring them from the metric labels alone. ## Export results Use the CSV export action to export the filtered result set. The base Calls CSV includes **Action Item** after **Notes**; a blank cell means the call has no saved action item. Recording export may be available for authorized users and supported calls. Before exporting, confirm the date range, filters, and selected columns. Treat exported call data according to your organization's privacy and retention policies. In an enterprise workspace, open **Calls**, apply the intended team and call filters, and choose **Export**. When call-classification reporting is enabled for the enterprise, the CSV includes **Service Type** and **Job Type**. These values are the persisted classifications assigned to each call; a blank value means that call does not have the corresponding saved classification. Other rollout-specific call and Coach exports can add fields such as: * **Is Bookable**, **Is Booked**, **Sub Reason**, and pre-call CRM observations * **Time to Availability (seconds)** * **Non-Booked Disposition Code** and **Non-Booked Disposition** * **ST Call Memo** * **Opportunity ID** and **AI Verified Outcome** for supported enterprise integrations These columns are controlled independently. Their absence does not mean the base export failed, and a blank cell means no value was available for that call. For supported enterprise integrations, **Opportunity ID** can also be a visible Calls-table column and searchable identifier, while **AI Verified Outcome** can be a visible column and filter. Match the workspace, date range, filters, and enabled columns before reconciling two exports. A team export and an enterprise export can legitimately have different optional fields. ## Review booked calls only Open **Channels → Booked Calls** for a focused list of booked calls. This page supports date filtering, CSV export, and call details, with columns such as date, customer name, phone, street address, and ZIP code. For routing analysis across all phone channels, use [Call Flows](/calls/call-flows) when it is enabled. # Invite managers and agents to Coach Source: https://help.avoca.ai/coach/access Choose Coach roles and permissions, invite team members, map agents to ServiceTitan, and troubleshoot access. Coach is most useful when managers can review the team and agents can inspect their own performance without receiving broader access than they need. Open **Settings → Business Info → Members → Team Members** to manage dashboard access. You need the **Invite members** permission to send invitations. The Coach product must also be enabled for the team before invited members can open it. ## Choose the right access pattern Start with the least-privileged role that covers the person's work. An administrator can customize individual permissions before sending the invitation or after the person joins. | Person | Recommended starting role | Typical Coach access | | - | - | - | | Coach owner or team administrator | Admin | Every Coach page, settings, invitations, score editing, and reclassification configuration | | CSR manager or team lead | Member | Overview, all Agent Performance, and call reclassification | | Operations or CX reviewer | Member | Overview, all Agent Performance, and reclassification without settings access | | Frontline CSR | Agent | Their own Agent Performance scorecard | An **Admin** is not required merely to review team performance. Give a Member additional settings or editing permissions only when their work requires them. ## Understand the default Coach permissions Avoca's starting role defaults are shown below. Enterprise defaults, team defaults, and individual overrides can change a member's effective permissions. | Permission | Admin | Member | Agent | | - | :-: | :-: | :-: | | View Coach | On | On | On | | View Coach Overview | On | On | Off | | View Coach Call Recovery | On | Off | Off | | View All Coach Agent Performance | On | On | Off | | View Own Coach Performance | On | On | On | | View Coach Reclassification | On | On | Off | | View Coach Settings | On | Off | Off | | Suggest Bookability Criteria Updates | On | Off | Off | | Edit Call Scores | On | Off | Off | | Edit Reclassification Config | On | Off | Off | An authorized administrator can configure shared defaults or customize an individual member. See [Set enterprise and team role defaults](/business-info/role-permission-defaults) for inheritance order, existing customizations, and resetting a member's overrides. **View Coach Settings** and **Edit Reclassification Config** are separate permissions. A person may be able to open settings without being allowed to change bookability criteria, automatic reclassification, or call reasons. ## Prepare the invitations Before inviting anyone, collect: * Each person's work email address * The role they should receive * Any Coach permissions that should differ from the role default * The correct ServiceTitan agent for anyone who will use **View Own Coach Performance** Decide separately who should be able to edit call scores and who should be able to change reclassification behavior. Keep both groups small so grading and production CRM updates remain controlled. ## Send invitations 1. Open **Settings → Business Info → Members**. 2. On **Team Members**, enter the person's work email. 3. Select **Admin**, **Member**, or **Agent**. 4. For a ServiceTitan agent, select the matching agent record. 5. Review or customize permissions when needed. 6. Add more invitation rows if you are onboarding several people. 7. Select **Send invites**. Team Members invitation form with email, role, ServiceTitan agent, and permission controls If an email already belongs to a member or has a pending invitation, Avoca skips that row and reports how many invitations were sent. ## Track pending invitations Open the **Invited** tab to review outstanding invitations. From this tab, an authorized administrator can: * Resend an invitation * Revoke an invitation * Confirm the selected role and ServiceTitan agent * See when the invitation was created and when it expires Pending team invitation with resend and revoke controls Ask the invitee to check spam or quarantine folders if the message does not arrive. ## Map an agent to ServiceTitan **View Own Coach Performance** uses the member's ServiceTitan agent ID to find the correct Coach scorecard. Set the mapping while sending the invitation, or update the member after they join. Mapping a dashboard member to a ServiceTitan agent is not the same as creating an **Employee Contact**. The member mapping controls Coach identity and dashboard access. Employee Contacts control operational routing and delivery. If an agent sees no performance data: 1. Confirm the member has **View Coach** and **View Own Coach Performance**. 2. Confirm the member is mapped to the correct ServiceTitan agent. 3. Confirm calls exist for that agent in the selected date range. 4. Check whether the calls are attributed to **Unassigned** or a different ServiceTitan agent. ## Verify access after the person joins Ask the new member to sign in and open **Products → Coach**. Verify the result against their job: | They need to… | They should be able to… | | - | - | | Manage team performance | Open Overview and the full Agent Performance roster | | Self-review as a CSR | Open only their linked Agent Performance scorecard | | Correct call disposition | Open supported call details and reclassification controls | | Work missed opportunities | Open Recovery, when enabled | | Configure rubrics and reporting | Open Coach Settings | | Calibrate AI grading | Unlock and edit call-level rubric answers | | Change automatic classification | Edit reclassification configuration | Continue with [Coach overview](/coach/overview), [Analyze agent performance](/coach/agent-performance), or [Configure and analyze rubrics](/coach/rubrics). ## Troubleshoot access ### The invitation email did not arrive Confirm the email spelling, check spam or quarantine folders, and resend the invitation from **Invited**. ### The person signed in but cannot see Coach Confirm that Coach is enabled for the team and that the member has **View Coach**. ### An agent cannot see their own scorecard Confirm **View Own Coach Performance** and the ServiceTitan agent mapping. If the member has no mapping, Coach cannot safely determine which agent page belongs to them. ### A Member cannot open Settings This is Avoca's starting default for Members. Check any enterprise, team, and individual settings, and grant **View Coach Settings** only when the person needs configuration access. ### A manager can view a score but cannot change it Grant **Edit Call Scores**. Viewing all Agent Performance does not imply score-editing access. ### A manager can view settings but cannot change reclassification Grant **Edit Reclassification Config**. This permission controls bookability and booked criteria, automatic reclassification settings, and call reasons. ### The company uses Single Sign-On Configure SAML under **Members → Single Sign-On** when it is enabled for the team. Coordinate provisioning and SSO-only enforcement with the identity-provider administrator and Avoca. See [Manage members, employee contacts, and SSO](/business-info/members-and-sso) for the broader access model. # Analyze agent performance Source: https://help.avoca.ai/coach/agent-performance Compare agent metrics, find agents who need review, inspect coaching insights, and export performance reports. Open **Coach → Agent Performance** to compare agents over the same date range and call population. Agent Performance appears only when it is enabled for your team. A role with "view own performance" access is taken directly to the linked agent's page and cannot browse the team roster. Coach evaluates calls after they end. New calls appear after ingestion, transcription, and scoring; Agent Performance is not a live in-call assistant. Coach call review showing an agent performance evaluation Coach agent performance analytics and coaching detail ## Review the team overview The **Performance Overview** starts with configurable metric cards. The standard metrics are: * **Total Calls** * **Booked Calls** * **Booking Rate** * **Average Score** * **Missed Opportunities:** leads that were not booked * **Positive Sentiment:** the positive share of calls with a sentiment classification Some teams also see **ST Booking Rate**, upsell context, average handling time, or rubric-category metrics. When booking-rate views are enabled for your team, the **Overall booking rate** and **Agent-by-agent booking rate** tabs choose whether a call Avoca transferred to one of your agents without booking counts against Avoca. See [Overall and Agent-by-agent booking rate](/coach/overview#overall-and-agent-by-agent-booking-rate). Use the **Metrics** menu to show or hide cards. Your choices are stored for the browser you are using. Coach Agent Performance team overview metrics ### Open an inline trend Select a metric card to open its trend chart. The chart uses the current filters and compares the selected range with the previous period. Select **View all performance metrics** to open the full **Performance Metrics** page. The full page plots the supported metrics over the selected range and can be exported as a PDF report. ## Filter the population Agent Performance filters can include: * Inbound and outbound direction * Agent group * Specific agents * Booked or unbooked calls * Leads or non-leads * Days of the week to exclude * One or more rubrics The rubric filter scopes every metric on the page to calls graded under the selected rubrics. All rubrics are selected by default. Selecting a strict subset of rubrics changes the metric population, not only the rubric columns. Compare agents only when their filters and rubric scope match. ## Use agent groups Agent groups can appear in one of two ways: * As a filter that narrows the overview and roster to one group * As expandable group rows that aggregate the members' performance The default group can be selected or expanded automatically. Agents who do not belong to a configured group can appear under **Ungrouped**. Group rows summarize their member agents. Open the group to inspect the individuals before drawing a conclusion from the aggregate. See [Configure Coach settings](/coach/settings#agent-groups) to create and maintain groups. ## Find agents who need review Coach can flag an agent as **Needs review** when their booking rate or average score falls into the red band configured for the team. Flagged agents are brought to the top of the flat roster, and the review banner can narrow the list to those agents. The threshold is a prioritization aid, not a performance verdict. Before coaching: 1. Check the number and type of calls in the range. 2. Compare the agent with an appropriate group. 3. Review the agent's missed opportunities and coaching insights. 4. Listen to representative calls. ## Configure and read the roster Search agents by name, choose a sort metric, and use **Columns** to show, hide, or reorder the table. Available columns can include: * Total Calls * Leads * Booked Calls * Unbooked Calls * Booking Rate * ST Booking Rate * Average Score * Average Handling Time * Upsell Calls * Rubric-category scores Not every column is available to every team. For example, ST Booking Rate requires ServiceTitan classification data and handling time requires the relevant timing data. Select **Export** to download the current agent-performance data as an XLSX file. The export follows the current date range and filters. Coach Agent Performance roster with agent metrics ## Open an agent Select an agent's name to open their detail page. The page carries the relevant date range, direction, booking, lead, excluded-day, and rubric context from the roster. An agent detail page contains: * The agent's configurable performance cards * Inline trends and a full Performance Metrics report * **Coaching Insights** * The agent's filtered calls table Individual Coach agent scorecard with performance metrics and coaching insights ### Coaching Insights Coach shows up to five of the agent's most frequently failed rubric items. Each row displays how often the item was missed. Expand an item to see: * The Coach Suggestion * A suggested script when one is available * Recent calls with the issue * A clickable issue timestamp * The item's success-rate trend * The change from the prior period Select **View issue** to open that call directly on the Coaching tab. Select **View all calls with this issue** to open the complete filtered list. Expanded Coach coaching insight with recommendation and related calls ### Full Rubric Performance Select **View score breakdowns by all categories** to open the agent's full Rubric Performance page. The page: * Groups criteria by rubric category * Shows success rate for each criterion * Compares it with the prior period * Supports the current direction and rubric filters * Can be exported as a PDF report See [Configure and analyze rubrics](/coach/rubrics) for the team-wide view and rubric setup. ### Agent calls The calls table supports search, configurable columns, pagination, and direct review. Open a call to: * Listen to the recording * Review the transcript and evaluation * Inspect classification history and customer history * Correct supported rubric answers or call details See [Review a Coach call](/coach/call-review). ## Interpret agent metrics fairly * Compare similar call directions, lead populations, and rubric scopes. * Use a meaningful call sample; a small denominator can create extreme rates. * Separate booking opportunity from booking outcome. * Account for calls attributed to **Unassigned** when CSR mapping is incomplete. * Treat sentiment as a supporting signal, not a substitute for the call evidence. * Use the same date window before and after a coaching intervention. * Review rubric criteria, not only the overall score. ## Give agents access to self-review Agents can review their own scorecard without seeing the full team roster. An administrator should: 1. Invite the person with the **Agent** role or grant **View Own Coach Performance**. 2. Map the dashboard member to the correct ServiceTitan agent. 3. Ask the agent to open **Products → Coach** and confirm the scorecard identity. If the member is not mapped, Coach cannot safely determine which ServiceTitan agent belongs to that user. See [Invite managers and agents to Coach](/coach/access). ## Recommended coaching workflow 1. Filter to the relevant team, group, direction, and rubric. 2. Review agents marked **Needs review**. 3. Open one agent and expand their top Coaching Insights. 4. Listen to multiple calls for the same issue. 5. Share the specific expected behavior and evidence with the agent. 6. Revisit the same metric and rubric item after new calls have accumulated. # Review a Coach call Source: https://help.avoca.ai/coach/call-review Use the recording, transcript, coaching evaluation, activity history, customer history, and supported edit controls on a Coach call. Open a call from the Coach Overview, Agent Performance, Rubric Performance, or a list of calls with a failed rubric item. Coach can open the review in a full page or in a side sheet without losing your place in the list. The exact cards and actions depend on the call data, integrations, enabled Coach features, and your permissions. ## Orient yourself The review header identifies the customer and provides the call recording when one is available. For ServiceTitan-connected calls, the **ServiceTitan** menu can link to the agent scorecard, customer, or job. The page is divided into: * A main review area with **Summary**, **Transcript**, **Coaching**, **Activity**, and **Customer History** * A right rail for customer information, disposition, the ServiceTitan call memo, revenue, tags, recovery tasks, and internal notes when supported Use the call's displayed date, customer, and handler to confirm that you opened the intended record before making a correction. Coach call review with transcript summary and call details rail ## Listen to the right recording A call can contain more than one leg, such as an Avoca AI interaction followed by a human transfer. When the recording control offers a leg selector: * Choose **Full call** for the end-to-end interaction. * Choose an individual leg to isolate the AI or human portion. * Use timestamps in coaching evidence to jump to the relevant point in the recording. If the full recording is sourced from ServiceTitan, it can contain audio that is not present in an Avoca-only leg. ## Use each review tab Coach call review tabs for Summary, Transcript, Coaching, Activity, and Customer History ### Summary The Summary tab presents the call summary and the best available outcome and next-step information. It is the quickest way to understand the call, but it should not replace listening when you are changing a score or classification. ### Transcript Use the Transcript tab to: * Confirm what the caller and agent actually said * Understand the sequence around an objection or booking decision * Validate the CSR assignment * Compare Coach's reasoning with the underlying conversation Transcripts are generated data and can contain recognition errors. Use the recording as the final source when wording or speaker identity matters. ### Coaching The Coaching tab can include: * Talk metrics * Objection-handling analysis * Rubric Grading * An overall score * The rubric selected for the call and why it was selected Rubric categories expand into individual criteria. Each criterion shows: * **Yes**, **No**, or **N/A** * The criterion's points or weight * Coach's reasoning * A suggestion when an improvement was identified * Clickable recording timestamps when available ### Activity Activity records the initial classification and later changes to fields such as call type, CSR, call reason, job, or call memo. Memo entries show a shortened previous and new value when available. Use Activity to distinguish the original Coach result from a later human or automated correction. ### Customer History Customer History shows other supported calls for the customer. Select another call to move through the timeline without leaving the review workflow. Use history to avoid treating one conversation as an isolated event when the customer has called repeatedly about the same issue. ## Review and correct rubric grading The rubric opens in **Locked** mode. 1. Listen to the relevant recording segment. 2. Switch the grading toolbar to **Unlocked**. 3. Select a criterion's answer to cycle between **Yes**, **No**, and **N/A**. 4. Update the reasoning when the evidence needs clarification. 5. Select **Save**. You can also print the evaluation. **Exclude from Grading** sets every rubric item to **N/A** and removes the call from score calculations. Use it only when the rubric genuinely does not apply to the call. The exclusion can be reversed by unlocking the rubric and grading it manually. A call-level rubric edit overrides the evaluation for that call; it does not rewrite the master rubric. If the same criterion is repeatedly misunderstood, update the rubric configuration instead of correcting calls one by one. Coach Rubric Grading panel with criterion results and AI reasoning ## Understand disposition The Disposition card separates: * **Qualification:** Lead or Not a Lead * **Booking:** Booked or Unbooked * **Reason:** the call reason, when applicable Call type and call reason are independent. For example, correcting a call from **Unbooked** to **Excused** does not by itself define the most accurate call reason. Coach can show a review banner when its suggested classification or CSR differs from the current data. Review the evidence before applying or rejecting a suggestion. Coach call review showing AI classification suggestions and review controls ## Edit call details Users with reclassification access can select **Edit call details**. For a supported ServiceTitan call, the editor has two scopes: * **ServiceTitan:** saves the selected changes and attempts to sync supported fields to ServiceTitan * **Avoca only:** updates Coach's record without changing ServiceTitan The editor can include: * CSR * Lead status * Booking status * Call reason * Tags * Linked job * Notes When Coach has proposed changes, the ServiceTitan tab can show each original and suggested value. Check only the rows you want to act on, then choose: * **Apply changes** to use the selected Coach suggestions * **Keep original** to retain the current ServiceTitan values for the selected rows ### Link a booked call to a job For supported ServiceTitan calls, marking a lead **Booked** requires a linked job. 1. Enter the ServiceTitan job number. 2. Select **Locate**. 3. Confirm the customer and job details. 4. Select **Attach this job**. 5. Save the call changes. If a field saves in Avoca but cannot sync to ServiceTitan, the review shows an error. Verify ServiceTitan permissions and retry rather than repeatedly changing other fields. See [Review and automate call reclassification](/coach/reclassification) before enabling automatic production changes. ## Manage tags Coach tags can be edited from the call-details editor. When an applied tag already appears in the right rail, it can also be updated there. * Tags mapped to a ServiceTitan tag can sync to the matching ServiceTitan call. * Unmapped tags remain Avoca-only. * Only tags eligible for the call's group rules are available. See [Configure Coach settings](/coach/settings) for tag-group conditions and ServiceTitan mapping. ## Read the ServiceTitan call memo For supported ServiceTitan rollouts, the right rail shows the current memo mirrored from ServiceTitan. A long memo is shortened to three lines; select **View full memo** to read the complete value. **No memo** means Coach does not currently have a mirrored memo for that call. The memo card is read-only. Use it as operational context alongside the recording, transcript, and Activity history; do not treat it as a replacement for the conversation evidence. ## Add internal notes Use **Internal Notes** for concise operational context that another reviewer needs. Do not copy sensitive information from the transcript unless it is necessary for the approved workflow. Internal notes do not contact the customer and do not replace the ServiceTitan customer record. ## Work recovery tasks from the call When Call Recovery is enabled, the right rail can show recovery tasks associated with the call. You can create a task, open an existing task, and update its status or assignment without leaving the review. See [Manage Call Recovery](/coach/recovery). ## Review checklist Before you close the call: * Confirm you listened to the correct recording leg. * Verify the current qualification, booking outcome, reason, CSR, and linked job. * Compare rubric reasoning with the recording. * Use **N/A** only when a criterion does not apply. * Decide whether the correction belongs in Avoca only or should sync to ServiceTitan. * Record an internal note only when it adds useful context. * Create or update a recovery task if the missed booking requires follow-up. # Use Enterprise Coach Source: https://help.avoca.ai/coach/enterprise Analyze Coach performance across teams and safely copy supported settings from one enterprise team to others. Enterprise Coach aggregates supported call, agent, and rubric reporting across the teams in an enterprise. It also provides team-aware settings pages for rubrics, tags, agent groups, and alerts. Enterprise Coach pages depend on enterprise access and enabled data experiences. Recovery is managed from an individual team's Coach workspace and is not an Enterprise Coach page. ## Review the enterprise Overview Open the enterprise workspace, then select **Coach → Overview**. Use the team selector inside **Filters** to report on: * All eligible teams * One team * A selected subset of teams The team selection is included in the active filter count and appears as a removable filter pill when it narrows the enterprise. The Overview can include: * Total Calls * Leads * Booked Calls * Booking Rate * Average Score * Average CSAT and Average FCR when survey data exists * Initial Booking Rate and Post Booking Rate * Call-performance trends * Top unbooked reasons * Top failed rubric items * Supported breakdowns Other Coach filters can be applied together with the team selection. Use **Clear all** to restore the default filter state and all eligible teams. When ServiceTitan memo reporting is enabled for the enterprise, **Filters → ServiceTitan Call Memo** can limit the current population to calls with or without a mirrored memo. The same rollout adds the memo column and read-only memo card when you open a call. It can be enabled independently from the team-level Coach experience. ### Group Team Performance by service type When service-type reporting is enabled for the enterprise, use **Group by → Service Types** above **Team Performance** to replace the team rows with service-type rows for the current date range and filters. Each row can show: * Total Calls * Leads * Booked * Booking Rate, calculated as booked calls divided by leads * Transferred * External Transfer Rate, calculated as calls transferred to your team divided by total calls * Recovered Calls without a persisted service-type classification appear in **Unclassified**. Keep that row in the total when reconciling the table; a large Unclassified population means the service-type rows are not a complete view of the enterprise's classified work. Use **Group by → Teams** when you need location-level accountability. Service-type grouping answers which kinds of work drive the outcome, while team grouping answers where the outcome occurred. ### Group Unbooked Reasons by service type When the same service-type experience is enabled, the **Unbooked Reasons** table has its own **Group by** control. Choose **Service Types** to replace the team rows with service-type rows for the current date range and filters. Each row shows total unbooked calls and, for **Call Back Later**, **Price Concern**, **Time Concern**, **Reject Agent**, and **Other Unbooked**: * The number and percentage of unbooked calls * The number later recovered The footer keeps the enterprise total and the recovery booking-rate impact for each reason group. Calls without a usable classification appear under **Unclassified**; include that row when reconciling the table. The **Group by** controls for **Team Performance** and **Unbooked Reasons** are independent. Set each table to the view needed for the question you are answering. ## Analyze enterprise agent performance Open **Agent Performance** to compare CSRs across the enterprise. Agents are grouped by name across teams. The page can include: * Enterprise performance cards and previous-period trends * Agent groups as a filter or expandable group rows * Direction and rubric filters * Rubric-category score columns * An XLSX export of the current agent rows Two different people with the same agent name can be aggregated as one enterprise agent. Keep agent naming consistent and unique across teams when enterprise-level attribution matters. Select an agent to open: * Their enterprise-wide performance cards * Full metric trends * Coaching Insights aggregated across teams * Calls handled by that agent name * Agent-level Rubric Performance When you open a call from the enterprise view, the review uses the call's owning team so supported edits and ServiceTitan links resolve in the correct context. ## Review enterprise Rubric Performance Open the full rubric view from **Top Failed Rubric Items** or an agent's Coaching Insights. You can: * Filter the analysis to selected teams * Filter calls by direction and other supported Coach fields * Review success rate and prior-period change by category and criterion * Expand a criterion for Coach Suggestions, recent calls, and its trend * Open every call where the criterion was missed Enterprise rubric options are deduplicated for analysis when rubrics share a title and direction across teams. Maintain equivalent rubric definitions if you expect their scores to be compared as one enterprise concept. ## Configure settings by source team Enterprise Coach Settings includes: * Rubrics * Tags * Agent Groups * Alerts & Reporting Each page uses a selected source team. Edit that team's configuration first, save it, and then use the available copy control when you intend to distribute it. Copy operations use the saved configuration. If the page has unsaved edits, save them before copying or explicitly choose the offered save-and-copy flow. ## Copy rubrics You can copy one saved rubric or all saved rubrics from the source team to selected target teams. Copying replaces the applicable rubric configuration on the targets. Before confirming: 1. Verify the source team. 2. Confirm whether you are copying one rubric or the full set. 3. Review every selected target team. 4. Confirm that the direction and selection criteria apply to those teams. A copied rubric is not automatically appropriate merely because the teams belong to the same enterprise. ## Copy tags You can copy one saved tag group or all saved tag groups. Existing target tag groups with matching normalized names are replaced rather than duplicated. Agent restrictions are resolved against each target team's agent directory, and unmatched agent names are reported. Review the warning for each target: * ServiceTitan tag mappings may differ by team. * An agent restriction can be dropped when the agent cannot be matched. * Copying all groups can replace existing target tag configuration. ## Copy agent groups Agent-group members are matched by agent name. Groups with the same name are updated in place. You can optionally delete non-matching groups so each target mirrors the source more closely. Use the delete-non-matching option carefully. Recovery-related groups are not part of the copy operation, but other target-specific groups can be permanently removed. The target team's available agents determine the final membership. Unmatched names are skipped and reported. ## Copy Alerts & Reporting Enterprise copy distributes the saved structure of: * Alert on/off state * Event routing * Daily-report mode * Delivery time * Included directions * Summary and deep-dive sections Each target team keeps its own recipients, channels, and destinations. This prevents a source team's email addresses, Slack channel, or Teams webhook from being copied into another brand. After copying, open at least one target team and verify its recipients and destinations before assuming the alerts or report will deliver. ## Safe enterprise rollout checklist * Use a representative source team. * Save and test the source configuration first. * Copy to a small target set before selecting every team. * Review unmatched agents or tags reported by the copy flow. * Preserve team-specific recipients and destinations. * Open a recent call in a target team to validate classification and rubric selection. * Compare enterprise metrics only after the target teams have accumulated calls under the new configuration. # Coach overview Source: https://help.avoca.ai/coach/overview Understand Coach metrics, filters, trends, call breakdowns, and the workflow from team performance to an individual call. Coach turns recorded calls into a reviewable operating system for call-center performance. Use it to understand lead volume and booking results, find coaching opportunities, inspect the calls behind a metric, and correct supported call data. Open **Products → Coach** in [dashboard.avoca.ai](https://dashboard.avoca.ai). Coach link in the Avoca dashboard Products navigation Coach analyzes calls after they end; it is not an in-call coaching assistant. Navigation is based on your team's enabled experience and your permissions. You may see a metrics-led **Overview**, a call-list Overview, **Agent Performance**, **Recovery**, and **Settings** in different combinations. ## Choose the right Coach page * **Overview** answers, "What happened across the team?" * **[Agent Performance](/coach/agent-performance)** answers, "Who needs attention, and what should we coach?" * **[Rubric Performance](/coach/rubrics)** answers, "Which expected behaviors are being missed?" * **[Call Review](/coach/call-review)** answers, "What happened on this specific call?" * **[Recovery](/coach/recovery)** turns missed bookings into follow-up work when enabled. * **[Reclassification](/coach/reclassification)** corrects call types, reasons, tags, and supported attribution. * **[Settings](/coach/settings)** controls classification, call reasons, tags, rubrics, groups, alerts, reports, and metric colors. * **[Enterprise Coach](/coach/enterprise)** rolls supported Coach reporting and configuration across multiple teams. Coach navigation showing Overview, Agent Performance, Recovery, and Settings If a manager or agent cannot open the expected page, see [Invite managers and agents to Coach](/coach/access). ## Start with a consistent review window 1. Set the date range before reading any metric. 2. Open **Filters** and narrow the population you want to evaluate. 3. Read the metric cards and their comparison period. 4. Use the chart, unbooked reasons, failed rubric items, and breakdowns to form a hypothesis. 5. Open the underlying calls before changing a rubric, script, call reason, or agent process. Coach Overview with metric cards and team performance analytics Comparison badges use the immediately preceding period of the same length unless the page says otherwise. Changing the date range or filters changes both the headline metrics and the calls used to calculate them. Coach Overview date range, filter, metric, and export controls Coach dashboard prepared for a morning team performance review ## Read the core metrics The metrics-led Overview can include: * **Total Calls:** calls in the selected range and filter set * **Leads:** calls Coach classified as genuine booking opportunities * **Booked Calls:** leads that resulted in a confirmed booking * **Booking Rate:** booked calls divided by leads * **Average Score:** average score across calls evaluated with an applicable Coach rubric Depending on your call experience and data sources, you may also see: * **Average Wait Time** and **Average Handling Time** * **Short Abandoned** and **Long Abandoned** calls * **Average CSAT** and **Average FCR** * **Initial Booking Rate**, **Post Booking Rate**, and **Calls Saved** A missing optional metric usually means the required source, integration, or rollout is not enabled. It does not necessarily mean the value is zero. Coach Overview metric cards for calls, leads, bookings, scores, and booking rate ### Booking Rate and ST Booking Rate Where both metrics appear, they use different classification sources: * **Booking Rate** uses Avoca's AI determination of leads and booked outcomes. * **ST Booking Rate** uses ServiceTitan call-type classification. Use the metric name shown in the interface when sharing a result. Do not compare the two rates as if they have identical denominators. ### Overall and Agent-by-agent booking rate When Avoca transfers a caller to one of your agents, Coach grades each leg of the call separately. A booking opportunity that Avoca hands off can therefore appear twice: once on Avoca's leg and once on your agent's. When booking-rate views are enabled for your team, tabs above the metric cards on the Overview and Agent Performance pages choose how to count it: * **Overall booking rate** leaves out Avoca legs that transferred the caller without booking. Each opportunity counts once, for the agent who received it. If Avoca transfers two bookable callers and your agent books both, Avoca shows 0 of 0 and your agent shows 2 of 2. * **Agent-by-agent booking rate** keeps every leg, so a bookable call Avoca transferred counts against Avoca. In the same example, Avoca shows 0 of 2 and your agent shows 2 of 2. A call that Avoca booked before transferring counts as Avoca's booking in both views. The selected tab applies to everything on the page, including the calls table and exports, so the counts always match the calls behind them. Without the tabs, Coach counts every leg, as in Agent-by-agent. To reproduce either view through the API, use the `is_transferred_out_leg` field on each call from `GET /api/coach`: drop the calls where it is `true` for Overall, or keep every call for Agent-by-agent. See [Authentication](/api-reference/authentication) to set up an API key. ### Average Score Average Score includes evaluated calls whose rubric applies. Calls with no evaluation or calls excluded from grading do not contribute in the same way as scored calls. If a team uses multiple rubrics, filter to a rubric before comparing performance for a specific call type. A blended average across dissimilar rubrics can hide a meaningful coaching problem. ## Use filters deliberately Available filters vary by team, but can include: * Agents and agent groups * Inbound or outbound direction * Business-hours status * Booking and lead status * Tags and campaigns * Current or suggested call type * Current or suggested call reason * ServiceTitan call memo presence * Coaching-score range * Survey results * Rubrics and failed rubric items * Customer sentiment * Short, inactive, unprocessed, misclassified, or reclassified calls * Days of the week to exclude Active filters appear as removable pills on the metrics-led Overview. Use **Clear all** to return to the page defaults. A filtered result is not a team-wide result. Preserve the date range and active filters when sharing a screenshot or investigating an apparent change. Coach filter drawer with agent, disposition, rubric, campaign, and call attribute filters ### Useful filter recipes Combine filters to answer one operational question at a time. For example, narrow to calls Coach believes were misclassified, or to one agent and failed rubric item before a coaching review. Coach filters configured to review misclassified calls Coach filter drawer configured for a focused coaching review ## Analyze the Overview ### Call Performance The performance chart shows how selected call metrics change over the review period. Use it to find when a change began, then narrow the range and inspect calls from the affected days. Coach Call Performance chart comparing total, bookable, and booked calls Select **View all analytics** to open **Metric Progression**. This read-only page carries the Overview's date range and filters and plots each supported Coach metric by day. Coach related analytics view with expanded performance trends ### Top Unbooked Reasons This section summarizes why leads did not book. Some teams can switch between reason and source views. Coach Top Unbooked Reasons chart Treat the result as a starting point: 1. Select a prominent reason. 2. Review several calls from different agents. 3. Separate agent behavior from availability, pricing, service area, policy, or classification issues. 4. Change the appropriate process only after the pattern is verified. See [Understand unbooked Avoca call reasons](/coach/unbooked-call-reasons) for the standard reason definitions. ### Top Failed Rubric Items This section ranks the rubric criteria most often marked **No**. Select an item to filter the relevant calls, or open **Rubric Performance** for category-level success rates, prior-period change, coaching suggestions, and a full call drill-down. Coach Top Failed Rubric Items panel See [Configure and analyze rubrics](/coach/rubrics). ### Call Flow visualization When reclassification analytics are enabled on the call-list Overview, the call-flow visualization shows how calls move through qualification and booking outcomes. Use it to identify large transitions, then open the calls behind the flow before changing classification policy. Coach Sankey call-flow visualization for qualification and booking outcomes ### Breakdowns Breakdowns compare one metric across a dimension such as: * Tag * Agent * Lead status * Booking status * Call direction * Suggested call type Supported metrics can include total calls, leads, booked calls, unbooked calls, non-leads, average score, and booking rate. The current call-flows experience supports one breakdown dimension at a time. If you need a more specific comparison, apply filters first and then choose the dimension. Coach metric breakdown configuration and chart ## If your Overview is a call list Some teams use the legacy call-data Overview. It combines metric cards, charts, a configurable calls table, and operational review actions. You can typically: * Choose which metric cards are visible * Show, hide, and reorder table columns * Search, filter, sort, and export the current data * Open a call in the review experience * Select calls for available bulk actions * Mark calls read or unread, archive calls, or refresh supported data * Review call-flow, unbooked-reason, rubric, and breakdown sections when enabled The first table cell shows **Read** or **Unread**. Unread rows also have a blue left border unless another row treatment, such as a misclassification warning, takes priority. The header reports both the full call count and the unreviewed count for the current date range and other filters. Select **Unreviewed only** to narrow the visible table without changing those header totals. Opening a call marks it reviewed automatically and updates the row and unreviewed count; hovering over a row does not. Use the available mark-read or mark-unread action when you need to restore or change its queue state deliberately. “Reviewed” here means someone opened the call or explicitly marked it read. It does not prove that a manager listened to the recording, completed a coaching review, or accepted a reclassification suggestion. Possible table columns include direction, summary, review state, score, sentiment, agent, customer, lead and booking status, current and suggested call type or reason, campaign, tags, CSAT, FCR, date, and duration. For supported ServiceTitan rollouts, the **Columns** menu also offers **ST Call Memo**. It is hidden by default because memo text can be long. The row shows the memo currently mirrored from ServiceTitan, and hovering reveals the full value. A dash means Coach does not have a mirrored memo for that call. Open **Filters → ServiceTitan Call Memo** and choose **Has Memo** or **No Memo** to isolate calls by whether a mirrored memo exists. **All Calls** removes that filter. The filter changes the complete Coach population behind the list and analytics; it does not search within memo text. When the same rollout is enabled for export, the Coach CSV includes **ST Call Memo** even when the table column is hidden. Team and Enterprise Coach can receive this capability independently, so compare the available column and export fields in the workspace you are using. Every Coach CSV ends with a block of columns read from the linked Avoca call, named to match the AI Calls export so the two can be compared column-for-column: **Avoca Call ID**, **Transferred**, **AI or Human**, **Emergency**, **Call Ended Reason**, **Forwarded To**, **Transfer Destination Name**, and **Action Item**. Transfer status and the emergency flag come from the linked Avoca call rather than from a Coach tag. Both are **Unknown** for non-Avoca or unlinked Coach calls; this is different from **No**, which means the linked Avoca call did not transfer or was not an emergency. **AI or Human** reads the linked Avoca call when there is one (blank if that call has no recorded value, exactly as the AI Calls export shows it) and otherwise falls back to the ServiceTitan agent: an Avoca AI agent reads as **AI**, any other agent as **Human**, and a call with no agent as **Unknown**. The free-text columns are blank when the Coach call has no linked Avoca call. Coach tags, including service-line tags, remain separate columns and classifications. Coach CSVs also include **Soonest Slot Offered (UTC)** and **Soonest Slot Days Out**, derived from the linked Avoca call's availability lookups. See [Report on soonest availability](/api-reference/soonest-availability) for export steps, Coach API examples, and how to calculate an average while preserving missing values. When Four Seasons non-booked dispositions are enabled for the team or its enterprise, the same block also carries **Non-Booked Disposition Code** and **Non-Booked Disposition**, resolved exactly as the AI Calls export resolves them. Selecting **Include rubric details** adds one column per rubric item showing how that criterion was scored on the call: **Yes**, **No**, **N/A**, or a dash when the item was not part of the rubric used for that call. Coach Calls table with configurable columns and call review rows Bulk actions and individual edit controls appear only when your role and team configuration support them. ## From signal to action Use this sequence to avoid optimizing around a misleading aggregate: 1. **Find the signal.** Start with a metric, unbooked reason, failed rubric item, group, or agent. 2. **Confirm the population.** Check the date range and filters. 3. **Inspect calls.** Listen to a representative sample and read the transcript and coaching evidence. 4. **Identify the cause.** Decide whether it is a coaching, staffing, availability, policy, rubric, or classification issue. 5. **Make the smallest change.** Coach the agent, update a setting, or correct the call. 6. **Measure again.** Compare the same metric and population after enough new calls have been evaluated. For a specific call, continue to [Review a Coach call](/coach/call-review). # Review and automate call reclassification Source: https://help.avoca.ai/coach/reclassification Validate Coach suggestions, configure automatic reclassification, correct calls manually, and protect ServiceTitan reporting. Coach reclassification compares the disposition on an ingested call with what happened in the transcript. It can suggest or apply corrections to the call type and, when configured, the call reason, tags, and CSR attribution. Use reclassification to make booking-rate reporting more accurate and surface qualified unbooked calls that may be recoverable. Reclassification runs after a call ends. New results usually appear after the call has been ingested, transcribed, and evaluated; automatic ServiceTitan updates can take additional time. ## Why reclassification matters Manual disposition is inconsistent at scale. A genuine lead can be marked excused, similar conversations can receive different reasons, and a recoverable opportunity can disappear from the team's workflow. Coach evaluates the transcript with one set of criteria, making the disagreement visible before the team decides whether to correct it automatically. Coach reclassification example comparing current and AI-determined call outcomes Coach analytics showing the reporting value of corrected call classifications ## Understand the classifications | Call type | Meaning | | - | - | | **Booked** | A job or appointment was booked | | **Unbooked** | A genuine service opportunity did not result in a booking | | **Excused** | The conversation was not a service request | | **Not a Lead** | The conversation did not represent a new booking opportunity, such as work related to an existing job | | **Abandoned** | No meaningful agent-customer conversation occurred, such as no answer or voicemail | Calls already classified as **Booked** are not call-type-reclassified by the standard policy. Supported call-reason, tag, CSR, or linked-job corrections can still be available. ## Choose how Coach handles each source type Open **Coach → Settings → Call Reclassification**. For each supported original disposition, choose: | Mode | Result | | - | - | | **Don't touch** | Coach leaves the source classification unchanged | | **Suggest changes** | Coach places a supported alternative in the review workflow | | **Change automatically** | Coach applies a supported alternative without waiting for review | When suggestions or automatic changes are enabled, select the target types Coach is allowed to use. Automatic reclassification can update production ServiceTitan data and changes the population behind Coach reporting. Validate the behavior in suggestion mode before enabling automatic changes. ## Roll out reclassification safely ### 1. Review suggestions 1. Open **Coach → Overview**. 2. Set a representative date range. 3. Filter for misclassified, unreviewed, qualified-unbooked, or empty-reason calls when those filters are available. 4. Open calls from different agents, directions, and source dispositions. 5. Compare the recording and transcript with the current and suggested call type, reason, tags, and CSR. 6. Apply accurate suggestions manually. Coach filters used to isolate calls requiring reclassification review Do not judge the configuration from one unusual call. Review a representative sample and look for a repeatable error pattern. ### 2. Correct the underlying guidance If suggestions repeatedly miss: * Refine inbound and outbound **Bookable criteria** * Refine inbound and outbound **Booked criteria** * Add clear, distinct **Call Reason** descriptions * Clarify tag-group conditions and tag descriptions * Configure a fallback CSR for voicemail and no-speaker calls Change the smallest rule that explains the repeated error, then review a fresh sample. ### 3. Prepare call reasons Open **Coach → Settings → Call Reasons**. 1. Pull unsynced reasons from ServiceTitan when applicable. 2. Add a precise description to every active reason. 3. Confirm whether each reason is bookable. 4. Deactivate obsolete or overlapping reasons. 5. Save the list. See [Understand unbooked Avoca call reasons](/coach/unbooked-call-reasons) for the standard unbooked-reason definitions. ### 4. Enable automatic changes narrowly Move one source disposition from **Suggest changes** to **Change automatically** only after its suggestions are consistently accurate. Then: 1. Monitor new calls for that source. 2. Review misclassified and low-confidence cases. 3. Confirm supported updates in ServiceTitan. 4. Expand to another source only after the first one remains reliable. Coach automatic reclassification setting for a source call type For automatic call-reason updates, Coach applies the reason only when confidence is at least **98%**. Lower-confidence disagreements remain suggestions unless **Always require a call reason** is enabled. If **Always require a call reason** is on, maintain accurate catch-all options such as an "Other Lead" and "Other Non-Lead" reason. Otherwise an uncertain call can be forced into a misleadingly specific reason. ## Correct one call manually Open a call from Overview, Agent Performance, Rubric Performance, or another Coach call list. 1. Review the recording, transcript, summary, current disposition, and Coach suggestions. 2. Select **Edit call details** when your permissions allow it. 3. Update only the fields supported for that call and source. 4. Save the smallest correction necessary. 5. Open **Activity** to confirm the initial and updated values. 6. If ServiceTitan sync is expected, verify the ServiceTitan record. Supported controls can include call type, call reason, tags, CSR, notes, linked job, and selected job fields. See [Review a Coach call](/coach/call-review#edit-call-details) for the complete call-review workflow. ## Manage CSR attribution When enabled, Coach can infer the CSR from the transcript. Choose whether Coach should: * Show the inferred CSR as a suggestion * Fill the CSR only when the call is unassigned * Correct an existing CSR when Coach identifies a different speaker Coach CSR reclassification behavior settings For no-speaker calls, configure a dedicated fallback CSR rather than attributing voicemail or abandoned calls to a real agent. Coach fallback CSR setting for calls without a detected speaker Validate CSR correction carefully because attribution affects individual performance reporting and can update ServiceTitan. ## Apply tags safely Under **Coach → Settings → Tags**, define: * When the group applies * Inbound, outbound, or both * How many tags Coach can or must select * A distinct description for every tag * The ServiceTitan tag mapping, when applicable Test tag descriptions against real calls before enabling automatic tag reclassification. Coach tag group settings with descriptions and selection behavior ## Connect reclassification to Recovery When Recovery is enabled, accurate classification determines which missed opportunities enter the work queue. Use the workflow: 1. Classify genuine leads accurately. 2. Identify qualified unbooked calls. 3. Send supported calls into Recovery. 4. Contact the customer promptly. 5. Record the outcome. Coach Recovery navigation for missed booking opportunities See [Recover missed bookings](/coach/recovery). ## Confirm automatic results Successfully processed calls show their updated review state and retain the classification history in **Activity**. Continue reviewing the low-confidence and disagreement cases even after automatic behavior is enabled. Coach call marked reviewed after reclassification ## Troubleshoot reclassification ### Reasons are missing or inaccurate Sync ServiceTitan reasons, add distinct descriptions, remove overlaps, and save. Reason descriptions are one of the strongest controls on selection accuracy. ### A call cannot be reclassified into ServiceTitan Confirm the call has an assigned ServiceTitan agent. Configure a fallback CSR for voicemail, no-answer, and other no-speaker calls. ### Suggestions never apply automatically Confirm the original source type is set to **Change automatically** rather than **Suggest changes**. Also confirm automatic reason or tag behavior is enabled for the field you expect to change. ### A booked call's call type did not change This is expected in the standard policy: calls already marked **Booked** are not call-type-reclassified. ### Coach Booking Rate differs from ST Booking Rate The metrics use different classification sources. Compare the same date range and call population, then use the call evidence to determine which classification needs attention. ### The same error keeps returning Correct the underlying bookability criteria, reason description, tag description, or CSR configuration instead of repeatedly overriding individual calls. For every configuration control, see [Configure Coach settings](/coach/settings). # Manage Call Recovery Source: https://help.avoca.ai/coach/recovery Prioritize missed booking opportunities, create follow-up tasks, assign the work, and track verified recovery outcomes. Open **Coach → Recovery** to turn missed booking opportunities into accountable follow-up work. Recovery appears only for supported teams and roles with Call Recovery access. It has two route-backed tabs: * **Recovery Analytics** for the missed-opportunity queue and outcome metrics * **Recovery Items** for the follow-up task workflow The selected date range applies to both tabs. Coach Recovery Items table with customer, assignee, status, and outcome fields A recovery task is internal work. Creating or updating a task does not call or message the customer automatically. ## Read Recovery Analytics The summary cards show: * **To Recover:** total missed opportunities minus recovered opportunities * **Recovered:** recovered opportunities out of total missed * **Recovery Rate:** recovered opportunities divided by missed opportunities * **Attempt Rate:** missed opportunities with at least one follow-up attempt * **Avg First Contact:** average time from the missed call to the first outbound attempt These metrics can change after the original call date as the team attempts follow-up and ServiceTitan outcomes sync. ### Objections Breakdown The breakdown groups missed opportunities by the recorded objection. Use it to identify recurring causes, then inspect the individual opportunities before changing a script or policy. An objection label is a classification. Confirm it against the call when the operational decision matters. ## Work the Recovery Queue Coach Recovery tab for recoverable unbooked calls The queue can include: * Priority * Customer * Issue and call summary * Objection * Age * Attempt count * Call agent * Task assignee or assigned team * Task status * Recovered job and revenue when available Use the expand control to see earlier missed calls associated with the same opportunity. This history helps you avoid creating duplicate tasks for repeated calls from the same customer. ### Queue filters * **Unassigned Agent:** opportunities without an attributed call agent * **Unassigned Team:** opportunities without a recovery-team assignment * **Show Recovered:** includes opportunities already matched to a recovered job The recovered indicator is based on recovery data available to Avoca, such as a matched ServiceTitan job. It is not inferred from a task note alone. ## Create a recovery task Select the plus button on an opportunity that does not already have a task. You can also create a task from the **Recovery Tasks** card in [Call Review](/coach/call-review#work-recovery-tasks-from-the-call). 1. Confirm or edit the title. 2. Add an optional description with the expected follow-up. 3. Set **Urgent**, **High**, **Medium**, or **Low** priority. 4. Select the relevant recovery tags. 5. Set a due date. 6. Select **Create Task**. After creation, use the task's edit dialog to assign an owner and manage its lifecycle. Check for an existing task and expand earlier missed calls before creating work. Duplicate tasks can result in repeated customer contact. ## Manage Recovery Items The top cards summarize task counts for: * In Progress * Completed * Booked * Lost The list starts with active work and can be filtered by: * In Progress * Need To Follow Up * Completed * Booked * Lost * Assigned to me * Any assignee or unassigned * Assigned recovery team, where team assignment is enabled * Date range Select a task row to edit it. ## Update a task The edit dialog can include: * Title * Description * Status * Priority * Due date * Assignee * Assigned team for supported teams * Outcome notes for terminal statuses * Lost reason when the status is Lost Task tags selected at creation are displayed for context. When available, use **View Coach Call** to review the source conversation and **View Customer in ServiceTitan** to open the customer record. ## Choose the correct status * **In Progress:** work has started and no additional waiting state is needed * **Need To Follow Up:** another customer contact is required * **Completed:** the operational work is closed without recording a booked or lost result * **Booked:** the recovery was successful * **Lost:** the recovery was unsuccessful For **Completed**, **Booked**, or **Lost**, add concise outcome notes. For **Lost**, select the most accurate lost reason. Do not mark a task **Booked** until the booking is verified. A task status and a ServiceTitan recovery match are related signals, but they are not interchangeable. ## Recommended recovery workflow 1. Filter the queue to unassigned or high-priority opportunities. 2. Review the issue, objection, summary, and earlier missed calls. 3. Create one task with a clear owner and due date. 4. Use the team's approved outbound workflow to contact the customer. 5. Set **Need To Follow Up** when another attempt is required. 6. Close the task with the correct terminal status and factual outcome notes. 7. Verify the booked job in ServiceTitan when the result is a recovery. ## Protect reporting quality * Keep assignments and due dates current. * Do not create another task merely because ownership changed. * Use Lost only after the team's follow-up policy has been completed. * Avoid unnecessary sensitive customer data in descriptions or outcome notes. * Compare metrics with the same call-date range. * Allow time for ServiceTitan job and revenue data to sync. Deleting a recovery task permanently removes its work record and cannot be undone. If the task only needs a new owner, date, priority, or status, edit it instead. # Configure and analyze rubrics Source: https://help.avoca.ai/coach/rubrics Create Coach rubrics, test rubric selection and grading, analyze failed criteria, and correct call-level evaluations. A Coach rubric defines the behaviors expected on a call and converts Coach's evaluation into a score. Rubrics power call-level Coaching, Average Score, Coaching Insights, and Rubric Performance. You configure rubrics under **Coach → Settings → Rubrics** and analyze their results from the Coach Overview or an agent page. Rubric editing requires Coach Settings access. Call-level grading controls can have separate permissions. ## Understand rubric structure Each rubric has: * **Title:** the name shown in settings and reports * **Direction:** Inbound or Outbound * **Active state:** whether Coach can use the rubric for new evaluations * **Selection criteria:** a plain-language description of when the rubric should apply * **Sections:** categories that organize related behaviors * **Criteria:** the individual goals Coach grades as Yes, No, or N/A * **Points:** the contribution of each criterion to the overall score Coach uses direction and selection criteria to choose the best active rubric for a call. Write selection criteria that distinguish call types, services, or situations instead of repeating the rubric title. ## Create a rubric 1. Open **Coach → Settings → Rubrics**. 2. Select **New rubric**. 3. Choose a blank inbound or outbound rubric, or start from a template. 4. Enter a distinct title. 5. Confirm the direction. 6. Describe when Coach should select the rubric. 7. Add sections and criteria. 8. Assign criterion points. 9. Turn on **Active** when the rubric is ready. 10. Select **Done**, then save the page-wide changes. Templates remain available even when other rubrics already exist. Coach Rubrics settings with active rubrics and a New rubric button The starter templates are: * Bookable Inbound * Not-bookable Inbound * Bookable Outbound * Not-bookable Outbound Treat a template as a starting point. Customize its criteria, categories, and points to the team's actual call-handling process before activation. ## Write effective criteria Each criterion should describe one observable behavior. Prefer: * "Confirmed the customer's service address" * "Explained the next step and expected arrival window" * "Acknowledged the pricing objection before offering an alternative" Avoid combining unrelated requirements into one criterion. A compound criterion is difficult to grade and difficult to coach. Use a consistent voice: * State what the agent should do. * Include the condition when it matters. * Avoid subjective words such as "good" or "professional" without defining the observable behavior. * Keep policy exceptions in the selection criteria or a separate rubric. ## Set points The editor shows the total across all criteria. Configure an intentional total of **100 points** so the score is easy to interpret. New criteria start with a small nonzero point value. Older or imported rubrics without meaningful weights can be normalized, but explicitly assigning points is safer and makes the rubric's priorities clear. A high-point criterion has a larger effect on Average Score. Review the point distribution before activating a rubric or comparing scores across a rubric change. ## Manage multiple rubrics Use separate rubrics when the expected behavior is materially different, such as: * Inbound booking calls * Outbound follow-up calls * A specialized service line * A distinct call purpose with different compliance steps For each rubric: * Set the correct direction. * Write mutually understandable selection criteria. * Keep only production-ready rubrics active. * Give similar rubrics distinct selection language. If several active rubrics could match, Coach chooses the best fit from the call and selection criteria. Use the Rubric Playground to verify that choice. Common production setups are: * **Inbound starter:** Bookable Inbound and Not-bookable Inbound * **Inbound and outbound:** separate bookable and not-bookable rubrics for both directions * **Advanced:** an additional intent- or service-specific rubric only when its selection criteria cleanly separate it from the general rubrics Do not add a specialized rubric merely to avoid N/A results on a few calls. First confirm the call population is meaningfully different and can be described with non-overlapping criteria. ## Test in the Rubric Playground Select **Test rubric** from the Rubrics page. You choose calls one of two ways: * **Filter calls:** build a cohort from a date range plus any Coach call filter — agent, booked status, call direction, tags, and the rest. Opens with 10 random calls from the last 30 days already loaded. * **Enter call IDs:** paste up to 25 Coach call IDs instead, when you want specific calls. In Filter calls, set the date range with the date picker (up to a year) and open **Filters** for everything else. **Pick** controls which matches are kept — Random, Lowest score, or Most recent — and **Calls** sets how many, up to 25. Lowest score is the fastest way to find calls a rubric grades too harshly. After pressing **Get calls** you see how many calls match the filter and how many of those are gradeable. Grading needs both a transcript and a ServiceTitan call payload, so those two numbers differ when some matches lack that data. Change any setting and press **Get calls** again to rebuild the cohort. Use explicit call IDs when you intentionally want to test older calls, or a call the filter excludes. The Playground uses the active rubric set and selects the best rubric for each call using the same direction and selection-criteria model as production grading. For each test: 1. Confirm the selected rubric. 2. Read the selection reasoning. 3. Review the criterion answers and evidence. 4. Compare the result with the recording — select **Open** on a call to view its transcript in a new tab. 5. Refine ambiguous selection criteria or grading criteria. 6. Re-run the test before saving a broad production change. The Playground is a configuration test. It does not replace reviewing real production trends after the change. ## Add the objection-handling playbook The Rubrics settings page includes an **Objection handling playbook**. Record the approved strategies Coach should reference when a call contains an objection. Keep the playbook: * Specific to the team's current policy * Organized around recognizable objection types * Written as coaching guidance, not unsupported promises * Updated when pricing, financing, scheduling, or escalation policy changes The playbook can surface in call reviews to help reviewers identify missed objection-handling opportunities. ## Analyze team-wide Rubric Performance From **Top Failed Rubric Items** on the Overview, select **See all** or open **Rubric Performance**. The page groups every available rubric item by category and shows: * Current success rate * Change from the prior period * Direction and rubric filters * Coach Suggestion and suggested script * Recent calls with the issue * A daily success-rate trend * A link to every call where the item was missed Success rate is the complement of the miss rate for the calls in the selected population. Always confirm the date range and rubric filter before comparing categories. ## Analyze one agent's rubric performance Open an agent from **Agent Performance**, then select **View score breakdowns by all categories**. The agent-level view uses the same category, criterion, success-rate, and prior-period structure, but scopes the calls to that agent. It can be exported as a PDF report. See [Analyze agent performance](/coach/agent-performance). ## Correct one call without changing the rubric Open the call's **Coaching** tab to review its rubric result. 1. Unlock the rubric. 2. Change the applicable criterion answers. 3. Update reasoning if needed. 4. Save the override. Use **Exclude from Grading** only when the entire rubric does not apply. Exclusion sets every criterion to N/A and removes the call from score calculations. See [Review a Coach call](/coach/call-review#review-and-correct-rubric-grading). ## Manage rubric changes safely * Test selection and grading before activation. * Change one concept at a time when possible. * Record when a material rubric change goes live. * Expect Average Score to shift when criteria or points change. * Compare pre-change and post-change periods cautiously. * Do not use a call-level override to compensate for a consistently ambiguous master rubric. * Save or discard pending changes before leaving the settings page. Disable an obsolete rubric to stop using it for new evaluations while preserving historical results. Deleting a rubric permanently removes its evaluation results, though it does not delete the underlying calls. ## Troubleshoot rubric selection ### Calls have no score Confirm at least one appropriate rubric is active, its direction and selection criteria cover the call, and the call finished processing. ### The wrong rubric graded a call Review the selected rubric on the call, then narrow overlapping criteria. Add explicit exclusions such as "Do not use for billing-only calls" where they distinguish the competing rubrics. ### Too many criteria are N/A Confirm the correct rubric was selected. If the criteria genuinely do not apply to a repeatable population, move them to the applicable rubric or create a distinct rubric with clear selection criteria. ### Scores changed after a rubric edit The scoring standard changed. Record the activation date and avoid treating the before-and-after score difference as agent improvement or decline without reviewing the rubric change. # Configure Coach settings Source: https://help.avoca.ai/coach/settings Configure call classification, reasons, tags, rubrics, agent groups, alerts, daily reports, and metric colors. Open **Coach → Settings** to control how Coach classifies calls, evaluates behavior, organizes agents, and distributes results. Coach Settings navigation and configuration panels The Settings tab and individual editing controls depend on your permissions, integrations, and enabled Coach features. A page can be visible but read-only for your role. ## Before you change a setting 1. Identify the problem using a specific call or a filtered report. 2. Decide whether the issue is call classification, call reason, tag logic, rubric grading, agent organization, notification delivery, or display. 3. Make the smallest configuration change that addresses the cause. 4. Save the page and test with representative calls. 5. Review new results with the same filters. Coach settings pages warn you before leaving with unsaved changes. Use the page's **Save**, **Cancel**, **Done**, or discard control instead of relying on navigation to preserve a draft. ## Call Reclassification Use **Call Reclassification** to define how Coach decides whether a call was a lead, whether it booked, and what to do when Coach disagrees with the current call type. See [Review and automate call reclassification](/coach/reclassification) for the recommended validation and rollout workflow. ### Behavior Settings Configure each source call type independently: * Unbooked * Abandoned * Excused * Not a Lead For each source, choose: * **Don't touch:** leave the source classification unchanged * **Suggest changes:** place the supported alternative in the review workflow * **Change automatically:** apply a supported alternative without waiting for review When suggestions or automatic changes are enabled, select the allowed target call types. Coach can target **Unbooked**, **Booked**, or **Excused** where the source rules support them. **Abandoned** is never a target, and calls already classified as **Booked** are not reclassified by this policy. Automatic reclassification changes Coach reporting and can update ServiceTitan for supported teams. Begin with suggestions when you are still validating new criteria. ### Bookable criteria Define what makes a call a genuine booking opportunity separately for: * Inbound calls * Outbound calls Write operational criteria that distinguish a lead from an informational, vendor, employee, spam, or otherwise non-bookable conversation. ### Booked criteria Define the evidence Coach should treat as a confirmed booking separately for inbound and outbound calls. Be explicit about what counts as confirmation. A customer expressing interest is not necessarily a booked job. ### Automatic CSR correction When available, choose how Coach handles the CSR it identifies from the transcript: * **Off:** show the inferred CSR as a suggestion * **Fill in missing CSRs:** assign the inferred CSR only when no real CSR is present * **Always correct CSRs:** also replace an existing CSR when the transcript clearly identifies a different person For ServiceTitan teams, an applied correction is pushed to ServiceTitan. For other teams, it updates Avoca's Coach record. ### Fallback CSR ServiceTitan teams can select a fallback CSR for calls where no speaker can be detected, such as abandoned calls, auto-attendant interactions, or voicemail. A fallback is a placeholder for attribution. It should not be interpreted as proof that the selected person handled the call. ### ServiceTitan Memo Sync When enabled, Coach writes an AI-generated, technician-facing memo into the ServiceTitan call's **ExcuseMemo** after each processed call. Choose how Coach handles an existing memo: * **Add to it, keeping what's there:** preserves CSR-written text and updates the Avoca-tagged block. * **Replace it with Avoca's memo:** writes only the generated Avoca memo. This can overwrite text entered by a CSR. Avoca retains a recovery copy of displaced text for 30 days. Use **Replace** only when a consistent machine-readable memo is more important than preserving existing text. Confirm that CSRs and other integrations do not rely on the current ExcuseMemo, then test with controlled calls before rollout. You can continue using the default or team-specific free-text prompt. For a consistent memo shape, select **Build the memo from fields** and configure: * The separator and field order * Whether each value comes from ServiceTitan data, the job type, or the transcript * Allowed values, or a free-form text, ZIP code, or date format * The value used when a field does not apply or cannot be determined * Optional conditions or branches based on an earlier field Fields that cannot be determined are filled with the configured fallback instead of being left blank. Review the example output, save the settings, and verify both a normal call and a call where one field does not apply. ### Understand the opportunity outcome memo field The built-in **Booked + opportunity outcome** signal combines the confirmed booking result with Coach's transcript-based opportunity decision. It can produce values such as `BOOKED_OPPORTUNITY`, `UNBOOKED_OPPORTUNITY`, `BOOKED_NON_OPPORTUNITY`, or `UNBOOKED_NON_OPPORTUNITY`. Coach treats the call as an opportunity only when it represents net-new revenue, including when the caller: * Books a new demand, inspection, or sales job * Asks for a new job but cannot get a suitable slot Coach treats anything about work already arranged as a non-opportunity. This includes rescheduling or bringing forward an existing appointment, asking for an earlier slot, cancelling, or following up about status, ETA, warranty, backorder, or billing. Install work and calls from employees, vendors, wrong numbers, or spam callers are also non-opportunities. This signal controls the structured memo field; it is separate from the team's editable **Bookable criteria** and call-reclassification policy. If another system parses the memo, test a new booking, a no-slot request for new work, a live reschedule, and an outright cancellation before relying on the field downstream. ## Call Reasons Call reasons explain why a call occurred. They are separate from call type, lead status, and booking status. ### Create or sync reasons You can: * Create a custom reason in Avoca * Pull the latest reasons from ServiceTitan * Search the configured list * Activate or deactivate a reason * Edit its description and bookability * Delete or hide a reason when it is no longer used For a ServiceTitan-managed reason, the name is controlled in ServiceTitan. Edit it there and sync again. Coach still needs a clear description so the model knows when to assign it. Each reason includes: * **Name** * **Description** * **Bookable** state * **Active** state Inactive reasons remain visible for historical reporting but are ignored when Coach categorizes new calls. ### Configure reason behavior * **Auto-reclassify by reason:** automatically updates the ServiceTitan call reason when Coach's confidence is at least 98%. Lower-confidence differences remain suggestions. * **Always require a call reason:** assigns the best available reason even below the normal confidence threshold. If you always require a reason, include accurate catch-all choices such as an "Other Lead" and "Other Non-Lead" reason. Otherwise, low-confidence calls can be forced into an overly specific category. See [Understand unbooked Avoca call reasons](/coach/unbooked-call-reasons) for the standard unbooked-reason definitions. ## Tags Coach tags classify signals such as objection type, call quality, customer intent, or another business-specific condition. ### Create a tag group A tag group defines the context and selection behavior for its tags: * **Name** * **Description** * **Call type condition** * **Call direction:** inbound, outbound, or both * **Selection rule:** how many tags in the group Coach can or must apply * **Enabled** state Disable a group when Coach should skip the group and every tag inside it. ### Create a tag Each tag can include: * A ServiceTitan tag mapping * A display label * A required classification description * Customer type: new, existing, or both * An optional agent restriction * An enabled state The description is the rule Coach reads. Missing descriptions block the page from saving. If a tag is mapped to ServiceTitan, its label is managed by the ServiceTitan tag. An unmapped tag can still be used inside Avoca. ### Import and sync tags ServiceTitan teams can import available tags, then add the descriptions Coach needs. Enable **Auto-reclassify by tag** to push mapped, enabled tags from enabled groups onto matching ServiceTitan calls. Unmapped tags remain Avoca-only even when automatic tag sync is on. ## Rubrics Rubrics define the expected agent behavior and scoring model. Use this page to: * Create inbound and outbound rubrics * Start from a default template * Set title, direction, active state, and selection criteria * Add sections and criteria * Assign criterion points * Test active rubrics with the Rubric Playground * Maintain the objection-handling playbook See [Configure and analyze rubrics](/coach/rubrics) for the full workflow. ## Agent Groups Agent groups organize agents for Coach filters, dashboards, comparisons, rubrics, alerts, and the daily report. To create a group: 1. Select **Edit**. 2. Select **New group**. 3. Name the group. 4. Add members. 5. Include unassigned calls if they should belong in the group. 6. Optionally mark it as the default group. 7. Save the group, then select **Done**. The default group is used as the fallback selection on supported Coach reports. Use one default that represents the most common operational view. Deleting a group does not delete its agents, but it removes that grouping from Coach. Confirm any downstream report or alert usage first. ## Alerts & Reporting This page has separate **Alerts** and **Daily Coach Report** sections. ### Alerts Enable real-time alerts, then configure supported channels: * **Email:** a fixed recipient list * **Slack:** a channel in the team's connected workspace * **Microsoft Teams:** an incoming webhook URL The event-routing matrix determines which enabled channel receives: * **Unbooked calls:** bookable inbound ServiceTitan calls that did not book, excluding Avoca AI agent calls * **Misclassified calls:** calls where Coach's call type or reason disagrees with ServiceTitan and the call has not been reclassified Both the global alert switch, the channel, and the event-to-channel route must be enabled for a standard alert to fire. Some teams use an Avoca-maintained custom alert rule set. On those teams, you can manage the available on/off and destination fields, while the underlying event rules remain managed by Avoca. ### Daily Coach Report Choose one delivery mode: * **Standard:** automatically sent to the team's admins and agents * **Custom:** choose recipients, timing, directions, and report sections * **Off:** do not send a daily report For a custom report, configure: * To and optional Cc recipients * Send time in the team's local timezone * Inbound and outbound call inclusion * Summary fields: calls, leads, booked calls, average score, and AI changes * Deep dives: top unbooked reasons and top failed rubric items The report window is the previous local day. Changing report recipients affects who receives operational call-performance data. Verify every address before saving. ## Display Display settings control the colors used for: * **Coaching Score** on call and agent tables * **Booking Rate** on team and agent performance For each metric, define the minimum value for the green, yellow, and red bands. The highest matching **greater than or equal to** rule wins. Keep a **≥ 0** catch-all rule so every value receives a color. Use **Reset to default** to restore: * Coaching Score: green at 80, yellow at 60, red at 0 * Booking Rate: green at 70, yellow at 50, red at 0 These thresholds influence visual prioritization, including the red state used to identify agents who may need review. They do not change the underlying metric. ## Validate a configuration change After saving: 1. Open a recent call that should match the new behavior. 2. Confirm the selected call type, reason, tags, and rubric. 3. Review the Activity tab for the initial and updated values. 4. If ServiceTitan sync is expected, open the ServiceTitan record. 5. Monitor new calls rather than assuming historical records will be recomputed. 6. Compare the same filtered population before and after the change. # Understand unbooked Avoca call reasons Source: https://help.avoca.ai/coach/unbooked-call-reasons Use the standard Avoca reason definitions to understand why qualified calls did not result in a booking. Unbooked call reasons explain the specific outcome that prevented a qualified service opportunity from becoming an appointment. Use these definitions when reviewing **Top Unbooked Reasons**, validating a suggested reason, or writing descriptions for a team's active reason list. The active list can differ by team. ServiceTitan teams can sync their own reasons, and administrators can create custom Avoca reasons. Use the names and descriptions shown in your team's **Coach → Settings → Call Reasons** page when they differ from this reference. ## Review unbooked reasons in Coach 1. Open **Coach → Overview**. 2. Set the date range and relevant agent, group, direction, or campaign filters. 3. Find **Top Unbooked Reasons**. 4. Select a prominent reason to inspect the underlying calls. 5. Compare the current and suggested reason with the recording and transcript. 6. Decide whether the pattern is caused by agent behavior, availability, policy, pricing, service area, or classification. A reason describes *why* the lead did not book. It is separate from the call type, lead status, booking status, and any tags. Coach Top Unbooked Reasons chart ## Standard unbooked reason definitions | Reason | Use when… | | - | - | | **Quote or Estimate Visit Scheduled, No Service Appointment Booked** | The customer agreed to a quote or estimate visit but did not commit to the actual service. | | **Membership Renewal Declined, No Service Requested** | The customer declined a membership or service-plan renewal and did not request service, cancellation, or an appointment. | | **Placed in Callback Queue, No Agreement to Schedule or Callback** | The customer entered a callback queue without explicitly agreeing to a callback or another next step. | | **Prioritization or Escalation Request for Existing Appointment** | The caller asked to prioritize or escalate an existing appointment without booking, rescheduling, or confirming a new appointment. | | **Customer Unavailable, No Agreement to Schedule or Callback** | The customer could not proceed and did not agree to a callback or another next step. | | **Outbound Informational or Promotional Message, No Customer Interaction** | An outbound informational or promotional message produced no customer interaction or booking attempt. | | **Company Document Request Only, No Service Scheduled** | The caller requested company documentation, such as a certificate of insurance or license, without discussing or scheduling service. | | **Pending Paperwork Completion Before Booking** | Required paperwork must be completed and returned before a membership or service appointment can be finalized. | | **Opted to Resolve Issue Independently** | The customer chose to handle the issue without scheduling service. | | **Customer Opted to Contact Internal Company Representative** | The customer declined scheduling and chose to contact another internal representative or manager. | | **Caller No Longer Associated with Property** | The caller is no longer responsible for the property and asked to be removed from contacts or notifications. | | **Multiple Estimates Required by Policy** | The customer or organization must collect multiple estimates before approving service. | | **Customer Declined Due to Required Credential or Certification** | The customer required a credential or certification the company does not have and declined to proceed. | | **Credit or Refund Opted Instead of Booking** | The customer chose a credit, refund, or account adjustment instead of scheduling service. | | **Advised to Use Online Form to Schedule** | The caller was directed to submit the request or schedule through an online form or portal. | | **Awaiting Contract Review Before Booking** | A contract must be reviewed or approved before scheduling can proceed. | | **Work Request Only, No Appointment Scheduled** | The call created or discussed a work request without setting an appointment. | | **Awaiting Down Payment Before Booking** | An invoice or required down payment must be received before an appointment can be scheduled. | | **Awaiting Company Follow-Up to Schedule Appointment** | The company must confirm details in a later follow-up and no appointment date or time was set. | | **Cancellation with Intent to Reschedule, No New Date Set** | An existing appointment was canceled and the customer intended to reschedule later without selecting a new date. | | **Awaiting Company-Generated Quote or Task Before Booking** | The company must create a quote, task, or invoice before scheduling can proceed. | | **Booking Prevented Due to Existing Open Ticket** | An open ticket or appointment prevented a duplicate or overlapping booking. | | **Estimate Accepted, No Appointment Scheduled** | The customer accepted an estimate but did not set an appointment date or time. | | **Cancellation Request Only, No New Booking** | The caller canceled an appointment without requesting rescheduling or new service. | | **Required Communication Channel Not Provided** | A required communication method, such as email or a portal, was unavailable. | | **Required Company Document Not Provided** | The company had not provided documentation the customer required before proceeding. | | **Opted to Schedule In-Person with Technician** | The customer declined to schedule on the call and planned to arrange service directly with a technician. | | **Customer Declined Callback, No Appointment Scheduled** | The customer declined a callback and no appointment was booked. | | **Account Hold or Restriction Prevented Booking** | An account hold or internal restriction prevented scheduling. | | **Company Refused Service Request** | The company declined the service request for an internal or unspecified reason. | | **Service Refused Due to Adversarial Behavior** | The company declined service because of adversarial, contentious, or disrespectful customer behavior. | | **Pending Financing Application Before Booking** | Financing approval is required before the appointment can be scheduled. | | **Agent Unable to Finalize Booking** | The agent could not complete the booking for an unspecified reason and did not arrange a callback or appointment. | | **Company Policy Restriction on Service Eligibility** | Company policy made the customer or equipment ineligible for service, such as an equipment-age or installation-origin restriction. | ## Maintain useful reason descriptions Good descriptions: * Separate easily confused outcomes * State the event that prevented booking * Avoid duplicating another active reason * Explain whether the reason represents a lead * Use a catch-all only when no specific reason is reliable If the wrong reason is selected repeatedly, improve the descriptions that distinguish the two reasons before adding another near-duplicate. ## Configure reason behavior Under **Coach → Settings → Call Reasons**, an authorized user can: * Sync reasons from ServiceTitan * Create Avoca-only reasons * Edit descriptions and bookability * Activate or deactivate reasons * Enable automatic reason reclassification * Require a reason on every supported call Automatic ServiceTitan reason updates require at least **98% confidence**. Lower-confidence differences remain suggestions unless the team requires a reason. See [Review and automate call reclassification](/coach/reclassification) for a safe rollout. # 3CX Source: https://help.avoca.ai/config/call-forwarding/3cx Set up your Avoca number in 3CX for after-hours and overflow coverage In order for your calls to be routed to Avoca, your team needs to ensure that call forwarding is set up to route to an external number (your Avoca number). Once you've received the number from your Customer Success Manager, follow the steps below. Each business's 3CX setup is slightly different — if these instructions don't match what you see, reach out to your Avoca Customer Success Manager or 3CX customer support for assistance. ## Setting Up Avoca for After-Hours Log into 3CX and navigate to **Settings** in the left sidebar, then click **Call Forwarding** and **Away**. Open the **"Forward external calls to"** menu and select **External Number**. Enter your Avoca number in the field to the right. You may need to remove any parentheses and spaces so the number is formatted in a way 3CX understands. Changes save automatically, but refresh the page and confirm the number is still there. Repeat step 2 for **Do Not Disturb**, **Lunch**, and **Business Trip** so you're forwarding to Avoca in all after-hours cases. You may also need to configure your global office hours under **Settings → Time Zone & Office Hours**, depending on your setup. Navigate to **Call Forwarding → Schedule** and enter your call center hours. Enable **"Automatically switch status to Available during office hours"** — this makes the overflow setup below work reliably. ## Setting Up Avoca for Overflow This makes your phones ring first during business hours, then forwards to Avoca if nobody answers. Open the **Call Forwarding → Available** menu. Under **Unanswered Calls**, set the **No Answer Timeout**. Best practice is typically **15–20 seconds** — the window your CSRs have to pick up before overflow goes to Avoca. Under **Unanswered Calls**, set **"Forward external calls to" → External Number** and enter your Avoca number. Under **Busy or not Registered**, set **"Forward external calls to" → External Number** and enter your Avoca number. Check **"Accept multiple calls"** at the bottom (if appropriate for your setup). **Once you've completed this process, place a test call during business hours for overflow, and a call after-hours, to ensure routing is working correctly.** This final step matters because the process can differ slightly for each company on 3CX depending on your setup. # Dialpad Source: https://help.avoca.ai/config/call-forwarding/dialpad Set up your Avoca number in Dialpad (ServiceTitan Phones Pro) In order for your calls to be routed to Avoca, your team needs to ensure that the fallback number associated with your phone setup is set to Avoca. If your ServiceTitan phone provider is **Phones Pro**, ServiceTitan provides a Dialpad where this configuration happens. Your Avoca forwarding number is provided by your Customer Success Manager. ## Set Avoca as Your Fallback (Overflow) In Dialpad, navigate to **Settings → Main Line**. Scroll down to **Call Routing** and click **Edit Call Routing**. Make sure you're viewing **Open Hours Routing**, then scroll to **Fallback Options**. If your fallback is set to another internal contact center, set up Avoca call forwarding in the **Contact Center** menu instead of the Main Line — configuring it on the Main Line may cause routing issues. And if you have multiple departments, set up call forwarding within **each** department. Click **"To a team member, room phone, or external number"** and add your Avoca number. Press Enter. If you don't see this option, review Dialpad's [external and outside transfer guide](https://help.dialpad.com/docs/enable-external-outside-transfers) and contact Dialpad Customer Care if your plan still requires them to enable it. ## Set Avoca as Your After-Hours Routing In the same **Edit Call Routing** view, select **Closed Hours Routing** and make sure **Routing Options** is set to **No Operator**. Click **"To a team member, room phone, or external number"** and add your Avoca number. Make sure you get a **"Changes Saved!"** notification. ## Troubleshooting If you don't see **Fallback Options** on the Main Line, your calls may route through a default Contact Center instead: 1. Go to **Settings → Contact Center**. 2. Find the default Contact Center. 3. Apply the same fallback and closed-hours steps inside the Contact Center's routing settings. ## Removing the "This Is a Recorded Call" Announcement To prevent the recorded-call announcement from playing when your Avoca number answers, add the Avoca number to Dialpad's recording **exception list**: **For Departments:** 1. Log in to Dialpad and open your **Admin Settings**. 2. Click **Departments** and choose the department to configure. 3. Open **Advanced Settings** and find **Automatic Call Recording**. 4. Check **"Automatically record calls to this department"**, then click **Edit Exception List**. 5. Add only the full Avoca forwarding number to exclude it from recording and the announcement. Do not enter an area code or number pattern, which could also exclude unrelated calls. **For Contact Centers:** 1. In **Admin Settings**, click **Contact Centers** and choose the one to configure. 2. Open **Advanced Settings** and find **Automatic Call Recording and Transcription**. 3. Select which call types to record, then click **Edit Exception List** and add the Avoca number. Calls to or from a number on the exception list are not recorded by Dialpad and the announcement is omitted. Before suppressing it, confirm your recording and disclosure requirements with your legal or compliance owner. Avoca's recording and disclosure settings are configured separately in your Avoca account. ## Test Your Routing Place one test call during business hours (let it ring until it overflows to Avoca) and one after hours (should reach Avoca immediately). # Five9 Source: https://help.avoca.ai/config/call-forwarding/five9 Forward calls from Five9 to Avoca for after-hours and overflow coverage Use this setup if your marketing tracking numbers or ServiceTitan tracking numbers ring into **Five9**, and you want Five9 to forward those calls to your Avoca number. ## Before You Start * Have your **Avoca forwarding number** ready (provided by your Avoca team). * Decide whether you want **after-hours** forwarding, **overflow / no-answer** forwarding, or **always forward** (Avoca answers first). In Five9, you route the inbound call to a point in your flow where Five9 places an outbound leg to an **external PSTN number** (your Avoca number) — either as an IVR step or as a fallback rule when a queue is closed, busy, or times out. ## Overflow Setup in the IVR Open the Five9 IVR editor and select the inbound IVR that receives the calls you want Avoca to cover. Select the Agent Transfer module used for the queue or overflow path and open its properties. Open the module's **Voice Mail** tab. This prevents calls from dropping into voicemail instead of overflowing to Avoca. In the **General** tab, set a suitable **Max Queue Time** so the caller stays on the line until the call moves to the next module, and set **Agent Transfer** to the phone number Avoca shared with you. On newer Five9 versions, the Agent Transfer module may not accept an external number. In that case, add a **third-party transfer module** instead — see [Five9's documentation](https://documentation.five9.com/bundle/ivr-admin/page/ivr-admin/modules/third-party-transfer-module.htm). ## Recommended Configurations * **After-hours forwarding** — when the queue is closed, route to **External Transfer → Avoca number**. * **Overflow (delay) forwarding** — let agents ring for a set timeout (typically **15–30 seconds**, depending on staffing), then route to **External Transfer → Avoca number**. * **Busy / max queue depth** — if the queue hits capacity, route to **External Transfer → Avoca number**. Five9 terminology and menus vary by account configuration. The key requirement is that the call is transferred to an **external phone number** (PSTN), with caller ID preserved if your Five9 policy supports it. ## Test 1. Place a test call during business hours and confirm it behaves as expected (answered by your team, or forwarded after the configured delay). 2. Place a test call after hours (or simulate closed hours) and confirm it forwards immediately to Avoca. # Intermedia Source: https://help.avoca.ai/config/call-forwarding/intermedia Forward Intermedia Unite hunt groups or auto attendants to Avoca Use this setup if your phone numbers route through **Intermedia Unite** and you want Intermedia to send calls to your Avoca forwarding number for overflow, after-hours, or temporary primary routing. Your Avoca forwarding number is provided by your Avoca Customer Success Manager or Technical Account Manager. Intermedia call flows vary by account. Many teams route inbound calls through an **Auto Attendant** and then into a **Hunt Group**. Configure the object that callers actually reach. If you are not sure, trace the inbound number's route before changing forwarding. ## Set Avoca as Your Hunt Group Overflow This keeps your team answering first, then forwards calls to Avoca if nobody answers within the timeout. Log in to Intermedia **HostPilot** as an admin. Navigate to **Services → Unite → Hunt Groups**, then select the Hunt Group that receives inbound calls from your main line, Auto Attendant, or tracking number. Find the Hunt Group's timeout or advanced timeout setting. Enable the timeout if it is not already enabled. Set **Timeout to** or **Move a call to** to **Phone Number**, then enter your Avoca forwarding number. Choose how long Intermedia should ring your team before forwarding to Avoca. A common starting point is **15-30 seconds**, depending on staffing and ring behavior. Intermedia notes that if the external number timeout is too long, another voicemail system may pick up before the expected route finishes. Always place a test call and confirm Avoca answers instead of voicemail. Save the Hunt Group and confirm the Avoca number remains selected as the timeout destination. ## Set Avoca as Your After-Hours Destination Use this if your team answers during business hours and Avoca answers when the office is closed. Check whether your account uses **Night Mode**, an **Auto Attendant after-hours menu**, or Hunt Group schedules. Navigate to **Intermedia Unite → Settings → Night Mode profiles**, select the profile used for after-hours routing, then open **Forwarding**. Add forwarding for the Hunt Group that should route to Avoca, choose **Phone number**, and enter your Avoca forwarding number. Night Mode sends Auto Attendants to their **After Hours** menu instead of asking for a forwarding destination. Open the Auto Attendant's **After Hours** settings and route the after-hours option to your Avoca forwarding number or to a Hunt Group whose timeout destination is Avoca. Save the routing changes and confirm the after-hours or Night Mode schedule is active when you expect it to be. ## Temporary Primary Forwarding Use this when Avoca should answer every call immediately, or when you need a temporary failover route during a staffing issue or outage. In HostPilot, navigate to **Services → Unite → Auto Attendant** and find the Auto Attendant that receives the inbound number. Click **Call routing override**, enter your Avoca forwarding number, and save the change. Intermedia Call Routing Override is manual. It forwards calls immediately while enabled, and it must be manually disabled when you want calls to return to the normal Auto Attendant flow. Call the forwarded number and confirm Avoca answers before using this in production. ## Troubleshooting ### Calls never reach Avoca Confirm you updated the Hunt Group or Auto Attendant that callers actually reach. Many Intermedia accounts have multiple Hunt Groups, Auto Attendants, or Night Mode profiles, and changing one object may not affect the route used by the public number. ### Calls go to voicemail instead of Avoca Review the Hunt Group timeout destination and voicemail settings. If the timeout destination is voicemail, company voicemail, or the current Hunt Group's voicemail, callers will not reach Avoca. ### After-hours behavior is inconsistent Check whether Night Mode is active and whether the Auto Attendant has its own after-hours menu. Night Mode can override normal Hunt Group or Auto Attendant behavior, so confirm which profile is active during your test. ### The call reaches Avoca too late Shorten the Hunt Group timeout. If callers wait too long, they may hang up before Avoca answers. ## Test Your Routing 1. Place a test call during business hours and let the Hunt Group timeout forward the call to Avoca. 2. Place a test call after hours, or turn on the relevant Night Mode/after-hours route, and confirm it reaches Avoca immediately. 3. If you used Call Routing Override, turn it off after testing unless Avoca should remain the primary answer path. 4. Send your Avoca team the Intermedia object you changed, the phone number tested, and whether the route is overflow, after-hours, or primary. ## Intermedia References * [Managing Hunt Groups on Intermedia Unite](https://support.intermedia.com/app/articles/detail/a_id/15235/~/managing-hunt-groups-on-intermedia-unite) * [Advanced Hunt Group General Settings](https://support.intermedia.com/app/articles/detail/a_id/27115/~/advanced-hunt-group-general-settings-on-intermedia-unite) * [Night Mode for Auto Attendants and Hunt Groups](https://support.intermedia.com/app/articles/detail/a_id/24407/~/night-mode-for-auto-attendants-and-hunt-groups) * [Call Routing Override](https://support.intermedia.com/app/articles/detail/a_id/23609) # Call Forwarding Overview Source: https://help.avoca.ai/config/call-forwarding/overview How to route calls from your phone system to Avoca — primary, after-hours, and overflow coverage This guide explains how calls from your phone system reach Avoca — either as your **primary call handling**, or as **after-hours** and **overflow (delay) coverage**. Provider-specific step-by-step guides: [Dialpad](/config/call-forwarding/dialpad), [RingCentral](/config/call-forwarding/ringcentral), [3CX](/config/call-forwarding/3cx), [Five9](/config/call-forwarding/five9), and [Intermedia](/config/call-forwarding/intermedia). ## Before You Start * Have your **Avoca forwarding number** ready — provided by your Avoca Customer Success Manager or Technical Account Manager. * Confirm which phone setup you use: * **ServiceTitan Phones (Phones Pro / Dialpad)** * **Your own phone system** (e.g., 3CX, Five9, RingCentral) * Decide the routing behavior you want: | Routing mode | Behavior | | - | - | | **Primary** | Avoca answers first, every call | | **After-hours** | Your team answers during business hours; Avoca answers after hours | | **Overflow (delay)** | Your team gets first chance to answer; Avoca picks up if no one answers within a set timeout | ## How Forwarding Works (High Level) 1. You advertise your existing phone numbers (for ServiceTitan users, typically **ServiceTitan tracking numbers**). 2. Your phone system's call routing is configured so that the relevant line **forwards to your Avoca number** — always, after hours, or on overflow. 3. Avoca's AI answers the forwarded leg, handles the conversation, and books the job. For ServiceTitan users, forwarding the **tracking number itself** keeps the call anchored to the original tracking number, so the entire interaction is tracked in ServiceTitan as a single continuous phone call. ## Choosing the Right Setup * **ServiceTitan Phones Pro / Dialpad** → use the [Dialpad guide](/config/call-forwarding/dialpad) (Fallback Options + Closed Hours Routing) * **RingCentral** → use the [RingCentral guide](/config/call-forwarding/ringcentral) (Forward to External number for overflow, plus closed-hours routing) * **3CX** → use the [3CX guide](/config/call-forwarding/3cx) (after-hours statuses + overflow timeouts) * **Five9** → use the [Five9 guide](/config/call-forwarding/five9) (IVR external transfer) * **Intermedia Unite** → use the [Intermedia guide](/config/call-forwarding/intermedia) (Hunt Group timeout + Night Mode routing) * **Another provider** → most systems support forwarding to an external number on no-answer, busy, or closed-hours conditions. Point that destination at your Avoca number, and contact your Avoca team if you'd like help. ## What Calls Look Like in ServiceTitan * If the caller dialed a **ServiceTitan tracking number**, ServiceTitan shows the incoming call against that tracking number; Avoca answers on the forwarded leg. Call outcomes, notes, and bookings sync back to the call record based on your account configuration. * If the caller dialed a **non-ServiceTitan number**, ServiceTitan may not automatically have a matching call record unless a separate tracking setup exists. * Typical call records include the customer's caller ID, the line dialed, duration, and recording (if enabled), plus Avoca's synced notes, outcomes, and any bookings or jobs created. ## Common Pitfalls * **You saved the number but routing still goes elsewhere** — check whether calls route via the Main Line or a Contact Center/department (Dialpad), and configure forwarding where the calls actually flow. * **Overflow never triggers** — confirm the no-answer timeout is set (15–20 seconds is a common starting point) and the line isn't configured to hit voicemail first. * **After-hours routing doesn't switch** — confirm your office-hours schedule is configured in your phone system. ## Test Your Routing (Required) 1. Place a test call **during business hours** and let it ring until it overflows to Avoca. 2. Place a test call **after hours** and confirm it reaches Avoca immediately. ## What to Send Avoca After Setup Share with your Avoca team: * Which phone system you used (Dialpad / RingCentral / 3CX / Five9 / Intermedia / other) * The phone number(s) that now forward to Avoca * Your intended routing behavior (primary, after-hours, or overflow — and the delay duration) * Confirmation that you completed the test calls ## Advanced Routing Need different forwarding behaviors or multiple Avoca numbers? Avoca supports granular options, configured with your account manager: * **Time-based routing** — different destinations by time of day, day of week, or custom schedules * **Call type-based routing** — emergency vs. estimate vs. service calls to different destinations * **Multi-number configurations** — unique rules per phone number # RingCentral Source: https://help.avoca.ai/config/call-forwarding/ringcentral Forward RingCentral call queues to Avoca for overflow, after-hours, or primary call handling Use this setup if your marketing tracking numbers, ServiceTitan tracking numbers, or main business lines route into **RingCentral**, and you want RingCentral to send calls to your Avoca forwarding number. RingCentral's current plan names are **Core**, **Advanced**, and **Ultra**; legacy accounts may still show **Standard**, **Premium**, or **Ultimate**. RingCentral's current [plan comparison](https://assets.ringcentral.com/us/datasheet/cloud-communications-comparison.pdf) lists advanced call-queue routing for Advanced and Ultra. If **Forward to External number** is missing, confirm your account's entitlement with RingCentral. Your Avoca forwarding number is provided by your Avoca Customer Success Manager or Technical Account Manager. RingCentral menus vary by plan and account configuration. These steps are written for the common **Call Queue** setup. If you do not see **Forward to External Number** in the places below, your RingCentral plan may need that option enabled, or your call flow may be using an IVR, Auto-Receptionist, or another queue instead. ## Set Avoca as Your Overflow Destination This keeps your team answering first during business hours, then sends calls to Avoca if nobody answers or the queue waits too long. Sign in to the [RingCentral Admin Portal](https://service.ringcentral.com/) as an admin. Navigate to **Phone System → Groups → Call Queues**, then select the call queue that receives the calls you want Avoca to answer. If the phone number first lands in an IVR or Auto-Receptionist, follow the routing path from that menu to the call queue that actually rings your team. Configure the queue that callers reach, not just the top-level company number. In the call queue settings, open **Call Handling & Members**. In the wait or advanced call-handling settings, find the rule for **when no one answers**. Set it to **Forward to External Number** and enter your Avoca forwarding number. In the **When members are available, but no members answer or all members are busy or unavailable, caller wait for** dropdown, select **Forward to External number** and enter your Avoca forwarding number. RingCentral treats **no answer** and **busy / unavailable** as separate controls. Configuring only no-answer forwarding still sends busy-state calls to the existing fallback (often voicemail) instead of Avoca. **Primary and Overflow Members** sends calls to other RingCentral call queues. It does not route calls to your Avoca forwarding number. If you want Avoca to catch callers who wait too long or reach a full queue, also set **when the maximum wait time is reached** and **when the queue is full** to **Forward to External Number**, then enter your Avoca forwarding number for each condition. Set the queue wait time or no-answer delay before Avoca receives the call. A common starting point is **15-30 seconds**, depending on how long you want your team to have before overflow. If the delay is too long, callers may hang up before Avoca answers. If the delay is too short, Avoca may answer calls your team could have handled. Test with your Avoca team and adjust after launch. Save the call queue settings and confirm the Avoca number remains in the forwarding destination. ## Set Avoca as Your After-Hours Destination Use this if your team should answer during business hours and Avoca should answer when the queue is closed. In the same call queue, open the business-hours schedule and verify it is **not** set to always open / 24/7. Confirm the **days**, **hours**, **holidays**, and **time zone** match when your office is actually closed. The after-hours forwarding destination only applies during that closed period — if the queue stays always open, you can save an Avoca destination and after-hours calls will still follow normal open-hours handling. For the closed-hours or after-hours rule, choose the option that forwards calls to an **external number**, then enter your Avoca forwarding number. Save the schedule and confirm the after-hours destination is the Avoca number. ## Set Avoca as Primary Call Handling Use this if Avoca should answer first for the selected line or queue. Find the RingCentral object that receives the inbound number: usually a **Call Queue**, **IVR**, or **Auto-Receptionist** route. If several numbers or departments share the same Auto-Receptionist or IVR, forwarding that object to Avoca affects **every** route that enters it — not only the line you intend. Prefer changing only the intended **downstream branch** (for example, the specific call queue or menu option for that department). If you must forward a shared Auto-Receptionist, first list its other inbound numbers and confirm none of them should keep their current department routing. Configure the chosen route to forward callers to an **external number** and enter your Avoca forwarding number. Only use primary forwarding when you intend for Avoca to answer before your team. For most teams, overflow or after-hours forwarding is safer during initial launch. Save the route and place a test call to confirm Avoca answers immediately. Also spot-check any other numbers that share the same Auto-Receptionist so they did not unexpectedly divert to Avoca. ## Troubleshooting ### Calls still go to voicemail Check the queue's **when no one answers**, **busy or unavailable**, **maximum wait time**, and **queue full** rules. If voicemail is selected for one of those conditions, RingCentral may send callers to voicemail instead of Avoca. ### The external number option is missing RingCentral plan settings can affect whether **Forward to External Number** appears for call queues. Contact RingCentral Support or your RingCentral admin if you only see voicemail, announcement, extension, or group destinations. ### Avoca is not receiving caller ID Confirm that the call is forwarded as a normal external phone call and that caller ID is preserved by the RingCentral route. If you use ServiceTitan tracking numbers, test with the exact tracking number callers will dial so your Avoca team can confirm how the call appears. ### Multiple queues or locations route differently Repeat the setup for every queue, location, department, or IVR branch that should use Avoca. Updating one queue does not automatically update every RingCentral route. ## Test Your Routing 1. Place a test call during business hours and let the queue ring until it overflows to Avoca. 2. Place a test call after hours or temporarily simulate closed hours and confirm it reaches Avoca immediately. 3. Send your Avoca team the RingCentral object you changed, the phone number tested, and the intended routing behavior. ## RingCentral References * [Managing call handling settings for call queues](https://support.ringcentral.com/article-v2/10514-call-queue-set-up-call-handling-how-calls-transferred-group-members.html) * [RingEX plan comparison](https://assets.ringcentral.com/us/datasheet/cloud-communications-comparison.pdf) * [Call queue routing options](https://support.ringcentral.com/release-notes/mvp/mvp-core/release-notes-june-2025.html) # API Integration Guide Source: https://help.avoca.ai/custom-integration/api-integration-guide End-to-end contract expectations for your custom integration with Avoca # API Integration Guide Use this handbook to align your custom integration API implementation with Avoca’s integration patterns. Each section outlines the baseline contract, validation rules, and operational playbooks we need before moving into certification. *** ## 1. API Foundations * **HTTPS everywhere** – Publish sandbox and production base URLs (for example, `https://sandbox.example.com/rest/forms/v1` and `https://api.example.com/rest/forms/v1`). Lock both to TLS 1.2+ and document any mutual-auth requirements. * **Header-based credentials** – Avoca sends a single authorization header per environment (e.g., `Authorization: Basic {token}`). Specify how secrets are rotated, distribution procedures, and any IP allow-listing so we can automate credential refresh. * **Two-step payload workflow** – Every transactional endpoint follows the same handshake: ```http theme={null} GET {base}/payload # returns { "data": { "payloadId": "" } } POST {base}/payload/{payloadId}/submit ``` * Document request/response schemas for `POST` calls, including required metadata inside the JSON body. * Capture timeout expectations (default 10 s) and retry limits (Avoca retries once after 500 ms unless flagged non-retryable). * Define validation error semantics: HTTP status codes, response envelope, and field-level error structure. * **Idempotency rules** – State whether resubmitting the same `payloadId` is rejected, overwritten, or treated as a no-op. If duplicates are detected, identify the error code and guidance so Avoca can distinguish retryable vs terminal failures. * **Response formats** – Prefer JSON bodies. If an endpoint must return plain text or mixed content, provide a schema (for example, `text/csv`, `text/plain` with delimiter notes) so Avoca can parse it safely. List any exceptions explicitly. *** ## 2. Customer & Identity Workflows * **Lookup by ID** – The response should include the full customer profile: primary and secondary addresses, scheduled appointments, equipment metadata, and free-form notes. Document which arrays may be empty and how null values appear. * **Customer creation** – Accept a constrained payload: customer name (≤30 characters), uppercase abbreviated address fields, `customerType` (`RES`/`COM`), campaign code, primary/secondary phone numbers, optional email. Specify formatting (e.g., phone digits only) and validation error messages. Include how you echo back or reference the new customer ID in the success payload. * **Propagation timing** – Clarify how long new customers take to surface in lookup endpoints. Note any throttling, duplicate-customer blocks, or rate limits so Avoca can pace retries appropriately. *** ## 3. Booking & Job Management * **Call-type catalogue** – Publish the enumerated call-type codes (`SC`, `CC`, `E`, `P`, etc.) with human-readable descriptions, and note whether additions are backward-compatible or require coordination. * **Job creation payload** – Require: `customerId`, formatted `callerPhone`, `campaignCode`, `callType`, `scheduledDate` (`YYYYMMDD`), `scheduledStartTime`/`scheduledEndTime` (`HHMM`), and default `salesPersonId`. Identify optional fields and how validation errors surface when time windows overlap or fall outside operating hours. * **Customer linkage** – If jobs must reference an existing customer, document failure envelopes for missing or invalid IDs and the remediation path (e.g., retry after lookup, create customer first). *** ## 4. Equipment & Parts * **Equipment submission** – Accept: customer number, sequential equipment number, `itemCode`, `serialNumber`, install flag (`Y`/`N`), numeric `ageYears`, optional `ladderSize`/`equipmentLocation`, problem notes, and problem codes. Document accepted enumerations and numeric formats. * **Part submission** – Link to equipment sequence numbers and require `partCode`, `quantity`, and `unitPrice`. Provide the canonical part-code dictionary (code, description, default price) and the escalation path to request new codes. * **Order dependencies** – Clarify workflow ordering (equipment before parts before job) and whether endpoints enforce uniqueness, allow updates, or support partial replacements. *** ## 5. Availability & Scheduling * **Timeframe endpoint** – Supply a high-level availability feed (e.g., array of dates or windows) that explains how to interpret empty results and standardized error responses. * **Granular slot lookup** – If supported, define a `GET` endpoint that accepts query parameters such as `callType`, `date` (`YYYYMMDD`), `equipmentAge`, and `installedByUs`. Return structured slots (`start`, `end`, `capacity`, `technicianType`) and document parameter validation rules with sample queries. *** ## 6. Operational Expectations * **Retries & SLAs** – Outline service-level targets, max retry guidance, and the contact route for automated timeout alerts. Avoca emails both teams after two failures—share the distribution group that should receive escalations. * **Credential & data hygiene** – Document rotation cadence for sandbox and production secrets, how sandbox data is refreshed, and any blackout periods that affect testing or deployments. * **Security & compliance** – List supported TLS versions, mutual-auth or certificate pinning requirements, logging/monitoring expectations, and any auditing or transcript retention policies that apply to payload contents. *** ## 7. Next Steps Review these guidelines with your engineering team, confirm sample payloads, and align on incident escalation contacts. Once the contract is finalized, Avoca will schedule certification testing that validates handshake behavior, error handling, and end-to-end workflows. # API & Integration Methods Source: https://help.avoca.ai/custom-integration/api-methods Endpoint design, authentication, and REST standards for the custom integration # API and Integration Methods This page is a **recommended specification for the API your team exposes to Avoca** — not documentation of existing Avoca endpoints. Production custom integrations today use the [two-step payload handshake pattern](/custom-integration/payload-handshake); a standard REST design like the one below is equally supported for new integrations. Endpoint paths, field names, and shapes are adapted to your system during the integration process. ### Recommended API Endpoints **Availability Management** ```http theme={null} GET /api/v1/availability ``` Purpose: Query available appointment slots Required parameters: * `service_type` (string) * `location_id` (string) * `date_range_start` (ISO 8601 datetime) * `date_range_end` (ISO 8601 datetime) * `provider_id` (string, optional) * `duration_minutes` (integer, optional) Sample request: ```json theme={null} { "service_type": "inspection", "location_id": "LOC-12345", "date_range_start": "2025-11-01T08:00:00Z", "date_range_end": "2025-11-07T18:00:00Z", "duration_minutes": 60 } ``` Expected response: ```json theme={null} { "available_slots": [ { "slot_id": "SLOT-789", "start_time": "2025-11-01T09:00:00Z", "end_time": "2025-11-01T10:00:00Z", "provider_id": "PROV-456", "provider_name": "John Smith", "price": 150.0, "currency": "USD" } ], "total_slots": 15, "next_available": "2025-11-01T09:00:00Z" } ``` **Booking Creation** ```http theme={null} POST /api/v1/bookings ``` Purpose: Create new appointment booking Required fields: * `slot_id` (string) * `customer` (object) – `name`, `email`, `phone`, and optional `address` * `service_type` (string) * `notes` (string, optional) * `notification_preferences` (object, optional) Sample request: ```json theme={null} { "slot_id": "SLOT-789", "customer": { "name": "Jane Doe", "email": "jane.doe@example.com", "phone": "+1-555-0123", "address": { "street": "123 Main St", "city": "Springfield", "state": "IL", "zip": "62701" } }, "service_type": "inspection", "notes": "Prefer morning appointments", "notification_preferences": { "sms": true, "email": true, "reminder_hours_before": 24 } } ``` Expected response: ```json theme={null} { "booking_id": "BOOK-12345", "confirmation_number": "CONF-ABC123", "status": "confirmed", "appointment_time": "2025-11-01T09:00:00Z", "customer": {}, "provider": {}, "created_at": "2025-10-31T14:30:00Z" } ``` **Booking Modifications** ```http theme={null} PATCH /api/v1/bookings/{booking_id} # Update existing booking PUT /api/v1/bookings/{booking_id}/cancel # Cancel existing booking GET /api/v1/bookings/{booking_id} # Retrieve booking details ``` Cancellation payload fields: * `reason` (string, optional) * `cancellation_type` (string: `customer_initiated`, `provider_initiated`) **Customer Management** ```http theme={null} GET /api/v1/customers/{customer_id} # Retrieve customer profile/history POST /api/v1/customers # Create customer profile PATCH /api/v1/customers/{customer_id}# Update customer details ``` **Service Catalog** ```http theme={null} GET /api/v1/services # Retrieve available services and pricing GET /api/v1/services/{service_id} # Detailed service information ``` **Pricing Queries** ```http theme={null} POST /api/v1/pricing/calculate ``` Purpose: Calculate pricing for a specific service configuration Required fields: * `service_type` (string) * `location_id` (string) * `modifiers` (array, optional) – add-ons, special requirements ### Integration Protocols & Standards **Primary Protocol: RESTful APIs** * Format: JSON (UTF-8 encoding) * Versioning: URL-based (e.g., `/api/v1/`) * HTTP methods: Full REST semantics (GET, POST, PATCH, PUT, DELETE) * Status codes: Standard HTTP status codes with detailed error responses **Webhook Support (Strongly Recommended)** – Avoca consumes webhooks for real-time event notifications. Webhook events we should receive: ``` booking.confirmed – Booking successfully created booking.updated – Booking details modified booking.cancelled – Booking cancelled booking.reminder – Appointment reminder (optional) availability.changed – Availability slots updated service.updated – Service catalog changes pricing.updated – Pricing changes ``` Webhook payload format: ```json theme={null} { "event_type": "booking.confirmed", "event_id": "evt_12345", "timestamp": "2025-10-31T14:30:00Z", "data": { "booking_id": "BOOK-12345", "status": "confirmed" } } ``` Webhook requirements: * Endpoint: We provide a unique webhook endpoint URL per integration * Security: HMAC signature verification (preferred) or secret token in header * Delivery: At-least-once delivery with retry logic * Response: 200 OK within 5 seconds * Idempotency: Duplicate webhook deliveries handled via `event_id` **GraphQL (Optional)** – We can support GraphQL if preferred. It reduces over-fetching, is useful for nested queries, and can coexist with REST endpoints. ### Authentication Methods **Preferred: OAuth 2.0 Client Credentials Flow** Implementation details: * Grant type: `client_credentials` * Token endpoint: `/oauth/token` * Token format: JWT (preferred) or opaque tokens * Token expiration: 1 hour recommended * Refresh strategy: Automatic refresh before expiration * Scopes: Role-based (e.g., `bookings:read`, `bookings:write`, `customers:read`) Request: ```http theme={null} POST /oauth/token Content-Type: application/x-www-form-urlencoded grant_type=client_credentials& client_id={our_client_id}& client_secret={our_client_secret}& scope=bookings:read bookings:write availability:read ``` Response: ```json theme={null} { "access_token": "eyJhbGc...", "token_type": "Bearer", "expires_in": 3600, "scope": "bookings:read bookings:write availability:read" } ``` **Alternative: API Keys** – If OAuth is not feasible: * API keys transmitted via `Authorization: Bearer {api_key}` * Separate keys for production and sandbox * Key rotation with grace period * Rate limiting and monitoring per API key **JWT Tokens** – If using JWT directly: * Algorithm: RS256 or ES256 (asymmetric preferred) * Claims: Include `iss`, `aud`, `exp`, `sub` * Key management: Public key endpoint for signature verification **Security Requirements** * Credentials stored in encrypted secrets management (1Password, AWS Secrets Manager) * Credentials never logged or exposed in errors * Automatic credential rotation supported * Per-environment credentials (development, staging, production) ### API Design Preferences **Data Formats** * Primary: JSON with UTF-8 encoding * Date/time: ISO 8601 (e.g., `2025-10-31T14:30:00Z`) * Decimal numbers: String representation for currency to avoid floating-point drift **Versioning Strategy** * URL-based versioning (e.g., `/api/v1/`) * Maintain at least one previous major version for backward compatibility * Deprecation notices: Minimum 90-day notice with `Sunset` HTTP header * Version negotiation: Current version advertised in response headers **Rate Limiting** * Recommended thresholds: * Standard operations: 1000 requests/minute per API key * Availability queries: 300 requests/minute * Bulk operations: 100 requests/minute * Rate limit headers: ``` X-RateLimit-Limit: 1000 X-RateLimit-Remaining: 847 X-RateLimit-Reset: 1698765432 ``` * 429 responses should include clear retry-after guidance * Allow reasonable burst capacity (e.g., 2× sustained rate for 10 seconds) **Pagination** ```http theme={null} GET /api/v1/bookings?page=2&per_page=50 # or GET /api/v1/bookings?cursor=eyJpZCI6MTIzfQ&limit=50 ``` Sample response: ```json theme={null} { "data": [], "pagination": { "total": 500, "page": 2, "per_page": 50, "next_cursor": "eyJpZCI6MTczfQ" } } ``` **Error Response Format** ```json theme={null} { "error": { "code": "SLOT_UNAVAILABLE", "message": "The requested time slot is no longer available", "details": { "slot_id": "SLOT-789", "reason": "booked_by_another_customer" }, "request_id": "req_abc123", "timestamp": "2025-10-31T14:30:00Z" } } ```
# Customization & AI Behavior Source: https://help.avoca.ai/custom-integration/customization-behavior Business rules, conversational handling, and personalization controls # Customization and AI Behavior Business rules (service areas, advance-notice windows, call-type eligibility, pricing) can be delivered two ways: **configured directly in Avoca** during onboarding — how current production integrations work — or **exposed via API** using shapes like the reference designs below for rules that change frequently. The endpoints on this page are a recommended specification for your API, not existing Avoca endpoints. ### Business Rules API Options **Eligibility & Validation Rules** ```http theme={null} GET /api/v1/business-rules/eligibility ``` Response: ```json theme={null} { "service_type": "inspection", "eligibility_rules": [ { "rule_id": "RULE-001", "type": "geographic", "condition": "customer_zip_code in service_area", "service_areas": ["62701", "62702", "62703"] }, { "rule_id": "RULE-002", "type": "temporal", "condition": "booking_advance_hours >= 24", "message": "Bookings require 24-hour advance notice" } ] } ``` **Dynamic Pricing Rules** ```http theme={null} GET /api/v1/business-rules/pricing ``` Response: ```json theme={null} { "base_pricing": { "inspection": 150.0, "maintenance": 200.0 }, "modifiers": [ { "type": "time_of_day", "condition": "hour < 8 OR hour > 18", "adjustment": "+25%", "label": "After-hours fee" }, { "type": "urgency", "condition": "booking_advance_hours < 48", "adjustment": "+50.00", "label": "Rush service" } ], "promotions": [ { "code": "SAVE20", "discount": "-20%", "valid_until": "2025-12-31", "conditions": ["first_time_customer"] } ] } ``` **Upselling & Cross-Selling Opportunities** ```http theme={null} GET /api/v1/services/{service_id}/recommendations ``` Response: ```json theme={null} { "primary_service": "inspection", "recommendations": [ { "service_id": "SVC-456", "name": "Maintenance Package", "description": "Annual maintenance plan", "price_increment": 100.0, "conversion_rate": 0.35, "talking_points": [ "Save 20% compared to individual visits", "Priority scheduling for members" ] } ] } ``` ### Training & Fine-Tuning Data Requirements **Historical Data for AI Training** – Request anonymized historical data: **Booking Patterns** ```http theme={null} GET /api/v1/analytics/bookings/export ``` Parameters: `date_range_start`, `date_range_end`, `anonymized=true` Purpose: Understand booking patterns, peak times, conversion factors Data needed: timestamps, service types, booking lead times, completion rates, cancellation reasons, interaction counts before booking **Conversation Transcripts (if available)** – Anonymized call transcripts, common questions and objections, successful booking flows, cancellation/modification patterns. **Service Performance Metrics** – Popular services, seasonal demand, geographic distribution, pricing sensitivity. **Data Privacy Commitments** * All training data fully anonymized (no PII) * Data used solely for AI improvement * Retention limited to training purposes * Compliance with GDPR and CCPA processing requirements * Data processing agreement (DPA) established before transfer ### Branding & Content APIs **Dynamic Script Content** ```http theme={null} GET /api/v1/content/scripts/{script_id} ``` Response: ```json theme={null} { "script_id": "welcome_call", "version": "2.1", "content": { "greeting": "Thank you for calling {company_name}. How can I help you today?", "service_intro": { "inspection": "Our certified inspectors provide comprehensive...", "maintenance": "Regular maintenance ensures..." }, "closing": "Is there anything else I can help you with today?" }, "variables": { "company_name": "Your Company", "phone_number": "1-800-555-0123" }, "updated_at": "2025-10-15T10:00:00Z" } ``` **Service Descriptions** ```http theme={null} GET /api/v1/content/services/{service_id}/description ``` Response: ```json theme={null} { "service_id": "SVC-123", "name": "Residential Inspection", "short_description": "Comprehensive home inspection service", "long_description": "Our certified inspectors examine...", "key_benefits": [ "Certified professionals", "Same-day reporting", "Satisfaction guaranteed" ], "duration": "60 minutes", "what_to_expect": "Our inspector will arrive...", "updated_at": "2025-10-15T10:00:00Z" } ``` **Voice Prompts & Branding** ```http theme={null} GET /api/v1/content/voice-prompts ``` Response: ```json theme={null} { "prompts": [ { "prompt_id": "hold_music", "url": "https://cdn.example.com/audio/hold.mp3", "duration_seconds": 180 }, { "prompt_id": "business_hours", "text": "Our business hours are Monday through Friday...", "audio_url": "https://cdn.example.com/audio/hours.mp3" } ] } ``` **Caching Strategy for Content** * Scripts and content cached with 24-hour TTL * Webhook notifications (`content.updated`) for immediate updates * Version numbers enable cache validation
# Data Exchange & Booking Process Source: https://help.avoca.ai/custom-integration/data-exchange Schemas, response patterns, and omnichannel booking flows # Data Exchange and Appointment Booking Process The schemas below are **reference shapes for the contract between Avoca and your API** — they illustrate the information Avoca can send and expects back, and are tailored to your system's actual field names and formats during the integration process. Existing production integrations use flatter, partner-specific payloads over the [payload handshake](/custom-integration/payload-handshake). Optional blocks (e.g. `notifications_sent`) apply only if your system provides them — customer notifications are typically sent by your system, not by Avoca. ### Inbound Data Schema (AI → Your APIs) **Booking Request Schema** ```json theme={null} { "booking": { "slot_id": "SLOT-789", "service": { "type": "inspection", "category": "residential", "add_ons": ["express_service"], "duration_minutes": 60 }, "customer": { "id": "CUST-123", "name": { "first": "Jane", "last": "Doe" }, "contact": { "email": "jane.doe@example.com", "phone": "+15550123", "preferred_method": "sms" }, "address": { "street_1": "123 Main St", "street_2": "Apt 4B", "city": "Springfield", "state": "IL", "zip": "62701", "country": "US" } }, "preferences": { "language": "en", "special_requests": "Please call before arrival", "accessibility_needs": [], "notification_preferences": { "booking_confirmation": ["email", "sms"], "reminder_24h": ["sms"], "reminder_2h": ["sms"] } }, "metadata": { "source": "voice_call", "campaign_id": "CAMP-456", "referral_code": "REF123", "notes": "Customer mentioned urgent need" } } } ``` **Availability Query Schema** ```json theme={null} { "query": { "service_type": "inspection", "location": { "id": "LOC-123", "or_zip": "62701", "radius_miles": 25 }, "date_range": { "start": "2025-11-01T00:00:00Z", "end": "2025-11-07T23:59:59Z" }, "time_preferences": { "preferred_times": ["morning", "afternoon"], "avoid_days": ["sunday"], "earliest_time": "08:00", "latest_time": "17:00" }, "provider_preferences": { "provider_id": "PROV-456", "attributes": ["certified", "experienced"] }, "filters": { "max_price": 200.0, "duration_minutes": 60 } } } ``` ### Expected API Responses **Success – Availability Check** ```json theme={null} { "status": "success", "request_id": "req_abc123", "data": { "available_slots": [ { "slot_id": "SLOT-789", "start_time": "2025-11-01T09:00:00Z", "end_time": "2025-11-01T10:00:00Z", "provider": { "id": "PROV-456", "name": "John Smith", "credentials": ["Licensed Inspector"], "rating": 4.8 }, "location": { "id": "LOC-123", "name": "Downtown Office", "address": "456 Oak Ave, Springfield, IL" }, "pricing": { "base_price": 150.0, "add_ons": [], "total": 150.0, "currency": "USD" }, "availability_score": 0.95 } ], "total_available": 15, "search_parameters": {} }, "metadata": { "response_time_ms": 145, "cached": false } } ``` **Success – Booking Creation** ```json theme={null} { "status": "success", "request_id": "req_def456", "data": { "booking": { "id": "BOOK-12345", "confirmation_number": "CONF-ABC123", "status": "confirmed", "appointment": { "start_time": "2025-11-01T09:00:00Z", "end_time": "2025-11-01T10:00:00Z", "timezone": "America/Chicago" }, "service": {}, "customer": {}, "provider": {}, "location": {}, "pricing": {}, "notifications_sent": { "confirmation_email": true, "confirmation_sms": true } }, "next_steps": { "customer_actions": [ "Check email for confirmation details", "Add to calendar via provided link" ], "preparation_instructions": "Please arrive 5 minutes early" } }, "created_at": "2025-10-31T14:30:00Z" } ``` **Error – Unavailable Slot** ```json theme={null} { "status": "error", "request_id": "req_ghi789", "error": { "code": "SLOT_UNAVAILABLE", "message": "The requested time slot is no longer available", "type": "booking_conflict", "details": { "slot_id": "SLOT-789", "reason": "recently_booked", "alternative_slots": [ { "slot_id": "SLOT-790", "start_time": "2025-11-01T10:00:00Z" } ] }, "recoverable": true, "suggested_action": "query_alternative_times" }, "timestamp": "2025-10-31T14:30:15Z" } ``` **Error – Validation Failure** ```json theme={null} { "status": "error", "request_id": "req_jkl012", "error": { "code": "VALIDATION_ERROR", "message": "Invalid request parameters", "type": "client_error", "details": { "field_errors": [ { "field": "customer.phone", "error": "invalid_format", "message": "Phone number must include country code", "provided_value": "555-0123" }, { "field": "service_type", "error": "invalid_value", "message": "Service type 'unknown' is not recognized", "valid_values": ["inspection", "maintenance", "repair"] } ] }, "recoverable": true, "suggested_action": "correct_parameters_and_retry" }, "timestamp": "2025-10-31T14:30:15Z" } ``` **Error Codes We Expect** * `SLOT_UNAVAILABLE` * `VALIDATION_ERROR` * `CUSTOMER_NOT_FOUND` * `SERVICE_NOT_AVAILABLE` * `DUPLICATE_BOOKING` * `RATE_LIMIT_EXCEEDED` * `AUTHENTICATION_FAILED` * `AUTHORIZATION_FAILED` * `INTERNAL_SERVER_ERROR` * `SERVICE_UNAVAILABLE` ### Latency & Asynchronous Handling **Timeout Configuration** * Availability queries: 5-second timeout * Booking creation: 10-second timeout * Customer updates: 5-second timeout * Webhook delivery: 30-second timeout **Retry Logic** * Automatic retries: 3 attempts with exponential backoff (1 s, 2 s, 4 s) * Idempotency: All mutations include idempotency keys (`Idempotency-Key: {unique_request_id}`) * Retry-safe: Only idempotent operations retried automatically * Circuit breaker: After 5 consecutive failures, 60-second cooldown period **Asynchronous Operations** ```http theme={null} POST /api/v1/bookings ``` `202 Accepted` response: ```json theme={null} { "status": "processing", "job_id": "job_abc123", "status_url": "/api/v1/jobs/job_abc123", "estimated_completion": "2025-10-31T14:31:00Z" } ``` Polling: ```http theme={null} GET /api/v1/jobs/job_abc123 ``` Response: ```json theme={null} { "status": "completed", "result": {} } ``` **Real-Time Conversational Handling** – During live customer interactions (phone/chat): * User experience priority: Display “checking availability…” messaging * Progressive disclosure: Show partial results as they arrive * Graceful degradation: Offer callback/email options if systems slow * Optimistic UI: Tentatively show likely success while awaiting confirmation ### Omnichannel Integration Flow **Voice Calls** ``` 1. Customer calls → Avoca AI answers 2. AI extracts intent (book appointment) 3. AI queries availability API in real time 4. AI presents options to customer verbally 5. Customer selects option 6. AI calls booking creation API 7. AI confirms booking details verbally 8. AI sends confirmation via SMS/email (your notification APIs or ours) ``` **SMS/Text** ``` 1. Customer texts request 2. AI parses intent from text 3. AI queries your APIs 4. AI responds via SMS with options 5. Customer replies with selection 6. AI creates booking 7. Confirmation sent via SMS ``` **Email** ``` 1. Customer emails request 2. AI processes email (async acceptable) 3. AI drafts response with availability options 4. Customer clicks link or replies 5. Booking created upon customer action 6. Email confirmation sent ``` **Cross-Channel Continuity** * Each customer interaction includes a `session_id` for conversation tracking * Customers can start on one channel (call) and complete on another (email link) * APIs should support lookup by customer identifier across channels
# Overview Source: https://help.avoca.ai/custom-integration/overview Shared custom integration implementation playbook Avoca is excited to collaborate with your team on a bespoke integration. This guide captures how we coordinate, formalize joint workflows, and record the evolving details that shape the custom integration program. # Payload Handshake Template Source: https://help.avoca.ai/custom-integration/payload-handshake Canonical Avoca payload contract for custom integration form-based submissions # Payload Handshake Integration Guide This playbook defines the shared payload pattern Avoca expects when exchanging short-lived submission tokens with your services. Every workflow uses the same handshake, response envelope, and metadata wrapper so Avoca can plug into new resources without custom engineering. *** ## 1. Handshake Overview ### 1.1 Request a Payload Token ```http theme={null} GET /rest/forms/v1//payload Authorization: Basic Accept: application/json ``` Successful responses mint a short-lived `payloadId`: ```json theme={null} { "data": { "payloadId": "44ef31b6-8d63-4a07-9363-b961792aac1e", "expiresAt": "2024-11-20T18:25:43.511Z" } } ``` ### 1.2 Submit the Resource Payload ```http theme={null} POST /rest/forms/v1//payload/{payloadId}/submit Authorization: Basic Content-Type: application/json ``` Request body: ```json theme={null} { "payload": { /* resource-specific body */ }, "metadata": { "source": "avoca", "summary": "optional human-readable call summary", "callId": "external-call-id" } } ``` ### 1.3 Standard Success Envelope ```json theme={null} { "data": { "message": "Submitted successfully", "reference": "optional client-side tracking number" } } ``` *** ## 2. Shared Error Envelope All endpoints return a consistent error shape. Flag retryable errors explicitly so Avoca can apply automated retry logic. ```json theme={null} { "error": { "code": "E_DUPLICATE", "message": "Customer already exists", "details": { "existingCustomerId": "0237077" }, "retryable": false } } ``` *** ## 3. Customer & Identity Payloads ### 3.1 Lookup by Phone or Address ```http theme={null} POST /rest/forms/v1/customer-lookup/payload/{payloadId}/submit Authorization: Basic Content-Type: application/json ``` ```json theme={null} { "phone": "3125550100", "address": "100 SAMPLE ST" } ``` Lookup responses may be stringified JSON (as shown) or structured objects—document whichever format you use and keep it consistent across environments. ```json theme={null} { "data": { "message": "{\"customers\":[{\"customerId\":\"CUST-1001\",\"name\":\"SAMPLE CUSTOMER\",\"email\":\"customer@example.com\",\"membership\":\"none\",\"customerType\":\"residential\",\"addresses\":[{\"street\":\"100 SAMPLE ST\",\"city\":\"CHICAGO\",\"state\":\"IL\",\"zip\":\"60601\",\"primaryPhone\":\"3125550100\",\"secondaryPhone\":\"\",\"scheduledAppointments\":[],\"equipment\":[{\"itemCode\":\"SAMPLE-AC\",\"serialNumber\":\"SAMPLE-SERIAL\",\"installedByUs\":\"Y\",\"ageYears\":\"15\",\"location\":\"GROUND\",\"ladderSize\":\"NO\",\"equipmentType\":\"AIR CONDITIONER\",\"warranty\":[]}]}],\"notes\":[]}]}" } } ``` ### 3.2 Create Customer ```http theme={null} POST /rest/forms/v1/customer-create/payload/{payloadId}/submit Authorization: Basic Content-Type: application/json ``` ```json theme={null} { "customerName": "JANE DOE", "streetAddress": "123 MAIN ST APT 2", "city": "CHICAGO", "state": "IL", "zipCode": "60601", "primaryPhone": "7735552121", "secondaryPhone": "8475550099", "email": "jane@example.com", "campaignCode": "OBCAVOCA", "customerType": "RES" } ``` ```json theme={null} { "data": { "message": "{\"status\":\"created\",\"customerId\":\"0459981\"}" } } ``` *** ## 4. Job Booking Payloads ### 4.1 Call-Type Catalogue Publish the active call types so Avoca can sync and validate options. ```json theme={null} { "callTypes": [ { "code": "SC", "description": "HVAC Service Call" }, { "code": "CC", "description": "HVAC Maintenance Call" }, { "code": "E", "description": "Sales Estimate" }, { "code": "P", "description": "Plumbing Service" } ] } ``` ### 4.2 Create Job Submission ```http theme={null} POST /rest/forms/v1/job-create/payload/{payloadId}/submit Authorization: Basic Content-Type: application/json ``` ```json theme={null} { "customerId": "0459981", "callerPhone": "7735552121", "campaignCode": "OBCAVOCA", "callType": "SC", "scheduledDate": "20241118", "scheduledStartTime": "0800", "scheduledEndTime": "1200", "salesPersonId": "0" } ``` ```json theme={null} { "data": { "message": "{\"status\":\"scheduled\",\"jobNumber\":\"JOB-889033\"}" } } ``` *** ## 5. Equipment & Parts Payloads ### 5.1 Equipment Submission ```http theme={null} POST /rest/forms/v1/job-equipment/payload/{payloadId}/submit Authorization: Basic Content-Type: application/json ``` ```json theme={null} { "customerId": "0459981", "sequenceNumber": "1", "itemCode": "ML180UH070P36A", "serialNumber": "S5912H40924", "installedByUs": "Y", "ageYears": "13", "problemCodes": "NA", "problemNotes": "Annual furnace maintenance, no issues reported.", "ladderSize": "NO", "equipmentLocation": "BASEMENT" } ``` ### 5.2 Parts Submission ```http theme={null} POST /rest/forms/v1/job-part/payload/{payloadId}/submit Authorization: Basic Content-Type: application/json ``` ```json theme={null} { "customerId": "0459981", "sequenceNumber": "1", "partCode": "C/C", "quantity": "1", "unitPrice": "139.95" } ``` ### 5.3 Part Catalogue Snapshot ```json theme={null} { "parts": [ { "code": "S/C", "description": "Service Call", "price": "85.00" }, { "code": "C/C", "description": "HVAC Clean & Check", "price": "139.95" }, { "code": "CMP-1", "description": "Care Program - 1 System", "price": "24.99" } ] } ``` *** ## 6. Availability Payloads ### 6.1 Timeframe Submission ```http theme={null} POST /rest/forms/v1/job-availability/payload/{payloadId}/submit Authorization: Basic Content-Type: application/json ``` ```json theme={null} { "timeframes": "next-available" } ``` ```json theme={null} { "data": { "message": "[{\"callType\":\"SC\",\"dates\":[\"20241118\",\"20241119\",\"20241120\"]}]" } } ``` ### 6.2 Detailed Slot Lookup (Direct API) ```http theme={null} GET /api/available-appointments?callType=SC&date=20241118&installedByUs=Y&equipmentAge=10 Authorization: Bearer Accept: application/json ``` ```json theme={null} { "callType": "SC", "date": "2024-11-18", "slots": [ { "start": "2024-11-18T13:00:00Z", "end": "2024-11-18T17:00:00Z", "capacity": 2, "technicianType": "HVAC" }, { "start": "2024-11-18T17:00:00Z", "end": "2024-11-18T21:00:00Z", "capacity": 1, "technicianType": "HVAC" } ] } ``` *** ## 7. Operational Expectations * **Timeouts & retries**: Document expected response times, retry windows, and whether errors are retryable. Avoca defaults to a 10 s timeout and retries once after 500 ms. * **Propagation**: Note how long new customers or jobs take to appear in lookup endpoints; Avoca currently waits 10 s before re-querying. * **Alerts**: Provide escalation contacts (emails or webhooks) for repeated timeouts; Avoca sends one alert after the second failure. * **Security**: Define TLS versions, credential rotation cadence, and any additional signing or encryption requirements beyond HTTPS. * **Versioning**: Describe how you will introduce new fields or endpoints (additive JSON properties, versioned paths) so Avoca can adopt changes without breaking. Use this template when publishing payload-based workflows to partners. Adjust field names or optional properties to match your systems, but keep the handshake pattern and envelope consistent so Avoca can integrate with minimal customization. # Identity and Access Controls Source: https://help.avoca.ai/custom-integration/security-access-controls Identity, access-management, and personnel safeguards used across Avoca. # Identity and Access Controls ## Access Lifecycle Access is provisioned according to role and business need, reviewed periodically, and removed when it is no longer required. Reviews cover privileged access, role appropriateness, service accounts, and exceptions to standard access patterns. ## Multi-Factor Authentication Multi-factor authentication is required for administrative access to critical systems where supported. This includes infrastructure consoles, source-control administration, database administration, and security-sensitive SaaS applications. ## Least Privilege and Accountability Avoca uses least-privilege principles throughout its environment: * Individual accounts are preferred over shared credentials * Elevated permissions are granted only when required * Centralized identity and single sign-on are used where appropriate * Service accounts and integration credentials are restricted and managed separately * Access changes and privileged actions are logged where supported ## Application Authorization Avoca applications use team- and role-based authorization to restrict access to customer data and administrative functions. Public API endpoints require the authentication mechanism documented for that endpoint, such as an API key, bearer token, or OAuth flow. For API key types and scopes, see [Authentication and Permissions](/api-reference/authentication). ## Personnel and Device Controls Personnel with access to Avoca systems are subject to security requirements appropriate to their role. Managed-device controls, security training, confidentiality obligations, and prompt offboarding support the technical access controls. ## Insider-Risk Safeguards Avoca combines least privilege, access reviews, individual accountability, logging, environment separation, and offboarding procedures to reduce malicious and accidental insider risk. # Data Protection and Privacy Source: https://help.avoca.ai/custom-integration/security-data-protection Encryption, data minimization, retention, and privacy considerations for Avoca data. # Data Protection and Privacy ## Encryption Avoca uses encrypted connections for customer and integration traffic and relies on managed infrastructure encryption for supported data stores and backups. Cryptographic keys and service credentials are restricted to the systems and personnel that require them. Custom integrations must use HTTPS with TLS 1.2 or later. Do not transmit credentials, payment information, or other sensitive values in URL parameters or logs. ## Tenant Isolation Avoca uses authenticated, team-scoped access patterns and authorization controls to separate customer data. API credentials and webhook secrets must be scoped and stored according to the applicable integration documentation. ## Data Minimization Collect and exchange only the data needed for the configured workflow. Avoid placing unnecessary personal data in free-text fields, logs, error messages, or support requests. ## Privacy Requests Requests to access, correct, export, or delete personal data are handled according to the applicable customer agreement, product behavior, and legal requirements. Do not assume that an undocumented API endpoint performs a complete privacy deletion. Contact Avoca Support for a privacy request or for help identifying the systems involved in a particular data flow. ## Retention and Consent Retention varies by product, data type, integration, and contractual requirement. Customers with a specific retention or legal-hold requirement should confirm it during implementation. Messaging and marketing workflows must respect the customer's current consent and opt-out state. See [How messaging registration and opt-outs work](/faq/10dlc-compliance) for customer-facing guidance. Avoca's controls support customer compliance efforts, but each customer remains responsible for determining the laws and consent requirements that apply to its use of the service. # Secure Development Lifecycle Source: https://help.avoca.ai/custom-integration/security-development How Avoca incorporates security into engineering, testing, and release management. # Secure Development Lifecycle ## Engineering Controls Security is incorporated into Avoca's software-development lifecycle through controls appropriate to the change and its risk. These include: * Peer review before production deployment * Automated checks for code quality, dependencies, and known vulnerabilities * Separation between development, testing, and production environments * Restricted production access and auditable deployment paths * Testing and rollback planning for material changes ## Security Enablement Engineers receive security guidance and awareness training appropriate to their responsibilities. Security owners use findings from reviews, incidents, dependency alerts, and external assessments to update engineering practices and priorities. ## Vulnerability Handling Potential vulnerabilities are assessed based on severity, exploitability, exposure, and customer impact. Remediation can include a code or dependency update, configuration change, temporary mitigation, additional monitoring, or coordinated provider action. See [Risk and Vulnerability Management](./security-risk-management) for the broader process. ## Change and Release Management Production changes follow controlled review, testing, and deployment workflows. Material customer-facing changes are communicated through the appropriate product, account, support, or release-notes channel; this help center is not the system of record for release history. # Governance, Policy, and Compliance Source: https://help.avoca.ai/custom-integration/security-governance How Avoca manages security policies, incidents, continuity, and contractual obligations. # Governance, Policy, and Compliance ## Policy Framework Avoca maintains documented security and privacy policies that support its control environment and SOC 2 program. Policies have assigned owners and are reviewed on a recurring basis or when material changes require an earlier review. The framework covers topics such as: * Access control and acceptable use * Secure development and change management * Risk, vulnerability, and vendor management * Incident response and business continuity * Data handling, retention, and privacy * Personnel security and security awareness ## Incident Response and Business Continuity Avoca maintains incident-response and business-continuity procedures for identifying, containing, investigating, recovering from, and learning from security or availability events. Response activities are coordinated across the relevant engineering, leadership, legal, customer, and provider contacts. Exercises, reviews, and operational events are used to improve the procedures over time. ## Regulatory and Contractual Commitments Security and privacy obligations vary by customer, data set, product configuration, and applicable law. Avoca evaluates those obligations through its contracts, data-processing terms, policies, and control program. A security certification does not by itself make every customer workflow compliant with every regulation. Customers remain responsible for configuring and using Avoca consistently with their own legal and regulatory obligations. ## Incident Communication When an incident requires customer notification, Avoca follows the timing, content, and delivery requirements in applicable law and customer agreements. Communications are designed to provide the confirmed scope, customer impact, protective actions, and material updates available at that stage of the response. For a copy of applicable security or data-processing terms, contact your Avoca account team. # Monitoring, Logging, and Resilience Source: https://help.avoca.ai/custom-integration/security-monitoring How Avoca approaches operational monitoring, audit evidence, backups, and service resilience. # Monitoring, Logging, and Resilience ## Logging and Monitoring Avoca collects application, infrastructure, deployment, authentication, and security events needed to operate the service, investigate incidents, and support its control program. Access to logs is restricted according to role, and sensitive values should not be written to logs. Monitoring is designed to surface conditions such as: * Elevated error or latency rates * Failed or suspicious authentication activity * Unexpected infrastructure or deployment changes * Provider degradation * Security findings that require investigation Retention varies by system, event type, operational need, and contractual or legal requirement. Customers with a specific retention requirement should confirm it during security or integration review. ## Backup and Recovery Critical data stores use managed backup and recovery capabilities appropriate to their role. Backup configuration, retention, and restoration procedures are reviewed as part of the continuity program. Recovery objectives depend on the affected service and customer agreement. Architecture-specific requirements should be confirmed during implementation rather than inferred from a generic platform target. ## Service Resilience Avoca uses managed cloud services, environment separation, scaling controls, provider monitoring, and operational response procedures to support service availability. When a dependency is degraded, the expected behavior depends on the workflow; an integration may retry, queue work, return a controlled error, or fall back to a manual process. ## Custom-Integration Expectations For a custom integration, both teams should agree on: * Request timeouts and retry behavior * Idempotency and duplicate prevention * Health and readiness checks * Error shapes and correlation identifiers * Monitoring ownership and escalation paths * Maintenance and incident communication * Recovery and data-reconciliation procedures Do not treat example health endpoints, latency values, or retention periods in an implementation plan as contractual commitments unless they are included in the signed integration agreement. # Platform Security Standards Source: https://help.avoca.ai/custom-integration/security-platform-standards Baseline security requirements for Avoca custom-integration connectivity. # Platform Security Standards ## Transport Security * Use HTTPS with TLS 1.2 or later for API and webhook traffic * Validate the complete certificate chain and hostname * Keep certificates current and use modern cipher suites * Do not disable certificate verification in production clients ## Authentication and Secrets * Use the authentication method agreed for the integration * Store credentials in an approved secrets manager * Scope credentials to the minimum required access * Rotate or revoke credentials after suspected exposure, personnel changes, or integration retirement * Never place production credentials in source control, examples, logs, or support tickets ## API Security * Validate input and enforce authorization on the server * Use parameterized data access and safe output encoding * Apply appropriate request-size, rate, and abuse controls * Return structured errors without sensitive implementation details * Use idempotency controls for retryable write operations ## Network and Availability Controls Network restrictions, static egress addresses, private connectivity, DDoS controls, and provider-specific firewall requirements depend on the integration architecture. Document them during technical design rather than assuming they are available for every Avoca endpoint. See [API and Integration Methods](./api-methods) for contract-design guidance. # Security Posture & Compliance Source: https://help.avoca.ai/custom-integration/security-posture Map of Avoca's security documentation for custom integration stakeholders. # Security Posture & Compliance This section has been reorganized into focused articles so you can jump directly to the controls you care about. Use the links below to navigate the security catalog. *** ## Program Overview * [Security Program Overview](./security-program-overview) — Leadership, third-party risk, SOC 2 certification, and customer assurance * [Governance, Policy, and Compliance](./security-governance) — Policy development, incident response, and regulatory commitments *** ## Operational Controls * [Risk and Vulnerability Management](./security-risk-management) — Continuous scanning, penetration testing, and infrastructure hardening * [Identity and Access Controls](./security-access-controls) — MFA enforcement, RBAC, insider risk mitigation * [Secure Development Lifecycle](./security-development) — Secure coding practices, training, and release management *** ## Data Protection & Resilience * [Data Protection and Privacy](./security-data-protection) — Encryption, data minimization, and privacy workflows * [Monitoring, Logging, and Resilience](./security-monitoring) — Telemetry, backup strategy, and integration reliability * [Platform Security Standards](./security-platform-standards) — Baseline transport, encryption, and API security requirements # Security Program Overview Source: https://help.avoca.ai/custom-integration/security-program-overview High-level overview of Avoca's security program and assurance practices. # Security Program Overview ## Executive Summary Avoca maintains a defense-in-depth security program designed to protect customer data across its cloud infrastructure, applications, personnel, and operating processes. Avoca is SOC 2 certified and maintains controls for access management, change management, monitoring, vendor oversight, and incident response. The exact scope and period covered by an assurance report can change. Customers conducting due diligence should request the current report and supporting materials from their Avoca account or security contact. ## Security Leadership and Accountability Security responsibilities are shared across executive and engineering leadership, with clear ownership for technical controls, compliance activities, risk decisions, and customer communication. Avoca also uses qualified external security and legal specialists when independent expertise is appropriate. Key practices include: * Executive visibility into material security risks and control gaps * Named owners for security controls and remediation work * Periodic policy, access, vendor, and risk reviews * Independent assurance and testing where required by the security program ## Third-Party Risk Management Avoca relies on cloud and software providers under a shared-responsibility model. Providers that handle sensitive data or support critical operations are evaluated according to their role and risk. Reviews can include: * Security and privacy documentation * Independent assurance reports or certifications * Data handling, retention, and deletion terms * Access controls and incident-notification commitments * Business continuity and service availability ## Personnel and Access Employees and contractors with system access are subject to security requirements appropriate to their role. Access is provisioned according to business need, protected with strong authentication, and removed when no longer required. See [Identity and Access Controls](./security-access-controls) for more detail. ## Customer Assurance Avoca's security program includes: * SOC 2 certification * Encryption for data in transit and at rest where supported by the service architecture * Role-based access and multi-factor authentication for privileged systems * Security monitoring and incident-response procedures * Vulnerability and dependency management * Vendor and personnel security controls For questionnaires, assurance reports, contractual security terms, or architecture-specific questions, contact your Avoca account team. # Security, Compliance, and Reliability Source: https://help.avoca.ai/custom-integration/security-reliability Quick links to data protection, reliability, and observability guidance. # Security, Compliance, and Reliability Looking for specific technical requirements? Dive into the focused pages below for detailed standards and guidance. *** ## Data Protection & Privacy * [Data Protection and Privacy](./security-data-protection) — Encryption expectations, data lifecycle controls, and consent management *** ## Operational Reliability * [Monitoring, Logging, and Resilience](./security-monitoring) — Logging, backups, service resilience, and custom-integration expectations * [Platform Security Standards](./security-platform-standards) — Transport security, network safeguards, and API hardening practices *** ## Supporting Practices * [Risk and Vulnerability Management](./security-risk-management) — Risk-based remediation, security testing, and infrastructure hardening * [Identity and Access Controls](./security-access-controls) — MFA, role-based authorization, and personnel safeguards # Risk and Vulnerability Management Source: https://help.avoca.ai/custom-integration/security-risk-management How Avoca identifies, assesses, and remediates security risks. # Risk and Vulnerability Management ## Risk Management Avoca evaluates technical, operational, vendor, and data-protection risks according to their likelihood and potential impact. Material risks are assigned owners and tracked through mitigation, acceptance, transfer, or avoidance. Inputs can include: * Automated dependency and infrastructure findings * Code and architecture reviews * Security assessments and penetration testing * Provider notices and independent assurance reports * Incidents, near misses, and customer-reported concerns ## Vulnerability Management Security findings are validated and prioritized based on severity, exploitability, affected systems, available mitigations, and customer exposure. Critical or actively exploitable issues receive immediate attention; lower-risk findings are scheduled according to the assessed risk and operational context. The remediation process can include: 1. Confirming the finding and affected scope 2. Applying temporary containment or compensating controls when needed 3. Developing and testing the permanent remediation 4. Deploying the change through controlled release procedures 5. Verifying the fix and recording supporting evidence ## Security Testing Avoca uses a combination of automated scanning, internal review, provider assurance, and independent testing. Scope and cadence are selected according to system risk and assurance requirements. ## Infrastructure Hardening Avoca applies layered controls across application, identity, network, and provider boundaries. Common measures include authenticated endpoints, least-privilege access, environment separation, rate and abuse controls, managed cloud protections, and security monitoring. ## Patch and Dependency Management Application dependencies and managed services are monitored for relevant security updates. Avoca prioritizes updates according to risk and uses its normal testing and deployment controls before production rollout, except when an urgent mitigation requires an accelerated response. # Architecture & Data Strategy Source: https://help.avoca.ai/custom-integration/technical-architecture How Avoca calls your APIs in real time, and what that means for latency and resiliency # Architectural Design ### Real-Time API Integration Avoca's AI agents call your APIs **synchronously, in real time, during live conversations**. When a caller asks for an appointment, the agent looks up the customer, checks availability, and books the job against your system while the caller is still on the line. The data types fetched live include: * **Live availability** – Appointment slot availability * **Customer lookup** – Current customer records and account status * **Service eligibility** – Eligibility checks based on your business rules * **Instant confirmations** – Immediate booking confirmations * **Booking modifications** – Cancellations, reschedules, and changes Avoca does not maintain a local cache of your availability, pricing, or customer data for custom integrations — every conversation works from fresh responses to keep bookings accurate. Relatively static reference data (service catalogs, business hours, service-area rules) is typically configured in Avoca during onboarding and updated through the joint integration process rather than fetched per call. ### Latency Expectations Because your API sits in the live conversation path, response time directly affects the caller experience: * **Target response times:** under 200 ms for availability checks; under 500 ms for booking operations * **Timeout:** Avoca times out requests after **10 seconds** * **Retries:** failed requests are automatically retried once after a short delay; repeated failures trigger alerts to Avoca's integration team The AI agent is designed to hold the conversation naturally while a request is in flight, but consistently slow endpoints will produce awkward pauses — keep hot paths fast. ### Hosting & Connectivity * Your APIs can be hosted on any cloud or on-premise environment reachable over the public internet via **HTTPS/TLS** — no VPN or special networking is required * Avoca's platform is hosted on US-based cloud infrastructure; for US operations, hosting your API in a US region minimizes latency * We defer to your organization's data residency requirements for customer data ### Failover & Redundancy (recommendations for your API) * Deploy redundantly with automatic failover where possible — if your API is down, the AI can still take messages and capture bookings for manual entry, but real-time booking is degraded * Expose a health check endpoint so issues can be detected quickly during testing and operations * Return clear, fast error responses rather than hanging — Avoca's timeout/retry handles transient failures gracefully
# Additional Technical Considerations Source: https://help.avoca.ai/custom-integration/technical-considerations Recommended edge-case, testing, and production-readiness requirements for custom integrations # Additional Technical Considerations ### Idempotency & Duplicate Prevention **Idempotency Key Implementation** ```http theme={null} POST /api/v1/bookings Idempotency-Key: req_abc123xyz ``` First request response: ```http theme={null} 201 Created {booking details} ``` Duplicate request with same key: ```http theme={null} 200 OK {same booking details} ``` Requirements: * Valid for at least 24 hours * Unique per request (UUID v4 recommended) * Server returns same response for duplicate keys * 409 Conflict allowed if key reused with different payload ### Batch Operations **Bulk Availability Check** ```http theme={null} POST /api/v1/availability/batch ``` Payload: ```json theme={null} { "queries": [ { "query_id": "q1", "service_type": "inspection", "start_time": "2025-11-01T09:00:00Z" }, { "query_id": "q2", "service_type": "inspection", "start_time": "2025-11-01T10:00:00Z" } ] } ``` Response: ```json theme={null} { "results": [ { "query_id": "q1", "available": true, "slots": [] }, { "query_id": "q2", "available": false, "reason": "provider_unavailable" } ] } ``` ### Internationalization **Multi-language Support** – If serving international customers: * Support `Accept-Language` header * Localize error messages * Respect locale-specific date/time formats * Handle multi-currency pricing Example: ```http theme={null} GET /api/v1/availability Accept-Language: es-MX ``` Response includes localized service names and descriptions. ### Testing Checklist Before production deployment we will validate: * [ ] All API endpoints functional and documented * [ ] Authentication working (OAuth, API keys, etc.) * [ ] Webhooks delivering successfully with retries * [ ] Error responses follow documented format * [ ] Rate limiting working as specified * [ ] Idempotency keys preventing duplicates * [ ] Timeout handling is graceful * [ ] SSL/TLS certificates valid * [ ] CORS policies correct (if applicable) * [ ] Health check endpoints responding * [ ] Monitoring and alerting configured * [ ] Sandbox and production environments separated * [ ] Load testing passed at expected volume * [ ] Security scan passed (OWASP, penetration test) * [ ] Disaster recovery tested * [ ] Runbook documented for common issues
## Summary This addendum provides a checklist of recommended contract and production-readiness topics. Confirm the requirements that apply to your integration during technical design. **Highlights** * **Architecture:** Real-time API-first workflows with explicitly documented timeout, retry, and fallback behavior * **Security:** Strong authentication, scoped credentials, encrypted transport, and risk-appropriate testing * **APIs:** RESTful JSON design, webhook support strongly preferred, detailed schemas provided * **Reliability:** Agreed latency and availability targets with robust error handling and retry logic * **Support:** Named owners, escalation paths, monitoring, and change-management expectations * **Timeline:** Project-specific phases for design, implementation, testing, and controlled rollout **Next Steps** 1. Review and confirm API specification alignment 2. Establish sandbox access and credentials 3. Schedule kickoff meeting and regular sync cadence 4. Begin Phase 1 discovery activities Please reach out if any technical requirements need clarification or if alternative implementation approaches should be discussed. # Technical Integration Source: https://help.avoca.ai/custom-integration/technical-integration API integration specifications for the custom integration program # Technical Integration Addendum This page now serves as a directory for the custom integration implementation library. Each topic has its own focused page so you can scan and share specifications quickly: * [Architecture & Data Strategy](./technical-architecture) – Real-time data access, latency, retries, and resiliency. * [API & Integration Methods](./api-methods) – Core endpoints, authentication models, rate limits, and error envelopes. * [Data Exchange & Booking Process](./data-exchange) – Payload schemas, success/error samples, and omnichannel flows. * [Customization & AI Behavior](./customization-behavior) – Business-rule APIs, personalization levers, and runtime controls. * [Security, Compliance, and Reliability](./security-reliability) – Logging standards, incident handling, and uptime targets. * [Testing, Deployment, and Support](./testing-support) – Validation, rollout, change management, and escalation planning. * [Additional Technical Considerations](./technical-considerations) – Idempotency, edge cases, and production readiness. * [API Integration Guide](./api-integration-guide) – Checklist for environment setup, idempotency, and credential rotation. * [Payload Handshake Template](./payload-handshake) – Reusable token minting and submission contract shared across workflows. Bookmark this index to jump directly to the specifications your team needs during implementation reviews or partner onboarding. # Testing, Deployment, and Support Source: https://help.avoca.ai/custom-integration/testing-support Plan custom-integration validation, rollout, monitoring, and support. # Testing, Deployment, and Support Every custom integration needs an implementation plan agreed by Avoca and the integration partner. The plan should identify environments, test data, owners, acceptance criteria, rollout stages, monitoring, and escalation routes. ## Test Environment When the partner provides a sandbox, document: * Sandbox base URL and authentication method * Test customers, services, locations, and availability * How to reset or recreate known test data * How to trigger webhook and failure scenarios * Differences between sandbox and production behavior Use synthetic or approved test data. Never copy production customer data into a sandbox unless the security and privacy owners for both organizations have approved it. ## Validation Scope Test at least: * Customer lookup and identity matching * Availability and booking happy paths * Validation errors and unavailable-slot behavior * Duplicate requests and idempotency * Authentication failure and credential rotation * Timeouts, retries, and partial dependency failure * Webhook signing, delivery, retry, and deduplication * Cancellation, rescheduling, and reconciliation when supported * Expected behavior when a dependency is unavailable Performance and security testing should match the expected production volume and risk. Agree on rate limits and load-test windows before generating high traffic against either party's environment. ## Implementation Phases A typical integration progresses through: 1. **Discovery and design** — confirm workflows, data ownership, API contracts, and security requirements. 2. **Development** — establish credentials, implement the contract, and add unit and contract tests. 3. **Integration testing** — validate end-to-end behavior and failure handling in non-production environments. 4. **User acceptance** — confirm the workflows with representative customer scenarios. 5. **Production rollout** — release to a limited scope, monitor, and expand after acceptance criteria are met. Timing depends on partner readiness, workflow complexity, available environments, and unresolved contract questions. Treat any estimate as project-specific rather than a standard Avoca SLA. ## Production Readiness Before go-live, record: * Production endpoints and credential owners * Approved IP or network controls, if any * Timeout, retry, and idempotency behavior * Logging and correlation identifiers * Dashboards, alerts, and on-call ownership * Rollback, disablement, and data-reconciliation procedures * Customer-support and engineering escalation contacts * Maintenance and incident-notification expectations ## Support Use [support@avoca.ai](mailto:support@avoca.ai) or **Settings → Support** in the Avoca dashboard for the initial Avoca support route unless the implementation plan names a dedicated partner channel. For an integration issue, include: * The affected environment and workflow * Approximate occurrence time and time zone * A safe request, event, or correlation identifier * Expected and observed behavior * Whether the issue is ongoing Do not include API keys, webhook secrets, complete customer payloads, or other sensitive data in the initial report. Response targets, severity definitions, deprecation notice, and after-hours escalation are governed by the applicable customer or partner agreement. Do not infer them from this guide. ## Change Management Maintain the OpenAPI specification and implementation guide with the integration. For a breaking change, agree on migration guidance, notice, testing, and any dual-version period before rollout. Release history is maintained in Avoca's separate release-notes system, not this help center. ## Provider-Specific Tooling The integration can use the partner's preferred CI/CD, monitoring, API-management, and work-tracking tools. During discovery, document how correlation identifiers, structured logs, health checks, and alerts map into those tools. # Demo Library Source: https://help.avoca.ai/demos Explore real-world examples of Avoca AI in action ## Welcome to the Avoca Demo Library This collection of demo calls showcases how Avoca's AI agents handle various customer service scenarios in the home services industry. Each demo represents actual AI-customer interactions, demonstrating the platform's capabilities across different situations. You may hear beeps and skips in the demo calls, as they were used to remove PII of customers. ## What You'll Find Our demo library is organized into three main categories: ### Inbound Calls Real examples of how Avoca handles incoming customer calls, including: * **Basic Bookings** - Standard appointment scheduling * **Emergency Calls** - Urgent service requests * **Price Inquiries** - Cost transparency and quotes * **Objection Handling** - Price, scheduling, and complaint management * **Appointment Management** - Confirmations, cancellations, and rescheduling ### Outbound Calls Examples of proactive customer outreach: * **Speed to Lead** - Quick response to new inquiries * **Rescheduling** - Proactive appointment changes * **Maintenance Calls** - Service reminders and tune-ups * **Empathetic Interactions** - Handling sensitive situations ### Other Examples Special demonstrations showcasing: * **Alternative Voices** - Different AI voice personalities (Sarah D2, Maddie, Chris) * **Multilingual Support** - Spanish language capabilities * **Advanced Empathy** - Exceptional emotional intelligence ## Key Features Demonstrated Throughout these demos, you'll see how Avoca: * Handles complex multi-party calls * Manages scheduling conflicts professionally * Addresses price objections without being defensive * Shows genuine empathy in sensitive situations * Adapts to different languages and cultural contexts * Maintains consistency across different voice options ## Getting Started Browse through the categories in the sidebar to explore specific scenarios. Each demo includes: * A brief overview of the scenario * Key highlights to watch for * The actual call recording * Detailed call information * Specific points to notice Whether you're evaluating Avoca for your business or looking to understand specific capabilities, these real-world examples provide insight into how our AI agents perform in actual customer interactions. Pay attention to how the AI agents handle transitions, objections, and emotional moments. These subtle capabilities make the difference between a robotic interaction and a truly helpful customer experience. # New Customer Booking for Rental Property Source: https://help.avoca.ai/demos/humans/book-and-take-message Watch how the agent handles a first-time customer booking for an Airbnb rental property ## Overview This demo showcases how a human agent efficiently handles a first-time customer call from a property owner reporting a plumbing issue at their Airbnb rental. The agent gathers all necessary information, books a same-day appointment, and clearly explains the dispatch process and fees. You may hear beeps and skips in the demo calls, as they were used to remove PII of customers. ## Key Highlights * **New Customer Onboarding**: Efficiently collects all required information for a first-time caller * **Property Owner Scenario**: Handles the complexity of owner vs. renter communication * **Same-Day Availability**: Books a morning appointment to address urgent issue * **Clear Fee Communication**: Explains the \$99 dispatch fee and waiver policy * **Dispatch Coordination**: Sets expectations for the 30-45 minute pre-arrival call ## Video Demo