# Act-On Source: https://docs.allgoodhq.com/integrations/act-on Connect your Act-On account so Mary can act on email replies — unsubscribes, contact syncs, and marketing list adds. The Act-On integration connects your Act-On instance to allGood for [Email Reply Management](/use-cases/erm/overview), so Mary can unsubscribe senders, sync contacts, and add them to marketing lists the moment she classifies a reply. Unlike allGood's API-key integrations, Act-On connects over OAuth: you log in with an Act-On user and approve access. There's no API key to create and no credentials to enter. ## Before you begin You'll need an **Act-On user login** to authorize the connection — a dedicated or shared user on **your own domain** works fine, your choice. That user needs permission to: * Read contact lists * Update list records * Manage marketing-email opt-outs You don't need to create an API key or enter any credentials — you just log in and approve. allGood only ever receives access tokens; your password is never shared or stored. ## Connect the integration In allGood, go to **Settings** → **Integrations**, then find **Act-On** under **CRM**. Act-On listed under Integrations → CRM Leave **Base URL** as the default for US-hosted Act-On accounts, or enter `https://api-eu.actonsoftware.com` if your account is EU-hosted. Leave **Account ID** blank unless you plan to use the [Fetch Act-On Contact](/use-cases/erm/act-on-actions#fetching-contact-data-optional) step — it's the only place that needs it. You'll find it in Act-On under **Account Details**, as the number in `Your Company (47294)`. Click **Connect Act-On account**. Create Act-On integration form with Base URL, Account ID, and Connect Act-On account A window opens on Act-On's login page. Sign in with your Act-On user and grant access. The window closes and the integration shows as connected. Act-On login window ## Confirm it worked Open any reply-management category, add an Act-On action, and check: * The **Marketing List** dropdown fills with your Act-On lists. * On **Sync Contact to Act-On**, after picking a list, the field picker shows that list's columns. If both populate, you're connected. ## Then: set up your actions Once connected, configure what Mary does per reply category — unsubscribes, contact syncs, and marketing list adds. See [Act-On Actions](/use-cases/erm/act-on-actions) for the full field-by-field reference, including tokens and best practices. ## Troubleshooting allGood support needs to register your environment's callback with Act-On. [Reach out to us](mailto:support@allgoodhq.com). Confirm your account has classic contact lists and that the authorizing user can read them. The authorizing user is likely missing a permission — list update or opt-out. Reconnect with a user that has both. # Airtable Source: https://docs.allgoodhq.com/integrations/airtable The Airtable integration allows Mary to receive work assignments directly from your Airtable bases. When records are assigned to Mary in Airtable, she automatically receives them and can start working. This integration connects your Airtable workflow with Mary's AI capabilities, allowing you to assign tasks to Mary just like you would assign them to any team member. ## What You'll Need Before you start: * **Airtable account for Mary** - Create a separate Airtable account that Mary will use to access your bases * **allGood account** - Access to Settings → Integrations * **Airtable base** - The base where you'll assign work to Mary ## What This Integration Does This integration allows you to assign work to Mary directly from Airtable: 1. You configure which Airtable tables Mary should monitor 2. When you assign a record to Mary in Airtable, she automatically receives it 3. Mary can read the record details, add comments, and access attachments 4. You can track Mary's progress by watching for her updates in Airtable This lets you use Airtable as your task management system while Mary handles the work you assign to her. ## IT Coordination Guide ### Security & Account Setup Requirements * Create a dedicated Airtable user account for Mary with appropriate permissions * Use a monitored email address for the service account (not personal email) * Webhook configuration required for task collaboration notifications * Store credentials securely according to company policy ## Step-by-Step Setup **Before you start:** Make sure you're signed into Airtable in your browser with Mary's Airtable account. If you're signed into a different Airtable account, sign out and sign in with Mary's account first. 1. Log into **allGood** with your own account 2. Go to **Settings** → **Integrations** 3. Under **Advanced**, click on **Airtable** 4. Click **Link your Airtable account** An Airtable authorization window will pop up. 5. **Select the base(s)** you want Mary to access (you can select multiple bases) 6. Click **Grant access** You'll be redirected back to the Integrations page. Go back to the Airtable page under Advanced, and you'll see "Connected" next to Mary's Airtable email address. Now tell Mary which table to watch and where to find important information in your records. Table_Configuration.png 1. In the **Table Configuration** section, select your **Base** 2. Select the **Table** where you'll assign work to Mary 3. **Map these three fields** (tell Mary where to find key information): * **Name Field**: Which field has the record's name? (like "Task Name") * **Assignee Field**: Which field shows who's assigned? (like "Assigned To") * **Attachment Field**: Which field has file attachments? (like "Attachments") 4. **Select Watch Fields**: Choose which field changes Mary should notice **We recommend selecting only the Assignee field.** This ensures Mary gets notified when work is assigned to her, but not for every other change to the record. * ✅ Mary gets notified when someone assigns the record * ❌ Mary ignores description changes * ❌ Mary ignores date changes 5. Click **Save Table Configuration** You'll see an orange success message. Once you've saved your table configuration, the "Create Subscription" section will appear. Create_Subscription.png 1. Select your **Base** (same one as Step 2) 2. Click **Subscribe** You'll see the subscription appear with a green "Active" status. Subscription_Active.png **Important:** You can only have one subscription per base. If you want to monitor multiple tables in the same base, just configure each table (Step 2) — they'll all use the same subscription. 1. Open your Airtable base 2. Upload a file to a record's attachment field (docx, csv, or excel file) 3. Assign the record to Mary (set the assignee field to Mary) 4. Mary will receive the assignment and start working on it ## Advanced Configuration ### Monitoring More Tables To add another table in the same base: 1. Go to **Table Configuration** 2. Select the same base, different table 3. Configure the fields and watch fields 4. Click **Save** 5. Scroll to **Create Subscription** 6. Click on your subscription to expand it 7. Click **Recreate Subscription** You need to recreate the subscription so it includes the new table's watch fields. ### Changing Watch Fields If you want to change watch fields for a table you already configured: 1. Update the watch fields in **Table Configuration** 2. Click **Save** 3. Scroll to **Create Subscription** 4. Click on your subscription to expand it 5. Click **Recreate Subscription** Recreate_Subscription.png Why recreate? Watch fields are set when the subscription is created. To change them, we have to delete the old subscription and create a new one with your updated settings. ### Subscription Status Click on a subscription to see: * ✅ Green "Active" = working * ⏰ Yellow "Expiring soon" = will auto-refresh * ❌ Red "Expired" = click Recreate allGood automatically refreshes subscriptions every 5 days to keep them active. ## Frequently Asked Questions This integration lets you assign work to Mary directly from Airtable. When you assign a record to Mary in Airtable, she automatically receives it and can start working on it. Integration Mary can: * Read records from tables you configure * Add comments to records when she completes work * Read file attachments from records Mary **cannot** access: * Tables you don't configure for her * Bases you don't set up You need to tell Mary which fields matter before she starts watching for changes. This way, Mary only pays attention to important changes (like when someone assigns a record to her) and ignores unimportant ones (like when someone changes a description). No, only **one subscription per base** is allowed. allGood uses a single subscription to monitor all tables you configure in a base, so multiple subscriptions aren't necessary. 1. Go to Table Configuration 2. Select your base and a new table 3. Configure the field mappings and watch fields 4. Save the configuration 5. Go to Create Subscription section 6. Expand your subscription and click "Recreate Subscription" You need to recreate the subscription so it can include the new table's watch fields. You must **recreate the subscription** for changes to take effect: 1. Update the watch fields or add new tables in Table Configuration 2. Save the changes 3. Go to Create Subscription section 4. Expand your subscription and click "Recreate Subscription" This is necessary because watch fields are set when the webhook is created. To update them, the webhook must be deleted and recreated with the new configuration. You must configure three fields for each table: * **Name Field**: Identifies the record (e.g., "Task Name") * **Assignee Field**: Shows who's assigned * **Attachment Field**: Contains file attachments Yes! Each table has its own configuration. For example, Table A might use "Task Name" as the name field while Table B uses "Project Title". Configure each table independently based on its structure. Airtable webhooks expire after 7 days if not refreshed. allGood automatically refreshes your webhooks before they expire to keep them active continuously. Only changes to **watch fields** trigger notifications. We recommend watching just the **Assignee** field — this way Mary gets notified when work is assigned to her, but not for every other change to the record. No. Airtable doesn't currently support notifications for comment changes, so Mary won't be notified when comments are added or updated — only when the watch fields you've configured are changed. Notifications typically arrive within seconds of the Airtable change. Normal delays are under 10 seconds. This can happen if the Airtable OAuth popup opens in a browser window where a different Airtable account is signed in (e.g., an incognito window or different browser profile). To fix this: 1. In the browser window you'll use for reconnection, go to [airtable.com](https://airtable.com) and confirm you're signed into **Mary's Airtable account** — sign out and back in if needed 2. In allGood, go to **Settings** → **Integrations** → **Airtable** 3. Click **Reconnect Airtable account** and complete the authorization 4. Verify the connected email matches Mary's Airtable account ## Troubleshooting When you assign a record to Mary in Airtable, you should see a new worksheet start in allGood with a kickoff message. If that's not happening, check: 1. ✅ Is the subscription status "Active"? 2. ✅ Did you change the Assignee field (the one you configured as the watch field)? 3. ✅ Is the Assignee field mapped correctly in Table Configuration? Common issues: Assignee field mapped to wrong column, subscription has expired, you changed a different field, or the OAuth connection is disconnected. This means you haven't configured any tables with watch fields yet. 1. Go to Table Configuration 2. Select a base and table 3. Configure field names 4. Select at least one watch field 5. Click Save Table Configuration 6. Try creating the subscription again You can only have one subscription per base. Options: 1. Use the existing subscription and configure more tables under it 2. Delete the existing subscription and create a new one 3. Recreate the existing subscription to update it Your authorization may have expired or been revoked. 1. Click "Reconnect Airtable account" 2. Complete the OAuth flow again 3. Your configurations will be restored This may indicate Airtable API problems or OAuth token expiration. 1. Manually recreate the subscription 2. If problem persists, reconnect your Airtable account 3. Contact support if issues continue * **Green "Active"**: Working correctly * **Yellow "Expiring in X days"**: Will be auto-refreshed soon * **Red "Expired"**: Needs manual recreation — click Recreate Subscription Contact allGood support with a screenshot of the error, the base and table names, steps to reproduce, and subscription status. # Asana Source: https://docs.allgoodhq.com/integrations/asana The Asana integration allows you to seamlessly connect your Asana workspace with allGood, enabling automated task management and team collaboration. This integration helps streamline your project workflows by syncing tasks, projects, and team updates between both platforms. With this integration, you can automatically create tasks, update project statuses, and ensure your team stays aligned across both systems without manual intervention. ## Prerequisites Before setting up the Asana integration with Mary, ensure you have: * **Asana Account** with admin permissions to create users and manage integrations * **Access to email** for the dedicated Asana user account verification * **Mary's profile picture** for account setup ([download link](https://s3.us-east-1.amazonaws.com/asana-user-private-us-east-1/assets/1209103770281194/profile_photos/1210211616340570/f0cfd301a390d5e7f11eccb067b9fe4f_huge.jpeg)) * **allGood account** with integration permissions ## IT Coordination Guide ### Security & Account Setup Requirements * Create a dedicated Asana user account for Mary with appropriate permissions * Include Mary's profile picture during account setup for user identification * Use a monitored email address for the service account (not personal email) * Webhook configuration required for task collaboration notifications * Store credentials securely according to company policy ## Step-by-Step Setup 1. **Log into Asana** with admin access 2. Navigate to **Admin Console** → **Members** 3. Click **Invite Members** 4. Set up Mary's account: * **Email**: Use monitored team email address * **Name**: Mary (allGood) * **Profile Picture**: Upload [Mary's picture](https://s3.us-east-1.amazonaws.com/asana-user-private-us-east-1/assets/1209103770281194/profile_photos/1210211616340570/f0cfd301a390d5e7f11eccb067b9fe4f_huge.jpeg) Asana profile page for Mary 5. **Send invitation** and complete verification process 1. **Log into allGood** and navigate to **Settings** → **Integrations** 2. Click **Add Integration** and select **Asana** 3. Click **Connect Asana Account** Asana OAuth authorization screen 4. Sign in using the **dedicated Mary Asana account** credentials 5. **Authorize** allGood to access your Asana workspace 6. Verify the integration shows as **Active** on your integrations page allGood integrations page with Asana marked as Active The allGood team will work with your IT team to ensure that this is done properly — please reach out and we can collaborate on this. 1. **In allGood**, navigate to the Asana integration settings 2. Click **Configure Webhook** 3. **Select your Asana workspace** from the dropdown 4. **Enable task collaboration notifications** 5. **Save webhook configuration** ***Coming Soon***\ *Screenshot: allGood webhook configuration screen for Asana* 1. **In Asana**, navigate to the projects where you want Mary available 2. Click **Share** on each project 3. **Add Mary's account** as a project member 4. **Set appropriate permissions** (typically "Editor" or "Commenter") Asana project sharing dialog with Mary added as member ## Verification & Testing If Asana shows "Active" status in allGood integrations, Mary was able to connect successfully. Create a test task in Asana and add Mary as a collaborator to confirm the integration and webhook are working properly. ## Frequently Asked Questions Yes, you need admin permissions in your Asana workspace to set up the integration and create the necessary service accounts. The integration uses OAuth 2.0 authentication. You'll need to authorize allGood to access your Asana workspace during the setup process. Yes, you can configure the integration to sync only specific projects, teams, or workspaces based on your needs. Data synchronization occurs in real-time for most operations, with some bulk operations running on scheduled intervals. The integration includes conflict resolution mechanisms that prioritize recent changes and provide audit trails for all modifications. ## Troubleshooting Common causes include: * Insufficient permissions * API rate limits * Network connectivity issues * Incorrect field mappings You can monitor sync status through the integration dashboard, which shows recent sync activities and any errors. * Review this page for setup steps and common issues * Contact our support team for technical assistance # Datasets Source: https://docs.allgoodhq.com/integrations/datasets ## What is a Dataset? A dataset is a reference copy of your marketing automation platform data (such as Marketo or Salesforce) that syncs into allGood's environment on a specified interval. Your marketing automation system remains the source of truth — allGood maintains a synchronized copy for efficient lookup and processing purposes. Users can view and refresh datasets, but cannot create or modify them directly. Datasets are managed by the allGood team and kept in sync with your source systems. *** ## Why Datasets Exist ### API Limitations Marketing automation platforms, particularly Marketo, have API limitations that make real-time lookups unreliable for the kind of operations allGood performs at scale: * **Rate limits and concurrency caps**: Restrictions on how quickly data can be retrieved on demand * **Response consistency issues**: Marketo may return incomplete or inaccurate information about what actually exists through the API * **Query latency**: Direct API queries introduce delays that compound when processing large volumes of data ### Performance Benefits Querying allGood's cached database copy is faster and more reliable than making repeated API calls for every lookup operation. This approach ensures: * **Consistent response times** regardless of your platform's current API load * **Accurate data validation** without taxing your API limits * **Scalable processing** that doesn't impact your other integrations and workflows Salesforce's API does not exhibit the same consistency issues, so dataset functionality is primarily a solution for Marketo-specific challenges. *** ## Sync Cadence Dataset synchronization is fully configurable based on your needs: * **Standard cadence**: Overnight syncs for most use cases * **High-frequency cadence**: Hourly syncs when near-real-time data is required The sync process is engineered to minimize impact on your marketing automation platform's API usage, ensuring that other integrations and processes running in your environment remain unaffected. *** ## What Datasets Enable Datasets are a foundational component that power multiple allGood capabilities by providing fast, reliable access to your existing database: ### Data Enrichment Optimization Before sending contact data to external enrichment providers, allGood checks the dataset to determine if the data already exists in your database: * **Smart enrichment**: Only enrich fields that are truly missing, not ones that already exist in your system * **Cost optimization**: Avoid unnecessary enrichment calls for data you already have * **Faster processing**: Skip enrichment entirely for records that are already complete ### Lead Screening and Validation Validate incoming leads against your existing database before processing: * **Existing contact detection**: Identify whether a lead is already in your system * **Data completeness checking**: Determine what information you already have for a contact * **Account relationship validation**: Verify connections to existing account records ### Lead Routing and Assignment Route leads based on existing database relationships: * **Account-based routing**: Assign leads to the same owner as their associated account * **Territory-based assignment**: Route based on existing territory rules in your database * **Relationship-aware routing**: Consider existing contact relationships when assigning new leads ### Lead-to-Account Matching Connect incoming leads to existing account records using your database as reference: * **Company matching**: Link leads to accounts based on company name, domain, and other identifiers * **Hierarchy awareness**: Understand parent-subsidiary relationships from your existing data ### Reporting and Analytics Provide insights into your data quality and coverage: * **Data completeness analysis**: Identify gaps in your existing database * **Quality trends**: Monitor data quality metrics over time *** ## Getting Started Datasets are configured and managed by the allGood team as part of your integration setup. If you're interested in enabling dataset functionality for your organization: 1. **Review your integration**: Ensure your Marketo or Salesforce connection is fully configured 2. **Discuss sync cadence**: Determine whether overnight or hourly syncing best fits your needs 3. **Contact allGood**: Reach out to your allGood representative to enable dataset functionality Once enabled, datasets work transparently in the background — you'll benefit from faster processing and more intelligent automation without changing your day-to-day workflows. # Forwarding Address Source: https://docs.allgoodhq.com/integrations/email/forwarding-address Configure your email client to forward messages to allGood. **Looking for the recommended setup?** For most customers, we recommend the [Custom Domain / Hosted Mailbox](/integrations/email/hosted-mailbox) approach instead. It delivers emails directly to allGood without forwarding rules and is required for features like OOO tracking. Use this page if you're testing, validating your setup before DNS changes go live, or need a workaround while waiting on IT. **Prerequisites**—you'll need the following information to get started: * Your allGood **forwarding address**, like `7OE3COUP@parse.allgoodhq.dev`. * Access to your email system (Gmail, Exchange, etc) for the **source mailbox** you want to forward from (we'll use `sales@yourcompany.com` as an example). Sign into Gmail, and open the source mailbox. 1. Go to **Settings > Filters and Blocked Addresses** 2. Click **Create a new filter** 3. Configure any filtering criteria for emails you'd like routed to Mary. 4. Choose **Forward To**, and enter your allGood **Forwarding Address** (like `7OE3COUP@parse.allgoodhq.dev`). 5. Click **Create Filter**. Send an email to your **Source Address**, and monitor allGood—within a few minutes, you should see the email come through and start being processed. To configure forwarding for Exchange, work with your IT team to forward all emails sent to your source mailbox to the allGood forwarding address. Once your team is ready for a production setup, switch to the [Custom Domain / Hosted Mailbox](/integrations/email/hosted-mailbox) method. It's more reliable, supports higher volumes, and unlocks the full feature set. # Hosted Mailbox + Custom Domains Source: https://docs.allgoodhq.com/integrations/email/hosted-mailbox Configure DNS records to enable direct email delivery to allGood. By setting up a dedicated subdomain (such as `replies.yourcompany.com`), your marketing emails are delivered directly to allGood and processed by Mary—no forwarding rules required. This is the recommended setup for all new customers. Emails are delivered directly to allGood without configuring forwarding in your email client or server. Handles high email volumes without relay limitations. Industry-standard email authentication protects against spoofing and phishing. **Prerequisites**—you'll need the following before getting started: * **DNS management access** for your domain. * **Authority to create subdomains** (or approval from your domain administrator). * **Basic DNS knowledge** (understanding of record types: MX, TXT, CNAME). * A **subdomain name decided** (e.g., `replies.yourcompany.com` or `marketing-replies.yourcompany.com`). **Estimated setup time:** 15–30 minutes for DNS configuration, plus 24–48 hours for DNS propagation. **No deliverability impact.** Because this subdomain only *receives* email—it never sends—there is no domain warming required and no risk to your existing sending reputation. Go to **Settings → Email Domains** and click **+ Add Domain**. Enter the reply subdomain that will receive your marketing replies (for example, `reply.yourcompany.com`) and click **Set up domain**. Always use a dedicated subdomain, never your root domain. Adding a new email domain in allGood When you submit, allGood sets up the domain automatically and returns the **DNS records** (the mail CNAME and two DKIM CNAMEs) for you to add at your DNS provider. The new domain immediately appears in your **Email Domains** list with a **Pending DNS** status and a checklist showing what still needs to be completed (**DNS Validated → Ready for MX Record Updates → Fully Live**). You will need to configure the following DNS records in your domain provider. Each serves a specific security and delivery purpose. Add all three CNAME records provided by allGood. The values below are illustrative — use the exact values shown in your allGood **DNS Record Details** panel. | Type | Host | Value | | ----- | ------------------------------------ | ------------------------------------------ | | CNAME | `em****.prod-erm.allgood.net` | `u*******.wl002.sendgrid.net` | | CNAME | `s1._domainkey.prod-erm.allgood.net` | `s1.domainkey.u*******.wl002.sendgrid.net` | | CNAME | `s2._domainkey.prod-erm.allgood.net` | `s2.domainkey.u*******.wl002.sendgrid.net` | Copy the exact host and value strings directly from the allGood platform to avoid typos. After updating your DNS records, click **Verify All** to validate every pending domain. allGood then checks the CNAME records you added. Validation typically completes within **10–15 minutes**, though in some cases it may take up to **24–48 hours**. Once the DNS records pass, allGood **automatically provisions inbound processing** for the domain — no manual configuration required. Behind the scenes we ensure your inbound connection exists and create the SendGrid Inbound Parse setting that forwards incoming mail to allGood. The domain then moves to **Ready for MX Record Updates**. Domain verification screen in allGood Do **not** add your MX record until the domain reaches **Ready for MX Record Updates** and the MX value is shown. Adding it earlier can disrupt mail delivery for the domain. The MX (Mail Exchange) record is the most critical record — it must be configured correctly for any emails to be delivered. Once the domain reaches **Ready for MX Record Updates**, the MX record appears in the domain's details. Add it at your DNS provider using the exact host shown there — the example below is illustrative and your host will be different. | Type | Host | Priority | Value | | ---- | ------------------ | -------- | ----------------- | | MX | `` | `10` | `mx.sendgrid.net` | allGood runs a final validation that resolves your domain's MX record to confirm it points to `mx.sendgrid.net`. Once it does, the domain flips to **Fully Live** and is ready to receive replies. **Important notes:** * The priority value should be **lower than** any existing MX records if you're adding this to a domain that already receives email. * Some DNS providers require a trailing period (`.`) at the end of the mail server address — check your provider's format. * If configuring a subdomain, ensure you use the subdomain name, not your root domain. Once DNS verification succeeds, confirm everything is working end-to-end: 1. **Send a test email** to your new subdomain (e.g., `test@replies.yourcompany.com`) 2. **Check allGood Email Reply Management** — the email should appear within 2–5 minutes 3. **Verify classification** — ensure the email is correctly classified by the AI **Test email checklist:** Email received in allGood Email correctly classified Automated actions triggered (if configured) CRM updates processed (if applicable) ## Troubleshooting Check the following common causes: * **DNS not propagated yet** — Wait 24–48 hours after making DNS changes. * **Wrong subdomain** — Verify emails are being sent to the exact subdomain you configured. * **MX priority conflict** — If other MX records exist, ensure your allGood record has the lowest priority number. * **Firewall blocking** — Check if your outbound email server can reach SendGrid's servers. Debugging steps: Use DNS lookup tools (`dig`, `nslookup`, or an online DNS checker) to verify your records have propagated correctly. Contact allGood support with the following information: * Test email timestamp * Sender and recipient email addresses * Screenshot of DNS verification status in allGood # Overview Source: https://docs.allgoodhq.com/integrations/email/index Clean Shot 2026 02 18 At 14 23
16@2x The allGood platform can trigger agentic flows based on incoming email messages. Our Email Reply Management product is built on this capability—allowing Mary to sort the signal from the noise in the thousands of emails you get responding to your outbound messaging. ## Getting emails into allGood You have two options to start routing emails to Mary for processing: You can generate a forwarding address, like [7OE3COUP@parse.allgoodhq.dev](mailto:7OE3COUP@parse.allgoodhq.dev) above, in allGood. Emails sent to this address will be routed to Mary. Forwarding shares infrastructure across all allGood customers. *We recommend this option only for simple integrations or testing.* This option allows you to forward all mailboxes on a domain (for instance, [foo@reply.yourcompany.com](mailto:foo@reply.yourcompany.com), and [bar@reply.yourcompany.com](mailto:bar@reply.yourcompany.com), and so on) to Mary, where Mary can react based on the alias (foo@, bar@) used. Custom domain gives your account dedicated processing and unlocks features like OOO tracking that forwarding can't support. *This is the recommended path for production use.* ## What happens next? Once emails are flowing into allGood, Mary takes over. She reads and classifies every reply automatically—sorting unsubscribes, out-of-office messages, bounces, and genuine inquiries into categories you define. From there, she can extract key data from each email and trigger downstream actions like updating Marketo records or adding contacts to static lists. # Google Source: https://docs.allgoodhq.com/integrations/google The Google integration enables seamless connectivity between allGood and Google Workspace services including Gmail, Google Drive, Google Calendar, and other Google applications. This integration streamlines your workflow by automatically syncing data and enabling two-way communication between platforms. Leverage the power of Google's ecosystem within allGood to enhance productivity, automate routine tasks, and maintain consistent data across your organization's tools. ## Prerequisites Before setting up the Google integration with Mary, ensure you have: * **Google Workspace account** with admin permissions to create service accounts * **IT department coordination** for creating dedicated Google accounts * **allGood account** with integration permissions ## IT Coordination Guide ### Security & Account Setup Requirements * Create a dedicated Google Workspace account for Mary (e.g., [mary-allgood-yourcompany@yourcompany.com](mailto:mary-allgood-yourcompany@yourcompany.com)) * Configure appropriate Google Workspace services (Drive, Docs, Sheets) * Set up folder structure with proper sharing permissions * Mary account needs at least "Viewer" access to files for integration use ## Step-by-Step Setup 1. **Work with your IT department** to create a new Google Workspace account 2. **Account format**: [mary-allgood-yourcompany@yourcompany.com](mailto:mary-allgood-yourcompany@yourcompany.com) 3. **Configure services**: Enable Google Drive, Docs, and Sheets access 4. **Set security settings** according to company policy 1. **Create main folder** in Google Drive called "allGood" 2. **Create subfolders** for organization: 1. **Right-click** the "allGood" folder 2. Click **Share** 3. **Add the Mary account** email address 4. **Set permissions** to "Editor" access 5. **Check "Notify people"** 6. **Important**: Check "Make available to people with access" Google Drive sharing dialog with Mary account and Editor permissions 1. **Log into allGood** and navigate to **Settings** → **Integrations** 2. Click **Add Integration** and select **Google** 3. Click **Connect Google Account** 4. Sign in using the **dedicated Mary Google account** credentials 5. **Review and accept** the required access scope permissions 6. Verify the integration shows as **Active** on your integrations page allGood integrations page with Google marked as Active ## Verification & Testing If Google shows "Active" status in allGood integrations, Mary was able to connect successfully. Ask Mary to retrieve content from a Google Doc in your shared folder to confirm the integration is working properly. ## Frequently Asked Questions The integration supports Gmail, Google Drive, Google Calendar, Google Sheets, and other Google Workspace services. While a Google Workspace account is recommended for full functionality, many features work with regular Google accounts. The integration uses OAuth 2.0 authentication. You'll need to authorize allGood to access your Google services during setup. Yes, you can configure specific scopes and permissions to limit access to only the Google services you want to integrate. All data is encrypted in transit and at rest. We follow Google's security best practices and maintain SOC 2 compliance. Google imposes various rate limits on their APIs. The integration includes intelligent rate limiting to ensure smooth operation. ## Troubleshooting Common causes include: * Expired OAuth tokens * Changed Google account passwords * Insufficient permissions * API access restrictions Check your internet connection, verify API quotas, review error logs, and ensure proper permissions are configured. * Review this page for setup steps and common issues * Contact our support team for technical assistance # HubSpot Source: https://docs.allgoodhq.com/integrations/hubspot The HubSpot integration connects your CRM, marketing automation, and sales pipeline directly with allGood. This powerful integration enables automatic synchronization of contacts, deals, companies, and marketing activities to provide a unified view of your customer journey. Streamline your sales and marketing processes by leveraging HubSpot's comprehensive customer data within allGood's workflow automation capabilities. ## Prerequisites Before setting up the HubSpot integration with Mary, ensure you have: * **HubSpot Account** with either [super admin](https://knowledge.hubspot.com/settings/hubspot-user-permissions-guide#super-admin) permissions or [App Marketplace Access](https://knowledge.hubspot.com/settings/hubspot-user-permissions-guide#settings) permissions * **Access to email** for the dedicated HubSpot user account verification * **allGood account** with integration permissions ## IT Coordination Guide ### Security & Account Setup Requirements * Create a dedicated HubSpot user account with appropriate permissions for integration use * User needs super admin or App Marketplace Access permissions to install the integration * Use a monitored email address for the service account (not personal email) * Store credentials securely according to company policy ## Step-by-Step Setup 1. **Log into HubSpot** with admin access 2. Navigate to **Settings** → **Users & Teams** 3. Click **Create User** 4. Set up user with appropriate permissions (super admin or App Marketplace Access) 5. Use a monitored team email address 6. Complete user verification process 1. **Log into allGood** and navigate to **Settings** → **Integrations** allGood settings page 2. Click **Add Integration** and select **HubSpot** 3. Select the use-case for pre-configured scopes, or choose them using the dropdown allGood HubSpot integration page with Select Scopes 4. Click **Connect HubSpot Account** 5. Sign in using the **dedicated HubSpot user credentials** created above HubSpot login screen popup 6. Verify the integration shows as **Active** on your integrations page If you need to update integration scopes by adding/removing them: 1. First, uninstall the app in HubSpot: * Go to HubSpot **Account Management → Integrations → Connected Apps** * Select **Action → Uninstall** HubSpot Connected Apps Screen 2. Navigate to **Settings** → **Integrations** in allGood 3. Click **Edit** next to your HubSpot integration 4. Click **Reconnect HubSpot Account** 5. Complete the OAuth flow with updated scopes ## Verification & Testing If HubSpot shows "Active" status in allGood integrations, Mary was able to connect successfully. Ask Mary to retrieve contact lists to confirm the integration is working properly. ## Frequently Asked Questions The integration works with all HubSpot plans, though some advanced features may require Professional or Enterprise subscriptions. The integration uses OAuth 2.0 authentication with your HubSpot account. You'll need admin permissions to authorize the connection. Yes, the integration supports synchronization of custom properties and fields from your HubSpot account. The integration supports contacts, companies, deals, tickets, products, and custom objects. Data synchronization occurs in real-time for most operations, with periodic bulk syncs for large datasets. ## Troubleshooting Common causes include: * Insufficient HubSpot permissions * API rate limits exceeded * Field mapping configuration issues * Data validation errors The integration includes duplicate detection and merge capabilities to maintain data integrity. * Review this page for setup steps and common issues * Contact our support team for technical assistance # “Marketo" Source: https://docs.allgoodhq.com/integrations/marketo Set up API credentials in Marketo and configure the allGood integration so Mary can read and update your Marketo Programs, Smart Lists, and lead data. Connect your Marketo instance to allGood so Mary can access your Programs, Smart Lists, and lead information. This setup requires administrator access to Marketo and takes about 15 minutes. Once connected, Mary will be able to retrieve program details, analyze campaign performance, and update token values — all without leaving your conversation. ## Before you begin You'll need: * **Administrator access** to your Marketo instance * **Permission to create API users** in Marketo's Admin panel * **allGood account** with integration permissions If you don't have Marketo admin access, forward this guide to your Marketing Ops team. They'll need the allGood IP addresses listed in Step 5 below. ## What happens during setup You'll create a dedicated API user in Marketo that allGood uses to access your data. This user has no login password — it exists only for API connections. You control exactly what data this user can access by setting its role permissions. The setup process generates four credentials: a Client ID, Client Secret, REST Endpoint URL, and Identity URL. You'll copy these into allGood to complete the connection. **Data access:** Once connected, Mary can read Marketo Programs, Smart Campaigns, Smart Lists, and lead records. Mary cannot delete Programs, send emails, or modify Smart Campaign logic. If your organization's security policy requires IP whitelisting, you'll add allGood's IP addresses in Step 5. ## Steps 1. Log into Marketo with administrator access 2. Go to **Admin** → **Users & Roles** → **Roles** 3. Click **New Role** Roles page showing New Role button 4. Name the role `allGood API Role` 5. Check the **Access API** checkbox under API Access 6. Click **Create** New Role form with API Access enabled This role grants API access without UI login permissions. The specific permissions are controlled at the LaunchPoint service level, which you'll configure in Step 3. 1. Go to **Admin** → **Users & Roles** → **Users** 2. Click **Invite New User** Users page showing Invite New User button 3. Enter an email address for the API user (example: `api-allgood@yourcompany.com`) 4. Enter a first and last name (example: "allGood API User") 5. Under **User Role**, select the `allGood API Role` you created in Step 1 6. Check **API Only** — this prevents the account from logging into Marketo's UI 7. Click **Send Invite** New API User form with role assignment Marketo will send an email to the address you specified, but no action is needed. API-only users don't require email confirmation. 1. Go to **Admin** → **LaunchPoint** 2. Click **New** → **New Service** LaunchPoint page showing New Service option 3. Configure the service: * **Display Name**: `allGood Integration` * **Service**: Select **Custom** * **Description** (optional): `API access for allGood Mary` * **API User**: Select the user you created in Step 2 4. Click **Create** New LaunchPoint form with configuration LaunchPoint generates the Client ID and Client Secret you'll need in Step 4. Don't close this window yet. 1. On the LaunchPoint services list, find the `allGood Integration` service you just created 2. Click **View Details** LaunchPoint service list showing View Details link 3. Copy the **Client ID** — it looks like `a1b2c3d4-e5f6-7890-abcd-ef1234567890` 4. Click **Show** next to Client Secret, then copy the secret value 5. Store both values temporarily in a secure location (you'll paste them into allGood in Step 6) Client ID and Secret display screen The Client Secret is shown only once. If you close this window without copying it, you'll need to delete the service and create a new one. 1. Go to **Admin** → **Web Services** 2. Scroll to the **REST API** section 3. Copy the **Endpoint** URL — it looks like `https://123-ABC-456.mktorest.com/rest` 4. Copy the **Identity** URL — it looks like `https://123-ABC-456.mktorest.com/identity` Web Services page showing REST API endpoints **If your Marketo instance has IP restrictions enabled:** Look for the **IP Restrictions** section on the same Web Services page. If it shows "Enabled," you must whitelist allGood's IP addresses before the integration will work: * `52.25.122.65` * `52.26.241.77` Add both addresses to the Allowed IP Addresses list. If you're not sure whether IP restrictions are enabled, check with your Marketo administrator or IT team before proceeding. IP Restrictions section with allGood IPs added 1. Log into allGood and go to **Settings** → **Integrations** 2. Click **Add Integration** and select **Marketo** allGood integrations page 3. Paste the four credentials you collected: * **Client ID** (from Step 4) * **Client Secret** (from Step 4) * **Endpoint URL** (from Step 5) * **Identity URL** (from Step 5) Marketo integration form with credential fields 4. Click **Save** allGood tests the connection immediately. If the credentials are valid and IP restrictions (if enabled) are configured correctly, the integration status changes to **Active** within a few seconds. allGood integrations page with Marketo marked as Active ## You're done — verify the connection Once the integration shows **Active** on your Integrations page, Mary can access your Marketo data. Test the connection by asking Mary a simple question like: * "Show me all Marketo Programs created this month" * "What Marketo Smart Lists exist in the Email Nurture workspace?" * "Get the token values for \[Program Name]" If Mary retrieves results, the integration is working. If Mary returns an error or says she cannot access Marketo, proceed to the troubleshooting steps below. ## Troubleshooting This means allGood could not authenticate with your Marketo instance. Check: 1. **Client ID and Client Secret** — Copy them again from the LaunchPoint service details and re-paste them into allGood. Make sure there are no extra spaces before or after the values. 2. **Endpoint and Identity URLs** — Verify you copied the full URLs from the REST API section, not the SOAP API section. 3. **LaunchPoint service configuration** — Confirm the API User assigned to the service is the API-only user you created, not a different user. If all credentials are correct and the error persists, your Marketo instance may have IP restrictions enabled. Proceed to the IP whitelisting step below. If your Marketo instance requires IP whitelisting: 1. Go to **Admin** → **Web Services** in Marketo 2. Scroll to **IP Restrictions** 3. If restrictions are enabled, add both allGood IP addresses to the allowed list: * `52.25.122.65` * `52.26.241.77` 4. Click **Save** 5. Return to allGood and click **Reconnect** on the Marketo integration Changes to IP restrictions take effect immediately. Test the connection again by asking Mary to retrieve a simple list of Programs. The API user's role may not have permission to access the resource Mary is trying to read. Common causes: * **Workspace restrictions** — If your Marketo instance uses Workspaces, the API user must be assigned to the Workspace containing the data Mary is trying to access. Check the user's Workspace assignments in **Admin** → **Users & Roles** → **Users**. * **Role permissions** — The allGood API Role must have **Access API** checked. Verify this in **Admin** → **Users & Roles** → **Roles**. After updating permissions, no reconnection is needed — changes take effect immediately. Contact allGood support and include: * The exact error message Mary returned * A screenshot of your LaunchPoint service configuration (with Client Secret hidden) * Whether IP restrictions are enabled in your Marketo instance * The Marketo instance ID (visible in your Endpoint URL — the part before `.mktorest.com`) Support will verify the configuration and work with your Marketo admin if needed. ## Frequently asked questions The allGood integration can read Marketo Programs, Smart Campaigns, Smart Lists, and lead records. It cannot delete Programs, send emails, modify Smart Campaign logic, or change lead data. The API-only user you create controls exactly what data is accessible through its role permissions and Workspace assignments. A dedicated API-only user ensures the integration operates independently of any individual employee's account. If someone leaves the company or has their password changed, the integration continues working. API-only users cannot log into Marketo's UI, reducing security risk. allGood's integration connects from these IP addresses: * `52.25.122.65` * `52.26.241.77` If your Marketo instance has IP restrictions enabled, you'll need to whitelist both addresses in **Admin** → **Web Services** → **IP Restrictions**. Yes. If your Marketo instance uses Workspaces, assign the API user only to the Workspaces where allGood needs access. The user can only read data from assigned Workspaces. Configure Workspace access in **Admin** → **Users & Roles** → **Users**. To disconnect allGood from Marketo: 1. In allGood: Go to **Settings** → **Integrations** → Marketo, and click **Disconnect** 2. In Marketo: Go to **Admin** → **LaunchPoint**, find the allGood Integration service, and click **Delete** Deleting the LaunchPoint service immediately invalidates the API credentials. Yes. Every request Mary makes to Marketo counts toward your daily API call limit (typically 10,000-100,000 calls per day depending on your Marketo subscription). Mary's queries are optimized to use minimal API calls, but high-frequency usage may approach your limit. Monitor API usage in Marketo at **Admin** → **Web Services** → **API Call Usage**. ## Related articles * Managing Mary's access to Marketo data * Updating Marketo Program tokens with Mary * Using Mary to analyze Marketo campaign performance # Connect Marketo to allGood via webhook Source: https://docs.allgoodhq.com/integrations/marketo/webhook Configure a Marketo webhook that sends lead data to an allGood worksheet when a Smart Campaign fires. Marketo webhooks let you push lead data to an allGood worksheet the moment a Smart Campaign fires. When a lead fills out a form, reaches a score threshold, or hits any other trigger you choose, Marketo sends their data to allGood automatically. From there, allGood runs the workflow you've built — enriching the record, routing it, or triggering downstream actions. This setup takes about 15 minutes once you have the prerequisites in place. Marketo's webhook configuration has a few steps where small mistakes cause hard-to-diagnose errors. This article flags each one as you reach it — follow the steps in order and you'll be set up correctly. If you find yourself running into issues, skip to the “Troubleshooting” section at the end of this article. ## Prerequisites * **A Marketo Smart Campaign to trigger the webhook from.** This can be an existing campaign, or you can create a new one for this purpose. * **A webhook payload template.** This payload determines the data Marketo sends to allGood. Reach out to allGood support for a template tailored to your use case, or use the default template provided in the steps below. * **An allGood webhook URL.** This looks like `https://webhook.allgoodhq.app/xxxxxxxxxxxxxx`. You can get this from allGood support, or by creating an Item Webhook in the allGood worksheet you want to connect to. First, create an allGood worksheet with your desired automation steps. Then open the worksheet settings and create an Item Webhook. The allGood worksheet settings panel showing the Item Webhook section with a generated webhook URL and Action dropdown Copy this URL — you'll paste it into Marketo in a later step. Set **Action** to **Add to Worksheet + Run Flow** if you want the flow to run automatically when new items arrive. Make sure you have all three prerequisites before continuing. If you have questions, contact allGood support and we can walk you through the process. ## Part 1: Create a webhook configuration in Marketo In Marketo, go to **Admin > Webhooks**. The Marketo Admin panel showing the Webhooks option highlighted in the left navigation menu Click **New Webhook** in the header. The Webhooks page header with the New Webhook button highlighted The New Webhook form appears. The Marketo New Webhook form showing empty fields for URL, Request Type, Template, Request Token Encoding, and Response type Under **URL**, enter the allGood webhook URL from your prerequisites. Under **Request Type**, select **POST**. Under **Template**, paste the payload template verbatim — copy it directly from this page and paste directly into Marketo. Do not use Word, Google Docs, or any other app as an intermediate step. Those applications silently add hidden formatting characters that cause `400` errors. If allGood support hasn't provided a custom template, use this default: ```text theme={null} { "First Name": {{lead.First Name}}, "Last Name": {{lead.Last Name}}, "Email": {{lead.Email Address}}, "Website": {{company.Website}}, "Company": {{company.Company Name}}, "Phone": {{lead.Phone Number}}, "Job Title": {{lead.Job Title}}, "SFDC Lead Id": {{lead.SFDC Id}}, "Mkto Lead Id": {{lead.Id}}, "State": {{lead.State}}, "Country": {{lead.Country}}, "Inferred Country": {{lead.Inferred Country}}, "Inferred State Region": {{lead.Inferred State Region}}, "Inferred Postal Code": {{lead.Inferred Postal Code}}, "Postal Code": {{lead.Postal Code}} } ``` Use the copy button in the top-right of the code block to copy it cleanly to your clipboard. Under **Request Token Encoding**, select **JSON**. Leave **Response type** as **None**. Click **CREATE** to save the configuration. After clicking **CREATE**, Marketo navigates you to a different page in webhook settings. Navigate back to the webhook before continuing. In the right-panel navigation menu, click the webhook you created to return to it. The Marketo webhooks right-panel showing the newly created webhook entry in the navigation list Under **Custom Headers**, click **EDIT**. The Marketo webhook configuration page showing the Custom Headers section with the EDIT button Add a new header. Set **Header** to `Content-Type` and **Value** to `application/json`. The Marketo custom headers editor with a new row showing Header as Content-Type and Value as application/json Click **SAVE**. Your completed webhook configuration should look like this: The Marketo webhook detail page showing the URL, POST request type, JSON payload template, JSON encoding, and the Content-Type custom header all configured When your configuration matches the screenshot above, the webhook is ready. The next step is to trigger it from a Smart Campaign. ## Part 2: Trigger the webhook from a Smart Campaign Create a new Smart Campaign in an appropriate location, or open an existing one. Under **Smart List**, add the trigger for the event you want to capture — for example, **Fills Out Form**, or any other lead-based trigger. Before activating this campaign, add a Smart List filter that excludes leads who have not consented to data processing or have opted out. The correct filter depends on how your Marketo instance handles compliance. Check with your marketing ops or legal team if you're unsure — sending lead data to a third-party system without valid consent may violate GDPR, CCPA, or similar regulations. Add the appropriate consent filter to your Smart List. Under **Flow**, add a **Call Webhook** action. Select the webhook you created in Part 1. Under **Schedule**, set the campaign to run each person through the flow every time they qualify. This ensures the webhook fires on repeat entries, not only the first. Click **Activate** to turn the campaign on. To confirm the setup is working, trigger the campaign with a test lead — for example, submit the form you set as the Smart List trigger using a test email address. Then go to **Marketing Activities > \[your campaign] > Results**. You should see a **Call Webhook** activity with a status of `200 OK`. Open your allGood worksheet — the test lead's data should appear as a new item within a few seconds. ## Troubleshooting If you see `400` errors or "Unparseable JSON" in the Marketo activity log, the cause is almost always a configuration error. Work through these checks in order. **Check 1: Template copied verbatim** Open the webhook configuration and compare your template to the one in this article character by character. Word, Google Docs, and similar apps can silently add hidden formatting characters when you paste through them — this breaks the JSON even when it looks correct on screen. Copy the template directly from this article and paste it directly into Marketo. **Check 2: Content-Type header set correctly** Confirm that the **Custom Headers** section contains exactly one entry: **Header** = `Content-Type`, **Value** = `application/json`. If this header is missing or misspelled, Marketo sends the webhook in the wrong format and allGood cannot parse it. **Check 3: You're editing the right webhook** Marketo navigates you away from the current webhook every time you save a setting. Confirm the webhook name shown at the top of the configuration page matches the one you created. If you're on a different webhook, your changes are going to the wrong place. ## Still need help? If you've worked through all three checks and the webhook is still failing, contact allGood and include: * The error code or activity log message from Marketo * A screenshot of your completed webhook configuration page * The step in this article where things went wrong # Salesforce Source: https://docs.allgoodhq.com/integrations/salesforce The Salesforce integration enables powerful connectivity between allGood and the world's leading CRM platform. This integration provides seamless synchronization of leads, opportunities, accounts, and custom objects to create a unified sales and customer management experience. Leverage Salesforce's comprehensive CRM capabilities within allGood to streamline your sales processes, automate workflows, and maintain consistent customer data across your organization. ## Capabilities Connecting Salesforce to the allGood platform enables deep integration with your CRM data. Key capabilities include: * **Lead-to-Account Matching**\ Mary finds the right account for every lead. We use agentic search to resolve duplicate Account records, fix typos, expand or contract acronyms and initialisms, and incorporate custom contextual clues and signals (ICP match, BDR assignment, etc.) to ensure the best possible match. * **Lead Routing**\ Mary understands your routing rules. We can handle MQL/AQL determination; understand your lead's geography even when data is missing, incomplete, or inconsistent; and route leads to your sales team based on the results of account-level research agents. * **Lead Conversion**\ Mary can figure out which of your Leads are worth converting to Contacts---tying in lead-to-account match information, agentic MQL/AQL/SQL determination, and other custom/contextual signals to make the best possible decision. Mary will also deduplicate Lead records by intelligently merging them into the same Contact when possible. * **List/Campaign Upload**\ Mary can take lists of leads/contacts, perform data cleaning and normalization, and upload them to Salesforce as members of a Salesforce/Pardot campaign. Mary can handle campaign status setup, and once the campaign has been created, Mary can create SFDC reports to track campaign performance. * **Data integration into other Mary use-cases**\ Connecting Salesforce data allows us to pull your CRM data into any other Mary use-case. We can query live data with SOQL, or run agentic search against a cloned snapshot of data in allGood's internal, tenant-isolated Snowflake data warehouse. ## Prerequisites Before setting up the Salesforce integration with Mary, ensure you have: * **Salesforce Account** with Enterprise access or API quota purchased * **Admin access** to your Salesforce instance to create users and profiles * **Access to email** for the dedicated Salesforce user account verification * **allGood account** with integration permissions ## Step-by-Step Setup 1. **Log in to Salesforce** with an admin account 2. Click the **gear icon** (top right) → **Setup** 3. In left navigation: **Administration** → **Users** → **Profiles** 4. Click **New Profile** 5. Set **Existing Profile** to **Read only** 6. Set **Profile Name** to **allGood User** 7. Click **Save** 1. On the Profiles page, click **Edit** next to your new profile 2. Scroll to **Standard Object Permissions** and **Custom Object Permissions** 3. Enable **View All Data** permissions for objects Mary should access. At the minumum, enable full read access for `User`, and full read-write access for `Account`, `Lead`, `Contact`, `Opportunity`, and `Campaign`. Clean Shot 2026 02 17 At 17 54 21@2x 4. Scroll to top and click **Save** 1. In left navigation: **Administration** → **Users** → **Users** 2. Click **New User** 3. Fill required fields: * **License**: Select **Salesforce** * **Profile**: Select **allGood User** * **Email**: Use accessible team email address that somehow indicates "allGood" * Make sure the `Marketing User` box is checked. 4. Click **Save** 5. **Copy the Username** and store it securely 1. Check the email inbox used for the new user 2. Open the Salesforce verification email 3. Follow the verification link and **set a password** 4. **Store the password** securely. 1. **Log into allGood** and navigate to **Settings** → **Integrations**. Click **Install** next to "Salesforce". allGood integrations page 2. **Select the right SFDC environment** (either production/live, sandbox, or a custom instance login URL) Clean Shot 2026 02 17 At 17 58 01@2x 3. Click **Connect to Salesforce** . Clean Shot 2026 02 17 At 17 58 45@2x 4. Sign in using the **allGood user credentials** created above 5. Verify the integration shows as **Active** on your integrations page ## Verification & Testing If Salesforce shows "Active" status in allGood integrations, Mary was able to connect successfully. ## Frequently Asked Questions The integration works with Professional, Enterprise, and Unlimited editions. Developer and Essentials editions have limited API access. The integration user needs "View All Data" permissions for objects you want to sync, plus API access permissions. The integration supports standard objects like Leads, Contacts, Accounts, Opportunities, and Cases, plus custom objects. Custom fields are fully supported and can be mapped between Salesforce and allGood according to your requirements. ## Troubleshooting Common causes include: * Incorrect credentials * IP restrictions * Security token issues * Expired passwords Salesforce has daily API limits. The integration includes smart batching and scheduling to optimize API usage. * Review this page for setup steps and common issues * Contact our support team for technical assistance # Salesforce Webhooks Apex Package Source: https://docs.allgoodhq.com/integrations/salesforce/apex_package This runbook walks a **Salesforce administrator** through installing the allGood Webhooks package in your org. When you finish, your org will send Lead and Contact changes to allGood automatically. It takes about 15 minutes. ## Prerequisites You should have received from allGood: * **The package files** * `allgood_sfdc_package__v.zip` — use this for a **first-time install**. * `allgood_sfdc_package__v__upgrade.zip` — use this if your org **has had a previous version** of allGood webhooks; it also removes obsolete components from the old version. * **One or more Webhook URLs**\ They look like `https://webhook.allgoodhq.app/abc123`. * **Optionally, an API key for each webhook** Not sure which package file to use? If allGood webhooks have ever been installed in this org, use the `__upgrade` file. Otherwise use the plain file. You will also need: * **A Salesforce login** with the **System Administrator** profile * **Permission to deploy metadata** and edit Custom Metadata The package only adds new components (a configuration type, a few Apex classes, and triggers on Lead and Contact). It does not modify existing fields, layouts, or data. ## Install the package You can install with [Workbench](https://workbench.developerforce.com) (no extra software) or the Salesforce CLI. Workbench is the simplest for most admins. Go to **[https://workbench.developerforce.com](https://workbench.developerforce.com)**. Under **Environment**, choose **Production** (or **Sandbox** if installing into a sandbox), accept the terms, and log in with your admin credentials. In the Workbench menu, go to **migration** → **Deploy**. Click **Choose File** and select the package file from "Prerequisites" — plain for a first-time install, `__upgrade` if a previous version was installed. Check these options: * **Rollback On Error** — so a failure leaves your org untouched. * **Test Level**: `RunSpecifiedTests` — Salesforce requires tests to run when deploying to Production. * **Run Tests** — paste the package's three test classes: ``` WebhookTriggerHandlerTests,WebhookServiceTests,WebhookConfigProviderTests ``` * **Ignore Warnings** — **only when deploying the `__upgrade` file**. Leave it unchecked for the plain first-time-install file. `RunLocalTests` runs **every** test in your org — yours, allGood's, and every other vendor's. Any failing test anywhere blocks the install, even when it has nothing to do with allGood. In an established org there is usually at least one, so this is the most common reason an otherwise-fine install fails. `RunSpecifiedTests` runs only the three allGood test classes. Salesforce still enforces coverage: every class and trigger in the package must be at least 75% covered by the tests you name. The allGood package ships at 100% coverage, so it passes comfortably. This does not weaken your org. It skips *running* unrelated tests during this one deployment; it does not change, disable, or delete anything of yours. The `__upgrade` file removes obsolete components left by older versions, and that cleanup list intentionally names components that may not be present in your org. Salesforce treats a "not found" deletion as a *warning*; without **Ignore Warnings**, that warning fails the whole deploy. Enabling it lets those skips pass while still deleting whatever obsolete components are present. Real problems still fail the deploy, and **Rollback On Error** keeps it all-or-nothing. The plain first-time-install file performs no deletions, so it does not need this option. Click **Next**, then **Deploy**. Wait for the status to show **Succeeded**. The package's automated tests run during the deployment and must pass — this is expected and takes a minute or two. To rehearse without changing anything, check **Check Only** and deploy. Salesforce validates the package and runs the tests but commits nothing. A successful validation can also be quick-deployed later without re-running the tests. If your team uses the Salesforce CLI, unzip the package and deploy the metadata folder. Add `--ignore-warnings` only for the `__upgrade` package: ```bash theme={null} # First-time install (plain package) sf project deploy start --metadata-dir \ --test-level RunSpecifiedTests \ --tests WebhookTriggerHandlerTests \ --tests WebhookServiceTests \ --tests WebhookConfigProviderTests \ --target-org # Upgrade (removes obsolete components) sf project deploy start --metadata-dir \ --test-level RunSpecifiedTests \ --tests WebhookTriggerHandlerTests \ --tests WebhookServiceTests \ --tests WebhookConfigProviderTests \ --ignore-warnings --target-org ``` Each test class needs its own `--tests` flag. Add `--dry-run` to validate without committing. ## Configure your webhooks Each webhook is one **configuration record**. Create one per object you want to send (Lead, Contact, or both); you can also create several for the same object if allGood gave you more than one URL. In Salesforce, go to **Setup**, then search for and open **Custom Metadata Types**. Next to **allGood Webhook Configuration**, click **Manage Records**. Click **New** and fill in the fields: | Field | What to enter | | ------------------------- | -------------------------------------------------------------------------- | | **Label** / **Name** | Any name you like, e.g. `Lead Webhook` (Name auto-fills) | | **Target SObject** | `Lead` or `Contact` | | **Webhook URL** | The full URL allGood gave you, e.g. `https://webhook.allgoodhq.app/abc123` | | **API Key** | The API key allGood gave you (leave blank if none) | | **Update Trigger Fields** | Comma-separated field API names that should send an update (see below) | | **Include Fields** | Optional: comma-separated extra field API names to add to the payload | | **Is Active** | Check this to turn the webhook on | Click **Save**. Repeat for each object / URL. ### About "Update Trigger Fields" This controls which **edits** send a webhook. Only changes to the fields you list here trigger an update event — this avoids sending a webhook on every unrelated edit. * Recommended for **Lead**: `Status, Email, Phone, Company` * Recommended for **Contact**: `Email, Phone, LastName, Status` If you leave **Update Trigger Fields** blank, edits never send a webhook. New records (inserts) always send a webhook regardless of this field. ## Verify it works Make sure the configuration record you created has **Is Active** checked. Create a new test **Lead** (or Contact). This should send an "insert" webhook. Edit one of the **Update Trigger Fields** on that record (e.g. change the Lead's Status). This should send an "update" webhook. Confirm with allGood that the events arrived, **or** check inside Salesforce: * **Setup** → **Apex Jobs** — you should see a recently completed `WebhookService` future job. * **Setup** → **Debug Logs** — enable logging for your user, repeat the test, and look for the outbound request and its HTTP response status. ## Reference * **What is sent**\ The record's standard fields (plus any **Include Fields** you list) as a JSON POST, with a `Metadata` section describing the event (object, insert vs. update, and the previous values on an update). The API key, if set, is sent as a bearer token. * **Reliability**\ Each event is delivered asynchronously and retried up to 3 times. * **Security**\ All traffic is HTTPS to allGood-owned domains, which are pre-approved by the package (Remote Site Settings). The API key is sent in the standard `Authorization` header. ## Turning it off * **Pause one webhook**: uncheck **Is Active** on its configuration record. * **Pause everything**: uncheck **Is Active** on all configuration records. * **Full uninstall**: remove the Apex triggers (`LeadTrigger`, `ContactTrigger`), then the Apex classes and the configuration type, via Setup or a destructive deployment. For anything else, contact [allGood support](mailto:support@allgoodhq.com). ## Troubleshooting Confirm a configuration record exists for that object and **Is Active** is checked. The edited field isn't in **Update Trigger Fields**. Add it (or set the recommended list). **Update Trigger Fields** is blank — add the fields that should trigger updates. The **API Key** is missing or wrong — re-enter the key allGood provided. The **Webhook URL** must be the exact allGood URL (it must begin with `https://webhook.allgoodhq.app`). Re-paste the URL allGood gave you. You deployed the `__upgrade` file without **Ignore Warnings** — re-deploy with it checked. If the failing test class is not one of `WebhookTriggerHandlerTests`, `WebhookServiceTests`, or `WebhookConfigProviderTests`, it is a pre-existing failure in your org and unrelated to this package. Set **Test Level** to `RunSpecifiedTests` and list only the three allGood classes, as described in "Set the deployment options" above. That is the recommended setting for every install. Those other failures are still worth fixing, but they should not hold up this deployment. Your org has a validation rule that the package's test records do not satisfy — for example, a rule requiring an Email on every Lead or an Account on every Contact. Apex tests cannot bypass validation rules, so the test records have to satisfy them. Make sure you are installing **version 0.6.1 or later**, which builds its test records to satisfy the most common required-field rules. If it still fails, send allGood support the exact error message and the rule it names — we will adjust the package's test data. As a stopgap, an administrator can temporarily deactivate that validation rule (**Setup** → **Object Manager** → the object → **Validation Rules**), deploy, and re-activate it immediately afterward. Re-run with **Rollback On Error** checked; capture the error and send it to allGood support. # Salesforce for Email Reply Management Source: https://docs.allgoodhq.com/integrations/salesforce/erm Connect Salesforce to allGood for Email Reply Management, and grant the exact permissions Mary needs to write reply-classification results back to your CRM. This guide walks you through connecting Salesforce to allGood for [Email Reply Management](/use-cases/erm/overview) and granting the dedicated allGood user the permissions Mary needs. For ERM, Mary looks a reply's sender up in Salesforce by email, then writes the result of her classification back to the matching **Contact** or **Lead** — flipping opt-out fields on `Unsubscribe`, recording rationale, and adding senders to campaigns. Because Mary acts on records she doesn't *own*, the permission setup below is stricter than a read-only sync, and getting it right is what makes the difference between Mary finding a record and Mary silently finding nothing. Already have Salesforce connected for another Mary use-case? You still need to confirm the [object permissions](#grant-object-permissions) and [field-level security](#field-level-security-fls) below — the ERM write-backs require `View All` / `Modify All` on **Contact** and **Lead**, which a read-only profile won't have. ## Prerequisites Before setting up the Salesforce integration for ERM, ensure you have: * **Salesforce Account** with Enterprise access or API quota purchased * **Admin access** to your Salesforce instance to create users and profiles * **Access to email** for the dedicated Salesforce user account verification * **allGood account** with integration permissions ## Step-by-Step Setup 1. **Log in to Salesforce** with an admin account 2. Click the **gear icon** (top right) → **Setup** 3. In left navigation: **Administration** → **Users** → **Profiles** 4. Click **New Profile** 5. Set **Existing Profile** to **Read only** 6. Set **Profile Name** to **allGood User** 7. Click **Save** Grant these on the **allGood User** profile (Setup → **Users** → **Profiles** → **allGood User** → **Edit**): | Object | Read | Create | Edit | View All | Modify All | | :------------------ | :--: | :----: | :--: | :------: | :--------: | | **Contact** | ✅ | ✅ | ✅ | ✅ | ✅ | | **Lead** | ✅ | ✅ | ✅ | ✅ | ✅ | | **Campaign** | ✅ | | ✅ | ✅ | | | **Campaign Member** | ✅ | ✅ | ✅ | | | **`View All` and `Modify All` on Contact and Lead are required, not optional.** The allGood user does not *own* the records it looks up by email. With only `Read`/`Edit`, Salesforce's sharing model hides records the user doesn't own, so Mary's lookup finds nothing, or the update fails on records it can't access. `View All` lets Mary find any matching record; `Modify All` lets her write to records she doesn't own. To set them: 1. Go to Setup → **Users** → **Profiles**, click **Edit** next to **allGood User**. 2. Under **Standard Object Permissions**, set the checkboxes exactly as in the table above: * **Contact** and **Lead** → **Read, Create, Edit, View All, Modify All** * **Campaign** → **Read, Edit, View All** * **Campaign Member** → **Read, Create, Edit** 3. Leave **Delete** unchecked on every object — the integration never deletes records. 4. Scroll to the top and click **Save**. Enable SFDC object permissions Object-level permissions do **not** cover individual fields — field access is controlled separately by Field-Level Security (FLS). Grant the allGood User profile **Read + Edit** on the fields Mary writes: 1. Go to Setup → **Object Manager** → **Contact** → **Fields & Relationships** → **Email Opt Out**. 2. Click **Set Field-Level Security**. 3. For the **allGood User** profile, check **Visible** and leave **Read-Only** unchecked, then **Save**. 4. Repeat for **Lead**: Object Manager → **Lead** → **Fields & Relationships** → **Email Opt Out** → **Set Field-Level Security** → **Visible** (not Read-Only) → **Save**. 5. Do the same for any other fields you configure Mary to write, plus **Company** on **Lead** (Salesforce requires it when creating new Leads). Standard required fields (**Email**, **Last Name**) are always visible and need no FLS change. 1. In left navigation: **Administration** → **Users** → **Users** 2. Click **New User** 3. Fill required fields: * **License**: Select **Salesforce** * **Profile**: Select **allGood User** * **Email**: Use accessible team email address that somehow indicates "allGood" * Make sure the `Marketing User` box is checked. 4. Click **Save** 5. **Copy the Username** and store it securely 1. Check the email inbox used for the new user 2. Open the Salesforce verification email 3. Follow the verification link and **set a password** 4. **Store the password** securely. 1. **Log into allGood** and navigate to **Settings** → **Integrations**. Click **Install** next to "Salesforce". allGood integrations page 2. **Select the right SFDC environment** (either production/live, sandbox, or a custom instance login URL) Select the right SFDC environment 3. Click **Connect to Salesforce** . Connect to Salesforce 4. Sign in using the **allGood user credentials** created above 5. Verify the integration shows as **Active** on your integrations page ## Verification & Testing If Salesforce shows "Active" status in allGood integrations, Mary was able to connect successfully. Object-level access and FLS only surface at execution time, so verify the write path end-to-end before going live: * Send a message against a category whose actions write to Salesforce. * Confirm the target **Contact**/**Lead** actually updated — including the `Email Opt Out` field for `Unsubscribe`. * If the record wasn't found or the update was silently skipped, re-check `View All` / `Modify All` on **Contact** and **Lead** and the FLS on the field being written. ## Frequently Asked Questions The allGood user doesn't *own* the Contact and Lead records it looks up by email. Salesforce's sharing model hides records a user doesn't own, so with only `Read`/`Edit`, Mary's lookup finds nothing (or the update fails on a record she can't touch). `View All` lets her find any matching record; `Modify All` lets her write to records she doesn't own. No. The integration never deletes records — leave **Delete** unchecked on every object. Almost always Field-Level Security. Object permissions don't cover individual fields — confirm the allGood User profile has the field set to **Visible** (not Read-Only) under **Set Field-Level Security** for both **Contact** and **Lead**. The integration works with Professional, Enterprise, and Unlimited editions. Developer and Essentials editions have limited API access. ## Troubleshooting This is a Field-Level Security issue, not a missing field. When the allGood User profile can't see a field, Salesforce reports it as if the column doesn't exist. Grant **Read + Edit** FLS on the field for the allGood User profile (see the [field-level security step](#field-level-security-fls) above). The allGood user likely lacks **View All** on Contact/Lead, so records it doesn't own are hidden by your org's sharing model. Enable **View All Records** on both Contact and Lead. The user can *read* the record but not *edit* one it doesn't own. Enable **Modify All Records** on Contact and Lead (in addition to Edit). Confirm three things: the **Marketing User** flag is enabled on the allGood user, the profile has **Edit** on **Campaign**, and it has **Create** on **Campaign Member**. All three are required to add a member. The field is missing **Edit** FLS for the allGood User profile. Salesforce silently drops fields the user can't edit. Grant Read + Edit FLS on each field Mary writes. Salesforce requires **Company** on new Leads. Grant the allGood User profile **Read + Edit** FLS on **Company** (Lead), and make sure the record has a value for it. Common causes include incorrect credentials, IP restrictions, security token issues, and expired passwords. * Review this page for setup steps and common issues - Contact our support team for technical assistance # Credential Security Source: https://docs.allgoodhq.com/integrations/security ## Your Integration Credentials Are Protected When you connect allGood to your marketing tools like Marketo, HubSpot, or Salesforce, we understand you're trusting us with sensitive access credentials. Here's how we protect that trust and keep your data secure. ## What This Means for You Your API keys and integration credentials are the digital keys that let allGood access your marketing platforms on your behalf. Just like you wouldn't leave your office keys lying around, we treat these credentials with the highest level of security. **Bottom line:** Your credentials are encrypted, monitored, and accessible only to authorized personnel with your explicit permission. ## How We Protect Your Credentials #### Encryption We encrypt all your API keys using AWS KMS with AES-256 encryption, the same enterprise-grade security that banks use for financial transactions. #### Strict Access Controls Only specific allGood team members can access your credentials, and only when necessary for your support or troubleshooting. All access requires multi-factor authentication with multiple verification steps. #### Secure Communication When your credentials travel between systems, they're protected by TLS 1.2+ encryption. All data transmission is encrypted end-to-end, and we never send credentials in plain text emails or chat. Network traffic is continuously monitored for suspicious activity. ## What Happens to Your Credentials **When you first connect** your integrations, you provide your API keys through our secure setup process, after which we immediately encrypt and store them securely in our database. We then test the connection to ensure everything works properly before activating the credentials for use in your workflows. **During normal operations**, your credentials are briefly loaded into memory only when needed for your specific requests. *** [*For additional security questions or concerns, please contact our security team at security@allgoodhq.com.*](mailto:security@allgoodhq.com) # Slack Source: https://docs.allgoodhq.com/integrations/slack Connect your Slack workspace to allGood to receive notifications about your automations directly in Slack. ## Setting Up 1. Navigate to **Settings** → **Integrations** in your allGood dashboard 2. Click **Connect Slack** and follow the OAuth authentication process 3. Select the Slack workspace you want to connect Once connected, add the allGood Slack app to any channels where you want to receive notifications: 1. Open the Slack channel 2. Click the **channel name** at the top 3. Select **Integrations** → **Add an App** 4. Find and add the **allGood** app After that, allGood can send notifications to those channels. ## Worksheet Notifications Worksheets can be configured to send notifications to specific Slack channels. For example: * **List upload status**: Get a notification in Slack when a list upload completes, including how many items completed successfully, how many are waiting for human approval, and how many need review. * **Lead-routing alerts**: Get a notification in Slack when lead-routing encounters an error, or needs human input. # Workfront Source: https://docs.allgoodhq.com/integrations/workfront The Workfront integration connects allGood with Adobe Workfront's work management platform. This integration enables seamless project management, resource allocation, and team collaboration by synchronizing projects, tasks, and workflows between both systems. Enhance your enterprise work management capabilities by combining Workfront's powerful project management features with allGood's automation and integration capabilities. ## Prerequisites Before setting up the Workfront integration with Mary, ensure you have: * **Adobe Workfront account** with admin permissions to create OAuth applications * **IT department coordination** for creating OAuth2 applications * **allGood (Mary) account** with any Access Level with at least these permissions: * View Projects * View Tasks * View Documents * View Users (make sure that the fine-tune setting of **"View Contact Info"** is turned on) * **Inbox access** to the allGood (Mary) account to receive verification codes ### Configuring Access Levels Navigate to **Setup** > **Access Levels** in Workfront. Setup > Access Levels page in Workfront Select the access level (e.g., **Contributor**) and click the edit icon to configure permissions. Select and edit the Contributor access level Under **Users**, make sure that the fine-tune setting **"View Contact Info"** is enabled. Fine-tune settings showing View Contact Info checkbox Assign the allGood (Mary) account to this access level. Edit Person Access tab showing Contributor access level ## IT Coordination Guide ### Security & Account Setup Requirements * Create a dedicated OAuth2 single-page web application in your Workfront instance * Configure application with appropriate permissions for allGood integration * Collect required credentials: Client ID, Client Secret, and Organization Domain * Store credentials securely according to company policy * Have inbox access to the allGood (Mary) account to receive verification codes ## Step-by-Step Setup **IT teams should follow the Adobe Workfront documentation** to create the OAuth2 application: [Create OAuth2 Applications — Adobe Workfront](https://experienceleague.adobe.com/en/docs/workfront/using/administration-and-setup/configure-integrations/create-oauth-application) **Summary of steps:** 1. Navigate to **Setup** > **System** > **OAuth2 Applications** Workfront main page showing Setup navigation OAuth2 Applications page in Workfront Setup 2. Click **Create app integration** 3. Select **Web Application** 4. Enter application name (e.g., "allGood Integration") and click **Create** New OAuth2 application dialog with Web Application selected 5. Copy the **Client ID** and **Client Secret** — make sure to keep these in a safe location until the integration is complete 6. Enter the **Redirect URI**: `https://allgoodhq.app/oauth2/workfront/callback` OAuth2 application details showing Client ID, Client Secret, and Redirect URI 7. Add the [allGood logo](https://drive.usercontent.google.com/u/0/uc?id=1G0mve--VKuPgLLEY8bRt04vh09MG71RU\&export=download) to the application 8. Add link to privacy policy: `https://www.allgoodhq.com/privacy-policy` 9. Click **Save** OAuth2 additional information page with allGood logo and privacy policy **Important**: Save the following credentials from the created application: * **Client ID** * **Client Secret** * **Organization Domain** (e.g., your-company.my.workfront.com) 1. **Log into allGood** and navigate to **Settings** > **Integrations** 2. Click **Add Integration** and select **Workfront** 3. **Enter the credentials** from Step 1: * Client ID * Client Secret * Organization Domain allGood Workfront integration form showing Client ID, Client Secret, Organization Domain, and Link account button 1. After saving credentials, click **Link your Workfront Account** 2. Make sure to keep your Client ID and Client Secret — you'll need them again later 3. Sign in using your **Workfront Admin credentials** allGood needs access to event subscriptions and only System Admins can create such subscriptions. Once the subscriptions are created, the connection can be re-established with the Mary account (Step 5). 4. **Authorize** allGood to access your Workfront instance Workfront OAuth authorization dialog for allGood Integration 5. Verify the integration shows as **Active** on your integrations page in allGood allGood Integrations page showing Workfront as Active 1. Click **Edit** on the Workfront Integration 2. Click **Subscribe** in the Event Subscriptions section — this will automatically configure the subscriptions necessary for allGood to access your Workfront instance Update Integration page showing Event Subscriptions with Subscribe button 3. Verify that the two subscriptions were created Event Subscriptions showing UPDATE TASK and CREATE NOTE subscriptions 1. Re-enter your **Client ID** and **Client Secret** and click **Link your Workfront Account** allGood Workfront integration form 2. Sign in using your **allGood (Mary) account credentials** * This is what gives Mary access to work on specific tasks assigned to her You may need to enter a verification code when signing in with the allGood account. Please ensure you're able to access the inbox linked to that email. ## Verification & Testing If Workfront shows **"Active"** status in allGood integrations, Mary was able to connect successfully. ### Simple Test To confirm the integration is working properly in Workfront: 1. Create a task specifically named **"Confirming Mary Access"** Workfront subtasks view showing 'Confirming Mary Access' task 2. Assign **Mary** to the task Assigning Mary allGood user to the task 3. Look for a note left by Mary saying **"Access confirmed. Thank you!"** in the Updates page Task Updates page showing Mary's 'Access confirmed. Thank you!' comment ## Frequently Asked Questions Yes, you need administrator access to set up the OAuth2 application and create event subscriptions. Once subscriptions are configured, the connection is re-established with the Mary account. The integration uses OAuth 2.0 authentication. You'll need to generate API credentials via a dedicated OAuth2 application and configure them in allGood during setup. The Redirect URI must be set to `https://allgoodhq.app/oauth2/workfront/callback`. The first connection (Step 3) uses an Admin account to create the required event subscriptions. The second connection (Step 5) links Mary's account so she can work on tasks assigned to her. Yes, you can configure the integration to sync only specific projects, portfolios, or teams based on your requirements. The integration supports projects, tasks, users, teams, portfolios, and custom forms from your Workfront instance. Resource allocation, time tracking, and capacity planning data sync bidirectionally to maintain consistency across platforms. ## Troubleshooting Common causes include: * Insufficient user permissions * API access restrictions * Network connectivity issues * Object-level sharing restrictions Check your API credentials, verify user permissions, and ensure your Workfront instance allows API access from the allGood IP addresses. This is expected. Ensure you have inbox access to the email address linked to the allGood (Mary) account so you can retrieve the verification code. * Review this page for setup steps and common issues * Contact our support team for technical assistance # Authentication & Login Source: https://docs.allgoodhq.com/ops/auth-and-login allGood supports multiple authentication methods to fit your company's security requirements. **A note on MFA:** allGood does not offer email-and-password login, so there is no separate allGood credential to protect. Every sign-in goes through a social provider (Google or Microsoft) or your SSO/SAML identity provider, and allGood does not manage passwords or MFA for either path. Authentication is handled entirely by your identity provider, and allGood honors whatever policies you set there. If your IT team requires MFA in Google Workspace, Microsoft Entra ID, Okta, or another provider, users must satisfy it before they can reach allGood. ## Authentication Methods ### Social Sign-On **Google and Microsoft OAuth** — Team members can sign in using their existing Google or Microsoft work accounts without creating a separate allGood password. ### SAML/SSO (Enterprise Only) **Single Sign-On** — Available for Enterprise customers only. Works with identity providers like Okta, Microsoft Entra ID (formerly Azure AD), and other SAML-compatible systems. Users sign in through your company's central authentication system. For SAML login, users need to enter their email address on the login screen to be routed to your organization's SSO provider. **Important:** If your organization uses SAML/SSO, users will only get access when your IT team provisions them in your identity provider (like Okta or Microsoft Entra ID). *** ## SSO Setup ### Prerequisites * You, or someone from IT, who can configure SSO (SAML) and verify your domain (requires DNS changes). * You will have received from allGood an admin setup link for SSO.\ *Should look like* `https://setup.allgoodhq.app/init?XXXXXXXXXX` ### Instructions On opening the admin setup link there will be two flows to complete: (A) Domain Verification, and (B) SSO. #### A. Domain Verification After clicking the setup link, the organization's admin is prompted to enter the domain they wish to verify. If the domain is valid, we identify the DNS service provider and display custom setup instructions to follow. #### B. SSO After selecting **Configure Single Sign-On**, choose your organization's identity provider from the list. Once selected, complete the instructions as prompted and test SSO sign-in. ### Testing Once you have completed both flows, you should be able to sign in at [`allgoodhq.app`](https://allgoodhq.app/login) using your organization email address. You will be redirected to your organization's sign-in page. *** ## Frequently Asked Questions Depending on your identity provider, the SAML login could take up to 24 hours to become live due to data propagation delays. Please check with your identity provider for details. Yes. Since we only allow logins from the verified domain, ensure that both your IDP and domain are correctly configured. Due to standard DNS propagation, this can take up to 4 hours, though most DNS providers complete it within a few minutes. allGood does not have its own email-and-password login, so there's no separate allGood credential for us to add MFA to. Every user signs in through a social provider (Google or Microsoft) or through your SSO/SAML identity provider. If MFA is set up on that account — whether it's your Google Workspace, Microsoft Entra ID, Okta, or other identity provider — it's enforced there before the user ever reaches allGood. We don't need to build our own MFA because there's no non-SSO, non-social entry point to protect. # Network Connectivity Source: https://docs.allgoodhq.com/ops/network-connectivity Some organizations have internal network policies that restrict access to external services. If your team is using allGood on a managed or restricted network, certain app features may be degraded if the required domains are blocked. Affected features include: * **Realtime updates** — UI changes may not appear until the page is refreshed * **In-app notifications** — background task updates may not be delivered * **Authentication and login** — users may be unable to sign in or switch tenants Visit **allgoodhq.app/connectivity-check** to run a live check of all required services from your network. *** ## Domains to allow-list Ask your IT or network team to allow outbound access to the following domains. | Domain(s) | Service | Protocols | | ---------------------------------- | ------------------------------------- | ---------------- | | `allgoodhq.com`, `*.allgoodhq.com` | allGood marketing website | HTTPS | | `allgoodhq.app`, `*.allgoodhq.app` | allGood product and API | HTTPS | | `*.prod.a.momentohq.com` | Realtime data provider | HTTP, SSE | | `*.courier.com` | In-app notifications provider | HTTP, WebSockets | | `*.workos.com` | App login and authentication provider | HTTPS | | `*.sentry.io`, `*.amplitude.com` | Telemetry and user analytics | HTTPS | # Snowflake Source: https://docs.allgoodhq.com/ops/snowflake The allGood Marketing Kernel is built on Snowflake. Every MK instance is backed by its own isolated Snowflake database, which is where your entities, records, activities and the full history of changes Mary makes all live. Because both sides speak Snowflake natively, moving data between allGood and your own warehouse doesn't need a pipeline. Snowflake's Secure Data Sharing connects the two accounts directly: * **No export.** Neither side ships files or stands up a pipe. Snowflake connects the two accounts and each reads the other's data where it already sits. * **No pipeline to maintain.** There's no sync to schedule, no job to monitor, and nothing to backfill when a schema changes. * **No storage cost on your side.** Shared data doesn't count against your Snowflake storage. You pay only for the compute you spend querying it. Reading a share is always live. Sharing data *into* allGood adds a second step — binding a table to a record type, so the platform can act on it — and that step does keep a copy on allGood's side. [Inbound Sharing](/ops/snowflake/inbound-sharing) covers it. Snowflake shares data directly only between accounts in the same cloud region. If your Snowflake account is NOT in AWS `us-west-2`, get in touch — that setup needs replication configured first. ## Sharing in both directions Share allGood data with your warehouse. Query your marketing data — entities, records, activities and every change Mary made — from your own Snowflake account, alongside the rest of your data. Give allGood access to data from your warehouse, so Mary can act on the product usage, account health and segmentation you already have. # Give allGood access to data from your warehouse Source: https://docs.allgoodhq.com/ops/snowflake/inbound-sharing Your warehouse already holds things Mary would benefit from knowing: product usage, support history, account health, revenue, the segmentation your team has already built. Inbound sharing lets allGood read that data directly, in place — the same Secure Data Sharing mechanism as [outbound](/ops/snowflake/outbound-sharing), pointed the other way. You publish a share containing whatever you choose, and allGood mounts it read-only. Reading the share is live — allGood queries your tables where they sit, and revoking the share ends that access immediately. Data you then bind into the Marketing Kernel works differently: allGood keeps its own copy of those rows as records, so the rest of the platform can act on them. That copy is allGood's, and it outlives the share — see [Disconnecting](#disconnecting). Setting it up is two halves: you run a short script in your own Snowflake account to publish a share, then you tell allGood which account it came from. ## Before you start * You need the **Admin** role in allGood to reach the Snowflake Data Sharing settings. * You need **ACCOUNTADMIN** (or another role that can create shares) in the Snowflake account holding the data. * Your Snowflake account must be in the same cloud region as your allGood account. The settings page names allGood's region at the top; if yours differs, contact allGood support before you begin. In allGood, go to **Settings → Snowflake Data Sharing** and find the **Bring Your Data into allGood** card. Click **Copy** to take the script, which creates a share, grants your data to it, and adds allGood's account as the consumer. By default it shares everything in one database. To change the database name — or the name of the share itself — click **⚙ Options**, or click the underlined values in the script. The share name is yours to choose. allGood identifies an incoming share by the **account** that published it, not by what it's called, so name it whatever fits your conventions. Paste the script into an SQL console and execute it as `ACCOUNTADMIN`. The `grant` block in the middle is the part to adjust if you don't want to share a whole database: ```sql theme={null} -- Adjust these grants to control what allGood can read through the share. grant usage on all schemas in database MY_DATABASE to share MY_SHARE; grant select on all tables in database MY_DATABASE to share MY_SHARE; grant select on all views in database MY_DATABASE to share MY_SHARE; ``` Narrow it to a single schema, name individual tables, or grant secure views you've built for the purpose — allGood reads exactly what this block gives it and nothing else. The last statement returns your account ID, which the next step needs: ```sql theme={null} select current_organization_name()||'.'||current_account_name(); ``` Back in allGood, click **I've Run This**. Paste the account ID into the field that appears and click **Connect Share**. allGood finds the share your account published, mounts it, and lists the tables it can now see. Use the account ID from the query above, not your account *locator* (the eight-character code like `AB12345` in some Snowflake URLs). The two look alike, and a locator won't match. If the share hasn't arrived yet — Snowflake can take a moment — allGood keeps checking every ten seconds and connects it as soon as it appears. You can leave the page open. The card now lists every table and view in the share, by schema. If a table you expected is missing, add it to the `grant` block and re-run that part of the script; it'll show up on the next page load without reconnecting. If the list is empty, the share was created but nothing was granted to it — check that the `grant` statements ran against the right database. ## Using the data Connecting a share makes it readable. To act on it, allGood binds a table to a record type in the Marketing Kernel, which keeps a set of records in step with your rows: new rows become records, changed rows update them, and deleted rows are marked as gone. Those records are a **copy**, held in allGood's own storage — that's what lets identity resolution, segments, policies and campaigns work against your data at the speed they need to. allGood re-reads the share on a schedule to keep the copy current, so it trails your warehouse by however often that runs. **Contact allGood support to bind synchronized data to a record set in MK.** We'll need to know which table, which column uniquely identifies a row, and which column changes when a row is updated. Once a table is bound, its record type gets a **Sync** page under **Setup → Record Types**, showing what it reads, how often, and how many records have changed each day — plus a **Sync Now** button. ## What allGood can read Only what your `grant` statements name. A few properties are worth knowing: Snowflake enforces this, not allGood. A database created from a share cannot be written to at all — no inserts, no updates, no new objects. Grant them to the existing share and they appear. The setup script's `grant … on all tables in database` covers tables that exist at the time it runs; add `grant select on future tables in database … to share …` if you want new tables picked up automatically. An allGood workspace connects exactly one inbound share. To bring in data from several databases, grant them all to the same share rather than creating a second one. If your account has published more than one share to allGood, connecting will tell you so rather than guessing. A single Snowflake account can only be connected to one allGood workspace at a time, because the account is how allGood tells shares apart. If you need to feed two workspaces, get in touch. ## Disconnecting Click **Disconnect** on the card and confirm. allGood immediately stops reading the share, and anything syncing from it stops. Nothing is deleted on your side — the tables stay in your account untouched — and records already synced into allGood stay too, frozen as they were. You can reconnect the same share later. To cut access from your own side instead, drop the share in Snowflake: ```sql theme={null} drop share MY_SHARE; ``` The other direction. Query allGood's entities, records and activity from your own warehouse. Load tabular data into allGood without Snowflake sharing. # Share allGood data with your warehouse Source: https://docs.allgoodhq.com/ops/snowflake/outbound-sharing The Snowflake Data Sharing settings page, showing one account already receiving data and the SQL to accept the share Outbound sharing gives your Snowflake account a read-only, live view of your allGood data. Once it's set up, your analysts query allGood's entities, records and activity history from your own warehouse, joined against whatever else you have there. Setting it up is two halves: you tell allGood which Snowflake account to share with, then you run a short script in that account to mount the share as a database. ## Before you start * You need the **Admin** role in allGood to reach the Snowflake Data Sharing settings. * You need **ACCOUNTADMIN** (or another role that can create databases and grant database roles) in the Snowflake account receiving the data. * Your Snowflake account must be in the same cloud region as your allGood account. If it isn't, contact allGood before you begin. In allGood, go to **Settings → Snowflake Data Sharing**. If you haven't shared with anyone yet, the page shows a single field asking for an account ID. Otherwise it lists the accounts already receiving data. allGood identifies your warehouse by its account ID — your organization name and account name joined by a dot, like `ACMEORG.ANALYTICS_PROD`. Run this in the Snowflake account you want the data in: ```sql theme={null} select current_organization_name()||'.'||current_account_name(); ``` Copy the single value it returns. This is **not** the same as your account *locator* (the eight-character code like `AB12345` that appears in some Snowflake URLs). The two look alike, and a locator will not work — it fails as though the share doesn't exist. Always use the query above. Paste the account ID into **Share data with another account** and click **Share Data**. The account appears in the table at the top of the page, split into its **Org ID** and **Account Name**. To share with more than one Snowflake account — a production warehouse and a sandbox, say — repeat this step for each one. Under **Accept shared data**, click **Copy**. Paste the script into an SQL console and execute it as `ACCOUNTADMIN` (or another sufficiently-privileged role) to accept the data share. The script names a database (`ALLGOOD_SHARED_DATA` by default) and a role (`ACCOUNTADMIN`) to grant access to. To change either, click **⚙ Options** — or click the underlined values in the script itself. The database exists only in your account, so you can call it whatever fits your naming conventions. The script grants access to whichever single role you chose. To let your analysts query the data, grant the shared database role onward to their roles: ```sql theme={null} grant database role ALLGOOD_SHARED_DATA.SHARED_ACCESS_ROLE to role YOUR_ANALYST_ROLE_HERE; ``` Query one of the shared views: ```sql theme={null} select count(*) from ALLGOOD_SHARED_DATA.MK_SHARE.ENTITY; ``` If you get a row count, you're done. If the database looks empty, check that you ran the third statement in step 5 and that you're querying as a role that holds `SHARED_ACCESS_ROLE`. ## Revoking access To stop sharing with an account, click **Revoke Share** on its row in the table and confirm. Revocation is immediate. Queries running against the shared database in that account stop returning rows, and the database has to be recreated with the script above if you later share with the same account again. Other accounts are unaffected. ## Data Schema Shared data lives in the `MK_SHARE` schema and is organized around four views. allGood's data model separates *who someone is* from *what you know about them* and *what they did*. **Entities** are resolved people and companies. **Records** are typed sets of fields attached to an entity — one record per source or per kind of fact. **Activities** are behavioural events. And every field change ever applied is kept as an auditable **data change**, along with the explanation of why it was made. ### `MK_SHARE.ENTITY` One row per resolved entity. | Column | Type | Description | | --------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | `id` | `UUID` | Stable entity identifier. | | `entity_type` | `VARCHAR` | Which kind of entity this is, from the entity types configured for your account. | | `created_at` | `TIMESTAMP_NTZ` | When the entity first appeared. | | `updated_at` | `TIMESTAMP_NTZ` | When the entity was last touched. | | `superseded_by` | `UUID` | `NULL` for a live entity. When identity resolution merges two entities, the merged-away one remains queryable and points at the survivor. | ### `MK_SHARE.RECORD` One row per record, holding its current field values. | Column | Type | Description | | ----------------------- | --------------- | --------------------------------------------------------------------------------------------------------------- | | `id` | `UUID` | Stable record identifier. | | `type` | `VARCHAR` | Which kind of record this is, from the record types configured for your account. | | `entity_id` | `UUID` | The entity this record currently belongs to. Join to `ENTITY.id`. | | `data` | `VARIANT` | The record's current field values, as a flat JSON object. | | `created_at` | `TIMESTAMP_NTZ` | When the record first appeared. | | `updated_at` | `TIMESTAMP_NTZ` | When the record was last changed. | | `first_reloc_entity_id` | `UUID` | The first entity this record was attached to. Differs from `entity_id` when identity resolution later moved it. | ### `MK_SHARE.ACTIVITY` One row per behavioural event. | Column | Type | Description | | ------------- | --------------- | ---------------------------------------------------------------------------- | | `id` | `UUID` | Stable activity identifier. | | `type` | `VARCHAR` | The kind of activity — an email open, a page view, a form submit, and so on. | | `occurred_at` | `TIMESTAMP_NTZ` | When the activity happened, as reported by its source. | | `data` | `VARIANT` | Payload for that activity type. | | `created_at` | `TIMESTAMP_NTZ` | When allGood received the activity. | Activities are deliberately not attached to an entity. They arrive at high volume and are matched to entities downstream, so to attribute activity to a person, join through the records that allGood derives from them rather than expecting an `entity_id` here. ### `MK_SHARE.DATA_CHANGE` An append-only log of every field change ever applied to a record — the audit trail behind everything in `RECORD`. | Column | Type | Description | | ------------- | --------------- | -------------------------------------------------------------------------------------------------------- | | `record_id` | `UUID` | The record that changed. Join to `RECORD.id`. | | `data_change` | `VARIANT` | What changed, as a flat JSON object of field to new value. | | `message` | `VARCHAR` | Why the change was made, in plain language, written by the agent or service that made it. May be `NULL`. | | `applied_at` | `TIMESTAMP_NTZ` | When the change was applied. | Changes that only re-attached a record to a different entity carry no field change, and are left out of this view. ### Working with the data Fields inside a `VARIANT` are read with Snowflake's path syntax, and should be cast to the type you expect: ```sql theme={null} select e.id as entity_id, r.data:email::varchar as email, r.data:company_name::varchar as company from ALLGOOD_SHARED_DATA.MK_SHARE.ENTITY e join ALLGOOD_SHARED_DATA.MK_SHARE.RECORD r on r.entity_id = e.id where true and e.superseded_by is null and r.type = 'person'; ``` To read the reasoning behind recent changes to a record: ```sql theme={null} select record_id, applied_at, data_change, message from ALLGOOD_SHARED_DATA.MK_SHARE.DATA_CHANGE order by applied_at desc limit 100; ``` A few things worth knowing: Identity resolution merges entities as it learns more, and the merged-away entity stays in `ENTITY` so that old IDs keep resolving. Add `where superseded_by is null` for a list of live entities only, or follow `superseded_by` to find where an old ID ended up. Sharing requires secure views, which is what keeps the underlying data inaccessible. Snowflake restricts some query optimizations against them, so expect them to be slower than an equivalent local table. If you're running heavy or repeated analysis, materialize what you need into a table in your own account first. `ACTIVITY` and `DATA_CHANGE` are append-only and current as of the moment you query. `ENTITY` and `RECORD` are rollups that allGood refreshes as it processes data, so they can trail the change log slightly. allGood's tables carry internal sequence numbers used for ordering and change tracking. They're meaningless outside the platform and are excluded from these views. # Configuring SSO and verifying your domain Source: https://docs.allgoodhq.com/ops/sso Configure allGood to use your enterprise IdP, and verify ownership of your domain. ## Prerequisites * You'll need an IT administrator who can configure a SAML SSO connection to your identity provider, and/or modify DNS records to verify ownership of your domain. * You'll need to reach out to your allGood support team for an admin setup link for SSO. \ It should begin with: `https://setup.allgoodhq.app/init?` Image ## Domain Verification If your org uses multiple domains, enter the domain name that can be found after the `@` in your email address. Image The admin portal will identfy your DNS provider based on the domain you supply, and will give you detailed instructions on how to add a DNS record verifying your ownership of that domain in allGood. ## SSO Setup If you don't see your particular IdP in the list of options, you can continue with "Custom SAML" or "Custom OIDC" at the bottom of the screen. Image The admin portal will give you specific, step-by-step instructions on how to configure SSO to allGood from your IdP. ## Testing SSO Once you have completed the domain verification and set up SSO, you'll be able to sign in to `allgoodhq.app` with an email address from your organization. Clean Shot 2026 03 04 At 17 29 00@2x This will redirect you to your organization's sign-in page. ## Frequently Asked Questions Depending on your identity provider, there might be a delay in propagating the relevant data and the SAML login could take up to 24 hours to become live. Please check with your Identity Provider for details. Yes, since we only allow logins from the domain you have verified, please make sure that your IDP and Domain are both correctly configured. If you're experiencing issues verifying your domain, reach out to allGood support—we can verify it manually if the DNS approach won't work in your environment. Due to standard DNS propagation, this process can also take up to 4 hours, however, with most DNS providers, this should likely only be a few minutes. Image # Users & Roles Source: https://docs.allgoodhq.com/ops/users-and-roles ## Adding Team Members The process for adding new users depends on your authentication method. ### Social Sign-On (Google/Microsoft OAuth) **Sending an invite**\ To add someone to your allGood instance, enter their email address and click **Invite User**. They'll receive an email invitation to join your organization. Once invited, the user will appear as **Pending** in the users table until they accept the invitation and complete their first login. ### SAML/SSO Organizations For organizations using SAML/SSO, you cannot directly invite users through allGood. Instead, your IT department needs to provision the user in your identity provider (Okta, Microsoft Entra ID, etc.) and grant them access to the allGood application. **Access flow:** 1. IT provisions the user in your SSO system 2. IT grants the user access to the allGood application 3. User logs in through your company's SSO portal 4. User automatically appears in your allGood team list *** ## User Roles The platform includes four roles, each building on the previous with additional capabilities: ### Basic User **Best for:** New team members, contractors, or users who need limited access * View existing worksheets and use pre-built templates * Cannot create new content or access advanced features ### Basic Campaign User **Best for:** New team members who need limited access to just running campaigns * View existing campaign and use pre-built campaign templates * Cannot use worksheets, or access advanced features ### Standard User **Best for:** Regular team members who actively work with data * All Basic User capabilities, plus: * Create and edit worksheets * View lab features (skills, teams, tools) * Set up and manage integrations ### Power User **Best for:** Advanced users, team leads, or technical specialists * All Standard User capabilities, plus: * Create and manage custom tools * Create and edit teams * Full access to lab management features ### Admin **Best for:** IT administrators, system owners, or designated administrators * Full access to all platform features * Manage system settings and user accounts * Configure Single Sign-On (SSO) * Access event logs and audit trails * Invite and remove users *** ## Permissions Matrix | Feature | Basic | Basic Campaign | Standard | Power User | Admin | | ------------------------------------ | ----- | -------------- | -------- | ---------- | ----- | | **Worksheets** | | | | | | | View existing worksheets | ✅ | ❌ | ✅ | ✅ | ✅ | | Use worksheet templates | ✅ | ❌ | ✅ | ✅ | ✅ | | Create and edit worksheets | ❌ | ❌ | ✅ | ✅ | ✅ | | **Lab Features** | | | | | | | View skills in the lab | ❌ | ❌ | ✅ | ✅ | ✅ | | Create and edit skills | ❌ | ❌ | ❌ | ✅ | ✅ | | View existing teams | ❌ | ❌ | ✅ | ✅ | ✅ | | Create and edit teams | ❌ | ❌ | ❌ | ✅ | ✅ | | View tool configurations | ❌ | ❌ | ✅ | ✅ | ✅ | | Create and edit custom tools | ❌ | ❌ | ❌ | ✅ | ✅ | | **System Features** | | | | | | | Set up and manage integrations | ❌ | ❌ | ✅ | ✅ | ✅ | | Manage system settings and view logs | ❌ | ❌ | ❌ | ❌ | ✅ | | Manage users (invite, remove, etc.) | ❌ | ❌ | ❌ | ❌ | ✅ | | **Campaigns** | | | | | | | View campaigns | ❌ | ✅ | ✅ | ✅ | ✅ | | Use campaigns | ❌ | ✅ | ✅ | ✅ | ✅ | | Create and manage campaigns | ❌ | ✅ | ❌ | ✅ | ✅ | *** ## Managing Roles To change a user's role: 1. Navigate to **Settings > Team** in allGood 2. Locate the user 3. Click their current role to open the role selector 4. Choose the appropriate role and save **Best practices:** * Start conservative — assign the minimum role needed * Review roles periodically as responsibilities change * Limit Admin access to essential personnel only ## Custom Roles and Access Control Beyond the standard roles, allGood supports custom roles and granular access control to match your organization's specific needs. ### Custom Roles Custom roles allow you to create tailored permission sets for different subteams within your organization. This is useful when: * Different departments need access to different features * You want to enforce specific guardrails for certain user groups * Teams require exposure to only relevant templates and use cases Custom roles are configured by the allGood team. Contact [support@allgoodhq.com](mailto:support@allgoodhq.com) to set up custom roles for your organization. ### Worksheet Access Control You can control who has access to view, use, or manage specific worksheets: ACL Demonstation 1. Open the worksheet you want to configure 2. Navigate to the worksheet's **Settings** 3. Update which roles have access to: * **View** — See the worksheet and its contents * **Use** — Run the worksheet with their own data * **Manage** — Edit the worksheet configuration ### Template Access Control Templates have two layers of access control: **Template visibility**\ In the template worksheet's settings, you can control which roles can see and use the template. **Instance visibility**\ You can also control who has access to worksheets created from the template. For example, you can configure a template so that instances are only visible to the user who created them — ensuring each user only sees their own work. Admins always have full access to all worksheets and templates, regardless of access control settings. Custom roles are built by combining the following permissions: | Permission | Description | | ----------------------------- | ------------------------------------- | | **Worksheets** | | | `worksheets:view` | View existing worksheets | | `worksheets:templates:use` | Use worksheet templates | | `worksheets:manage` | Create, edit, and delete worksheets | | **Campaigns** | | | `campaign:view` | View campaigns | | `campaign:use` | Run campaigns | | `campaigns:manage` | Create, edit, and delete campaigns | | **Lab — Skills** | | | `lab:skills:view` | View skills in the lab | | `lab:skills:manage` | Create, edit, and delete skills | | **Lab — Teams** | | | `lab:teams:view` | View existing teams | | `lab:teams:manage` | Create, edit, and delete teams | | **Lab — Tools** | | | `lab:tools:view` | View tool configurations | | `lab:tools:manage` | Create, edit, and delete custom tools | | **Lab — Schemas** | | | `lab:schemas:view` | View schemas | | `lab:schemas:manage` | Create, edit, and delete schemas | | **Integrations** | | | `integrations:manage` | Set up and manage integrations | | `widgets:integrations:manage` | Manage widget integrations | | **System** | | | `users:manage` | Invite, remove, and manage users | | `system:manage` | Access system settings and logs | *** ## Need Help? Contact your system administrator or reach out to [support@allgoodhq.com](mailto:support@allgoodhq.com). *** ## Troubleshooting * **Social Sign-On**: Ensure they're using the correct Google/Microsoft account associated with your organization * **SAML/SSO**: Verify with IT that the user is properly provisioned in your identity provider # Overview Source: https://docs.allgoodhq.com/overview ## Build, review, and deploy chat-driven multi-channel campaigns without leaving allGood. Demand Generation as a Service is a four-stage campaign workspace where Mary, your AI marketing agent, takes you from a rough idea to live Marketo emails, LinkedIn ads, and blog posts. You provide the direction; Mary handles the planning, copywriting, design, and asset creation. Each campaign moves through four stages in sequence: **Plan → Write → Design → Deploy**. You can work through them in a single session or pick up where you left off; every stage saves its output as an artifact the next stage reads from. You don't need a polished brief to get started. Mary is designed to ask the right questions and fill in sensible defaults from your ICP and brand guidelines. Starting rough is fine. ## Campaign list The landing page shows every campaign in your workspace with its current status. Clean Shot 2026 06 15 At 20 05 46@2x Click any row to open the campaign workspace and pick up where you left off. ## Creating a campaign Click **+ New campaign** from the campaign list to open the creation modal. Clean Shot 2026 06 15 At 20 06 17@2x Give the campaign a descriptive name — something that identifies the audience, angle, or launch. You can change it later. Select a starting shape for the campaign. **Start scratch** opens a blank Plan workspace and lets Mary shape the campaign from your brainstorm. Once you select a template, a **What we'll do next** callout appears summarizing exactly what will happen when you open the workspace. Click **Open Plan →** to enter the campaign workspace. The campaign is created in Draft status and you land on the Plan stage. *** ## Stage 1: Plan The Plan stage is where you brief Mary on the campaign — audience, angle, channels, timing, and brand context. The output is a **Campaign Brief** artifact that every downstream stage reads from. Clean Shot 2026 06 15 At 20 08 42@2x Copy ### Shared context Before starting the chat, wire up the references and channels Mary will use across all stages of the campaign. Clean Shot 2026 06 15 At 20 08 42@2x 2 Copy **References** give Mary the brand, audience, and asset context she needs to produce on-brand output: **Channels** determine which assets Mary produces. Toggle on the channels you want included in this campaign: * **Email · Marketo** — multi-touch email sequence built directly in Marketo * **LinkedIn ads** — ad copy matched to the campaign angle * **Blog post** — long-form content that reinforces the campaign message You can add or remove channels during the Plan stage. Once you move to Write, the channel selection from your Campaign Brief drives what Mary produces — changes at that point require updating the brief. ### Starting the plan Once your references and channels are set, choose how to kick off the planning conversation: Clean Shot 2026 06 15 At 20 11 02@2x Select one of Mary's suggested starting points — **Brainstorm a campaign idea**, **Plan a new product launch campaign**, **Plan a nurture email sequence**, or **Plan a re-engagement campaign** — or describe the campaign in your own words in the free-text field. Either way, Mary reads your references, asks clarifying questions, and works with you to lock in the plan. ### The Campaign Brief When the plan is finalized, Mary produces a **Campaign Brief** markdown artifact. The brief captures audience, angle, channels, timing, copy direction, constraints, and any open questions — everything Write and Design need to do their work without re-asking you. Review the open questions section of the brief before moving on. Mary flags decisions she made with defaults — churn data availability, blog topic, re-engagement offer — so you can confirm or correct them before copy is written. *** ## Stage 2: Write The Write stage is where Mary takes your Campaign Brief and produces the actual copy — emails, LinkedIn ads, and blog posts — ready for design and deployment. ### What Mary needs The Write stage pulls in two inputs: | Input | Source | | ------------------- | ------------------------------------------------------------------------------------------------------------------------- | | **Campaign Brief** | Auto-populated from your Plan stage output. | | **Content & Links** | Optional. Blog posts, case studies, product pages, or resource URLs you want woven into the copy as proof points or CTAs. | ### Writing the copy Use the **Continue with** suggestions to kick off the writing session — **Write copy for all channels**, **Write a 3-email nurture sequence**, **Write a LinkedIn launch post**, or **Repurpose copy across channels** — or describe what you want in your own message. Clean Shot 2026 06 16 At 01 50 12@2x You can tell Mary things like your audience and goal (e.g., "existing customers, expand") and the cadence you want (e.g., "5 emails, every 2–3 weeks"). Mary will sequence the campaign accordingly. ### Reviewing copy output Once Mary finishes writing, all completed pieces appear organized by channel — **Email · Marketo**, **LinkedIn ads**, **Blog post** — with a count per channel. Each piece shows its day, title, artifact slug, and a version indicator. Clean Shot 2026 06 16 At 01 55 11@2x Expand any piece to read the full copy inline. You can also switch between the **preview** (eye icon) and **raw markdown** (code icon) views, access previous versions via the version dropdown, or download the copy. Edit any piece directly in the interface before moving on. Once you're satisfied, click **Continue to Design →** in the banner at the top of the stage. *** ## Stage 3: Design The Design stage turns your approved copy into channel-ready assets. For email, Mary selects modules from your Marketo template that fit the copy, then builds the emails directly in Marketo. Clean Shot 2026 06 16 At 02 07 08@2x ### Building assets Use the **Continue with** suggestions to start: **Build everything from my copy**, **Build just a few emails**, **Turn my LinkedIn copy into a post**, or **Turn my blog copy into an article**. Mary will produce variants for each asset — typically 1–5 per piece depending on the variant count you set. Review each variant and pick the ones you want to carry forward to Deploy. *** ## Stage 4: Deploy The Deploy stage is where you choose which variants and assets to use and send the campaign live. Select the email variants you want, confirm the LinkedIn and blog assets, and deploy. *** # Creating a Campaign in allGood for Marketo Users Source: https://docs.allgoodhq.com/use-cases/campaigns/create-in-allgood Complete walkthrough of building and managing campaigns in allGood ## Overview The Campaign Builder is where you turn your campaign briefs into live marketing programs. This guide walks through the complete workflow from campaign setup to launch, designed for marketing ops teams who need full visibility and control over their campaigns. The Campaign Builder follows a clear workflow that keeps strategy separate from execution. You provide the campaign brief, select a campaign template that matches your program type, and Mary handles the heavy lifting—creating assets, checking everything is set up correctly, and managing all the connections across your marketing tools. ## Step 1: Select Campaign Template Step 1 Start A New Campaign From the **Campaigns** tab, you'll see your available campaign templates. Each template is a pre-configured campaign type that defines: * **What gets created:** Emails, landing pages, Marketo programs, Salesforce campaigns, etc. * **What's required:** Program IDs, folder paths, UTM parameters, campaign member statuses * **Automation steps:** How Mary builds, deploys, and monitors your campaign * **Content requirements:** Which content fields are required and which are optional Choose templates based on what you need to create, not just the channel. For example, a webinar template might include Marketo emails, Goldcast integration, landing pages, and Salesforce campaigns—all managed together as one program. Templates are versioned, so when you create a campaign, it locks to that specific template version. This means your campaign won't break if the template gets updated later. ## Step 2: Upload Campaign Brief Step 2 Drag And Drop Brief Doc Or Upload Google Doc Link ### How to Upload * **From your computer:** Drag and drop `.docx` files or Word documents * **From Google Docs:** Paste a Google Docs link (make sure sharing is set so Mary can access it) ### What Happens When You Upload Mary reads through your brief and extracts the key information: * **Document structure:** Your H1 and H2 headings become the navigation for your campaign * **Content extraction:** Mary identifies which content maps to which asset * **Campaign details:** Dates, owners, program IDs, compliance requirements * **Content formatting:** Converts your brief into a format that works efficiently with AI If you would like to make any larger changes to your content, feel free to make changes to your doc and then resubmit it. ## Step 3: Start Campaign Step 3 Run The Campaign Once The Upload Is Complete! Give your campaign a name and click **Start Campaign**. This creates: * **Campaign record** with Draft status * **Asset placeholders** for each deliverable (emails, landing pages, etc.)—all starting in Draft * **Content library** organized by asset * **Activity log** for tracking all changes ## Step 4: Campaign Overview & Asset Status Step 4 Wait On The Campaign Overview Page As Mary Begins Building Out The Campaign The Campaign Overview page shows all the assets in your campaign. For each one, you'll see: * **Status:** Draft → In Review → Ready → Live → Done (or Error if something goes wrong) * **Asset type:** Marketo program, email, landing page, Salesforce campaign, etc. * **Last update:** Most recent activity from the log ### Understanding Asset Status | Status | Description | | ------------- | ----------------------------------------------------------------- | | **Draft** | Asset is created, content extracted, waiting for Mary to validate | | **In Review** | Mary has validated everything and it's ready for you to approve | | **Ready** | You've approved it and it's queued for deployment | | **Live** | Deployed to Marketo with confirmed IDs and URLs | | **Done** | Mary has verified everything is still live and working correctly | | **Error** | Validation failed or deployment hit an issue | **What's Mary doing?** For each asset, Mary runs quality checks that: * Validate all required content is present * Check image URLs are secure (HTTPS only) * Verify CTA links follow your standards (HTTPS, approved domains, UTM parameters) * Build draft versions with all content in place * Log everything for your records ## Step 5: Editing & Mary's Task Management Clean Shot 2026 02 16 At 14 04 49@2x Click any asset from Campaign Overview to open the editor. This is where you can make changes through natural conversation with Mary. ### Mary's Task List Every asset has its own task list. Mary tracks everything that needs to be done: * **In Progress:** Tasks Mary is actively working on * **Completed:** Finished changes with timestamps * **Needs Attention:** Items blocked by missing information or validation errors If Mary can't complete something (missing URL, unclear request, validation failure), she'll flag it in "Needs Attention" and explain exactly what's blocking her. ### Making Multiple Changes at Once Image6 Image5 You can request several changes in one message. For example: > *"@Mary unbold 'more than build emails?', Change the bullet points to a numbered list, and change 'MARY IS NOW A FULL CAMPAIGN MANAGER' to title case"* Mary breaks this into separate tasks. Each one gets: * Its own line item in the task list * Clear assignment to the right content field * Individual completion tracking * Independent execution (if one is blocked, the others still get done) No more losing track of requests in Slack threads—everything is captured, queued, and visible to your whole team. ### Live Email Preview Image7 The preview shows exactly how your Marketo email will look, including: * **Real-time updates:** As Mary completes tasks, the preview refreshes automatically * **Side-by-side view:** Task list stays visible so you can track progress * **Actual content:** All Marketo tokens show their real values * **Proper layout:** Images, CTAs, and text blocks display in the correct structure You're looking at the actual email, not guessing how tokens will render. What you see is what will go live in Marketo. ### Content Field Highlighter Image1 Click any section of the preview to see which tokens control it. The highlighter shows: * **Token name** (e.g., Banner, Banner URL) * **Current value** (the actual content or URL) * **Where it comes from** (campaign-wide default or asset-specific override) **Benefits for marketing ops:** * **Precise edits:** Know exactly which field controls which content * **Inheritance visibility:** See if content is inherited from the campaign or specific to this asset * **Quick troubleshooting:** If an image won't load or a link is broken, you immediately know which field to fix **For your stakeholders:** Instead of describing "the hero image" or "the CTA," they can click the section and reference the exact field name. No more ambiguity in feedback. No need to understand tokens. ## Step 6: Approve and Launch Once all edits are complete and validation passes: 1. **Review:** Asset moves to In Review after passing all checks 2. **Approve:** Click approve (or let Mary auto-approve if that's configured in your template) 3. **Deploy:** Mary launches the asset, which means she: * Creates or updates assets in Marketo * Gets back confirmed IDs and URLs * Logs all outcomes in your activity log 4. **Live:** Asset shows as Live with direct links to edit or preview in your marketing tools ### What Gets Created Depending on your template, Mary can create: * **In Marketo:** Programs, emails (with all tokens populated), landing pages, smart campaigns * **Other integrations:** Goldcast events, Zoom webinars All IDs and URLs are saved in your campaign record and visible in Campaign Overview. ## Step 7: Monitoring and Maintenance After launch, Mary periodically checks that: * Assets are still live (URLs work, programs exist) * Nothing has been manually changed in Marketo that conflicts with your campaign * Performance data is collected (if configured in your template) Mary won't re-check if nothing has changed. You can always force a manual check if needed. ## Common Workflows ### Adding Assets Mid-Campaign Need to add a regional variant or follow-up email after your campaign is already set up? * Mary can create new assets from your existing campaign * Content automatically inherits from the parent campaign by default * Regional overrides (e.g., APAC-specific hero copy) only affect the new asset * Only the new asset goes through build and deploy—existing assets aren't touched ### Fixing Validation Errors If an asset gets stuck in Error status: 1. Check the activity log for the specific error message 2. Common issues: missing Marketo program ID, non-HTTPS image URL, or unapproved CTA domain 3. Update the content through the chat interface 4. Mary automatically re-runs validation once you fix the issue ## Best Practices Use H1 and H2 headings to organize your brief. Mary uses these to understand your campaign structure, so "Email 1 Content" as an H1 makes it crystal clear what goes where. Make sure all required content is in your brief (program IDs, event dates, etc.). It's much faster to add these in the document than to go back and forth in chat later. Instead of "change the hero image," say "change the email 1 hero\_banner to \[URL]" (could be multiple hero images in the campaign). Mary can figure out ambiguous requests, but being specific saves time. The activity log is your complete audit trail. If something fails, the log shows exactly what went wrong and which content field caused the issue. Put shared content at the campaign level (brand colors, legal disclaimers, UTM parameters). Regional or asset-specific versions can override these as needed. ## Troubleshooting Check the activity log for validation errors. Common causes: missing program ID, non-HTTPS image, or required content field not filled in your brief. Use the content highlighter to verify the field exists. If it's not there, it wasn't extracted from your brief. You can add it manually through chat. The program ID points to a Marketo program that doesn't exist or you don't have permission to access. Verify the ID in Marketo and update your campaign. Mary handles this automatically. All requests are queued and processed in order. The task list shows who requested what and when. Mary doesn't automatically detect changes made directly in Marketo. Use "Force Re-check" to sync your campaign state with what's actually live. # Creating a Campaign in allGood for Users Without Marketo Experience Source: https://docs.allgoodhq.com/use-cases/campaigns/create-in-allgood-basic ## Overview allGood's Campaign Builder is where you go to turn your campaign content into a real, live marketing program—emails, landing pages, and everything in between. You don't need to know how any of the technical tools work behind the scenes. You write your content, upload it, and Mary takes care of building everything for you. This guide walks you through exactly what to do at each step. *** ## Step 1: Choose a Campaign Type Step 1 Start A New Campaign When you open the **Campaigns** tab, you'll see a list of campaign types to choose from—things like "Webinar," "Product Launch," or "Nurture Email Series." Each one is a pre-built starting point that tells Mary what to create for you. Pick the one that matches what you're trying to do. Not sure which to pick? Think about your end goal. Running an event? Choose a webinar type. Sending a series of follow-up emails? Choose a nurture type. Your marketing ops team can help if you're unsure. *** ## Step 2: Upload Your Campaign Brief Step 2 Drag And Drop Brief Doc Or Upload Google Doc Link Your campaign brief can either be a Google document or a Word document (`.docx`) that contains all your campaign content—email copy, landing page text, dates, links, images, and so on. Think of it as your complete campaign plan in one document. **How to upload:** * **From your computer:** Drag and drop your Word document onto the upload area * **From Google Docs:** Paste a shareable link to your Google Doc Once uploaded, Mary reads through your brief and figures out what goes where—which content belongs to which email, what the subject lines are, what images to use, and so on. *** ## Step 3: Name and Start Your Campaign Step 3 Run The Campaign Once The Upload Is Complete! Give your campaign a name—something descriptive like "Spring Product Launch" or "Q2 Webinar Series"—then click **Start Campaign**. Your team may have strict naming convention, so please ask your allGood admin before continuing. This kicks things off. Mary will begin setting up your campaign and you'll be taken to an overview page where you can watch everything come together. *** ## Step 4: Watch Mary Build Your Campaign Step 4 Wait On The Campaign Overview Page As Mary Begins Building Out The Campaign The Campaign Overview page shows everything that's being built for your campaign—each email, landing page, and any other deliverables. Each one shows a status so you always know where things stand. ### What the Statuses Mean | Status | What's happening | | ------------- | ------------------------------------------------------ | | **Draft** | Mary is setting this up | | **In Review** | Ready for you to look over and approve | | **Ready** | Approved and queued to go live | | **Live** | Published and active | | **Done** | Live and confirmed to be working correctly | | **Error** | Something needs your attention—Mary will tell you what | You don't need to do anything during this step. Just wait for Mary to finish—it usually only takes a few minutes. *** ## Step 5: Review and Make Edits Clean Shot 2026 02 16 At 14 04 49@2x Click on any item in your Campaign Overview to open it and see a preview. This is where you can ask Mary to make changes—just type what you want in plain language, like you're sending a message to a colleague. ### Mary Keeps Track of Everything Image6 Image5 On the right side of the screen, you'll see a running task list of everything you've asked Mary to do. Each request gets its own line so nothing gets lost. You can see what's done, what's in progress, and if anything is waiting on more information from you. You can ask for multiple changes at once—no need to send one message per edit: > *"Make the headline bold, change the button text to 'Register Now', and swap the banner image for this one \[attach image]"* Mary will handle each change separately and check them off as she goes. ### See Exactly How Your Email Will Look Image7 The preview on the left shows your actual email—not a rough mockup, but the real thing with your real content. As Mary makes changes, the preview updates automatically so you always know what you're approving. ### Not Sure What to Change? Click on It. Image1 If something in the preview doesn't look right but you're not sure what to call it, just click on that part of the email. A label will pop up showing the name of that section (like "Banner Image" or "CTA Button"). You can then tell Mary exactly what you want changed using that name. This is crucial for giving Mary feedback. Instead of saying "that image at the top," say "change the Banner Image to this new one"— which will help Mary get it right the first time. *** ## Step 6: Approve and Go Live Once you're happy with how everything looks, it's time to launch. 1. **Review:** Each item moves to "In Review" once Mary finishes building it 2. **Approve:** Click the approve button, or tell Mary: *"This looks good, please go ahead and launch"* 3. **Go live:** Mary publishes everything—your emails are activated, your landing pages are live That's it. Mary handles all the publishing steps behind the scenes. *** ## Step 7: After Launch Once your campaign is live, Mary keeps an eye on things in the background—making sure your emails and landing pages are still working correctly. You can still make changes after launching. Just open the campaign and ask Mary—she can update copy, swap images, or fix anything that needs adjusting. *** ## Common Questions Click on the part that looks wrong to find out what it's called, then tell Mary what you'd like changed. You can also just describe what you see: "The image at the top isn't loading" and Mary will try her best to figure it out. Always feel free to reach out to your allGood CSM via Slack if Mary seems confused. Sometimes Mary needs a little more information—like a missing link or a piece of content that wasn't in your brief. Just respond to her question in the chat and she'll continue where she left off. Yes. Mary processes everyone's requests in order and keeps a complete log of who asked for what and when, so nothing gets overwritten accidentally. Just ask Mary in the same campaign. She can update content, fix broken links, or make adjustments even after everything is published. If an item shows "Error" status, Mary will tell you what the problem is. You can also ask her directly: "What went wrong with this?" and she'll explain in plain language and tell you how to fix it. *** ## Tips for a Smooth Launch * **Put everything in your brief upfront.** The more complete your brief, the faster Mary can build your campaign without needing to ask follow-up questions. * **Use clear section names in your brief.** Headings like "Email 1 Subject Line" or "Landing Page Headline" make it easy for Mary to know where each piece of content belongs. * **Be specific when asking for changes.** "Change the button in Email 1 to say 'Sign Up Now'" is easier for Mary to act on than "update the button." * **Use the click-to-identify feature.** If you're not sure what something is called, click it in the preview—Mary will show you the name so you can reference it directly. # Creating a Campaign in Asana for Marketo Users Source: https://docs.allgoodhq.com/use-cases/campaigns/create-in-asana Complete walkthrough of building and managing campaigns in Asana for MOps teams This guide walks Marketing Operations professionals through the complete workflow for creating and managing campaigns using Mary, the allGood agent. As a MOps practitioner, you'll use this process to orchestrate multi-channel campaigns across your marketing stack—from Marketo programs to Salesforce campaigns to landing pages—all through a unified interface. *** ## Getting Started The task title becomes your campaign identifier. Use a clear, descriptive name that follows your team's naming conventions (e.g., `Q1_2025_Product_Launch_Webinar` or `EMEA_Nurture_Series_March`). Image3 Your campaign brief must be in `.docx` format. This document should contain: * Program details (Marketo folder path, template name, required tokens) * Email content (subject lines, body copy, CTAs) * Landing page content and structure * UTM parameters and compliance requirements (if applicable) Image4 File must be in `.docx` format. PDF, Google Docs links, and other formats are not currently supported. This step triggers Mary to begin processing your campaign. You can either add her as a collaborator or assign the task directly to her — this won’t change how Mary handles the task. The choice simply comes down to what works best for your team internally. Image2 Image1 Mary requires three critical pieces of information to proceed. If any are missing from your brief, she'll pause and request them: | Field | Description | Example | | ----------------- | ------------------------------------------------------ | ------------------------------------------------ | | **Folder path** | The Marketo folder where the program should be created | `/Marketing Activities/2025/Demand Gen/Webinars` | | **Template name** | The program template to clone | `Standard Webinar Template v3` | | **Campaign name** | Confirmed unique name for this campaign instance | `Product_Launch_Q1_2025` | Mary will not proceed until all three are provided. This ensures programs are created in the correct location with the appropriate structure. If Mary detects an existing Marketo program with the same name, she'll proactively ask for clarification: > *"I just want to confirm, I already see a Campaign in Marketo with that name, should I use that, or do you want to give me a new name?"* * **Confirm:** Mary will use the existing program and update its assets based on your brief. Be certain you want to overwrite existing content. * **Provide new name:** Mary will create a new program with your updated name. **MOps Best Practice:** Always verify in your MAP before confirming. Check the program's last modified date and existing campaigns to ensure you're not overwriting live or historical programs. Consider implementing a naming convention with date stamps or version numbers (e.g., `Product_Launch_Q1_2025_v1`). Once all requirements are met, Mary automatically provisions and configures: * Marketo program with correct folder placement and naming * Email assets populated with your content, subject lines, and CTAs * Landing pages with approved copy and proper UTM tracking * Tokens and variables mapped from your brief * Integration with Salesforce campaigns (if configured) If your brief is missing required content elements, Mary creates specific tasks for each missing item. She cannot proceed to deployment until all content is provided. **Example request from Mary:** > *"Please provide your content for Email 2 because it's missing from your briefing document. I need: subject line, preview text, body copy, and CTA button text."* Respond directly in the Asana task comments with the missing content. Mary will automatically incorporate your responses and continue the build process. *** ## Receiving Test Emails & QA Process Once all campaign assets are built, Mary automatically initiates the quality assurance workflow. ### Automatic Test Email Delivery Assuming your brief contained all required information, Mary automatically sends test emails to designated recipients. This behavior can be configured based on your team's preferences: | Mode | Behavior | | --------------- | --------------------------------------------------------------------------------------------------------------- | | **Default** | Auto-send to predefined MOps team email addresses upon asset creation | | **On-demand** | Send only when explicitly requested: [*"@Mary, send test emails to john@company.com"*](mailto:john@company.com) | | **Stakeholder** | Include specific email addresses from your brief's approval list | ### Landing Page Quality Assurance For landing pages, Mary provides direct preview links to the staged pages: * **Preview URL:** Non-indexed staging link for content review * **Edit URL:** Direct link to the page editor in your CMS/MAP *** ## Making Revisions & Content Updates During the QA phase, you can request revisions directly in the Asana task. Mary understands natural language commands and can handle a wide range of content and formatting changes. ### Supported Revision Types * *"@Mary update the subject line to 'New Product Launch: Early Access for VIP Customers'"* * *"@Mary change the CTA button text from 'Learn More' to 'Register Now'"* * *"@Mary replace the second paragraph in Email 1 with: \[new content]"* * *"@Mary bold the intro text in Email 2"* * *"@Mary change the bullet list in the landing page to a numbered list"* * *"@Mary make the product name in the headline use our brand color (hex #0066CC)"* * *"@Mary swap out the Email 1 banner image with this new image"* (attach updated image file) * *"@Mary replace the product screenshot in the landing page with the attached version"* * *"@Mary use the updated company logo across all emails"* Mary handles multiple revisions intelligently. You can request several changes in a single message ("@Mary update subject line, bold the intro, and swap the banner image") and she'll process them all. ### What Happens After Revision Requests 1. Mary confirms she understands your request 2. She makes the changes across all relevant assets (emails, landing pages, tokens) 3. Updated test emails are automatically resent (if configured) 4. Preview links are refreshed to show the latest version 5. Mary logs all changes in the campaign event history for compliance purposes *** ## Approval & Deployment Once you've completed QA and all stakeholders have approved the campaign assets, you're ready to deploy. ### Triggering Deployment Simply tell Mary: > ***"@Mary approve and deploy this campaign"*** or ***"@Mary this looks good, please make it live"*** Mary will: * Activate the Marketo program and approve all assets * Publish landing pages to production URLs * Log the deployment event with timestamps and IDs for audit trail *** ## Post-Deployment & Ongoing Management After deployment, Mary continues to monitor your campaign and can assist with updates and troubleshooting. *** ## MOps Best Practices & Tips Create standardized `.docx` templates for different campaign types (webinars, nurtures, events, product launches). Include clearly labeled sections for all required fields. This reduces back-and-forth with Mary and speeds up processing time. Establish team-wide naming conventions for campaigns, programs, and assets. Include identifiers like date, region, campaign type, and version (e.g., `2025_Q1_NA_Webinar_ProductLaunch_v1`). This prevents accidental overwrites and improves searchability. Mary maintains a complete audit trail of all campaign activities. Use this for compliance reporting, troubleshooting, and stakeholder communication. You can ask *"@Mary show me the full event history for this campaign"* at any time. Set up automatic stakeholder notifications in your brief. Include approvers' email addresses so Mary can automatically share previews with legal, compliance, product marketing, or executive reviewers. This streamlines multi-stakeholder approvals. *** ## Getting Help & Support If you encounter issues or need assistance: * **Ask Mary directly:** *"@Mary what went wrong with this deployment?"* or *"@Mary why didn't the email send?"* * **Review error logs:** Mary provides detailed error messages with specific resolution steps * **Check the event history:** *"@Mary show me all errors for this campaign"* reveals technical details * **Contact support:** For platform issues or integration problems, reach out to your allGood support team with the campaign ID This documentation reflects the current Asana integration workflow. For questions about other integrations (Jira, Monday.com, etc.) or advanced configuration options, consult the full allGood platform documentation or contact your MOps admin. # Creating a Campaign in Asana for Users Without Marketo Experience Source: https://docs.allgoodhq.com/use-cases/campaigns/create-in-asana-basic This is a quick reference guide for marketing team members who want to launch campaigns using Mary. No technical knowledge required—just follow these steps in Asana and Mary handles the rest. ## What You Need to Get Started Before creating a campaign, have these ready: * **Campaign Brief:** A Word document (`.docx`) with your campaign content * **Campaign Name:** A clear name for your campaign **What goes in your brief?** Include your email content, landing page copy, any images you want to use, and details like campaign dates and target audience. Think of it as your complete campaign plan in one document. *** ## Step-by-Step: Launch Your Campaign Open Asana and create a new task. Give it your campaign name as the title. Image1 Click the attachment icon and upload your Word document with all your campaign details. Must be a `.docx` file (Word document). PDFs and Google Docs won't work. Click **"Add collaborator"** or **"Assign task"** and select Mary. This tells her to start working on your campaign. Image4 Image7 Mary will review your brief and may ask questions if she needs more information. Just reply in the task comments by typing `@Mary` followed by your response. **Example:** *"@Mary update the subject line to \[Subject]"* Here are some examples of what Mary will ask for in Asana: Image6 Image8 *Simply respond with the information and she'll continue building your campaign.*  While Mary works in Asana, you can also jump into the allGood platform to review your emails in real time. ### Live Email Preview Image3 The preview shows exactly how your email will look, including: * **Real-time updates:** As Mary completes tasks, the preview refreshes automatically * **Side-by-side view:** Task list stays visible so you can track progress * **Actual content:** All content is displayed exactly as it will appear in the email * **Proper layout:** Images, CTAs, and text blocks display in the correct structure You're looking at the actual email, not guessing how your content will show up. What you see is what your recipients will see—no need to wait for test emails. ### Content Field Highlighter Image2 Click any section of the preview to see which content section controls it. The highlighter shows: * **Content section name** (e.g., Banner, Banner URL) * **Current value** (the actual content or URL) * **Where it comes from** (campaign-wide default or asset-specific override) **Benefits for your team:** * **Precise edits:** Know exactly which field controls which content * **Inheritance visibility:** See if content is inherited from the campaign or specific to this asset * **Quick troubleshooting:** If an image won't load or a link is broken, you immediately know which field to fix Instead of describing "the hero image" or "the CTA," you can click the section and reference the exact field name. No more ambiguity in feedback. No need to understand Marketo. Mary will automatically send you test versions of your emails. Check them in your inbox and make sure everything looks good. **What to check:** * Does the content look right? * Are the images showing correctly? * Do the links work? * Is the formatting clean? If you need to make changes, just tell Mary in the Asana comments using plain language: ``` "@Mary update the subject line to: Spring Sale - 30% Off" "@Mary make the headline bold" "@Mary replace the banner image with this new one" [attach image] ``` Mary will make the changes and send updated test emails. **Tips for clear requests:** * If there are multiple similar types of content (e.g., multiple CTAs), be sure to state which one you're referring to * Be as specific as possible: say *"@Mary make Email 1's subject line bold"* — NOT *"@Mary make the subject bold"* * If you only reference the content itself (e.g., *"@Mary change 'Learn More!' to 'Click Here!'"*) Mary may get confused about where that content lives in the email. Instead try: *"@Mary, change the CTA in email 1 to 'Click Here'"* When everything looks perfect, tell Mary to launch: > *"@Mary this looks good, please launch the campaign"* Mary will activate everything and your campaign will go live. *** ## Common Questions Mary will ask you to confirm. If you want to update that existing campaign, say yes. If you want a new campaign, give her a different name. *Tip: Add dates to your campaign names to avoid confusion (e.g., "Product Launch - March 2025")* Once you submit your brief, Mary typically has your campaign ready for review within minutes. Complex campaigns with multiple emails might take a bit longer. Yes! Just ask Mary in the same Asana task. She can update content, pause sends, or make corrections even after launch. No problem! Mary will catch missing information and ask for it. You can also fix mistakes by requesting changes before approval. By default, test emails go to you and your marketing team. You can ask Mary to send to specific people: [*"@Mary send test emails to john@company.com"*](mailto:john@company.com) Mary will tell you exactly what the issue is and how to fix it. You can also ask her: *"@Mary what went wrong?"* and she'll explain. *** ## Quick Tips for Success * **Be Descriptive:** The more detail in your brief, the less back-and-forth with Mary * **Use Clear Names:** Include dates and campaign type in your task titles * **Review Carefully:** Check those test emails thoroughly before approving * **Ask Questions:** Mary understands plain language—just ask if you're unsure *** ## Campaign Brief Template Not sure how to build a propper campaign brief that Mary can understand? Click here to learn more about creating a campaign brief template. *** ## Need Help? You can ask Mary anything directly in your Asana task: ``` "@Mary what's the status of this campaign?" "@Mary can you show me the preview link?" "@Mary how do I change the send date?" ``` She's there to help every step of the way! **Remember:** Mary handles all the technical setup behind the scenes. You focus on your campaign content and strategy—she takes care of the rest. # What We Support in Asana Source: https://docs.allgoodhq.com/use-cases/campaigns/supported-in-asana What you can (and can't) do when refining campaigns through Asana When you're working with Mary through Asana to refine campaign deliverables, she can handle a lot—but not everything. Here's what's supported and what isn't. *** ## What We Support ### Text Formatting & Styling Add or remove italics, bold, underline, text color, bullets, numbered lists, and checklists Convert text to title case, sentence case, lowercase, or uppercase Change text alignment to left, right, center, or justified Add indentation, insert blank lines, or adjust spacing in content blocks ### Links & URLs * **Hyperlinks:** Add or modify hyperlinks within content tokens * **Link formatting:** Convert links into Marketo-compatible format ### Images * **Image swapping:** Replace images by providing new URLs * **Dimension control:** Reformat images to specific dimensions (if you don't specify, Marketo will auto-stretch to fit the module) *** ## What We Do NOT Support These limitations help maintain campaign integrity and prevent unintended changes to your deliverables. ### Specificity Requirements Any changes **without explicitly naming which token (content section name)** you're referencing will not be processed. | ❌ Vague Request | ✅ Specific Request | | ----------------------------- | -------------------------------------- | | *"Make that section shorter"* | *`"Shorten the hero_body_copy token"`* | ### Brief & Document Handling * **Post-submission edits:** Making changes to your Google Doc after it's been submitted to Mary *(Support coming soon)* * **Resubmissions:** Resubmitting the same brief document *(Support coming soon)* ### Structural Changes * **Module operations:** Swapping out or rearranging modules within templates * **Partial module edits:** Removing individual components from a module (e.g., "Remove the third button from the CTA module") ### Tooling Limitations * **Image editor:** Using the allGood image editor directly in Asana *** ## How to Work Effectively with Mary Always name the token, deliverable, or section you want to change. Instead of "update the copy," try: *`"Change the email_subject token to 'Join us for Q2 Planning'"`* If you're not sure what tokens exist or what state a deliverable is in, ask Mary—she'll answer immediately if the data exists. Mary processes instructions during the next prepare or deploy run for that deliverable. She won't re-run everything unless something actually changed. *** ## Examples ### ✅ Supported Requests ``` "Change the cta_button_text token to all caps" "Add bold formatting to the first sentence in hero_body_copy" "Swap the hero_image URL to https://cdn.example.com/new-banner.jpg" "Change alignment of footer_disclaimer to center" "Convert webinar_description to title case" ``` ### ❌ Unsupported Requests ``` "Update that image" → Not specific about which token "I edited the Google Doc, can you refresh?" → Post-submission edits not supported yet "Remove the third button" → Partial module edits not supported "Swap out the hero module for a different one" → Module swapping not supported ``` # Frequently Asked Questions Source: https://docs.allgoodhq.com/use-cases/email-builder/faq **Are images supported?** Yes, images are support by making use of Marketo Rich Text. To ensure proper updating of the image, make sure the destination token is a `Rich Text` one. With a `Rich Text` token, the image directly uploaded to the Google Doc will be updated into Marketo. Traditional `Image` tokens will not update, however a `Text` one containing a link to an image will work if the token is updated to text representing the new link. *** **Is basic formatting of text supported?** Yes, in your Google Doc you can use basic formatting such as Bold, Italics, Bullet points and Mary will correctly format the email content in Marketo. See the table below for specifics | Formatting | Supported | Example | | :---------------- | :----------------------- | :---------------------------------------------------------- | | Bold | Supported | | | Italics | Supported | | | Links | Supported | | | Bullets | Supported | | | Underline | Not Directly Supported\* | \Your text goes here\ | | Strikethrough | Supported | | | Special Character | Supported | | | Indent | Not Directly Supported\* | \Your text goes here\ | | Alignment | Not Directly Supported\* | \Your text goes here\ | \*Not directly supported indicates that this formatting your file will not automatically be transferred over as it is not achievable in markdown, but with example indicators the agent can still help achieve the desired formatting. If you are interested in formatting that is not in the list above, please drop us a message and we can look into how Mary can learn new formatting skills. *** **What file types are supported?** Currently, we support Google Docs, Word Docs, and PDF files for the campaign brief. However, we recommend using Google Docs for the best experience as not all features are supported in other file types. If you have a specific file type in mind, please reach out to us and we can explore options. | File Type | Formatting | Embedded Images | Image Links | | :--------- | :--------- | :-------------- | :---------- | | Google Doc | ✅ | ✅ | ✅ | | Word Doc | ✅ | ❌ | ✅ | | PDF | ✅ | ❌ | ✅ | *** **Can buttons be created in emails with links to assets?** Yes, we can support creating buttons and other links to gated content as part of an email in the campaign. # Add Mary Instructions Source: https://docs.allgoodhq.com/use-cases/email-builder/feature-add-mary-instructions ## Overview You can tell Mary how you want to process your tokens. Mary will read “Mary instructions” and try to follow them. There are some use cases: * Append UTM parameters in every link * Remove “https\://” or specific text in the brief doc. * Validate specific token values # Add document-level instructions For example, add “Mary instructions” sections like this example. Added Mary Instructions section Mary appended the UTM parameters on URLs # Add token-level instructions You can add Mary instruction on the token level like this as well. Added Mary instruction on Intro-Text *Note: Marketo does not support emojis.* Mary updated Intro-Text more interesting # Email Layout Optimization Source: https://docs.allgoodhq.com/use-cases/email-builder/feature-email-layout-optimization Mary intelligently adjusts templates based on your content: * **3-column layout → 2-column**: Automatically switches when you have fewer speakers or content blocks * **Module Selection**: Picks the right combination of text, image, and CTA modules Let’s remove token values in Feature 3 in [the sample campaign brief](https://docs.google.com/document/d/1B1DLehVMdtlGfqVqnzq8836Cs7b0wfLZui_wN-7buAs/edit?tab=t.0). Image3 Image1 #### (Recommended) You can also add more explicit instructions on [Mary Instructions](./feature-add-mary-instructions) section. Image2 This way, Mary has a more specific way to replace the modules, and will update the layout more reliably. # Real-time Editing Source: https://docs.allgoodhq.com/use-cases/email-builder/feature-real-time-editing ## Making Changes Make quick changes to your campaigns through simple chat commands. Mary understands natural language requests and can instantly update your email content without requiring technical expertise. ## Simple Chat Commands ### Content Updates Modify your campaign content with natural language: * **"Change the subject line to..."**: Update email subject instantly * **"Update the event date to..."**: Modify dates and times * **"Make the headline more engaging"**: Enhance copy for better performance * **"Add a call-to-action button"**: Insert CTAs where needed Image2 ## Real-time Previews ### Instant Preview Generation See your changes immediately: * **"Send me a preview"**: Mary generates and sends a preview email * **"Preview with different subject lines"**: Test multiple options * **"Send to my test email"**: Get previews in your actual inbox Image1 ## Advanced Editing Capabilities ### Content Optimization Mary can enhance your content for better performance: * **Engagement Optimization**: Suggest improvements for higher open rates * **Clarity Enhancement**: Improve readability and comprehension * **Brand Voice**: Maintain consistent tone across all content * **Personalization**: Add dynamic content and personalization tokens Image3 The real-time editing feature makes campaign refinement as simple as having a conversation, ensuring your final campaigns perfectly match your vision. # Update Preheader Source: https://docs.allgoodhq.com/use-cases/email-builder/feature-update-preheader ## Constraints Preheader is unsupported with tokens from Marketo ([https://experienceleague.adobe.com/en/docs/marketo/using/product-docs/email-marketing/general/email-editor-2/email-editor-v2-0-overview](https://experienceleague.adobe.com/en/docs/marketo/using/product-docs/email-marketing/general/email-editor-2/email-editor-v2-0-overview)) Image1 # How Mary updates Preheader There are two ways to support the Preheader update 1. Use static preheader 1. No change required, Mary will read Preheader section on your brief doc and update the Email metadata directly. 2. Use tokenized preheader 1. Add preheader content on top of the email template. This is the common practice to place an invisible element on top of an email. So this content won’t be visible in the actual email. However, it is still visible as preview (preheader) text. ```html theme={null}
{{my.Preheader-Title}} - {{my.Preheader-Description}}
``` *Example: Tokenized preheader HTML code* 1. Add tokens for the preheader, for above example, “**Preheader-Title**” and “**Preheader-Description**” 2. Mary will update the tokens from the brief doc. # Overview Source: https://docs.allgoodhq.com/use-cases/email-builder/index details Email Builder enables campaign creation with no Marketo experience required. Focus on simple repetitive campaigns that follow predictable patterns, with Mary handling the technical complexity while you focus on content and strategy. *** ## Get Email Builder Setup Follow the [quick setup guide](/use-cases/email-builder/quick-setup) to prepare templates, integrations, and tokens. Use [Tokenize your emails](/use-cases/email-builder/tokenize-your-emails) to make templates dynamic and reusable. Align your team with the [Campaign brief playbook](/use-cases/email-builder/prepare-the-campaign-brief). *** ## Launch a campaign using Email Builder * [Launch a campaign](/use-cases/email-builder/launch-a-campaign-in-allgood) — end-to-end walkthrough inside allGood. * [Launch with Asana](/use-cases/email-builder/launch-a-campaign-with-asana) — coordinate campaign work from Asana. * [Launch with Workfront](/use-cases/email-builder/launch-a-campaign-with-workfront) — operationalize launches alongside Workfront projects. ### Features There are several features available in Email Builder that enhance its functionality and user experience. Explore: * [Real-time editing with Mary](/use-cases/email-builder/feature-real-time-editing) * [Add Mary instructions](/use-cases/email-builder/feature-add-mary-instructions) * [Email layout optimization](/use-cases/email-builder/feature-email-layout-optimization) * [Update preheader](/use-cases/email-builder/feature-update-preheader) # Launch a Campaign in allGood Source: https://docs.allgoodhq.com/use-cases/email-builder/launch-a-campaign-in-allgood This comprehensive guide will walk you through the process of launching a marketing campaign in allGood with the Email Builder system. Once Mary has been configured to build your campaign, follow these steps to automate your campaign creation process. ## Prerequisites Before beginning, ensure you have completed the following: * Email Builder setup has been successfully configured * A valid Campaign Brief has been prepared (refer to "Preparing the Campaign Brief" guide) * Program Name and campaign details are finalized and ready for implementation ## Step-by-Step Guide * Click "**Start Email Builder**" in the allGood platform and upload the Campaign Brief Home - Start Email Builder on allGoodhq.app. * For Google Docs, select the file from your Google Drive or paste the link to the file * For Google Drive, you will need to authorize allGood to access your Google Drive the first time you use it * If you paste a link to a Google Doc, make sure your Google Integration is set up correctly and the file is shared with the allGood service account * For Word docx, upload the file directly Mary Chat window showing the upload screen to share the campaign brief. * Once the file is uploaded, Mary will go ahead and build your campaign automatically! * Here's what Mary will do: * Clone the program * Update the tokens in the new program * Update the email layout if necessary * Send a test email to the specified address Mary Chat window showing campaign build progress. If Mary encounters any issues, she will ask for your help and you can provide the necessary information Mary Chat window requesting user input. Once Mary has built the campaign, you can make manual updates. **Make updates through built-in UI** #### Content section Click "**View/Edit Content**" on the right sidebar. And you can see "**Edit Content**" popup and directly make changes to the tokens. Content section Edit Content popup #### Content - Images section The images section is right below the content section. You can see all the uploaded images found in the campaign brief doc. Content - Images section You can click on each image and preview the actual image. Preview image Now you can also edit the image. Let's click the "**Edit**" button. Edit image Tune image Apply Filter on image #### Preview Email Drafts section This section lists all the emails within the program. Preview Email Drafts * You can click the "**Preview**" button and it will open up your Marketo email preview screen. * You can check the emails you want to preview and click the "**Send**" button to send the draft emails. **Make updates through Mary** * Some examples of manual updates include: * Updating the email layout * Making changes to the content * Sending a test email to another address * You can simply ask Mary to make these changes for you, and she will do her best to help Mary making additional changes as requested by the user. # Launch a Campaign via Asana Source: https://docs.allgoodhq.com/use-cases/email-builder/launch-a-campaign-with-asana This comprehensive guide will walk you through the process of launching a marketing campaign using Asana integration with the Email Builder system. Once Mary has been configured to build your campaigns, follow these steps to automate your campaign creation process. ## Prerequisites Before beginning, ensure you have completed the following: * Email Builder setup has been successfully configured * A valid Campaign Brief has been prepared (refer to "[Preparing the Campaign Brief](./prepare-the-campaign-brief.mdx)" guide) * Program Name and campaign details are finalized and ready for implementation * Asana integration is successfully configured [allGood-Asana Setup guide](../../integrations/asana.mdx) ## Step-by-Step Process 1. **Attach Campaign Brief File** * Navigate to your Asana task * Upload your prepared campaign brief document as an attachment * Ensure the file is properly formatted and contains all required campaign details 2. **Add Mary as Collaborator** * In the task settings, add Mary to the collaborators list * This action triggers Mary to begin processing your campaign request * **Important: Mary must be added as a collaborator AFTER the campaign brief is attached** Asana task interface with file attachment and collaborator assignment options Once Mary is added as a collaborator, the system automatically begins processing your request: * Mary will post an initial comment in the Asana task * A link will be provided in the comment directing you to the campaign worksheet * The worksheet name will automatically match your Asana task name for easy reference Asana task comment from Mary with processing confirmation and worksheet link When Mary requires additional information, clarification, or approvals: 1. **Provide Detailed Responses with "@Mary" mention.** * Use "**@Mary**" mention in Asana comments Asana comment interface with Mary mention and response example Verify you received the sample email * Sometimes the preview email is delayed for a few minutes. * In some instances, the email could be marked as spam. Check your spam folder. * You can also comment "**@Mary** send sample emails to \<[youremail@company.com](mailto:youremail@company.com)>" Email verification screenshot Upon successful completion of your campaign development: 1. **Review Final Output** * Mary will confirm completion in both Asana and allGood platforms * All completed tasks will be clearly marked with completion status * A distinctive logo indicates messages originating from Asana 2. **Access Your Campaign** * A direct link to your newly created email program in Marketo will be provided * The worksheet will inherit the name of the new email program allGood completion interface with Marketo program link and task status indicators ## Best Practices ### File Management * Always attach campaign briefs before adding Mary as a collaborator * Use clear, descriptive file names for easy identification * Ensure campaign briefs are complete and properly formatted ### Communication * Be specific and detailed in your responses to minimize revision cycles * Use @Mary mentions in Asana for all communication directed to the system * Monitor both Asana and allGood platforms for updates and requests ### Organization * Maintain consistent task naming conventions for easy tracking * Keep all campaign-related communications within the designated task * Regularly check completion status and follow provided links for final deliverables ## Support For additional assistance or technical issues, refer to the comprehensive documentation library or contact the support team through the allGood platform. ## Frequently Asked Questions Yes, any team member with access to the task can interact with Mary by using @Mary in comments. Yes, assigning Mary to the task automatically adds her to the collaborators list. Mary only requires collaborator access, allowing you to maintain your preferred organizational structure for task assignments. The campaign brief must be attached BEFORE adding Mary as a collaborator. Mary processes task information immediately upon being added to the collaboration list. If you attach the file after adding Mary, you must remove and re-add her as a collaborator to trigger proper processing. Button to remove Mary as a collaborator for re-adding All conversations and campaign details remain accessible through the allGood platform. Navigate through the worksheet link to view comprehensive communication history, task progress, and campaign deliverables. You can request reasonable adjustments throughout the campaign development process. All revision requests should be clearly communicated through either the allGood interface or Asana comments using @Mary. # Launch a Campaign via Workfront Source: https://docs.allgoodhq.com/use-cases/email-builder/launch-a-campaign-with-workfront This comprehensive guide will walk you through the process of launching a marketing campaign using Workfront integration with the Email Builder system. Once Mary has been configured to build your campaigns, follow these steps to automate your campaign creation process through your Workfront project management workflow. ## Prerequisites Before beginning, ensure you have completed the following: * Email Builder setup has been successfully configured * A valid Campaign Brief has been prepared (refer to "[Preparing the Campaign Brief](./prepare-the-campaign-brief.mdx)" guide) * Program Name and campaign details are finalized and ready for implementation * Workfront integration is successfully configured [allGood - Workfront Setup guide](../../integrations/workfront.mdx) ## Step-by-Step Process 1. **Attach Campaign Brief Document** * Navigate to your Workfront task or subtask * In the Documents section, upload your prepared campaign brief * Ensure the file is properly formatted and contains all required campaign details * Verify the document appears in the task's document library 2. **Add Mary as Task Assignee** * On the same page, add Mary as the assignee * This action triggers Mary to begin processing your campaign request * **Important: Mary must be assigned AFTER the campaign brief document is attached** Workfront task interface with uploaded campaign brief and Mary as assignee Once Mary is assigned to the task, the system automatically begins processing your request: * Mary will post an initial comment in the Workfront task * A link will be provided in the comment directing you to the campaign worksheet * The worksheet name will automatically match your Workfront task name for easy reference Workfront task updates showing Mary's initial processing comment and worksheet link When Mary requires additional information, clarification, or approvals: 1. **Provide Detailed Responses with "@Mary" mention.** * Use Workfront's "**@Mary**" mention feature in comments Workfront comment interface demonstrating Mary mention usage Verify you received the sample email * Sometimes the preview email is delayed for a few minutes. * In some instances, the email could be marked as spam. Check your spam folder. * You can also comment "**@Mary** send sample emails to \<[youremail@company.com](mailto:youremail@company.com)>" Email verification screenshot Upon successful completion of your email build: 1. **Review Final Output** * Mary will confirm completion in both Workfront and allGood platforms * All completed tasks will be marked with completion status * A distinctive logo indicates messages originating from Workfront 2. **Access Your Campaign** * A direct link to your newly created email program in Marketo will be provided * The worksheet will inherit the name of the new email program allGood completion interface showing Marketo link and task status ## Best Practices ### File Management * Always attach campaign briefs before assigning Mary * Use clear, descriptive file names for easy identification * Ensure campaign briefs are complete and properly formatted ### Communication * Be specific and detailed in your responses to minimize revision cycles * Use **@Mary** mentions in Workfront for all communication directed to the system * Monitor both Workfront and allGood platforms for updates and requests ### Organization * Maintain consistent task naming conventions for easy tracking * Keep all campaign-related communications within the designated task * Regularly check completion status and follow provided links for final deliverables ## Support For additional assistance or technical issues, refer to the comprehensive documentation library or contact the support team through the allGood platform. ## Frequently Asked Questions Yes, any team member with access to the Workfront task can interact with Mary by using @Mary in task updates or comments. The campaign brief must be uploaded BEFORE assigning Mary to the task. Mary processes task information immediately upon being added. If you upload the file after assigning Mary, you must un-assign her from the task and re-assign her to trigger proper processing. Workfront unassign button for Mary All conversations and campaign details remain accessible through the allGood platform. Navigate through the worksheet link to view comprehensive communication history, task progress, and campaign deliverables. You can request reasonable revisions throughout the campaign development process. All revision requests should be clearly communicated through either the allGood interface or Workfront comments using **@Mary**. # Prepare the Campaign Brief Source: https://docs.allgoodhq.com/use-cases/email-builder/prepare-the-campaign-brief ## Overview Campaign brief is a document that contains Campaign information to run a new Marketo Program. This includes Template Program information to be cloned, new program name, and the folder name. Also, specify all the token information in the program that Mary will automatically update within the program. allGood will provide a sample template Campaign brief. But the format is not restricted to the sample as long as it contains the necessary information. # Supported Format There are two formats supported. * Upload MS Word docx(.docx) * Google Docs * Via Direct link * Via download as **MS Word docx** and upload the file * Make sure your Google integration user is accessible with the doc by **anyone with the link** or **shared with the user** Google doc is shared publicly with the link Google doc is shared with Google integration user in allGood * Check out more details for Google Setup [allGood - Google Setup Guide](../../integrations/google.mdx) # Campaign Brief components ## Program Details Program details must include: * The name of the program to be cloned * The name of the new program * The name of folder you would like the new program to be cloned into Image5 ## Email Content List out all tokens in 2-column table format with their respective token names in Marketo. * (optional) We recommend you split up the tokens into two categories: * Email Basics and Email Content Image4 ## Content Formatting Mary will pass any of the formatting of the content over to the email * Don’t be shy when adding multiple types of formatting to one token * As long as the token is a Rich Text token, Mary will be able to add the correct formatting | Formatting | Supported | Example | | ----------------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | | Bold | Yes | **Bold text** | | Italic | Yes | *Italic text* | | Link | Yes | Click [here](https://allgoodhq.com) for more information | | List | Yes (Bullet and Numbered) | - Bullet list 1
- Bullet list 2
- Bullet list 3
1. Numbered list 1
2. Numbered list 2
3. Numbered list 3 | | Underline | Yes | Underlined text | | Strikethrough | Yes | ~~Strikethrough~~ | | Special Character | Yes | © ® ™ | | Indent | Yes (Only 1-level indent) | Single indent works (~~Nested indent does not work~~) | | Alignment | No \* |
Aligning center is not supported
| | Line height | No \* | Custom line-height is not supported | | Color | No \* | This is not supported | | Highlight color | No \* | This is not supported | | Font size | No \* | This is not supported | | Font style | No \* | This is not supported | | Emojis | No \* | 😀 is not supported | *Table: Supported Content formatting* Image7 > **Inline CSS Support** > > NOTE: While text styling such as font size, color, and alignment are not directly supported, you can still specify > inline CSS in the content. For example, to change the font size, you can use > `Your Text Here`. > > However, please note that not all email clients may render > inline CSS consistently, so it's advisable to test the email across different clients to ensure the desired appearance. If you are interested in formatting that is unsupported or not in the list above, please drop us a message, and we can look into how Mary can learn new formatting skills. ## Handling Images Images are supported with **Text** tokens and directly uploaded into your Marketo assets. Note that **The Image token is not supported.** ### Token naming convention To tell Mary to process image properly, make sure to have “**image-URL**” in the name of the tokens explicitly, for example * Header-image-URL * Banner-image-URL * Footer-image-URL ### Add images There are two ways to fill out images in your token * Add image URL * Make sure the image URL is publicly accessible * Embed image * You can directly embed an image in the image URL Image10 ### Specify image dimensions Mary will follow the image dimensions in the token and transform the image with the dimensions before uploading the image. Image6 ### Specify File name By default, Mary uploads images in Marketo following this rule. * Public URL is provided * If the image file name is on the URL, Mary will upload the image with the name. * For example - [https://cdn.prod.website-files.com/6537ecf8dd6837236ee1b763/671928c38a76da7c1f729de7\_8408aba1e79257bb7eeefff1117c6e1e\_maryv2-p-1080.png](https://cdn.prod.website-files.com/6537ecf8dd6837236ee1b763/671928c38a76da7c1f729de7_8408aba1e79257bb7eeefff1117c6e1e_maryv2-p-1080.png) * File name would be “**671928c38a76da7c1f729de7\_8408aba1e79257bb7eeefff1117c6e1e\_maryv2-p-1080.png**” * If the image file name is not identifiable, Mary will upload the image with this naming convention * **\\_\\_\.png** * For example) 1131\_Image-URL2\_V3FKDPDA.png * Embeded image is provided * Mary will upload the image with this naming convention * **\\_\\_\.png** * For example) 1131\_Image-URL2\_V3FKDPDA.png This is annoying to manage randomly created images in your Marketo assets. Mary supports a specific file name by adding **File name: \.** Then Mary will follow with the file name instead of the default behavior above. Image9 ### Where can I find the images uploaded in my Marketo? You can find all the images uploaded In your Marketo -> Design Studio -> Images and Files Image8 ## Advanced: Add Mary Instructions You can tell Mary how you want to process your tokens. There are some use cases: * Append UTM parameters in every links * Remove “https\://” or specific text in the brief doc. * Validate specific token values Learn more on [Feature: Add Mary Instructions](./feature-add-mary-instructions.md) ## Advanced: Email Layout Optimization Learn more on [Feature: Email Layout Optimization](./feature-email-layout-optimization.md) # Getting Started with Email Builder Source: https://docs.allgoodhq.com/use-cases/email-builder/quick-setup ## Overview Email Builder automates Marketo program cloning by creating new programs, updating tokens, and verifying results. You can manage token updates directly or import them from campaign briefs, then send sample emails to confirm everything looks correct. This eliminates the manual work of cloning programs, filling individual tokens, and handling image uploads/resizing. ## Prerequisites * An [Integration with Marketo](/integrations/marketo) has already been setup. ## How it works *Diagram: Overview of how Email Builder works.* ## Step-by-Step Guide For this quick start, we will use a sample template program and sample campaign brief to start. * allGood will create a sample template program with a sample email. Checkout program in Marketo -> Marketing Activities -> Search for "**NL - YYYY.MM.DD - allGood Customer Newsletter**". Image6 Image7 * allGood will provide a Campaign Brief template, which will contain Program Details and Tokens for the program * Copy the brief doc into your Google drive. * In "Program Details", fill out the template program to clone, as well as the new program name and folder to clone into Image4 * The sample campaign brief already have basic sample content * Update any content such as subject and diescription * Utilize text formatting abilities within the document (refer to [the Preparing the Campaign Brief for more details](./prepare-the-campaign-brief.md)) Image1 * Sign in to [allGoodhq.app](https://allgoodhq.app) * In the "**Home**" screen, click "**Start Email Builder**". This will guide you to the Worksheet screen. Image20 Image3 * Click "**From link**" button * Paste the Campaign brief url into the link Image2 Image17 * Click "**Import**" button * Mary will start building your program from the template program Image9 Image14 * Verify you received the sample email * Sometimes the preview email is delayed for a few minutes. * In some instances, the email could be marked as spam. Check your spam folder. * You can also click "**Preview**" button to see the preview email in Marketo Image5 Image21 You have successfully built a new email with Mary! You can learn more details in the next steps. Next steps: * [Tokenize your emails](./tokenize-your-emails.md) * [Prepare a Campaign brief doc](./prepare-the-campaign-brief.md) * [Launch a campaign with allGood](./launch-a-campaign-in-allgood.md) * [Launch a campaign with Asana](./launch-a-campaign-with-asana.md) * [Launch a campaign with Workfront](./launch-a-campaign-with-workfront.md) Learn more about additional features * [Real-time editing with Mary](./feature-real-time-editing.md) * [Add Mary Instructions](./feature-add-mary-instructions.md) * [Email Layout Optimization](./feature-email-layout-optimization.md) * [Update Preheader](./feature-update-preheader.md) # Tokenize Your Emails Source: https://docs.allgoodhq.com/use-cases/email-builder/tokenize-your-emails ## Creating Program Tokens 1. Navigate to the **My Tokens** tab in your template program 2. Create your tokens. Any text you would like formatted from your briefing doc needs to be a **Rich Text token** type and any URL or Image must be a standard **Text token** type. **NOTE:** Other token types are not supported. Create tokens in the My Tokens tab **NOTE** * Marketo will not let you save your tokens with empty values. * Please input some filler text as a dummy value to save and close your tokens. Mary will overwrite these filler values. (a simple dash does the job) Enter a dummy value to save a token # Tokens to your Email(s) ## Insert Tokens * Add each of your tokens where you’d like Mary to populate the content. Example of tokenized email content Tokenized email showing fields filled by Mary ## Image and URL tokens must be placed directly in modules **NOTE** To tell Mary to process the image properly, make sure to have “**image-URL**” in the name of the tokens explicitly, for example * Header-image-URL * Banner-image-URL * Footer-image-URL Tokenized image URL example Tokenized button with link example ## Preheader Preheader is unsupported with tokens from Marketo ([https://experienceleague.adobe.com/en/docs/marketo/using/product-docs/email-marketing/general/email-editor-2/email-editor-v2-0-overview](https://experienceleague.adobe.com/en/docs/marketo/using/product-docs/email-marketing/general/email-editor-2/email-editor-v2-0-overview)) Mary only supports Preheader with static content. Learn more about it on [Feature: Update Preheader](./feature-update-preheader.mdx) Tokens are not supported in the Preheader # Advanced Enrichment Strategies Source: https://docs.allgoodhq.com/use-cases/enrichment/advanced-strategies ## Multi-Step Enrichment Workflows ### Sequential Provider Strategy Stack enrichment steps to maximize hit rates while controlling costs: ``` Step 1: Basic Enrichment (ZoomInfo) ↓ Step 2: Advanced Enrichment (allGood system) ``` **How it works:** 1. First step checks your preferred provider (e.g., ZoomInfo) 2. Second step fills remaining gaps using allGood's advanced system 3. Only leads with missing data after step 1 get processed in step 2 **Benefits:** * Maximizes use of existing data provider subscriptions * Advanced enrichment only runs when needed (cost control) * Higher overall completion rates ### Targeted Enrichment by Lead Segment Create different enrichment profiles for different lead types: **Enterprise Leads Profile** * Advanced mode with all data elements enabled * Comprehensive field set including phone numbers * Always enrich (even overwrite existing data) * Custom instructions: "Focus on finding executive assistants and decision makers" **SMB Leads Profile** * Basic mode with cost-effective provider * Essential fields only (no phone discovery) * Only when missing data * Custom instructions: "Prioritize direct contact information" **Event Attendee Profile** * Advanced mode with professional email focus * Event-specific metadata fields * Custom instructions: "Use event context to validate company information" ## Advanced Configuration Techniques ### Dynamic Field Instructions Use specific instructions for different field types: **LinkedIn URL Field** ``` Instructions: Only accept LinkedIn profiles that match the exact name and company. Verify the profile is active and recently updated. ``` **Email Field** ``` Instructions: Prioritize work email addresses ending in company domains. Avoid generic emails like info@company.com or sales@company.com. ``` **Job Title Field** ``` Instructions: Standardize job titles using common formats. Focus on finding specific roles rather than generic titles like 'Manager'. ``` ### Smart Overwrite Rules Configure when to overwrite existing data: **Always Overwrite Fields** * Phone numbers (often outdated) * Job titles (frequently change) * LinkedIn URLs (for verification) **Never Overwrite Fields** * Names (usually accurate in source data) * Email addresses (if from recent form fills) * Custom fields with manual input **Conditional Overwrite** * Company names (only if current data looks incomplete) * Industries (only if current data is generic) ### Advanced Custom Instructions **Industry-Specific Enrichment** ``` For technology companies: - Focus on finding engineering and product roles - Prioritize GitHub and Stack Overflow profiles - Use company funding stage to validate seniority levels For healthcare leads: - Verify professional licenses where applicable - Focus on institutional email addresses - Skip personal contact information for compliance ``` **Role-Based Processing** ``` For C-level executives: - Always find LinkedIn profiles for validation - Look for recent news mentions or company announcements - Find executive assistant contact information when available For individual contributors: - Focus on direct contact information - Skip phone number discovery unless specifically needed - Prioritize professional social media profiles ``` ## Quality Control and Validation ### Confidence Scoring Setup Configure metadata fields to track data quality: **Enrichment Confidence** ``` Field: enrichment_confidence_score Instructions: Rate the confidence level of enriched data from 1-10, where 10 means all fields were found with high accuracy from primary sources. ``` **Source Attribution** ``` Field: primary_data_source Instructions: Record which data provider supplied the majority of enriched information. ``` **Match Quality** ``` Field: linkedin_match_quality Instructions: Rate how well the LinkedIn profile matches the input data (exact, likely, possible). ``` ### Data Validation Rules Use custom instructions for validation: **Email Validation** ``` Verify email addresses follow these rules: - Must be from the lead's company domain when possible - Avoid role-based emails (sales@, info@, support@) - Check for common typos in domain names - Flag personal emails for potential replacement ``` **Company Validation** ``` Validate company information by: - Confirming company size matches industry expectations - Verifying company location against other data points - Checking that industry classification is specific, not generic - Flagging potential duplicate or subsidiary relationships ``` ## Cost Optimization Strategies ### Smart Phone Discovery Instead of enabling phone discovery for all leads, use targeted approaches: **High-Value Leads Only** * Create separate profiles for leads above certain revenue thresholds * Use conditional logic based on lead scoring * Focus on decision-makers and C-level contacts **Campaign-Specific Discovery** * Enable phone discovery only for outbound calling campaigns * Disable for email-only nurture campaigns * Use different profiles based on campaign type ### Provider Cost Management **Credit Monitoring** ``` Field: api_credits_used Instructions: Track estimated API credits consumed during enrichment to monitor costs and optimize provider usage. ``` **Provider Selection Logic** ``` Use this provider priority order: 1. Free/low-cost sources first (LinkedIn public data, company websites) 2. Mid-tier providers for standard business information 3. Premium providers only for high-value leads or missing critical data ``` ### Batch Processing Optimization **Lead Prioritization** * Process highest-value leads first * Batch similar lead types together * Schedule bulk enrichment during off-peak hours **Incremental Enrichment** * Start with basic fields for all leads * Add advanced fields only for qualified leads * Use lead progression to trigger more comprehensive enrichment ## Next Steps * **A/B Testing**: Compare different enrichment strategies with sample lead sets * **Integration Planning**: Connect enriched data to your CRM and marketing automation * **Advanced Analytics**: Set up reporting to measure enrichment ROI * **Continuous Optimization**: Regular review and adjustment of enrichment profiles ## Troubleshooting Track these metrics to optimize your enrichment strategy: **Hit Rate Metrics** * Overall completion percentage by provider * Field-specific success rates * Cost per successful enrichment **Quality Metrics** * Data accuracy validation scores * Manual review feedback integration * Downstream campaign performance correlation - Solution: Add company domain validation - Use multiple search variations (Full name + company, Email domain + name) - Implement fuzzy matching for similar company names * Solution: Implement source priority rules * Cross-validate critical fields across multiple providers * Use recency signals to prefer newer information * Solution: Tighten matching criteria in custom instructions * Add validation steps for critical fields * Implement manual review workflows for uncertain matches Log the reasoning for each field enrichment decision, including which sources were checked and why specific data was chosen or rejected. Record response times, success rates, and data quality for each provider used during enrichment. # Frequently Asked Questions Source: https://docs.allgoodhq.com/use-cases/enrichment/faq ## General Questions **Basic enrichment** uses a single data provider to perform one lookup per lead. You choose the specific provider (like ZoomInfo or Clearbit) and lookup method. It's cost-effective and predictable. **Advanced enrichment** uses allGood's intelligent system that searches the web first to find LinkedIn profiles, then tries multiple data providers automatically to maximize hit rates and data quality. Yes! This is actually a recommended strategy. Set up a workflow with Basic enrichment first (using your preferred provider), then Advanced enrichment second to fill in any remaining gaps. This maximizes your existing provider subscriptions while ensuring comprehensive coverage. Enrichment costs vary by provider and data elements: * **Basic mode**: Depends on your selected provider's pricing * **Advanced mode**: Uses allGood's provider network with usage-based pricing * **Phone/Email discovery**: Adds significant cost but improves contact rates * **LinkedIn-only enrichment**: Most cost-effective option in Advanced mode Enable expensive features like phone discovery only when needed for specific campaigns. **Standard contact fields**: Name, Email, Job Title, Company, LinkedIn URL, Phone **Company information**: Industry, Employee Count, Revenue, Location, Website **Contact details**: Address, City, State, Country, Social profiles **Custom fields**: Any field you define, with specific instructions for what to find Data accuracy depends on several factors: * **LinkedIn profiles**: Highest accuracy when found, as professionals maintain their own data * **Multiple provider validation**: Advanced mode cross-checks sources for better accuracy * **Recency**: Newer data from active sources is typically more accurate * **Matching criteria**: Stricter matching rules improve accuracy but may reduce hit rates Use metadata fields to track confidence scores and validate critical data manually. ## Technical Questions Advanced enrichment uses web search to find LinkedIn profiles by: 1. Searching for "FirstName LastName Company" variations 2. Validating profile matches against input data 3. Extracting professional information from the profile 4. Using the profile as a foundation for additional data provider lookups allGood's Advanced enrichment system: * **Prioritizes LinkedIn data** as the most reliable source * **Uses recency signals** to prefer newer information * **Cross-validates** critical fields across sources * **Applies custom instructions** to resolve conflicts * **Tracks source attribution** in metadata fields for transparency **Basic mode**: You select the specific provider and lookup method **Advanced mode**: allGood manages provider selection automatically, but you can: * Use custom instructions to specify preferences * Exclude certain data types or sources * Set quality thresholds that influence provider selection The overwrite setting is configured per field: **Overwrite disabled**: Only fills empty/missing fields, preserves existing data **Overwrite enabled**: Replaces existing data with enriched information **Best practice**: Enable overwrite for frequently outdated fields (job titles, phone numbers) and disable for stable fields (names, company names). ## Setup and Configuration 1. Go to **Settings > Enrichment** 2. Click **Create Enrichment Profile** 3. Configure mode, fields, and instructions 4. Save with a descriptive name 5. Attach to different Skills or Flow steps as needed Create multiple profiles for different scenarios (high-value leads vs. bulk processing). Metadata fields store information about the enrichment process itself, not about the lead. Useful examples: * **Enrichment Date**: When the data was enriched * **Primary Source**: Which provider supplied most data * **Confidence Score**: How reliable the enriched data is * **LinkedIn Found**: Whether a LinkedIn profile was located This helps with quality control, troubleshooting, and campaign optimization. Good custom instructions are specific and actionable: **Bad - Vague**: "Find good data" **Good - Specific**: "Only enrich technology companies with 50+ employees. Focus on finding work email addresses, not personal ones." **Bad - Too restrictive**: "Only use data from the past 30 days" **Good - Balanced**: "Prefer recent data but accept older information if it's the only source available" Yes! Always test with a small sample first: 1. Create your enrichment profile 2. Upload a small test file (10-20 leads) 3. Run the enrichment step 4. Review results and adjust configuration 5. Scale up to your full dataset ## Troubleshooting Common causes and solutions: **Input data quality issues** * Ensure names are properly formatted * Check for typos in company names * Verify email addresses are accurate **Overly restrictive matching** * Review custom instructions for overly specific criteria * Consider enabling "fuzzy matching" for company names * Add LinkedIn URL as a field to improve matching accuracy **Provider coverage gaps** * Switch to Advanced mode for better provider coverage * Try different lookup methods in Basic mode * Check if your lead segments are well-covered by your chosen provider **Phone/email discovery enabled** * These features significantly increase costs * Disable if not needed for current campaign * Use targeted profiles that enable these features selectively **Always enrich setting** * Processes leads even with complete data * Switch to "Only when missing data" for cost control * Use separate profiles for validation vs. completion **Advanced mode on large datasets** * Uses multiple providers automatically * Consider Basic mode for budget-conscious bulk processing * Use sequential enrichment (Basic first, then Advanced) **Matching errors** * Tighten matching criteria in custom instructions * Add validation fields like LinkedIn URL * Enable manual review for high-value leads **Outdated source data** * Providers may have stale information * Use multiple sources for validation * Implement confidence scoring to flag uncertain data **Name conflicts** * Common names may match wrong people * Add company domain validation * Include more identifying information in matching 1. **Add specific field instructions** ``` Job Title Instructions: Only accept C-level titles (CEO, CTO, CFO, CMO). Reject generic titles like "Manager" or "Associate". ``` 2. **Enable field-level overwrite selectively** * Disable overwrite for fields getting wrong data * Only fill when the field is truly empty 3. **Add validation metadata** ``` Field: job_title_confidence Instructions: Rate confidence in job title accuracy from 1-10 ``` 4. **Use custom validation logic** ``` Instructions: Cross-check job title against LinkedIn profile. Flag mismatches for manual review. ``` ## Best Practices **Use Advanced enrichment when:** * Data quality is more important than cost * You have incomplete lead databases * You need maximum hit rates * LinkedIn profiles are important for your use case **Use Basic enrichment when:** * You have a preferred data provider * Cost control is critical * You need predictable provider sourcing * You're processing large volumes of similar leads **Quarterly refreshes** for: * Job titles (change frequently) * Company information (growth, acquisitions) * Contact information (phone, email changes) **Annual reviews** for: * Name and basic demographics * Industry classifications * Location data **Event-triggered enrichment** for: * New leads from campaigns * Lead status changes (qualification, opportunity) * Account expansion activities **Essential fields for all profiles:** * LinkedIn URL (improves matching accuracy) * Email (for professional contact discovery) * Job Title (for persona targeting) * Company (for account intelligence) **Optional fields based on use case:** * Phone (only if doing outbound calling) * Industry/Company size (for segmentation) * Location (for territory assignment) **Always include metadata:** * Enrichment date * Primary data source * Match confidence level 1. **Regular profile optimization** based on performance metrics 2. **Feedback loops** from sales teams about data accuracy 3. **A/B testing** of different enrichment strategies 4. **Quality scoring** and manual review workflows 5. **Source performance monitoring** to identify declining providers ## Getting Help If you need additional assistance: * **Documentation**: Review the setup guide and advanced strategies * **Support Team**: Contact support for provider-specific issues * **Best Practices**: Schedule a consultation for optimization recommendations * **Community**: Join user discussions about enrichment strategies # Overview Source: https://docs.allgoodhq.com/use-cases/enrichment/index ## Overview Lead enrichment automatically fills missing contact information by finding data from LinkedIn, web searches, and third-party data providers. allGood's enrichment system helps you complete incomplete lead records, validate existing data, and enhance your contact database for better campaign targeting. Clean Shot 2026 08 17 At 13 23 42@2x ## How It Works ### Basic Enrichment Mode Basic mode uses a single data provider to perform one lookup per lead. This approach is: * **Cost-effective** - Uses one provider per enrichment step * **Predictable** - Clear data sourcing from a specific provider * **Configurable** - Choose from providers like ZoomInfo, Clearbit, or LinkedIn Perfect for when you have a preferred data provider or want to control costs while still filling in missing lead information. ### Advanced Enrichment Mode Advanced mode uses allGood's intelligent enrichment system that: * **Searches LinkedIn first** - Finds the lead's LinkedIn profile through web search * **Uses multiple providers** - Automatically tries different data sources to maximize hit rates * **Validates results** - Ensures data accuracy by cross-referencing sources * **Finds professional contacts** - Locates work emails and phone numbers when needed Best for maximizing data quality and completion rates when working with incomplete lead databases. Clean Shot 2026 08 17 At 13 30 13@2x ## Common Use Cases ### Sequential Enrichment Strategy Stack multiple enrichment steps to create a fallback strategy: 1. **First step**: Basic enrichment with ZoomInfo 2. **Second step**: Advanced enrichment to fill remaining gaps This approach checks your preferred provider first, then uses allGood's advanced system for anything still missing. ### Event Lead Processing After collecting leads from events or webinars: * **Fill incomplete registrations** - Many attendees provide minimal information * **Professional contact discovery** - Find work emails instead of personal ones * **Company intelligence** - Add missing company and job title data for better follow-up ### Database Hygiene Projects Clean and enhance existing contact databases: * **Complete missing fields** - Fill gaps in historical data * **Validate existing information** - Confirm accuracy of current records * **Professional contact updates** - Replace personal emails with business ones ## Configuration Options ### Field Selection Choose which fields to enrich: * **Standard fields**: Name, Email, Job Title, Company, LinkedIn URL * **Contact details**: Phone numbers, addresses, social profiles * **Company data**: Industry, employee count, revenue, location Clean Shot 2026 08 17 At 13 37 16@2x ### Overwrite Settings Control whether to overwrite existing data: * **Always overwrite** - Replace existing data with enriched information * **Preserve existing data** - Only fill empty fields * **Field-specific rules** - Different handling per field type ### When to Enrich **Always enrich**: Process every lead regardless of data completeness **Only when missing data**: Skip leads that already have complete information Clean Shot 2026 08 17 At 13 35 50@2x ### Data Element Preferences (Advanced Mode) **Professional Email Discovery**: * Enable to find work email addresses * Automatically replaces personal emails (Gmail, Hotmail, etc.) * Uses specialized email finding providers **Phone Number Discovery**: * Enable to find contact phone numbers * Searches multiple providers for coverage * Adds significant cost but improves contact rates ### Custom Instructions Provide specific guidance for the enrichment process: ```text theme={null} Only enrich leads from technology companies. Prioritize finding LinkedIn profiles for all C-level executives. Avoid using data from leads in the healthcare industry. Focus on finding professional email addresses for sales roles. ``` ## Best Practices ### Cost Management * Use basic mode for budget-conscious projects * Enable phone/email discovery selectively based on campaign needs * Set up sequential enrichment to balance cost and coverage ### Data Quality * Always include LinkedIn URL as a field - it's a reliable unique identifier * Use custom instructions to specify data quality requirements * Set up validation rules for critical fields ### Privacy Compliance * Review data sources for compliance with regional regulations * Configure consent tracking for enriched data where required * Implement data retention policies for enriched information ## Next Steps * **Set up your first enrichment**: Create an enrichment profile in Settings * **Configure data providers**: Connect your preferred third-party data sources * **Create enrichment workflows**: Build multi-step enrichment processes * **Monitor performance**: Track hit rates and data quality metrics # Enrichment Setup Guide Source: https://docs.allgoodhq.com/use-cases/enrichment/setup-guide ## Creating Your First Enrichment Profile Enrichment profiles are reusable configurations that define how to enrich your leads. You can attach these profiles to Skills and Flow steps across different workflows. 1. Navigate to **Settings** in the main menu 2. Click **Enrichment** to view your enrichment profiles 3. Click **Create Enrichment Profile** to start **Advanced Enrichment** (Recommended) * Uses allGood-managed web search and multiple data providers * Higher hit rates and data quality * Automatically finds LinkedIn profiles first * Best for comprehensive lead enrichment **Basic Enrichment** * Single data provider lookup * Lower cost per enrichment * Predictable data sourcing * Best when you have a preferred provider **Always** * Enriches every lead, even if data is already complete * Good for data validation and updating existing records * Higher cost but ensures freshest information **Only when missing data** (Recommended) * Only enriches leads with empty fields * More cost-effective for partial datasets * Skips leads that are already complete If you chose Basic Enrichment: 1. **Select Provider**: Choose from available data sources * ZoomInfo: Business contact database * LinkedIn: Professional profile data * Clearbit: Company and contact information 2. **Choose Lookup Method**: Select how to find leads * By email address (most reliable) * By name and company * By LinkedIn URL **Professional Email Discovery** * ✅ Enable for B2B campaigns requiring work contacts * Uses specialized email finding providers * Replaces personal emails automatically **Phone Number Discovery** * Enable only when phone outreach is critical * Significantly increases enrichment costs * Searches across multiple phone number providers Choose which fields should be enriched: **Essential Fields** * LinkedIn URL (highly recommended for unique identification) * Email (if you need professional contacts) * Job Title * Company **Additional Fields** * First Name / Last Name * Phone (only if phone discovery is enabled) * Industry * Company size/employee count * Location (City, State, Country) **Field Configuration Options** * **Instructions**: Specific guidance for each field * **Overwrite**: Whether to replace existing data Metadata fields store information about the enrichment process itself: **Useful Metadata Fields** * **Enrichment Source**: Which provider found the data * **Confidence Score**: How confident the system is in the data * **LinkedIn Profile Found**: Whether a LinkedIn profile was located * **Enrichment Date**: When the enrichment occurred Provide specific guidance for the enrichment agent: **Example Instructions** ``` Focus on technology companies with 100+ employees. Only use LinkedIn data for C-level executives. Prioritize finding professional email addresses over phone numbers. Skip enrichment for leads from educational institutions. ``` 1. **Name your profile** with something descriptive like "Standard B2B Enrichment" 2. **Add a description** explaining when to use this profile 3. **Save** the configuration 4. **Test** with a small sample of leads first ## Using Your Enrichment Profile ### In Worksheets 1. Add an "Advanced Enrichment" step to your workflow 2. Select your enrichment profile from the dropdown 3. Run a test with sample data ### In Skills 1. When configuring agent skills, attach your enrichment profile 2. The agent will use these settings automatically during execution ### Multiple Profiles Strategy Create different profiles for different scenarios: **High-Value Leads Profile** * Advanced mode with email and phone discovery * Comprehensive field enrichment * Always enrich (even if data exists) **Bulk Processing Profile** * Basic mode with preferred provider * Essential fields only * Only when missing data **Event Leads Profile** * Advanced mode focused on professional contacts * Custom instructions for event context * Metadata tracking for event attribution ## Next Steps * **Monitor Performance**: Track enrichment hit rates and costs * **Optimize Profiles**: Adjust settings based on results * **Scale Up**: Apply successful profiles across more workflows * **Advanced Features**: Explore custom field mappings and validation rules ## Troubleshooting * Add LinkedIn URL as a field (improves matching accuracy) * Use Advanced mode for better provider coverage * Check custom instructions for overly restrictive criteria * Switch to Basic mode for budget control * Disable phone number discovery * Use "Only when missing data" setting * Enable overwrite for fields that need updating * Add validation metadata fields * Use custom instructions to specify quality requirements * Check data provider API key configuration * Verify you have sufficient credits with the provider * Try switching to a different lookup method # Act-On Actions Source: https://docs.allgoodhq.com/use-cases/erm/act-on-actions What Mary does after she classifies a reply — Act-On contact syncs, marketing list adds, and native opt-outs. **Actions** are what Mary *does* once she's classified a reply and pulled out any [extracted data](/use-cases/erm/data-extraction). They run automatically the moment a match is confirmed, so by the time an email shows up in the [Messages](/use-cases/erm/untitled-page-1) feed, the downstream work in Act-On is already done. Actions are configured per category. A reply that lands in `Unsubscribe` runs one set of actions; one that lands in `Left Company` runs another. ## Available action types ### Forward Email Forward Email action configuration Forward the classified reply to another email address. This is the go-to action when a reply needs a human — for example, routing a `Human Request` reply to your shared sales inbox, or looping a specific rep in on `Out-Of-Office` replies for accounts they own. Forward Email is a **generic action** and works the same way regardless of which marketing automation platform you're connected to. | Field | What it does | | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | | `To` | Destination email address. Accepts tokens (e.g., `{{ owner.email }}`). | | `Subject` | Subject line for the forwarded message. Defaults to `Fwd: {{ subject }}`. | | `Message` | Optional custom message body. Supports **Markdown** formatting and token insertion via **Insert Data**. Leave empty to use the default forwarding template. | | `Original Email` | Controls how the original email is included in the forward — see below. | The `Original Email` dropdown controls what happens with the source message: | Option | Behavior | | ---------------- | ------------------------------------------------------------------------- | | `Include Inline` | Original message body is appended directly beneath your message | | `Include Quoted` | Original message is included as a quoted reply — the familiar default | | `Don't Include` | Forward only contains the message you wrote; the original body is dropped | Under **Advanced**: | Field | What it does | | --------------- | -------------------------------------------------------------------------------------------------------------------- | | `Message Style` | Rendering style for the forwarded email. `AllGood Branded` uses the allGood template; other styles may be available. | | `CC` | Additional addresses to CC on the forward. Accepts tokens. | | `Reply-To` | Override the reply-to address so recipient replies land somewhere other than the original sender. | | `From Name` | Display name shown in the recipient's inbox (e.g., "Support Team" instead of the raw address). | ### Add to Worksheet Add to Worksheet action configuration Push the sender into an allGood worksheet, optionally running it through the worksheet's flow steps. This is how you take a classified reply and hand it off to another allGood workflow — for example, adding a `Human Request` sender to a follow-up worksheet that triages and routes them, or pushing extracted replacement contacts from `Left Company` replies into a new-lead worksheet. Add to Worksheet is a **generic action** and works the same way regardless of which marketing automation platform you're connected to. | Field | What it does | | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `Worksheet` | The worksheet to add the contact to. Search by name to pick from your existing worksheets. | | `Include all email data` | When checked, attaches the full email content (subject, body, from, headers) to the worksheet row. Useful when downstream flow steps need access to the raw reply. | | `Fields` | Map worksheet fields to values or tokens. Left column is the worksheet field name; right column is the value or token to write. Click **+ Add Field** to add more mappings. | Under **Advanced**: | Field | What it does | | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `Behavior` | Choose whether Mary just adds the contact to the worksheet, or adds and immediately runs them through the worksheet's flow steps (`Add to Worksheet + Run Flow`). | | `Include source metadata` | Attaches metadata about where the entry originated (which ERM configuration, category, classification rationale, etc.) so downstream steps can reference it. | | `Only If` | Standard [conditional expression](#conditional-actions) that must evaluate to `true` for the action to run. Use to fan out behavior within a single category. | ### Sync Contact to Act-On Sync Contact to Act-On action configuration Create or update a contact in an Act-On **marketing list**, identified by the sender's email address. Mary writes the contact into the list you select, creating it if it doesn't exist yet and updating it if it does — both in a single call. Act-On writes are **list-scoped**: every sync targets a specific marketing list rather than a global contact table. Pick the list from the **Marketing List** dropdown, which is populated from the contact lists in your Act-On account. You can set: * **Static values** — e.g., `Unsubscribed = true` * **Dynamic values** — tokens that resolve at runtime from Mary's classification or [extracted data](/use-cases/erm/data-extraction), e.g., `Unsubscribe Reason = [allGood] {{ classification }}: {{ rationale }}` Each row in the **field map** pairs an Act-On list **column** with a value or token. Use the field picker to choose from the columns on the selected list — the keys are the column names exactly as they appear in Act-On (e.g., `First Name`, `Company`), not internal API names. The email address is always included automatically — it's the lookup key. There's no sync-mode dropdown. Act-On's list-record endpoint always upserts (create-or-update) in one call, so the sync both creates the contact when it's missing and updates it when it already exists. Common tokens you can reference: | Token | What it resolves to | | ---------------------------------- | ---------------------------------------------------------------------------------------- | | `{{ classification }}` | The category Mary assigned (e.g., `Unsubscribe`) | | `{{ rationale }}` | Mary's plain-English reasoning for the classification | | `{{ from.address }}` | The sender's email address | | `{{ from.name }}` | The sender's display name | | `{{ extractedFields[""] }}` | Any field defined in [Data Extraction](/use-cases/erm/data-extraction) for that category | | `{{ enriched[""] }}` | Any field produced by an enrichment step earlier in the pipeline | ### Add to Act-On List Add to Act-On List action configuration Add the sender to a specific Act-On marketing list. Mary writes the contact into the list you select from the **Marketing List** dropdown. Like the sync action, this **upserts** by email — it creates the contact on the list if they aren't there yet and leaves an existing record in place otherwise. Because of that, you don't need to sync the contact first: adding to a list will never fail just because the contact was missing. ### Unsubscribe in Act-On Unsubscribe in Act-On action configuration Opt the sender out of marketing email in Act-On. This is the cleanest way to honor an opt-out, because it records the suppression in Act-On directly rather than just flipping a field on a list. The opt-out is keyed on the email address and is idempotent — Mary doesn't need to look the contact up first, so an unsubscribe is always honored. Under **Advanced**, you can set a **Subscription Category**: | Field | Behavior | | ------------------------------- | ------------------------------------------------------------------------------------------------------ | | Blank (default) | Account-level opt-out — the sender is suppressed from all marketing email. | | A category (e.g. `Newsletters`) | Scopes the opt-out to a single Act-On subscription category, leaving the contact subscribed to others. | Because the opt-out doesn't require a prior lookup, there's no **skip if not found** toggle on this action — it applies the suppression by email regardless of whether the contact already exists on a list. ## Example: Unsubscribe actions Here's the action chain a typical `Unsubscribe` category would run: Honor the opt-out so the suppression is recorded in Act-On and respected on future sends. Leave **Subscription Category** blank for an account-level opt-out. Record the reason on the contact for the audit trail. Because the sync upserts, it also guarantees the contact is on your suppression list. | Field | Value | | -------------------- | ------------------------------------------------- | | `Unsubscribed` | `true` | | `Unsubscribe Reason` | `[allGood] {{ classification }}: {{ rationale }}` | The `{{ rationale }}` token is particularly useful here — it gives your ops team a human-readable audit trail directly on the contact record explaining *why* Mary marked someone as unsubscribed. ## Stacking and reordering actions You can configure multiple actions per category, and they run in the order they're listed. Use the up/down arrows on each action row to reorder them. Click **+ Add Action** to add more. Order matters mainly for **field dependencies** — if a later action references a field set by an earlier action, make sure the order reflects that dependency. Unlike some platforms, Act-On's **Add to Act-On List** and **Sync Contact to Act-On** both upsert by email, so you don't need to order a sync before a list-add to make sure the contact exists — either action will create it. ## Conditional actions Every action supports an **only-if** condition — a token expression that must evaluate to `true` for the action to run. This lets you fan out behavior within a single category. For example, only add to a "Hot Leads" list when an extracted `intent` field is `high`, while still running the rest of the chain for everyone. Act-On actions don't expose a **skip if not found** toggle. None of them do a prior contact lookup — syncs and list-adds upsert by email, and unsubscribes apply by email — so there's no "missing contact" case to skip or error on. ## Fetching contact data (optional) If you want to reference a sender's existing Act-On fields inside your action templates — for example, writing their `Owner` or `Region` into a forward — add a **Fetch Act-On Contact** step to the category's data pipeline. It looks the contact up by email and exposes the record to later templates: | Token | What it resolves to | | ---------------------------------- | --------------------------------------- | | `{{ actOnContact.email }}` | The fetched contact's email address | | `{{ actOnContact["FIELD_NAME"] }}` | Any field on the fetched Act-On contact | **Fetch Act-On Contact** is the only piece of Act-On that needs an **Account ID**. Set it on the Act-On integration (**Settings → Integrations → Act-On**) — the fetcher can't look contacts up without it. None of the actions above require it. ## Best practices * **Use the `[allGood]` prefix in audit fields.** Following the example above (`Unsubscribe Reason = [allGood] ...`) makes it easy to see at a glance which records were touched by Mary versus a human or another system. * **Use the list's column names, and pick from the field picker.** The field-map keys must match the columns on the selected marketing list exactly. The picker lists them for you so you don't have to guess — a column name that doesn't exist on the list will fail at execution time. * **Prefer the native unsubscribe.** For opt-outs, use **Unsubscribe in Act-On** rather than just setting a field on a list — it records the suppression in Act-On so it's honored on future sends. * **Pick the right list up front.** Every sync and list-add targets one marketing list. If you suppress and report out of a dedicated list (e.g. `Unsubscribed by Mary`), point both the sync and the add at it. * **Test the full chain, not just the classification.** The [Test Suite](/use-cases/erm/test-suite) validates categorization and extraction; once those pass, sanity-check the actions against a sandbox Act-On account before going live. # Categories Source: https://docs.allgoodhq.com/use-cases/erm/categories Define the buckets Mary uses to classify every incoming reply — and the plain-English prompts that teach her how to recognize them. A **category** is a bucket that an incoming reply can fall into. You give it a name and write a plain-English prompt that tells Mary how to recognize it. When an email arrives, Mary reads the body, subject, and metadata, compares it against every category you've defined, and picks the best match. Categories are the foundation of every reply management workflow — they're the layer that everything else ([data extraction](/use-cases/erm/data-extraction) and [actions](/use-cases/erm/actions)) hangs off of. The Categories & Actions configuration page ## Default categories Every workspace ships with a starting set of categories that cover the most common reply types. You can customize the prompts, rename them, or delete them entirely. | Category | What it captures | | ----------------- | ---------------------------------------------------------------------- | | **Unsubscribe** | Real people actively asking to be removed from your list | | **Bounce** | Delivery failure notifications | | **Left Company** | Auto-replies indicating the recipient no longer works there | | **Human Request** | Genuine replies from a person who wants a response | | **Changed Email** | Notifications that the person's email address has changed | | **Out-Of-Office** | Temporary unavailability messages | | **Auto Reply** | Generic automated responses (e.g., "Thanks, we received your message") | | **Spam** | Irrelevant or junk messages | | **Other** | Anything that doesn't fit another category | ## Writing a good category prompt The prompt is the most important part of each category. Mary reads it literally, so the more specific and clear you are, the more accurately she'll classify. A strong prompt does two things: it tells Mary **what to look for** and **what to rule out**. > *"Real people asking to be removed from our email list. Look for phrases like 'please remove me,' 'stop emailing me,' or 'why am I still getting these emails.' Be careful — don't count emails that just have 'unsubscribe' in the footer, those are usually spam."* Notice how this prompt tells Mary both what to look for **and** what to explicitly rule out. That kind of nuance matters — without the second sentence, promotional emails with unsubscribe footers could be miscategorized. > *"Automatic replies saying the person doesn't work at that company anymore. Messages like 'John no longer works here' or 'This employee has left the organization.' No new contact info is provided."* This prompt also distinguishes Left Company from a similar-looking scenario — because if a replacement contact *is* mentioned, that's worth noting separately in the [data extraction](/use-cases/erm/data-extraction) step. > *"Automatic responses indicating that the recipient is currently unavailable. Common phrases include 'out of office,' 'on vacation,' or 'will return on \[date].' These are temporary — the person will be back."* The final sentence ("the person will be back") is a conceptual cue for Mary that helps her distinguish this from Left Company, where the person is gone permanently. ### Tips for writing prompts that hold up * **Lead with the positive case.** Open with what Mary *should* match, in the phrasing she's likely to see in real emails. * **Name the false positives.** If a similar-looking reply belongs in a different category, call it out explicitly. Mary will use that contrast to disambiguate. * **Quote the phrases.** Specific example phrases ("please remove me," "no longer works here") give Mary concrete anchors to look for. * **Keep it short.** Two or three sentences is usually enough. Long prompts dilute the signal. ## Adding a new category The default set covers the common cases, but if your workflow has a reply type that doesn't fit — say, "Requesting Pricing" or "Meeting Reschedule" — you can add a category of your own. Open a new category form from the Categories & Actions page. Use a short, descriptive name. This name will appear in Messages, Search, and your action configuration. Describe the reply type in plain English, following the patterns above. Lead with the positive case, name the false positives, and quote example phrases. Before relying on the category in production, add a few cases to the [Test Suite](/use-cases/erm/test-suite) — both positives you expect to match and negatives that shouldn't. Treat each category like a piece of routing logic in a smart campaign: validate it with real examples before you let it run against live traffic. The [Test Suite](/use-cases/erm/test-suite) is built for exactly this. *** # Data Extraction Source: https://docs.allgoodhq.com/use-cases/erm/data-extraction Pull structured fields out of incoming replies so you can use them in downstream Marketo updates and list adds. Classifying a reply tells you *what kind* of email it is. **Data Extraction** tells you *what's in it*. For some categories — Left Company, Out-Of-Office, Changed Email — the body of the reply contains information you'll want to use downstream: a replacement contact, a return date, a new email address. Data Extraction is how Mary pulls those values out as named fields. Once extracted, those values become variables you can reference in your [Actions](/use-cases/erm/actions) — for example, creating a new Marketo lead using the extracted `newContactEmail`. The Extract Data configuration UI ## How extraction works For each category, you define a list of fields. Each field has: * **A field name** — the variable name you'll reference in actions (e.g., `newContactEmail`) * **A description** — a plain-English explanation of what the field contains, which Mary uses to find it in the email When a reply matches the category, Mary reads the email and tries to populate each field. If a field isn't present and you haven't marked it as required, Mary leaves it blank. ## Example configurations ### Left Company When a reply tells you the recipient has left the company, you often want to capture the replacement contact's details so you can route them into your nurture flow. | Field name | Description | | ----------------- | --------------------------------------------------- | | `newContactEmail` | Email address of a replacement contact, if provided | | `newContactName` | Name of a replacement contact, if provided | ### Out-Of-Office For OOO replies, the most useful piece of data is when the person is coming back — so you can pause outreach until then. | Field name | Description | | ------------ | -------------------------------------------- | | `returnDate` | The date the person will return, if provided | ### Changed Email For "I have a new email" replies, capture the new address so you can update the lead record. | Field name | Description | | ---------- | ------------------------------ | | `newEmail` | The person's new email address | ## Required vs. optional fields Each field can be marked as **Required** or left as optional. Mark a field as **Required** if the email must contain that data to be processed. If a required field can't be found, the email will be flagged for review rather than processed automatically — preventing partial or broken downstream actions. Use **Required** when the field is load-bearing for an action — for example, if your "Changed Email" category is wired up to update the lead's primary email, you want the extraction to be all-or-nothing. Leave the field **optional** when the data is nice-to-have but not blocking — for example, the return date on an OOO. If Mary can't find it, you probably still want the email classified and logged. ## Using extracted values in actions Once a value is extracted, it's available as a variable in the [Actions](/use-cases/erm/actions) configuration for that category. Reference it with the standard token syntax — for example, `{{ newContactEmail }}` — anywhere the action accepts a dynamic value. This is how the full chain comes together: a reply gets classified, fields get pulled, and those values flow directly into the Marketo updates and list adds you've configured. Before relying on an extraction in production, add the case to the [Test Suite](/use-cases/erm/test-suite) with an extraction check. Use **Exact** matching for structured values (dates, emails) and **Semantic** matching for free-text fields the model may paraphrase. # Migrating from Drift Source: https://docs.allgoodhq.com/use-cases/erm/drift-migration Connect your Drift (SiftRock) account to allGood and start your email-reply management migration. This guide walks you through connecting your Drift (SiftRock) account to allGood and starting your migration. It takes just a few minutes. **Before you start**—you'll need the following: * Your **Drift username (email) and password** — the same ones you use to sign in at `email.drift.com`. * Access to allGood **Settings** with admin permissions. ## Migration steps In allGood, go to **Settings** and select the **Integrations** tab. Under **Migration**, locate the **Drift** integration. The Drift integration under Migration Open the Drift integration and enter your **Drift username (email)** and **password**, then click **Create integration**. Your credentials are stored securely (encrypted) and are used only to read your Drift configuration. Entering your Drift username and password Wait for the confirmation that the **integration is connected**. Back in **Settings → Integrations**, find the **Drift** integration again and click **Edit settings**. Then click **Begin migration**. allGood will start pulling your Drift configuration. This can take a moment — you'll see a "Fetching your Drift configuration…" message while it runs. Click Begin migration to pull your Drift configuration When the migration finishes, you'll see a **summary of your Drift instance** — including your configured skills and what each one does. Summary of your migrated Drift configuration Once you've completed these steps, **let the allGood team know**. We'll take it from there and reach back out to finish your migration. **Questions or something not working?** Reach out to the allGood team and we'll help you through it. # Eloqua Actions Source: https://docs.allgoodhq.com/use-cases/erm/eloqua-actions What Mary does after she classifies a reply — Eloqua contact updates, shared list adds, and native unsubscribes. **Actions** are what Mary *does* once she's classified a reply and pulled out any [extracted data](/use-cases/erm/data-extraction). They run automatically the moment a match is confirmed, so by the time an email shows up in the [Messages](/use-cases/erm/messages) feed, the downstream work in Eloqua is already done. Actions are configured per category. A reply that lands in `Unsubscribe` runs one set of actions; one that lands in `Left Company` runs another. ## Available action types ### Forward Email Forward Email action configuration Forward the classified reply to another email address. This is the go-to action when a reply needs a human — for example, routing a `Human Request` reply to your shared sales inbox, or looping a specific rep in on `Out-Of-Office` replies for accounts they own. Forward Email is a **generic action** and works the same way regardless of which marketing automation platform you're connected to. | Field | What it does | | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | | `To` | Destination email address. Accepts tokens (e.g., `{{ owner.email }}`). | | `Subject` | Subject line for the forwarded message. Defaults to `Fwd: {{ subject }}`. | | `Message` | Optional custom message body. Supports **Markdown** formatting and token insertion via **Insert Data**. Leave empty to use the default forwarding template. | | `Original Email` | Controls how the original email is included in the forward — see below. | The `Original Email` dropdown controls what happens with the source message: | Option | Behavior | | ---------------- | ------------------------------------------------------------------------- | | `Include Inline` | Original message body is appended directly beneath your message | | `Include Quoted` | Original message is included as a quoted reply — the familiar default | | `Don't Include` | Forward only contains the message you wrote; the original body is dropped | Under **Advanced**: | Field | What it does | | --------------- | -------------------------------------------------------------------------------------------------------------------- | | `Message Style` | Rendering style for the forwarded email. `AllGood Branded` uses the allGood template; other styles may be available. | | `CC` | Additional addresses to CC on the forward. Accepts tokens. | | `Reply-To` | Override the reply-to address so recipient replies land somewhere other than the original sender. | | `From Name` | Display name shown in the recipient's inbox (e.g., "Support Team" instead of the raw address). | ### Add to Worksheet Add to Worksheet action configuration Push the sender into an allGood worksheet, optionally running it through the worksheet's flow steps. This is how you take a classified reply and hand it off to another allGood workflow — for example, adding a `Human Request` sender to a follow-up worksheet that triages and routes them, or pushing extracted replacement contacts from `Left Company` replies into a new-lead worksheet. Add to Worksheet is a **generic action** and works the same way regardless of which marketing automation platform you're connected to. | Field | What it does | | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `Worksheet` | The worksheet to add the contact to. Search by name to pick from your existing worksheets. | | `Include all email data` | When checked, attaches the full email content (subject, body, from, headers) to the worksheet row. Useful when downstream flow steps need access to the raw reply. | | `Fields` | Map worksheet fields to values or tokens. Left column is the worksheet field name; right column is the value or token to write. Click **+ Add Field** to add more mappings. | Under **Advanced**: | Field | What it does | | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `Behavior` | Choose whether Mary just adds the contact to the worksheet, or adds and immediately runs them through the worksheet's flow steps (`Add to Worksheet + Run Flow`). | | `Include source metadata` | Attaches metadata about where the entry originated (which ERM configuration, category, classification rationale, etc.) so downstream steps can reference it. | | `Only If` | Standard [conditional expression](#conditional-actions) that must evaluate to `true` for the action to run. Use to fan out behavior within a single category. | ### Sync Contact to Eloqua Sync Contact to Eloqua action configuration Create or update a contact record in Eloqua, identified by the sender's email address. Mary looks the contact up by email, then creates or updates it depending on the sync mode you choose. You can set: * **Static values** — e.g., `leadStatus = Subscriber` * **Dynamic values** — tokens that resolve at runtime from Mary's classification or [extracted data](/use-cases/erm/data-extraction), e.g., `leadStatus = [allGood] {{ classification }}` Each row in the **field map** pairs an Eloqua contact field's internal name with a value or token. The email address is always included automatically — it's the lookup key. You also choose a **sync mode** under the advanced tab: | Mode | Behavior | | ------------------ | ----------------------------------------------------------------------- | | `Create or Update` | Update the contact if it exists, otherwise create it (the safe default) | | `Create Only` | Create a new contact; fail if one already exists for that email | | `Update Only` | Update an existing contact; fail (or skip) if no contact is found | Common tokens you can reference: | Token | What it resolves to | | ---------------------------------- | ---------------------------------------------------------------------------------------- | | `{{ classification }}` | The category Mary assigned (e.g., `Unsubscribe`) | | `{{ rationale }}` | Mary's plain-English reasoning for the classification | | `{{ from.address }}` | The sender's email address | | `{{ from.name }}` | The sender's display name | | `{{ extractedFields[""] }}` | Any field defined in [Data Extraction](/use-cases/erm/data-extraction) for that category | ### Add to Eloqua Shared List Add to Eloqua Shared List action configuration Add the sender's contact to a specific Eloqua shared list. Mary looks the contact up by email and adds them to the list you select. The list is identified by ID, and allGood will display the list name for confirmation once you've picked it from the shared lists in your Eloqua instance. When adding a contact to an Eloqua shared list, the contact must already exist in Eloqua. If it might not, add a **Sync Contact to Eloqua** action *before* the **Add to Eloqua Shared List** action — the sync (in `Create or Update` mode) will create the contact if it doesn't exist. ### Unsubscribe in Eloqua Unsubscribe in Eloqua action configuration Opt the sender out of email in Eloqua. Mary looks the contact up by email and sets their subscription status to unsubscribed (`isSubscribed = false`). This is the cleanest way to honor an opt-out, because it uses Eloqua's native subscription status rather than just flipping a custom field. If the contact isn't found in Eloqua, this action skips quietly by default. You can flip this behavior with the **skip if not found** toggle if you'd rather treat a missing contact as a hard error. ## Example: Unsubscribe actions The full Unsubscribe action chain in the Eloqua category editor Here's the action chain a typical `Unsubscribe` category would run: Honor the opt-out using the Unsubscribe in Eloqua action so the suppression is respected everywhere Record the reason on the contact for the audit trail. Using `Create or Update` mode also guarantees the contact exists before the later steps run. | Field | Value | | --------------- | ------------------------------------------------- | | `leadStatus` | `Unqualified` | | `allgoodReason` | `[allGood] {{ classification }}: {{ rationale }}` | Drop the contact into the Mary-managed unsubscribe list for downstream reporting and suppression. | Field | Value | | ------------- | ---------------------------------- | | Email address | `{{ from.address }}` | | List | `Unsubscribed by Mary` (ID: 19044) | The `{{ rationale }}` token is particularly useful here — it gives your ops team a human-readable audit trail directly on the contact record explaining *why* Mary marked someone as unsubscribed. ## Stacking and reordering actions You can configure multiple actions per category, and they run in the order they're listed. Use the up/down arrows on each action row to reorder them. Click **+ Add Action** to add more. Order matters in two cases: * **Dependent actions.** If an `Add to Shared List` depends on the contact existing, put `Sync Contact to Eloqua` (in `Create or Update` mode) first. * **Field dependencies.** If a later action references a field set by an earlier action, make sure the order reflects that dependency. ## Conditional actions Every action supports an **only-if** condition — a token expression that must evaluate to `true` for the action to run. This lets you fan out behavior within a single category. For example, only add to a "Hot Leads" list when an extracted `intent` field is `high`, while still running the rest of the chain for everyone. Actions that look a contact up by email also expose a **skip if not found** toggle, which controls whether a missing contact is treated as a quiet skip or a hard error. ## Best practices * **Use the `[allGood]` prefix in audit fields.** Following the example above (`allgoodReason = [allGood] ...`) makes it easy to see at a glance which records were touched by Mary versus a human or another system. * **Use field *internal* names, not labels.** The field map keys must be Eloqua's internal contact field names, not the friendly labels shown elsewhere in the UI. A field name that doesn't exist will fail at execution time. * **Prefer the native unsubscribe.** For opt-outs, use **Unsubscribe in Eloqua** rather than just setting a custom field — it updates Eloqua's subscription status so suppression is honored everywhere. * **Test the full chain, not just the classification.** The [Test Suite](/use-cases/erm/test-suite) validates categorization and extraction; once those pass, sanity-check the actions in a sandbox Eloqua instance before going live. * **Watch the order when adding to lists.** Most shared-list add failures we see are contacts that didn't exist yet. Lead with a **Sync Contact to Eloqua** in `Create or Update` mode to be safe. # Enrichment Source: https://docs.allgoodhq.com/use-cases/erm/enrichment Fill in the details an incoming reply doesn't contain — job title, company, LinkedIn URL — so your downstream actions have the full picture. Classifying a reply tells you *what kind* of email it is. [Data Extraction](/use-cases/erm/data-extraction) tells you *what's in it*. **Enrichment** goes one step further: it looks the contact up across third-party data providers and fills in the fields the email itself never mentioned — things like job title, company, or LinkedIn URL. Enrichment runs as a dedicated step in the pipeline, after extraction and before your [Actions](/use-cases/erm/actions): > Classify → Fetch → Extract → **Enrich** → Actions Once the contact is enriched, those values become variables you can reference in that category's actions — for example, setting a Marketo `Title` field from the enriched job title, or creating a brand-new lead for a replacement contact with their company already filled in. Enrichment is **optional and configured per category**. A reply that lands in `Left Company` might enrich a newly-extracted contact; one that lands in `Unsubscribe` needs no enrichment at all. This page covers wiring enrichment into a Reply Management category. For help building or tuning the **enrichment profile** itself — picking Basic vs. Advanced mode, choosing data providers, and deciding which fields to look for — start with the [Enrichment Setup Guide](/use-cases/enrichment/setup-guide), or read [Lead Enrichment](/use-cases/enrichment/index) for how enrichment works across allGood. ## Adding enrichment to a category Navigate to **Reply Management → Categories & Actions**, then click **Enrich** on the category row to open the enrichment panel. The panel has two parts: **who** to enrich (the enrichment input) and **which profile** to enrich them with. The enrichment panel, set to enrich the person who sent the reply By default, Mary enriches the person who sent the reply. Point the input somewhere else to enrich a different contact — see [Enrichment input](#enrichment-input-who-to-enrich) below. Pick a profile from the list, or click **Create New Profile**. The profile decides *how* enrichment runs — which data providers to use and which fields to look for. Your enrichment configuration is saved with the rest of the category. Click **Save & Publish** on the Categories & Actions page when you're ready to push it live. Reference the results in that category's [Actions](/use-cases/erm/actions) with `{{ enriched["Field"] }}`. To turn enrichment off for a category, open the panel and click **Remove enrichment from *\[category]***. ## Enrichment input (who to enrich) The **Enrichment Input** section controls *whose* details Mary looks up. By default she enriches the person who sent the email — the input ships pre-set to the sender's address. To enrich **someone other than the sender** — most commonly a new contact mentioned in the reply — click **+ Add Field** and map one or more fields to a value from the email. Each row is a pair: * **Field** — what the value *is*, in enrichment's vocabulary (`Email`, `First Name`, `Last Name`, `LinkedIn URL`, `Company`) * **Value** — where to find it, as a token. This can reference the sender (`{{ from.address }}`), an [extracted field](/use-cases/erm/data-extraction) (`{{ extractedFields["newContactEmail"] }}`), or fetched CRM data **Map only what you actually have.** There's no required set of fields — a single `Email` row is a perfectly valid input, and often it's all a reply gives you. Add more rows only when the reply reliably contains more; each extra field gives enrichment another signal to match on, but a blank one costs you nothing. The **Field** name matters — it tells Mary what each value represents so she can run the right lookups (an `Email` drives email-based lookups, a `LinkedIn URL` drives LinkedIn lookups, and so on). Stick to the suggested names so the value is actually used. Leave the input untouched. Mary enriches whoever sent the reply. | Field | Value | | ------- | -------------------- | | `Email` | `{{ from.address }}` | In a `Left Company` category, you might [extract](/use-cases/erm/data-extraction) a replacement contact's details, then enrich *them* instead of the sender. | Field | Value | | ------------ | ------------------------------------------ | | `Email` | `{{ extractedFields["newContactEmail"] }}` | | `First Name` | `{{ extractedFields["newFirstName"] }}` | | `Last Name` | `{{ extractedFields["newLastName"] }}` | Plenty of replies name a replacement contact by email address and nothing else. That's enough — map the email on its own and let enrichment fill in the name, title, and company. | Field | Value | | ------- | ------------------------------------------ | | `Email` | `{{ extractedFields["newContactEmail"] }}` | Enrichment input pointed at a replacement contact extracted from the reply When enriching an extracted contact, mark the extract field as **Required** (or add an **only runs if** condition to the downstream action) so you don't act on a half-empty record when the reply didn't actually name a replacement. ## Choosing an enrichment profile An **enrichment profile** is a reusable recipe for *how* to enrich a contact — which data providers to use, which fields to look for, and when to skip. The same profile can be shared across many categories, and across other parts of allGood such as [List Upload](/use-cases/list-upload/features/enrich). From the enrichment panel you can: * **Select a profile** — click any profile in the list to use it for this category. The selected profile is highlighted, and each row shows whether it's an **Advanced** or **Basic** profile plus how many categories already use it. * **Create a new profile** — click **Create New Profile** to spin one up and open it for editing. * **Edit a profile** — click **Edit** on any profile to change its fields, providers, and run conditions. | Badge | What it means | | -------------------------- | ------------------------------------------------------------------------------------------------------------- | | **Advanced** | Searches the web for a LinkedIn profile first, then tries multiple providers automatically. Higher hit rates. | | **Basic** | A single lookup against one provider you choose. Cheaper and more predictable. | | **Used by *n* categories** | How many Reply Management categories already point at this profile. | | **Not used by ERM yet** | The profile exists in your workspace but no category uses it — it may still be in use elsewhere in allGood. | Because profiles are shared, editing one affects **every** category, skill, and flow step that uses it. Check the usage count on the row before you change a profile's internals — if only one category should change, create a new profile instead. Configuring a profile's internals — enrichment mode, the fields to find, provider lookups, and when-to-run rules — is covered in the [Enrichment Setup Guide](/use-cases/enrichment/setup-guide). See [Lead Enrichment](/use-cases/enrichment/index) for how enrichment works more broadly. ## Using enriched values in actions Once a contact is enriched, each field the profile produced is available as a variable in that category's [Actions](/use-cases/erm/actions). Reference it with the `enriched` token: ``` {{ enriched["First Name"] }} {{ enriched["Last Name"] }} {{ enriched["Job Title"] }} {{ enriched["Company"] }} {{ enriched["LinkedIn URL"] }} ``` You don't have to type these from memory — open the `{}` token picker on any action field and choose **Enriched Fields** to see everything the enrichment step produces. Picking enriched fields from the token picker in a Sync Lead to Marketo action This is how the chain comes together: a reply is classified, a contact's identity is assembled (sender or extracted), Mary enriches it, and those values flow straight into your Marketo updates, list adds, or new-lead creation. ## Example: enrich a replacement contact from a "Left Company" reply A common pattern: someone has left, the reply names their replacement, and you want to create that replacement as a fully-enriched lead in Marketo. In the `Left Company` category's [Data Extraction](/use-cases/erm/data-extraction), capture the replacement's details. | Field name | Description | | ----------------- | --------------------------------------------------- | | `newContactEmail` | Email address of a replacement contact, if provided | | `newFirstName` | First name of a replacement contact, if provided | | `newLastName` | Last name of a replacement contact, if provided | In the enrichment panel, point the input at the extracted contact and pick a profile — here, one built for new contacts rather than the workspace default. | Field | Value | | ------------ | ------------------------------------------ | | `Email` | `{{ extractedFields["newContactEmail"] }}` | | `First Name` | `{{ extractedFields["newFirstName"] }}` | | `Last Name` | `{{ extractedFields["newLastName"] }}` | Only `Email` is needed here — drop the name rows if your replies don't reliably include them, and enrichment will resolve the name itself. Add a **Sync Lead to Marketo** action (`Create or Update`) that identifies the lead by the extracted email and fills the rest from the enriched values. | Marketo field | Value | | ------------- | -------------------------------- | | `company` | `{{ enriched["Company"] }}` | | `title` | `{{ enriched["Job Title"] }}` | | `LinkedIn__c` | `{{ enriched["LinkedIn URL"] }}` | ## How enrichment behaves * **Skipped when not configured.** Categories without an enrichment profile skip the step entirely — no credits consumed. * **Skipped when there's nothing to enrich.** If the input resolves to no contact — for example, no replacement email was extracted — enrichment is skipped for that reply. * **Blank fields, not errors.** If enrichment runs but finds no match, the `enriched` fields come through empty rather than failing the reply. Downstream actions still run, so guard anything load-bearing with an **only runs if** condition. * **The profile decides when to run.** A profile can be set to only enrich when data is missing, so Mary won't burn credits re-fetching fields you already have. See the [Enrichment Setup Guide](/use-cases/enrichment/setup-guide). * **Every run is traceable.** Open a reply in [Messages](/use-cases/erm/messages) to see the enrichment result — which providers were tried, what was found, and the full agent run. Validate enrichment the same way you validate everything else in Reply Management: add the case to the [Test Suite](/use-cases/erm/test-suite) so you can confirm the right contact gets enriched before the configuration goes live. # Getting Started with Email Reply Management Source: https://docs.allgoodhq.com/use-cases/erm/getting-started Go from zero to a working inbox in a few steps. Mary reads every reply that lands in your marketing inbox, sorts it into a category, and takes the action you've told her to take — automatically, 24/7. Here's how to go from zero to a working inbox in a few steps. We recommend reading the entire guide before starting any of the steps. ## Step 1a: Connect your inbox Start working with your IT team to point your marketing Reply-To email addresses at allGood. This step may take time so we recommend kicking this off as soon as possible. * Docs: [Hosted Mailbox + Custom Domains](/integrations/email/hosted-mailbox) ## Step 1b: Set up your integration user At the same time, begin the process for setting up your integration user. Depending on your organization structure, you may also need to work with your IT team for this. While your IT team is setting up the hosted mailbox, start the set-up in allGood — once you have the integration user, go ahead and connect it in allGood. * Docs: [Marketo Integration](/integrations/marketo) · [HubSpot Integration](/integrations/hubspot) · [Salesforce Integration](/integrations/salesforce/erm) ## Step 2: Hop into allGood and start with what's already built **Review the Default Categories.** Every workspace comes with 7 out-of-the-box categories, already trained and ready to run — no setup required: Unsubscribe, Out of Office, Spam, Bounce, Sales Request, Left Company, and Other. Each one comes with sensible default actions already wired up, so you get value from day one. * Read: [Email Reply Management, Ready on Day One](https://allgoodhq.com/blog/email-reply-management-day-one) * Docs: [Categories](/use-cases/erm/categories) **Migrating off Drift Email?** You don't need to rebuild anything. Connect your Drift account and allGood automatically reads your existing setup and recreates it — every rule, route, and action — as a working allGood configuration. * Read: [Drift Email Is Ending. Migrating to allGood Takes Minutes.](https://allgoodhq.com/blog/drift-to-allgood-migration) * Docs: [Migrating from Drift](/use-cases/erm/drift-migration) ## Step 3: Make it yours (optional) The defaults cover the common cases, but you can rename categories, edit their definitions, or add your own for whatever your team sees in its inbox. A clear definition is the single biggest lever for accurate classification. * Read: [Best Practices for Writing Category Definitions in ERM](https://allgoodhq.com/blog/erm-category-definitions) * Docs: [Setting Up or Altering a Category](/use-cases/erm/setting-up-or-altering-a-category) · [Data Extraction](/use-cases/erm/data-extraction) ## Step 4: Turn categories into automations Every category can trigger real actions in your MAP or CRM — updating a record, adding someone to a list, forwarding a hot lead to sales. A few ideas to get you started: suppress leads while they're out of office, auto-create a new contact when someone leaves their company, or log the reason behind every unsubscribe. * Read: [3 Email Reply Automations You Can Build in allGood](https://allgoodhq.com/blog/build-with-erm) * Docs: [Marketo Actions](/use-cases/erm/marketo-actions) · [HubSpot Actions](/use-cases/erm/hubspot-actions) · [Eloqua Actions](/use-cases/erm/eloqua-actions) · [Salesforce Actions](/use-cases/erm/salesforce-actions) ## Step 5: Test before it touches real replies Once you've finalized your configuration and before live emails start flowing through (be sure to coordinate with IT on this), use our Test Suite to validate your set-up. The Test Suite lets you check categorizations and extracted fields against real reply examples — so you catch a broken definition in testing, not in your inbox. * Read: [Introducing the Email Reply Management Test Suite](https://allgoodhq.com/blog/erm-test-suite) * Docs: [Test Suite](/use-cases/erm/test-suite) ## Keep an eye on things Once you've finished testing and you're happy with your set-up, give IT the green light to start sending emails into allGood. Once live, the [Messages](/use-cases/erm/messages) view shows every reply Mary has processed, the category she assigned, and her reasoning for the call — the fastest way to spot-check a category after a change. ## Go deeper The full technical rundown of how an email gets processed, start to finish. Have any more questions? Reach out to [support@allgoodhq.com](mailto:support@allgoodhq.com) # HubSpot Actions Source: https://docs.allgoodhq.com/use-cases/erm/hubspot-actions What Mary does after she classifies a reply — HubSpot contact updates, static segment adds, and native unsubscribes. **Actions** are what Mary *does* once she's classified a reply and pulled out any [extracted data](/use-cases/erm/data-extraction). They run automatically the moment a match is confirmed, so by the time an email shows up in the [Messages](/use-cases/erm/messages) feed, the downstream work in HubSpot is already done. Actions are configured per category. A reply that lands in `Unsubscribe` runs one set of actions; one that lands in `Left Company` runs another. ## Available action types ### Forward Email Forward Email action configuration Forward the classified reply to another email address. This is the go-to action when a reply needs a human — for example, routing a `Human Request` reply to your shared sales inbox, or looping a specific rep in on `Out-Of-Office` replies for accounts they own. Forward Email is a **generic action** and works the same way regardless of which marketing automation platform you're connected to. | Field | What it does | | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | | `To` | Destination email address. Accepts tokens (e.g., `{{ owner.email }}`). | | `Subject` | Subject line for the forwarded message. Defaults to `Fwd: {{ subject }}`. | | `Message` | Optional custom message body. Supports **Markdown** formatting and token insertion via **Insert Data**. Leave empty to use the default forwarding template. | | `Original Email` | Controls how the original email is included in the forward — see below. | The `Original Email` dropdown controls what happens with the source message: | Option | Behavior | | ---------------- | ------------------------------------------------------------------------- | | `Include Inline` | Original message body is appended directly beneath your message | | `Include Quoted` | Original message is included as a quoted reply — the familiar default | | `Don't Include` | Forward only contains the message you wrote; the original body is dropped | Under **Advanced**: | Field | What it does | | --------------- | -------------------------------------------------------------------------------------------------------------------- | | `Message Style` | Rendering style for the forwarded email. `AllGood Branded` uses the allGood template; other styles may be available. | | `CC` | Additional addresses to CC on the forward. Accepts tokens. | | `Reply-To` | Override the reply-to address so recipient replies land somewhere other than the original sender. | | `From Name` | Display name shown in the recipient's inbox (e.g., "Support Team" instead of the raw address). | ### Add to Worksheet Add to Worksheet action configuration Push the sender into an allGood worksheet, optionally running it through the worksheet's flow steps. This is how you take a classified reply and hand it off to another allGood workflow — for example, adding a `Human Request` sender to a follow-up worksheet that triages and routes them, or pushing extracted replacement contacts from `Left Company` replies into a new-lead worksheet. Add to Worksheet is a **generic action** and works the same way regardless of which marketing automation platform you're connected to. | Field | What it does | | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `Worksheet` | The worksheet to add the contact to. Search by name to pick from your existing worksheets. | | `Include all email data` | When checked, attaches the full email content (subject, body, from, headers) to the worksheet row. Useful when downstream flow steps need access to the raw reply. | | `Fields` | Map worksheet fields to values or tokens. Left column is the worksheet field name; right column is the value or token to write. Click **+ Add Field** to add more mappings. | Under **Advanced**: | Field | What it does | | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `Behavior` | Choose whether Mary just adds the contact to the worksheet, or adds and immediately runs them through the worksheet's flow steps (`Add to Worksheet + Run Flow`). | | `Include source metadata` | Attaches metadata about where the entry originated (which ERM configuration, category, classification rationale, etc.) so downstream steps can reference it. | | `Only If` | Standard [conditional expression](#conditional-actions) that must evaluate to `true` for the action to run. Use to fan out behavior within a single category. | ### Sync Contact to HubSpot Sync Contact to HubSpot action configuration Sync Contact to HubSpot action configuration Create or update a contact record in HubSpot, identified by the sender's email address. Mary looks the contact up by email, then creates or updates it depending on the sync mode you choose. You can set: * **Static values** — e.g., `lifecyclestage = subscriber` * **Dynamic values** — tokens that resolve at runtime from Mary's classification or [extracted data](/use-cases/erm/data-extraction), e.g., `hs_lead_status = [allGood] {{ classification }}` Each row in the **field map** pairs a HubSpot contact property's internal name (the same name you see in HubSpot **Settings → Properties**) with a value or token. The `email` property is always included automatically — it's the lookup key. You also choose a **sync mode** under the advanced tab: | Mode | Behavior | | ------------------ | ----------------------------------------------------------------------- | | `Create or Update` | Update the contact if it exists, otherwise create it (the safe default) | | `Create Only` | Create a new contact; fail if one already exists for that email | | `Update Only` | Update an existing contact; fail (or skip) if no contact is found | Common tokens you can reference: | Token | What it resolves to | | ---------------------------------- | ---------------------------------------------------------------------------------------- | | `{{ classification }}` | The category Mary assigned (e.g., `Unsubscribe`) | | `{{ rationale }}` | Mary's plain-English reasoning for the classification | | `{{ from.address }}` | The sender's email address | | `{{ from.name }}` | The sender's display name | | `{{ extractedFields[""] }}` | Any field defined in [Data Extraction](/use-cases/erm/data-extraction) for that category | ### Add to HubSpot Static Segment Add to HubSpot Static Segment action configuration Add the sender's contact to a specific HubSpot static segment (static list). Mary looks the contact up by email and adds them to the segment you select. The segment is identified by ID, and allGood will display the segment name for confirmation once you've picked it from the list of static segments in your HubSpot instance. When adding a contact to a HubSpot static segment, the contact must already exist in HubSpot. If it might not, add a **Sync Contact to HubSpot** action *before* the **Add to HubSpot Static Segment** action — the sync (in `Create or Update` mode) will create the contact if it doesn't exist. ### Unsubscribe in HubSpot Unsubscribe in HubSpot action configuration Opt the sender out of all marketing email in HubSpot. Mary looks the contact up by email and sets their subscription status to unsubscribed-from-all. This is the cleanest way to honor an opt-out, because it uses HubSpot's native subscription preferences rather than just flipping a property. If the contact isn't found in HubSpot, this action skips quietly by default. You can flip this behavior with the **skip if not found** toggle if you'd rather treat a missing contact as a hard error. ## Example: Unsubscribe actions The full Unsubscribe action chain in the HubSpot category editor Here's the action chain a typical `Unsubscribe` category would run: Honor the opt-out using the Unsubscribe in Hubspot action so the suppression is respected everywhere Record the reason on the contact for the audit trail. Using `Create or Update` mode also guarantees the contact exists before the later steps run. | Field | Value | | ---------------- | ------------------------------------------------- | | `hs_lead_status` | `UNQUALIFIED` | | `allgood_reason` | `[allGood] {{ classification }}: {{ rationale }}` | Drop the contact into the Mary-managed unsubscribe segment for downstream reporting and suppression. | Field | Value | | ------------- | ---------------------------------- | | Email address | `{{ from.address }}` | | Segment | `Unsubscribed by Mary` (ID: 19044) | The `{{ rationale }}` token is particularly useful here — it gives your ops team a human-readable audit trail directly on the contact record explaining *why* Mary marked someone as unsubscribed. ## Stacking and reordering actions You can configure multiple actions per category, and they run in the order they're listed. Use the up/down arrows on each action row to reorder them. Click **+ Add Action** to add more. Order matters in two cases: * **Dependent actions.** If an `Add to Static Segment` depends on the contact existing, put `Sync Contact to HubSpot` (in `Create or Update` mode) first. * **Field dependencies.** If a later action references a field set by an earlier action, make sure the order reflects that dependency. ## Conditional actions Every action supports an **only-if** condition — a token expression that must evaluate to `true` for the action to run. This lets you fan out behavior within a single category. For example, only add to a "Hot Leads" segment when an extracted `intent` field is `high`, while still running the rest of the chain for everyone. Actions that look a contact up by email also expose a **skip if not found** toggle, which controls whether a missing contact is treated as a quiet skip or a hard error. ## Best practices * **Use the `[allGood]` prefix in audit fields.** Following the example above (`allgood_reason = [allGood] ...`) makes it easy to see at a glance which records were touched by Mary versus a human or another system. * **Use property *internal* names, not labels.** The field map keys must be HubSpot's internal property names (found in **Settings → Properties**), not the friendly labels shown elsewhere in the UI. A property name that doesn't exist will fail at execution time. * **Prefer the native unsubscribe.** For opt-outs, use **Unsubscribe in HubSpot** rather than just setting a property — it updates HubSpot's subscription preferences so suppression is honored everywhere. * **Test the full chain, not just the classification.** The [Test Suite](/use-cases/erm/test-suite) validates categorization and extraction; once those pass, sanity-check the actions in a sandbox HubSpot instance before going live. * **Watch the order when adding to segments.** Most static-segment add failures we see are contacts that didn't exist yet. Lead with a **Sync Contact to HubSpot** in `Create or Update` mode to be safe. # Marketo Actions Source: https://docs.allgoodhq.com/use-cases/erm/marketo-actions What Mary does after she classifies a reply — Marketo updates, static list adds, and more. **Actions** are what Mary *does* once she's classified a reply and pulled out any [extracted data](/use-cases/erm/data-extraction). They run automatically the moment a match is confirmed, so by the time an email shows up in the [Messages](/use-cases/erm/messages) feed, the downstream work in Marketo is already done. Actions are configured per category. A reply that lands in `Unsubscribe` runs one set of actions; one that lands in `Left Company` runs another. ## Available action types ### Forward Email Forward Email action configuration Forward the classified reply to another email address. This is the go-to action when a reply needs a human — for example, routing a `Human Request` reply to your shared sales inbox, or looping a specific rep in on `Out-Of-Office` replies for accounts they own. Forward Email is a **generic action** and works the same way regardless of which marketing automation platform you're connected to. | Field | What it does | | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | | `To` | Destination email address. Accepts tokens (e.g., `{{ owner.email }}`). | | `Subject` | Subject line for the forwarded message. Defaults to `Fwd: {{ subject }}`. | | `Message` | Optional custom message body. Supports **Markdown** formatting and token insertion via **Insert Data**. Leave empty to use the default forwarding template. | | `Original Email` | Controls how the original email is included in the forward — see below. | The `Original Email` dropdown controls what happens with the source message: | Option | Behavior | | ---------------- | ------------------------------------------------------------------------- | | `Include Inline` | Original message body is appended directly beneath your message | | `Include Quoted` | Original message is included as a quoted reply — the familiar default | | `Don't Include` | Forward only contains the message you wrote; the original body is dropped | Under **Advanced**: | Field | What it does | | --------------- | -------------------------------------------------------------------------------------------------------------------- | | `Message Style` | Rendering style for the forwarded email. `AllGood Branded` uses the allGood template; other styles may be available. | | `CC` | Additional addresses to CC on the forward. Accepts tokens. | | `Reply-To` | Override the reply-to address so recipient replies land somewhere other than the original sender. | | `From Name` | Display name shown in the recipient's inbox (e.g., "Support Team" instead of the raw address). | ### Add to Worksheet Add to Worksheet action configuration Push the sender into an allGood worksheet, optionally running it through the worksheet's flow steps. This is how you take a classified reply and hand it off to another allGood workflow — for example, adding a `Human Request` sender to a follow-up worksheet that triages and routes them, or pushing extracted replacement contacts from `Left Company` replies into a new-lead worksheet. Add to Worksheet is a **generic action** and works the same way regardless of which marketing automation platform you're connected to. | Field | What it does | | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `Worksheet` | The worksheet to add the contact to. Search by name to pick from your existing worksheets. | | `Include all email data` | When checked, attaches the full email content (subject, body, from, headers) to the worksheet row. Useful when downstream flow steps need access to the raw reply. | | `Fields` | Map worksheet fields to values or tokens. Left column is the worksheet field name; right column is the value or token to write. Click **+ Add Field** to add more mappings. | Under **Advanced**: | Field | What it does | | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `Behavior` | Choose whether Mary just adds the contact to the worksheet, or adds and immediately runs them through the worksheet's flow steps (`Add to Worksheet + Run Flow`). | | `Include source metadata` | Attaches metadata about where the entry originated (which ERM configuration, category, classification rationale, etc.) so downstream steps can reference it. | | `Only If` | Standard [conditional expression](#conditional-actions) that must evaluate to `true` for the action to run. Use to fan out behavior within a single category. | ### Sync Lead to Marketo Sync Lead to Marketo action configuration Create or update a lead record in Marketo, identified by the sender's email address. Mary looks the lead up by email, then creates or updates it depending on the sync mode you choose. You can set: * **Static values** — e.g., `unsubscribed = true` * **Dynamic values** — tokens that resolve at runtime from Mary's classification or [extracted data](/use-cases/erm/data-extraction), e.g., `unsubscribedReason = [allGood] {{ classification }}: {{ rationale }}` Each row in the **field map** pairs a Marketo lead field's internal name (the same name you see in Marketo **Admin → Field Management**) with a value or token. The email address is always included automatically — it's the lookup key. You also choose a **sync mode** under the advanced tab: | Mode | Behavior | | ------------------ | -------------------------------------------------------------------- | | `Create or Update` | Update the lead if it exists, otherwise create it (the safe default) | | `Create Only` | Create a new lead; fail if one already exists for that email | | `Update Only` | Update an existing lead; fail (or skip) if no lead is found | Common tokens you can reference: | Token | What it resolves to | | ---------------------------------- | ---------------------------------------------------------------------------------------- | | `{{ classification }}` | The category Mary assigned (e.g., `Unsubscribe`) | | `{{ rationale }}` | Mary's plain-English reasoning for the classification | | `{{ from.address }}` | The sender's email address | | `{{ from.name }}` | The sender's display name | | `{{ extractedFields[""] }}` | Any field defined in [Data Extraction](/use-cases/erm/data-extraction) for that category | ### Add to Marketo Static List Add to Marketo Static List action configuration Add the sender's lead to a specific Marketo static list. Mary looks the lead up by email and adds them to the list you select. The list is identified by ID, and allGood will display the list name for confirmation once you've picked it from the static lists in your Marketo instance. When adding a lead to a Marketo static list, the lead must already exist in Marketo. If it might not, add a **Sync Lead to Marketo** action *before* the **Add to Marketo Static List** action — the sync (in `Create or Update` mode) will create the lead if it doesn't exist. allGood will warn you if this ordering is wrong. ## Example: Unsubscribe actions The full Unsubscribe action chain in the Marketo category editor Here's the action chain a typical `Unsubscribe` category would run: Mark the lead as unsubscribed and record the reason for the audit trail. Using `Create or Update` mode also guarantees the lead exists before the next step runs. | Field | Value | | -------------------- | ------------------------------------------------- | | `unsubscribed` | `true` | | `unsubscribedReason` | `[allGood] {{ classification }}: {{ rationale }}` | Drop the lead into the Mary-managed unsubscribe list for downstream reporting and suppression. | Field | Value | | ------------- | ---------------------------------- | | Email address | `{{ from.address }}` | | List | `Unsubscribed by Mary` (ID: 19044) | The `{{ rationale }}` token is particularly useful here — it gives your ops team a human-readable audit trail directly on the lead record explaining *why* Mary marked someone as unsubscribed. ## Stacking and reordering actions You can configure multiple actions per category, and they run in the order they're listed. Use the up/down arrows on each action row to reorder them. Click **+ Add Action** to add more. Order matters in two cases: * **Dependent actions.** If an `Add to Static List` depends on the lead existing, put `Sync Lead to Marketo` (in `Create or Update` mode) first. * **Field dependencies.** If a later action references a field set by an earlier action, make sure the order reflects that dependency. ## Conditional actions Every action supports an **only-if** condition — a token expression that must evaluate to `true` for the action to run. This lets you fan out behavior within a single category. For example, only add to a "Hot Leads" list when an extracted `intent` field is `high`, while still running the rest of the chain for everyone. Actions that look a lead up by email also expose a **skip if not found** toggle, which controls whether a missing lead is treated as a quiet skip or a hard error. ## Best practices * **Use the `[allGood]` prefix in audit fields.** Following the example above (`unsubscribedReason = [allGood] ...`) makes it easy to see at a glance which records were touched by Mary versus a human or another system. * **Use field *internal* names, not labels.** The field map keys must be Marketo's internal field names (found in **Admin → Field Management**), not the friendly labels shown elsewhere in the UI. A field name that doesn't exist will fail at execution time. * **Test the full chain, not just the classification.** The [Test Suite](/use-cases/erm/test-suite) validates categorization and extraction; once those pass, sanity-check the actions in a sandbox Marketo instance before going live. * **Watch the order when adding to lists.** Most static-list add failures we see are leads that didn't exist yet. Lead with a **Sync Lead to Marketo** in `Create or Update` mode to be safe. # Messages Source: https://docs.allgoodhq.com/use-cases/erm/messages A live view of every email Mary has processed — with full reasoning behind each classification. The **Messages** page is your operational view into everything Mary has handled. It shows every processed reply, the category she assigned, and — if you click in — exactly *why* she classified it that way and what actions she fired. This is where you go when you want to confirm the system is working, debug a specific reply, or audit a category's behavior after a prompt change. The Messages feed view ## The message feed Processed emails are displayed as cards showing: * The email **subject line** * The sender's **name and email address** * The **category** Mary assigned (e.g., `→ Human Request`) Cards are listed newest-first by default. ## Filtering by category Use the tab bar at the top to slice the feed by category. Click **Unsubscribe** to see only unsubscribe replies, **Bounce** for bounces, and so on. **Recents** shows the most recently processed emails regardless of category. Filtering the Messages feed by category Filtering is the fastest way to spot-check a category after you've edited its prompt — open the tab, scan the recent matches, and confirm they all look right. ## Inspecting an individual email Click any message card to open the detailed view. The detail panel is structured around the full processing pipeline, so you can see exactly what happened at each step. The detailed view of a single processed message The top of the panel shows: * The full **email body** as it arrived * The **classification** Mary assigned and her **plain-English reasoning** for why she made that call Below that, expandable sections walk through the rest of the pipeline: | Section | What it shows | | ------------------- | ----------------------------------------------------------------------------------------------------------- | | **Classify Email** | Mary's full reasoning for the category she chose | | **Extract Fields** | The values Mary pulled from the email body (if [extraction](/use-cases/erm/data-extraction) was configured) | | **Fetch Data** | Any data retrieved from external systems (e.g., Marketo) before extraction | | **Execute Actions** | Which [actions](/use-cases/erm/actions) ran and their outcomes (success / failure / details) | | **Original Email** | The raw email as it arrived, headers and all | This view is the single best debugging tool when something looks off — you can see Mary's reasoning, the values she extracted, and the result of every action she fired, all in one place. ## Re-running a misclassified email If you spot an email that was classified incorrectly, you don't have to wait for a similar reply to arrive again to test your fix. Click **Re-run** on the detail view and Mary will reprocess the email using your current category configuration. This is the standard workflow for tightening up a category prompt: Spot it in the feed or via [Search](/use-cases/erm/search). Edit the [category](/use-cases/erm/categories) that should have caught it — or the one that incorrectly caught it. Open the message and click **Re-run**. Confirm the new classification is correct. Add the email to the [Test Suite](/use-cases/erm/test-suite) as a regression check so the fix can't quietly break later. Re-runs use your current configuration, so they're also a quick way to retroactively reclassify a backlog of emails after a category change — open them one by one and re-run. # Overview Source: https://docs.allgoodhq.com/use-cases/erm/overview Mary reads, classifies, and acts on every reply that lands in your marketing inbox — automatically. When you send marketing emails, replies come back. Lots of them. Unsubscribes, out-of-office messages, people who've changed jobs, bounce notifications, genuine sales inquiries — and a mountain of spam. Sorting through all of this manually is tedious and error-prone. **Mary's Email Reply Management (ERM)** handles this automatically. Every reply that arrives in your configured inbox is read and classified by Mary's AI. Based on the category it falls into, Mary can extract key pieces of information from the email and then trigger downstream actions — like updating a Marketo record, adding someone to a static list, or creating a new contact. ## The three building blocks The whole system is built around three concepts you configure yourself: Define the buckets replies fall into. Give each one a name and a plain-English prompt describing how Mary should recognize it. Tell Mary which fields to pull from emails in a given category — replacement contacts, return dates, new email addresses, and more. Configure what happens automatically after classification — syncing Marketo fields, adding to static lists, and more. ## How an email gets processed When a reply hits your inbox, here's exactly what happens: The reply lands in your dedicated allGood inbox address (e.g., `8IEJ8ZOP@parse.allgoodhq.app`). Every message sent to this address is automatically picked up and queued for processing. Mary reads the full email — subject line, body, and metadata — and compares it against the categories you've defined. She picks the best match based on the description you wrote for each category. Mary reads the full email — subject line, body, and metadata — and compares it against the categories you've defined. She picks the best match based on the description you wrote for each category. If you've set up data extraction for that category, Mary pulls specific pieces of information out of the email — for example, a replacement contact's name and email address from a "Left Company" auto-reply. Mary reads the full email — subject line, body, and metadata — and compares it against the [categories](/use-cases/erm/categories) you've defined. She picks the best match based on the description you wrote for each category. If you've set up data extraction for that category, Mary pulls specific pieces of information out of the email — for example, a replacement contact's name and email address from a "Left Company" auto-reply. With the email classified and data in hand, Mary fires the actions you've configured for that category — updating a Marketo lead, adding someone to a static list, and so on. If you've set up [data extraction](/use-cases/erm/data-extraction) for that category, Mary pulls specific pieces of information out of the email — for example, a replacement contact's name and email from a "Left Company" auto-reply. With the email classified and data in hand, Mary fires the actions you've configured for that category — updating a Marketo lead, adding someone to a static list, and so on. With the email classified and data in hand, Mary fires the [actions](/use-cases/erm/actions) you've configured for that category — updating a Marketo lead, adding someone to a static list, and so on. ## Where to next Define how Mary recognizes a reply type. Pull structured data out of incoming replies. Trigger Marketo updates and list adds automatically. Validate categorizations and extractions with the Test Suite. See every reply Mary has handled and why she classified it the way she did. Find specific emails across every category and field. # Salesforce Actions Source: https://docs.allgoodhq.com/use-cases/erm/salesforce-actions What Mary does after she classifies a reply — Salesforce contact/lead updates, campaign adds, and native unsubscribes. **Actions** are what Mary *does* once she's classified a reply and pulled out any [extracted data](/use-cases/erm/data-extraction). They run automatically the moment a match is confirmed, so by the time an email shows up in the [Messages](/use-cases/erm/messages) feed, the downstream work in Salesforce is already done. Actions are configured per category. A reply that lands in `Unsubscribe` runs one set of actions; one that lands in `Left Company` runs another. ## Available action types ### Forward Email Forward Email action configuration Forward the classified reply to another email address. This is the go-to action when a reply needs a human — for example, routing a `Human Request` reply to your shared sales inbox, or looping a specific rep in on `Out-Of-Office` replies for accounts they own. Forward Email is a **generic action** and works the same way regardless of which marketing automation platform you're connected to. | Field | What it does | | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | | `To` | Destination email address. Accepts tokens (e.g., `{{ owner.email }}`). | | `Subject` | Subject line for the forwarded message. Defaults to `Fwd: {{ subject }}`. | | `Message` | Optional custom message body. Supports **Markdown** formatting and token insertion via **Insert Data**. Leave empty to use the default forwarding template. | | `Original Email` | Controls how the original email is included in the forward — see below. | The `Original Email` dropdown controls what happens with the source message: | Option | Behavior | | ---------------- | ------------------------------------------------------------------------- | | `Include Inline` | Original message body is appended directly beneath your message | | `Include Quoted` | Original message is included as a quoted reply — the familiar default | | `Don't Include` | Forward only contains the message you wrote; the original body is dropped | Under **Advanced**: | Field | What it does | | --------------- | -------------------------------------------------------------------------------------------------------------------- | | `Message Style` | Rendering style for the forwarded email. `AllGood Branded` uses the allGood template; other styles may be available. | | `CC` | Additional addresses to CC on the forward. Accepts tokens. | | `Reply-To` | Override the reply-to address so recipient replies land somewhere other than the original sender. | | `From Name` | Display name shown in the recipient's inbox (e.g., "Support Team" instead of the raw address). | ### Add to Worksheet Add to Worksheet action configuration Push the sender into an allGood worksheet, optionally running it through the worksheet's flow steps. This is how you take a classified reply and hand it off to another allGood workflow — for example, adding a `Human Request` sender to a follow-up worksheet that triages and routes them, or pushing extracted replacement contacts from `Left Company` replies into a new-lead worksheet. Add to Worksheet is a **generic action** and works the same way regardless of which marketing automation platform you're connected to. | Field | What it does | | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `Worksheet` | The worksheet to add the contact to. Search by name to pick from your existing worksheets. | | `Include all email data` | When checked, attaches the full email content (subject, body, from, headers) to the worksheet row. Useful when downstream flow steps need access to the raw reply. | | `Fields` | Map worksheet fields to values or tokens. Left column is the worksheet field name; right column is the value or token to write. Click **+ Add Field** to add more mappings. | Under **Advanced**: | Field | What it does | | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `Behavior` | Choose whether Mary just adds the contact to the worksheet, or adds and immediately runs them through the worksheet's flow steps (`Add to Worksheet + Run Flow`). | | `Include source metadata` | Attaches metadata about where the entry originated (which ERM configuration, category, classification rationale, etc.) so downstream steps can reference it. | | `Only If` | Standard [conditional expression](#conditional-actions) that must evaluate to `true` for the action to run. Use to fan out behavior within a single category. | ### Sync Contact/Lead to Salesforce Sync Contact/Lead to Salesforce action configuration Create or update a record in Salesforce, identified by the sender's email address. Mary looks the record up by email — preferring a **Contact**, then falling back to a **Lead** — then creates or updates it depending on the sync mode you choose. You can set: * **Static values** — e.g., `leadStatus = Unqualified` * **Dynamic values** — tokens that resolve at runtime from Mary's classification or [extracted data](/use-cases/erm/data-extraction), e.g., `allgood_reason = [allGood] {{ classification }}` Each row in the **field map** pairs a Salesforce field's API name with a value or token. The email address is always included automatically — it's the lookup key. You also choose a **sync mode** under the advanced tab: | Mode | Behavior | | ------------------ | ---------------------------------------------------------------------- | | `Create or Update` | Update the record if it exists, otherwise create it (the safe default) | | `Create Only` | Create a new record; fail if one already exists for that email | | `Update Only` | Update an existing record; fail (or skip) if no record is found | Common tokens you can reference: | Token | What it resolves to | | ---------------------------------- | ---------------------------------------------------------------------------------------- | | `{{ classification }}` | The category Mary assigned (e.g., `Unsubscribe`) | | `{{ rationale }}` | Mary's plain-English reasoning for the classification | | `{{ from.address }}` | The sender's email address | | `{{ from.name }}` | The sender's display name | | `{{ extractedFields[""] }}` | Any field defined in [Data Extraction](/use-cases/erm/data-extraction) for that category | ### Add to Salesforce Campaign Add to Salesforce Campaign action configuration Add the sender to a specific Salesforce campaign as a campaign member. Mary looks the record up by email and adds them to the campaign you specify. The campaign is identified by its **Campaign ID** — the 15- or 18-character Salesforce Campaign record ID. When adding someone to a Salesforce campaign, the Contact or Lead must already exist in Salesforce. If it might not, add a **Sync Contact/Lead to Salesforce** action *before* the **Add to Salesforce Campaign** action — the sync (in `Create or Update` mode) will create the record if it doesn't exist. ### Unsubscribe in Salesforce Unsubscribe in Salesforce action configuration Opt the sender out of email in Salesforce. Mary looks the record up by email — preferring a **Contact**, then falling back to a **Lead** — and sets their email opt-out status. This is the cleanest way to honor an opt-out, because it uses Salesforce's native email opt-out field rather than just flipping a custom field. If the record isn't found in Salesforce, this action skips quietly by default. You can flip this behavior with the **skip if not found** toggle if you'd rather treat a missing record as a hard error. ## Example: Unsubscribe actions The full Unsubscribe action chain in the Salesforce category editor Here's the action chain a typical `Unsubscribe` category would run: Honor the opt-out using the Unsubscribe in Salesforce action so the suppression is respected everywhere. Record the reason on the record for the audit trail. Using `Create or Update` mode also guarantees the record exists before the later steps run. | Field | Value | | ---------------- | ------------------------------------------------- | | `leadStatus` | `Unqualified` | | `allgood_reason` | `[allGood] {{ classification }}: {{ rationale }}` | Drop the record into the Mary-managed unsubscribe campaign for downstream reporting and suppression. | Field | Value | | ------------- | -------------------- | | Email address | `{{ from.address }}` | | Campaign ID | `701dL00002GXH2OQAX` | The `{{ rationale }}` token is particularly useful here — it gives your ops team a human-readable audit trail directly on the record explaining *why* Mary marked someone as unsubscribed. ## Stacking and reordering actions You can configure multiple actions per category, and they run in the order they're listed. Use the up/down arrows on each action row to reorder them. Click **+ Add Action** to add more. Order matters in two cases: * **Dependent actions.** If an `Add to Salesforce Campaign` depends on the record existing, put `Sync Contact/Lead to Salesforce` (in `Create or Update` mode) first. * **Field dependencies.** If a later action references a field set by an earlier action, make sure the order reflects that dependency. ## Conditional actions Every action supports an **only-if** condition — a token expression that must evaluate to `true` for the action to run. This lets you fan out behavior within a single category. For example, only add to a "Hot Leads" campaign when an extracted `intent` field is `high`, while still running the rest of the chain for everyone. Actions that look a record up by email also expose a **skip if not found** toggle, which controls whether a missing record is treated as a quiet skip or a hard error. ## Best practices * **Use the `[allGood]` prefix in audit fields.** Following the example above (`allgood_reason = [allGood] ...`) makes it easy to see at a glance which records were touched by Mary versus a human or another system. * **Use field *API* names, not labels.** The field map keys must be Salesforce's API field names, not the friendly labels shown elsewhere in the UI. A field name that doesn't exist will fail at execution time. * **Prefer the native unsubscribe.** For opt-outs, use **Unsubscribe in Salesforce** rather than just setting a custom field — it updates Salesforce's native email opt-out so suppression is honored everywhere. * **Test the full chain, not just the classification.** The [Test Suite](/use-cases/erm/test-suite) validates categorization and extraction; once those pass, sanity-check the actions in a sandbox Salesforce instance before going live. * **Watch the order when adding to campaigns.** Most campaign-add failures we see are records that didn't exist yet. Lead with a **Sync Contact/Lead to Salesforce** in `Create or Update` mode to be safe. # Search Source: https://docs.allgoodhq.com/use-cases/erm/search Find specific emails across every processed reply — by sender, body content, category, or any extracted field. The **Search** page lets you find specific emails across every reply Mary has processed. It's the fastest way to confirm a specific contact's reply was picked up, debug a category that doesn't look right, or audit how Mary handled a particular sender. The Search page ## How to search By default, search runs across all indexed fields at once — drop in a keyword, sender name, or phrase and you'll see every email it appears in. For more targeted queries, use the dropdown to scope your search to a single field. ## Searchable fields | Field | What you can search | | ----------------- | ----------------------------------------------------------- | | `Category` | Filter by classification (e.g., all `Unsubscribe` emails) | | `from` | Find emails from a specific sender address | | `body` | Search the full text of the email body | | `cc` | Find emails where a specific address was CC'd | | `newContactEmail` | Find emails where a replacement contact email was extracted | | `newContactName` | Find emails where a replacement contact name was extracted | | `newEmail` | Find emails where a new email address was extracted | | `returnDate` | Find Out-Of-Office emails with a specific return date | | `received_at` | Search by when the email was received | | `metadata` | Search across message metadata | Results appear as cards just like the [Messages](/use-cases/erm/messages) feed, and you can click into any result to view the full processing detail. ## Common debugging patterns A few search workflows that come up regularly: * **"Did this person's reply get processed?"** Search `from` for the sender's email. If nothing comes up, the reply never reached Mary — check your inbox forwarding rules. * **"Why was this reply classified that way?"** Find the email, click into it, and review Mary's reasoning in the **Classify Email** section of the detail view. * **"Is this category over-firing?"** Filter by `Category` and skim the matches. If you see replies that shouldn't be there, tighten the [category prompt](/use-cases/erm/categories) to rule them out — and add the misclassified examples to the [Test Suite](/use-cases/erm/test-suite) as regression checks. * **"Where did we route the replacements from last quarter's left-company replies?"** Search `newContactEmail` with a date range on `received_at` to pull every extracted replacement contact. When you find a misclassified email through Search, open it and use the **Re-run** button in the [Messages](/use-cases/erm/messages) detail view to reprocess it against your current configuration — no need to wait for a similar reply to come in. # Setting Up or Altering a Category Source: https://docs.allgoodhq.com/use-cases/erm/setting-up-or-altering-a-category A technical walkthrough for allGood admins on how to configure email categories, extract data, and define automated actions in Reply Management. ## Overview Reply Management gives you full control over how incoming emails are classified and acted on. You can work from the out-of-the-box (OOTB) categories that come pre-configured, edit them to fit your use case, or build entirely new categorizations and workflows from scratch. Every category workflow is made up of three parts: