Email notifications

FormFlow sends automated email notifications through SendGrid using dynamic templates. There are 4 message categories that you should create custom templates for:

  • SUCCESS

  • VALIDATION

  • ERROR

  • REJECTION

Each category can have its own SendGrid template with custom branding and styling.

In addition to a message_category, each message will also have a message_type, and you will want to handle different types of messages with in-template logic, as well as define a fallback condition to send a generic email in case you encounter a new type of email in the future.

Email Notification Types

Success emails

Positive confirmations as feedback to the user that all is going according to plan.

Processing has begun

If an email is well received, we are able to pull all of its attachments, and all attachments are valid, then we reply to user to say that their submission is being processed.

Example Payload:

{
  "subject": "Your Submission is Being Processed",
  "message_category": "SUCCESS",
  "message_type": "processing_started",
  "submission_id": "ab761b6e-c9ba-41ef-9d08-b41c4e1de35b",
  "suggested_message": "Thank you for your submission. We have successfully received your documents and processing has begun. You will be notified once the process is complete.",
  "data": {}
}
Submission completed

If email loopback functionality is enabled, and Ledger integration is configured, and the submission is completed, and it has been successfully exported to Ledger, we inform the user of this.

Example Payload:

{
  "subject": "Submission Processed Successfully",
  "message_category": "SUCCESS",
  "message_type": "submission_completed",
  "submission_id": "ab761b6e-c9ba-41ef-9d08-b41c4e1de35b",
  "suggested_message": "Your submission has been successfully processed and exported to our system. Thank you for using FormFlow.",
  "data": {}
}

Validation emails

Information requests – something about a submission is incomplete and requires the submitting user's attention.

Missing fields

If email loopback functionality is enabled and an extraction is complete, but there are validation errors.

Example Payload:

{
  "subject": "Additional Information Required - Submission #12345",
  "message_category": "VALIDATION",
  "message_type": "missing_fields",
  "submission_id": "ab761b6e-c9ba-41ef-9d08-b41c4e1de35b",
  "suggested_message": "Thank you for your submission. We have reviewed your documents and found that some required information is missing or incomplete. Please review the items listed below and resubmit your documents with the necessary details.",
  "data": {
    "missing_fields": [
      "Policy holder's date of birth",
      "Vehicle registration number",
      "Proof of no claims bonus",
      "Current insurance certificate expiration date"
    ]
  }
}

Rejection emails

Active rejections: something about the submisison is unsatisfactory. It is likely that the user can do something about the situation.

Unsupported attachments

If one or more attachments are not supported, then we advise the user that their submission will not be processed.

Example Payload:

{
  "subject": "Submission Not Supported",
  "message_category": "REJECTION",
  "message_type": "unsupported",
  "submission_id": "ab761b6e-c9ba-41ef-9d08-b41c4e1de35b",
  "suggested_message": "Thank you for your submission. Unfortunately, we are unable to process the documents you have submitted as they do not match the required format or document type we currently support.",
  "data": {
    "rejection_reasons": [
      "The submitted documents are in an unsupported file format",
      "Only PDF, PNG, and JPEG files are accepted",
      "Please resubmit your documents in a supported format"
    ]
  }
}
Whitelist rejection

If email whitelisting is configured, and the emailing user is not whitelisted by domain or email address, then we advise the user that their submission is not accepted.

Example Payload:

{
  "subject": "Access Restricted",
  "message_category": "REJECTION",
  "message_type": "whitelist",
  "submission_id": "no-submission",
  "suggested_message": "We appreciate your interest. However, access to this service is currently limited to authorized partners and pre-approved organizations.",
  "data": {
    "rejection_reasons": [
      "Your email address or domain is not currently authorized",
      "Please contact your account manager to request access"
    ]
  }
}

Error emails

Advisory email regarding processing failures. In these cases it is unlikely that the user can do something, and they should probably contact a support channel.

Pre-processing error

If there is an unexpected issue reading the incoming email, then we respond with a generic error message.

Example Payload:

{
  "subject": "Error Reading Your Submission",
  "message_category": "ERROR",
  "message_type": "preprocessing",
  "submission_id": "no-submission",
  "suggested_message": "We encountered an issue while reading your email submission. Please try resubmitting your documents, or contact support if the problem persists.",
  "data": {
    "error_messages": [
      "Unable to parse email content",
      "Attachment extraction failed"
    ]
  }
}
Processing error

If there is an issue during processing, then we respond with an error message, detailing the submission ID, failure stage and a short error stack.

Example Payload:

{
  "subject": "Submission Processing Failed",
  "message_category": "ERROR",
  "message_type": "processing",
  "submission_id": "ab761b6e-c9ba-41ef-9d08-b41c4e1de35b",
  "suggested_message": "We encountered an issue while processing your submission. Our technical team has been notified and is investigating the problem.",
  "data": {
    "error_messages": [
      "There was a problem during processing, and your documents have not been processed.\n Processing Step: convertFiles.\n Error message: Some error message.\n Submission ID: ab761b6e-c9ba-41ef-9d08-b41c4e1de35b.\n If the issue persists, please contact your Account Manager."
    ]
  }
}
Export error

If Ledger integration is configured, but exporting a submission fails even after it passes validation, then we respond with a generic error message.

Example Payload:

{
  "subject": "Export to System Failed",
  "message_category": "ERROR",
  "message_type": "export",
  "submission_id": "ab761b6e-c9ba-41ef-9d08-b41c4e1de35b",
  "suggested_message": "Your submission was processed successfully, but we encountered an issue exporting it to our external system. Our team has been notified and will resolve this shortly.",
  "data": {
    "error_messages": [
      "Export to Ledger failed",
      "Connection timeout to external service",
    ]
  }
}


