Enable error signals in the Connect web library

The error signal captures when users encounter errors on your site, helping marketers identify and segment users who experience issues during critical processes. This enables targeted outreach and recovery campaigns for users who encounter obstacles.

Focus on high-impact errors:

  • Payment errors
  • Promo code validation failures
  • Account registration issues
  • Checkout process errors
  • Any error that leads users away from the happy path and results in lost sales opportunities

📘

Important

The error signal doesn't replace error monitoring solutions. Its purpose is to enable marketers to segment users who experienced issues and deliver personalized recovery messages.

Availability: Premium and Ultimate


Implementation considerations

Error types

Two error types are supported.

User errors - Caused by user input that doesn't pass validation:

  • Form validation failures
  • Incorrect payment details
  • Invalid promo codes
  • Missing required fields
  • Format errors (invalid email, phone number, etc.)

Application errors - Generated by the application itself:

  • 4xx error pages (404, 403, etc.)
  • 5xx server errors
  • System failures
  • API errors

Detection strategies

User errors:

  • Check for error messages after form submission.
  • Listen for validation feedback elements appearing in the DOM.
  • Monitor error message containers on page load (if page reloads on submission).

Application errors:

  • For 4xx/5xx errors, your application must display error placeholder pages that include the Connect library.
  • The library cannot capture errors if it doesn't load on the error page.

Surface visibility

Make sure all important user errors are communicated in the interface. If something happens silently without user-facing feedback, it won't be captured by this signal.

Contact mapping

Any signal can be mapped to a contact. Use the audience object to provide a customer ID (contact key) or an addressable attribute (email or phone number). You can provide several identification records in the same signal — for example, a contact key and an email address. For details on how Connect processes identification records, see How behavior signals are processed in Connect.

Several sources of identification are available:

  • User identification stored in browser cookies
  • Temporary session-based storage
  • Persistent client-side storage
  • Data layer (for example, Google Tag Manager dataLayer)
  • URL parameters passed during navigation
  • Login API monitoring (capture identifier during successful authentication)

If none of these options are available, work with your development team to make the identifier accessible to the Connect library.

🚧

Important

We recommend attaching identifiers to as many signals as possible. However, if an identifier is missing, the system falls back on other signals from the same user session in order to identify the website visitor.


Configuration

Method

TLT.logSignal(signalObject)

Sends the signal to the Acoustic Connect endpoint as a JSON object. The Connect library must be initialized before calling this method.

Signal structure

Top-level fields

  • audience: Array of objects - Create an object for contact mapping and any number of additional objects to update contact attributes.
  • category: String - Valid value - Behavior.
  • consent: Object - Consent preferences to update for the contact. At least one of the following channel fields is required: email, sms or whatsapp.
  • description: String - Description of the signal
  • effect: String - Describes the effect of the signal on engagement. Valid values: negative, positive. Use negative for all error signals.
  • name: String - Name to differentiate this signal from others (for example, "error from website"). Max length - 256 chars.
  • signalType (required): String - Valid value - error.

Audience object

Create an object with one or more identifiers for contact mapping (recommended) and any number of additional objects for other contact attributes you want to update.

  • name (required): String - Name of contact attribute. To get the full list of available attributes, use the Contact attributes query.
  • value: The new value of the contact attribute. Its format depends on the attribute type (text, number, Boolean or date). If you send an empty or null value, it will be ignored and the contact attribute won't be updated.

📘

Note

  • For date attributes, use the following format: yyyy-MM-dd'T'HH:mm:ssXXX.
  • For phone number attributes, use the ISO E.164 format: +[country code][area code][phone number] — no spaces, dashes or special characters. If the + symbol is omitted, Connect adds it automatically.
  • Consent object

Each channel accepts multiple entries to set different consent statuses per consent group in a single call.

  • enableOverrideExistingOptOut (required): Boolean - When true, current opt-out statuses will be overridden by new statuses. When false, contacts who have unsubscribed from communications won't have their consent status updated.
  • email: Array of objects - Consent entries for the email channel. The objects support the following fields:
    • status (required): Enum - Consent status for the email channel. Valid values: OPT_IN, OPT_OUT, OPT_IN_UNVERIFIED.
    • consentGroupIds: Array of strings - The IDs of consent groups a new status applies to. If you skip this field or send an empty array, the new consent status will be applied to all consent groups.
  • sms: Array of objects - Consent entries for the SMS channel. The objects support the following fields:
    • status (required): Enum - Consent status for the SMS channel. Valid values: OPT_IN, OPT_OUT, OPT_IN_UNVERIFIED.
    • consentGroupIds: Array of strings - The IDs of consent groups a new status applies to. If you skip this field or send an empty array, the new consent status will be applied to all consent groups.
  • whatsapp: Array of objects - Consent entries for the WhatsApp channel. The objects support the following fields:
    • status (required): Enum - Consent status for the WhatsApp channel. Valid values: OPT_IN, OPT_OUT, OPT_IN_UNVERIFIED.
    • consentGroupIds: Array of strings - The IDs of consent groups a new status applies to. If you skip this field or send an empty array, the new consent status will be applied to all consent groups.

📘

Note

To get the IDs of consent groups, use the dataSets query.

Signal content

  • errorIdentifier: String - An identifier assigned to the error (for example, "promoCode", "payment", "registration")
  • errorText (required): String - The content of the error message received
  • errorType (required): String - Type of error. Valid values: APPLICATION, USER.
  • signalCustomAttributes: Array of objects - Additional custom attributes. Each object has name and value string fields.

Notes:

  • If any required field is missing or invalid, the entire signal will be discarded.
  • Optional fields enhance the signal but won't prevent processing if omitted or invalid.

Basic example

// Initialize the Connect library
if (window.TLT) {
    TLT.initPremium({
        appKey: "APP_KEY",
        postUrl: "COLLECTOR_URL",
        callback: function() {
            const signal = {
                // Required fields
                signalType: "error",
                errorType: "USER",
                errorText: "Invalid promo code",

                // Optional fields
                category: "Behavior",
                name: "error from website",
                errorIdentifier: "promoCode",
                effect: "negative",

                // Contact mapping
                audience: [
                    {
                        name: "Email",
                        value: "[email protected]"
                    }
                ]
            };

            // Send the signal
            TLT.logSignal(signal);
        }
    });
}

Complete implementation example

This example captures promo code and payment errors during checkout. The audience identifier is the email address entered in the checkout form.

// Initialize the Connect library
if (window.TLT) {
    TLT.initPremium({
        appKey: "APP_KEY",
        postUrl: "COLLECTOR_URL",
        callback: function() {
            const href = window.location.href;

            // Retrieve email address entered in the checkout form
            const email = document.querySelector('input[name="email"]')?.value || "";

            // Capture coupon code errors from query string
            if (href.includes("/checkout/?CouponCodeErrorMessage=")) {
                const errorText = href.split("checkout/?CouponCodeErrorMessage=")[1];

                if (errorText) {
                    const signal = {
                        signalType: "error",
                        category: "Behavior",
                        name: "error generated by website",
                        effect: "negative",

                        // Required fields
                        errorType: "USER",
                        errorText: errorText.replaceAll("%20", " "),

                        // Optional fields
                        errorIdentifier: "promoCode"
                    };

                    if (email) {
                        signal.audience = [
                            {
                                name: "Email",
                                value: email
                            }
                        ];
                    }

                    // Optional: Log signal for debugging
                    console.log("error signal:", JSON.stringify(signal, null, 2));

                    // Send signal to Connect
                    TLT.logSignal(signal);
                }
            }

            // Capture payment errors on checkout page
            // These appear after page reload when form submission fails
            if (href.includes("/checkout/")) {
                const errorElement = document.querySelector('form[action="/checkout/Payment/"] > div.notice-error');

                if (errorElement) {
                    const errorText = errorElement.innerText || "";

                    if (errorText) {
                        const signal = {
                            signalType: "error",
                            category: "Behavior",
                            name: "error generated by website",
                            effect: "negative",

                            // Required fields
                            errorType: "USER",
                            errorText: errorText.replaceAll("\n", " "),

                            // Optional fields
                            errorIdentifier: "payment"
                        };

                        if (email) {
                            signal.audience = [
                                {
                                    name: "Email",
                                    value: email
                                }
                            ];
                        }

                        // Optional: Log signal for debugging
                        console.log("error signal:", JSON.stringify(signal, null, 2));

                        // Send signal to Connect
                        TLT.logSignal(signal);
                    }
                }
            }
        }
    });
}

Best practices

Use descriptive identifiers - Make errorIdentifier values clear and consistent (for example, "payment", "promoCode", "registration").

  1. Clean error text - Remove unnecessary characters, newlines, or encoding artifacts before sending.
  2. Consider timing - Some errors appear immediately, others after page reload. Adjust your detection logic accordingly.
  3. Test error paths - Verify signals fire correctly by intentionally triggering errors during testing.
  4. Don't duplicate error monitoring - This signal is for marketing segmentation, not technical debugging.

Troubleshooting

Signals not firing for errors?

  • Verify error messages are visible in the DOM when you check for them.
  • Check timing - errors that appear after async operations may need setTimeout.
  • Confirm the Connect library loads on error pages (especially 4xx/5xx pages).
  • Use console.log() to verify error elements are found.

Application errors not captured?

  • Ensure your application displays error placeholder pages (not browser default pages).
  • Verify the Connect library is included on all error page templates.
  • Check that the library initializes successfully on error pages.

Error text looks garbled?

  • Clean up URL encoding (replace %20 with spaces).
  • Remove excess whitespace and newlines.
  • Trim leading/trailing spaces.

Too many duplicate signals?

  • Check if error messages persist across page loads.
  • Add logic to prevent re-firing on page refresh.
  • Consider using session storage to track already-reported errors.

Related pages

How behavior signals are processed in Connect