Setting Up SendGrid Templates

FormFlow uses SendGrid's dynamic templates to send emails. Each template uses Handlebars syntax to dynamically insert data from the payload.

Template Structure

All email payloads follow a standardized, flattened structure for SendGrid:

{
  subject: string;              // Email subject line
  message_category: string;     // SUCCESS, VALIDATION, ERROR, or REJECTION
  message_type: string;         // Specific type within category
  submission_id: string;        // Unique submission identifier
  suggested_message: string;    // Main message body
  data: {                       // Optional additional data
    // Category-specific fields
  }
}

Example: Validation Template Setup

1. Create the HTML Template in SendGrid:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Validation - Missing Information</title>
</head>
<body style="margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif; background-color: #e8e8e8;">
    <table role="presentation" style="width: 100%; border-collapse: collapse;">
        <tr>
            <td align="center" style="padding: 40px 20px;">
                <table role="presentation" style="max-width: 700px; width: 100%; border-collapse: collapse;">
                    <!-- Logo -->
                    <tr>
                        <td style="padding: 0 0 30px 0;">
                            <img src="https://insly.com/wp-content/uploads/2024/06/Logo-with-text-4.png" alt="Insly" style="height: 40px; display: block;">
                        </td>
                    </tr>
                    
                    <!-- Content Card -->
                    <tr>
                        <td style="background-color: #ffffff; border-radius: 8px; padding: 50px 40px; box-shadow: 0 2px 8px rgba(0,0,0,0.08);">
                            <h1 style="margin: 0 0 30px 0; color: #1a1a1a; font-size: 28px; font-weight: 600; line-height: 1.3;">
                                Additional information is required
                            </h1>
                            
                            <!-- Dynamic suggested message -->
                            <p style="margin: 0 0 20px 0; color: #333333; font-size: 18px; line-height: 1.6;">
                                {{suggested_message}}
                            </p>
                            
                            <!-- Conditional missing fields list -->
                            {{#if data.missing_fields}}
                            <p style="margin: 0 0 15px 0; color: #333333; font-size: 18px; line-height: 1.6;">
                                The following fields are missing or incomplete:
                            </p>
                            <ul style="margin: 0 0 20px 0; padding-left: 25px; color: #333333; font-size: 18px; line-height: 1.8;">
                                {{#each data.missing_fields}}
                                <li>{{this}}</li>
                                {{/each}}
                            </ul>
                            {{/if}}
                            
                            <p style="margin: 25px 0 0 0; color: #333333; font-size: 18px; line-height: 1.6;">
                                Please provide the missing information and resubmit your documents.
                            </p>
                        </td>
                    </tr>
                    
                    <!-- Footer -->
                    <tr>
                        <td style="padding: 30px 0 0 0;">
                            <p style="margin: 0 0 10px 0; color: #888888; font-size: 15px; line-height: 1.6;">
                                This automated email was sent by FormFlow, and responses will not be read.
                            </p>
                            <p style="margin: 0; color: #888888; font-size: 15px; line-height: 1.6;">
                                With questions, please reach out to your customer success representative, or to 
                                <a href="mailto:[email protected]" style="color: #888888; text-decoration: underline;">[email protected]</a>
                            </p>
                        </td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
</body>
</html>

2. Understanding Handlebars Syntax:

  • {{variable}} - Inserts the value of a variable

  • {{#if condition}}...{{/if}} - Conditional rendering

  • {{#each array}}...{{/each}} - Loop through array items

  • {{this}} - Current item in a loop

3. Key Template Variables:

All templates have access to these flattened variables:

  • {{subject}} - Email subject

  • {{message_category}} - Category (SUCCESS, VALIDATION, ERROR, REJECTION)

  • {{message_type}} - Specific message type

  • {{submission_id}} - Submission identifier

  • {{suggested_message}} - Main message content

  • {{data}} - Object containing category-specific fields

4. Category-Specific Data Fields:

Validation emails:

{{data.missing_fields}} - Array of missing field names

Error emails:

{{data.error_messages}} - Array of error message strings

Rejection emails:

{{data.rejection_reasons}} - Array of rejection reason strings

Success emails:

{{data.confirmation_details}} - Array of confirmation message strings

5. Configure in Organization Settings:

Inside FormFlow's settings tab editor you can assign the SendGrid template IDs to their respective message categories. Here you can see the templates object has truncated SendGrid template IDs, you should include yours in full.

{
  "sendgrid": {
    "api_key": "SG.xxxxx",
    "from_email": "[email protected]",
    "from_name": "FormFlow",
    "templates": {
      "validation": "d-abc123...",
      "error": "d-def456...",
      "rejection": "d-ghi789...",
      "success": "d-jkl012...",
      "fallback": "d-mno345..." // this one has to be set
    }
  }
}

6. Testing Your Template:

Use SendGrid's template editor test feature with this sample data:

{
  "subject": "Test Validation Email",
  "message_category": "VALIDATION",
  "message_type": "missing_fields",
  "submission_id": "test_12345",
  "suggested_message": "This is a test validation message.",
  "data": {
    "missing_fields": [
      "Test Field 1",
      "Test Field 2"
    ]
  }
}

Best Practices

  1. Always provide fallback content - Use {{#if}} blocks to handle missing data gracefully

  2. Keep inline styles - Email clients have limited CSS support

  3. Test across email clients - Use services like Litmus or Email on Acid

  4. Use semantic HTML - Tables for layout (email client compatibility)

  5. Optimize images - Host externally and use absolute URLs

  6. Keep file size small - Some email clients truncate large emails

Last updated

Was this helpful?