Skip to main content

Overview

This troubleshooting guide covers the most common issues users encounter with GoBlue, providing step-by-step solutions and prevention strategies. Issues are organized by category with clear diagnostic steps and resolution paths.
If you can’t find a solution here, check our Community Discord or contact support at [email protected].

Quick Diagnostics

System Health Check

Run through this checklist to identify the general area of your issue:
1

App Connectivity

Check: Can you access GoBlue app settings and see your forms? Issues: Network connectivity, app updates, account authentication
2

Form Configuration

Check: Are your forms active and properly configured? Issues: Webhook URLs, message templates, field validation
3

Message Queue

Check: Are messages being created when webhooks are sent? Issues: Webhook processing, template rendering, contact creation
4

iOS Shortcuts

Check: Is the iOS Shortcut running and processing messages? Issues: Shortcut configuration, permissions, automation triggers
5

Message Delivery

Check: Are messages actually being sent via iMessage? Issues: Message content, recipient validation, delivery confirmation

Error Code Reference

401 Unauthorized: Invalid or missing API key 403 Forbidden: Insufficient permissions 404 Not Found: Resource doesn’t exist 429 Too Many Requests: Rate limit exceeded
500 Internal Server Error: Temporary server issue 502 Bad Gateway: Service temporarily unavailable 503 Service Unavailable: Maintenance or overload
FORM_INACTIVE: Form is disabled TEMPLATE_ERROR: Message template has syntax errors PHONE_INVALID: Phone number format is invalid RATE_LIMIT_EXCEEDED: Too many messages for timeframe

Form and Webhook Issues

Webhook Not Triggering Messages

Symptoms:
  • Webhook appears to send successfully
  • No new messages appear in GoBlue queue
  • No error messages in external system
Diagnostic Steps:
# Test webhook directly
curl -X POST https://api.goblue.app/v1/forms/YOUR_FORM_ID/webhook \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "Test",
    "lastName": "User",
    "phoneNumber": "+1234567890"
  }'
Common Causes & Solutions:
  1. Wrong Webhook URL
    • Check form ID in URL matches your form
    • Verify URL is copied correctly without extra characters
    • Ensure using HTTPS, not HTTP
  2. Form is Inactive
    • Open GoBlue app → Forms tab
    • Check form status (should show “Active”)
    • Toggle form off and on to reactivate
  3. Invalid JSON Format
    • Validate JSON using online validator
    • Ensure proper content-type header
    • Check for special characters or encoding issues
  4. Missing Required Fields
    • Verify phoneNumber field is included
    • Check field names match exactly (case-sensitive)
    • Include all required fields defined in form
Symptoms:
  • Messages appear in queue
  • Template variables not replaced (showing instead of actual name)
  • Messages sent with unreplaced variables
Diagnostic Steps:
  1. Check message content in GoBlue app
  2. Verify webhook data structure
  3. Compare field names in webhook vs template
Solutions:
// Wrong: Field name mismatch
{
  "first_name": "John",  // Underscore format
  "phoneNumber": "+1234567890"
}
// Template: Hi {{firstName}}, ...  // camelCase format

// Correct: Matching field names
{
  "firstName": "John",   // camelCase matches template
  "phoneNumber": "+1234567890"
}
Prevention:
  • Use consistent naming convention
  • Test templates with sample data
  • Document required field names
Symptoms:
  • External system reports webhook failures
  • Intermittent success/failure pattern
  • Timeout errors in logs
Diagnostic Steps:
# Check response time
time curl -X POST https://api.goblue.app/v1/forms/YOUR_FORM_ID/webhook \
  -H "Content-Type: application/json" \
  -d @test-data.json
Solutions:
  1. Increase Timeout Values
    • Set webhook timeout to 30+ seconds
    • Implement retry logic in external system
  2. Reduce Payload Size
    • Remove unnecessary fields from webhook data
    • Split large payloads into multiple smaller ones
  3. Implement Queue System
    // Instead of direct webhook calls
    async function processLeads(leads) {
      for (const lead of leads) {
        await sendWebhook(lead);
        await sleep(1000); // Rate limiting
      }
    }
    

Form Configuration Issues

Causes:
  • Form was manually deactivated
  • Too many failed webhook attempts
  • Account limits reached
Solutions:
  1. Reactivate Form:
    • Open GoBlue app → Forms tab
    • Tap the inactive form
    • Toggle “Active” switch on
  2. Check Account Limits:
    • Settings → Account Usage
    • Verify you haven’t exceeded form limits
    • Upgrade plan if necessary
  3. Reset Failed Attempts:
    • Contact support to reset failed webhook counter
    • Fix underlying webhook issues first
Common Template Issues:
// Wrong: Mismatched braces
Hi {firstName}, thanks for {{serviceType} inquiry!

// Wrong: Spaces in variable names
Hi {{first name}}, thanks for your inquiry!

// Wrong: Special characters
Hi {{firstName}}, thanks for your {{service-type}} inquiry!

// Correct: Proper syntax
Hi {{firstName}}, thanks for your {{serviceType}} inquiry!
Validation Tool:
function validateTemplate(template) {
  const variables = template.match(/\{\{([^}]+)\}\}/g) || [];
  const issues = [];
  
  variables.forEach(variable => {
    const varName = variable.replace(/\{\{|\}\}/g, '').trim();
    
    if (varName.includes(' ')) {
      issues.push(`Variable "${varName}" contains spaces`);
    }
    
    if (!/^[a-zA-Z][a-zA-Z0-9]*$/.test(varName)) {
      issues.push(`Variable "${varName}" contains invalid characters`);
    }
  });
  
  return issues;
}

iOS Shortcuts Issues

Shortcut Not Running

Symptoms:
  • Messages stay in “queued” status
  • No notification or indication shortcut ran
  • Manual shortcut execution works fine
Common Causes:
  1. Automation Not Set Up
    • Open Shortcuts app → Automation tab
    • Verify GoBlue automation exists and is enabled
    • Check automation trigger conditions
  2. Background App Refresh Disabled
    • Settings → General → Background App Refresh
    • Ensure “Shortcuts” is enabled
    • Enable “Background App Refresh” globally
  3. Low Power Mode Active
    • Low Power Mode disables background automation
    • Disable Low Power Mode or run shortcuts manually
  4. iOS Focus Modes
    • Focus modes can block automation
    • Check Focus settings for automation permissions
Solutions:
Settings → Shortcuts → Advanced
✓ Allow Running Scripts
✓ Allow Sharing Large Amounts of Data  
✓ Allow Untrusted Shortcuts (if using custom shortcuts)
Diagnostic Steps:
  1. Check Shortcut Logs:
    • Open Shortcuts app
    • Run GoBlue shortcut manually
    • Look for error messages or failed steps
  2. Test API Connection:
    # Add this as first step in shortcut for debugging
    Get Contents of URL: https://api.goblue.app/v1/messages/YOUR_API_KEY
    Show Result (to see if API is accessible)
    
  3. Verify Permissions:
    • Messages app permissions
    • Network access permissions
    • Contact access (if using contact data)
Common Solutions:
  1. Update Shortcut Configuration:
    • Re-import latest shortcut from GoBlue docs
    • Check API key is correctly entered
    • Verify URL format is correct
  2. Fix Message Format Issues:
    // Common formatting problems in shortcuts
    
    // Wrong: Trying to send empty messages
    if (messageContent.length === 0) return;
    
    // Wrong: Invalid phone number format
    phoneNumber = phoneNumber.replace(/[^\d+]/g, '');
    
    // Wrong: Message too long for SMS
    if (messageContent.length > 160) {
      // Split or truncate message
    }
    
Symptoms:
  • Messages delivered to incorrect phone numbers
  • Recipient complaints about receiving wrong messages
  • Cross-contamination between campaigns
Root Causes:
  1. Contact Data Corruption
  2. Shortcut Logic Errors
  3. Race Conditions in Processing
Prevention & Fixes:
// Add validation in shortcut
function validateRecipient(message) {
  // Check phone number format
  if (!/^\+\d{10,15}$/.test(message.phoneNumber)) {
    throw new Error(`Invalid phone: ${message.phoneNumber}`);
  }
  
  // Verify message content matches recipient
  if (!message.content.includes(message.firstName)) {
    console.warn('Name mismatch in message');
  }
  
  return true;
}

Performance and Reliability Issues

Symptoms:
  • Long delays between queue and delivery
  • Messages sent hours after scheduled time
  • iOS device feels sluggish during processing
Optimization Strategies:
  1. Batch Size Optimization:
    // Instead of processing all messages at once
    const batchSize = 10; // Process 10 messages at a time
    const batches = chunk(messages, batchSize);
    
    for (const batch of batches) {
      await processBatch(batch);
      await sleep(5000); // 5 second delay between batches
    }
    
  2. Reduce API Calls:
    • Cache message data locally
    • Batch status updates
    • Only fetch new messages, not entire queue
  3. Optimize Shortcut Logic:
    • Remove unnecessary steps
    • Use efficient text processing
    • Minimize network requests
Error Handling in Shortcuts:
// Add try-catch equivalent logic in shortcuts

1. Get Messages from API
2. If (No Messages Found):
Exit Shortcut
3. For Each Message:
Try: Send Message
If Error: Log Error, Continue to Next
4. Update Status for Successful Messages
Common Crash Causes:
  • Memory issues with large message batches
  • Network timeouts
  • iOS version compatibility
  • Corrupted shortcut data
Solutions:
  • Reduce batch sizes
  • Add error handling to each step
  • Update iOS and Shortcuts app
  • Rebuild shortcut from scratch if corrupted

Message Delivery Issues

iMessage vs SMS Problems

Diagnostic Questions:
  1. Are failing recipients iPhone users or Android users?
  2. Do failures happen consistently for same recipients?
  3. Are messages over 160 characters?
Common Patterns:
// Check delivery patterns
const failureAnalysis = {
  androidUsers: [], // May need SMS fallback
  longMessages: [], // May be truncated or split
  internationalNumbers: [], // May have formatting issues
  blockedNumbers: [] // Recipient blocked sender
};
Solutions by Recipient Type:
  • iPhone → iPhone: Should use iMessage (blue bubbles)
  • iPhone → Android: Falls back to SMS (green bubbles)
  • International: Verify country code format
  • Landlines: Cannot receive text messages
Common Formatting Problems:
// Problem: Emoji causing encoding issues
Original: "Thanks for your order! 🎉"
Received: "Thanks for your order! □"

// Problem: Line breaks not preserved
Template:
Hi John,

Thanks for your inquiry.

Best regards,
Sarah

Received: "Hi John, Thanks for your inquiry. Best regards, Sarah"

// Problem: Special characters
Original: "Visit our café"
Received: "Visit our caf?"
Solutions:
// Sanitize message content
function sanitizeMessage(content) {
  return content
    .replace(/[^\x00-\x7F]/g, '') // Remove non-ASCII characters
    .replace(/\n\n/g, '\n') // Normalize line breaks
    .trim(); // Remove extra whitespace
}

// Test with different character sets
const testMessages = [
  'Basic ASCII text',
  'Text with émojis 🎉',
  'Multi-line\ntext\nformatting',
  'Special chars: café, naïve, résumé'
];

Rate Limiting and Throttling

Symptoms:
  • Some messages fail with rate limit errors
  • Delays in message processing
  • Inconsistent delivery times
Rate Limits:
  • iOS Shortcuts: ~30 messages per minute
  • GoBlue API: 1,000 requests per hour
  • Carrier Limits: Varies by provider
Solutions:
// Implement proper rate limiting
class RateLimiter {
  constructor(maxPerMinute = 30) {
    this.maxPerMinute = maxPerMinute;
    this.queue = [];
    this.processing = false;
  }
  
  async sendMessage(message) {
    return new Promise((resolve) => {
      this.queue.push({ message, resolve });
      this.processQueue();
    });
  }
  
  async processQueue() {
    if (this.processing || this.queue.length === 0) return;
    
    this.processing = true;
    const startTime = Date.now();
    let processedCount = 0;
    
    while (this.queue.length > 0 && processedCount < this.maxPerMinute) {
      const { message, resolve } = this.queue.shift();
      
      try {
        await this.actualSendMessage(message);
        resolve({ success: true });
      } catch (error) {
        resolve({ success: false, error });
      }
      
      processedCount++;
      
      // Add small delay between messages
      await new Promise(r => setTimeout(r, 2000)); // 2 seconds
    }
    
    this.processing = false;
    
    // If more messages in queue, schedule next batch
    if (this.queue.length > 0) {
      const elapsed = Date.now() - startTime;
      const waitTime = Math.max(0, 60000 - elapsed); // Wait until next minute
      setTimeout(() => this.processQueue(), waitTime);
    }
  }
}

Data and Contact Issues

Contact Creation Problems

Symptoms:
  • Same person appears multiple times in contacts
  • Phone number variations creating separate records
  • Different forms creating duplicate entries
Common Causes:
// Phone number format variations
const variations = [
  '+1234567890',
  '1234567890', 
  '(123) 456-7890',
  '123-456-7890',
  '123.456.7890'
];
// All should be normalized to same format
Prevention:
function normalizePhoneNumber(phone) {
  // Remove all non-digit characters except +
  let normalized = phone.replace(/[^\d+]/g, '');
  
  // Add country code if missing
  if (!normalized.startsWith('+')) {
    if (normalized.length === 10) {
      normalized = '+1' + normalized; // US default
    } else if (normalized.length === 11 && normalized.startsWith('1')) {
      normalized = '+' + normalized;
    }
  }
  
  return normalized;
}

// Use normalized phone as unique identifier
const normalizedPhone = normalizePhoneNumber(webhookData.phoneNumber);
Data Validation:
function validateContactData(data) {
  const errors = [];
  
  // Required fields
  if (!data.phoneNumber) {
    errors.push('Phone number is required');
  }
  
  // Phone number format
  if (data.phoneNumber && !/^\+\d{10,15}$/.test(data.phoneNumber)) {
    errors.push('Invalid phone number format');
  }
  
  // Name validation
  if (data.firstName && data.firstName.length > 50) {
    errors.push('First name too long');
  }
  
  // Email validation
  if (data.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data.email)) {
    errors.push('Invalid email format');
  }
  
  return errors;
}

Data Synchronization Issues

Symptoms:
  • Messages sent but contact status stays “New”
  • Manual status updates not saving
  • Status changes not reflected in reports
Troubleshooting:
// Check if status updates are being sent
async function debugStatusUpdate(contactId, newStatus) {
  try {
    const response = await fetch(`/api/contacts/${contactId}`, {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ status: newStatus })
    });
    
    if (!response.ok) {
      console.error('Status update failed:', response.statusText);
      return false;
    }
    
    const updated = await response.json();
    console.log('Status updated:', updated);
    return true;
  } catch (error) {
    console.error('Status update error:', error);
    return false;
  }
}
Common Fixes:
  • Verify iOS Shortcut is sending status updates
  • Check network connectivity during updates
  • Manually refresh contact list in app

Performance and Scaling Issues

High Volume Processing

Optimization Strategies:
  1. Pagination Implementation:
    async function processLargeContactList(contacts) {
      const pageSize = 50;
      
      for (let i = 0; i < contacts.length; i += pageSize) {
        const page = contacts.slice(i, i + pageSize);
        await processContactPage(page);
        
        // Brief pause to prevent overwhelming system
        await new Promise(resolve => setTimeout(resolve, 1000));
      }
    }
    
  2. Database Query Optimization:
    • Use indexes on frequently queried fields
    • Limit returned fields to necessary data only
    • Implement proper caching strategies
  3. Memory Management:
    • Process contacts in batches
    • Clear processed data from memory
    • Monitor memory usage during operations
Queue Monitoring:
async function monitorQueueHealth() {
  const queueStats = await getQueueStatistics();
  
  const warnings = [];
  
  if (queueStats.queuedMessages > 1000) {
    warnings.push('High queue volume detected');
  }
  
  if (queueStats.averageProcessingTime > 300) { // 5 minutes
    warnings.push('Slow processing detected');
  }
  
  if (queueStats.failureRate > 0.05) { // 5%
    warnings.push('High failure rate detected');
  }
  
  return warnings;
}
Solutions:
  • Increase processing frequency
  • Add additional iOS devices for processing
  • Implement priority queuing
  • Optimize message templates for faster processing

Account and Authentication Issues

API Key Problems

Common Causes:
  1. Expired or Invalid API Key
  2. Incorrect Key Format
  3. Key Not Properly Configured
Diagnostic Steps:
# Test API key validity
curl -I https://api.goblue.app/v1/messages/YOUR_API_KEY

# Expected: 200 OK
# If 401: Invalid API key
# If 403: Key lacks permissions
Solutions:
  1. Regenerate API Key:
    • Open GoBlue app → Settings
    • Tap “Regenerate API Key”
    • Update key in all integrations
  2. Verify Key Format:
    // Correct format
    const apiKey = 'goblue_sk_1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p7q8r9s0t';
    
    // Check format
    if (!apiKey.startsWith('goblue_sk_') || apiKey.length !== 50) {
      throw new Error('Invalid API key format');
    }
    
Limit Types:
  • Monthly message limit
  • Active forms limit
  • API request rate limit
  • Storage limit
Check Usage:
async function checkAccountLimits() {
  const usage = await getAccountUsage();
  
  const warnings = [];
  
  if (usage.messages / usage.messageLimit > 0.9) {
    warnings.push('Approaching monthly message limit');
  }
  
  if (usage.forms >= usage.formLimit) {
    warnings.push('Maximum forms limit reached');
  }
  
  return warnings;
}
Solutions:
  • Upgrade account plan
  • Optimize message efficiency
  • Archive unused forms
  • Implement better targeting to reduce waste

Network and Connectivity Issues

Connection Problems

Symptoms:
  • Some API calls succeed, others fail
  • Timeouts during webhook processing
  • Inconsistent message delivery
Debugging Network Issues:
class NetworkDiagnostics {
  async testConnectivity() {
    const tests = [
      { name: 'GoBlue API', url: 'https://api.goblue.app/health' },
      { name: 'DNS Resolution', url: 'https://8.8.8.8' },
      { name: 'General Internet', url: 'https://google.com' }
    ];
    
    const results = [];
    
    for (const test of tests) {
      const start = Date.now();
      try {
        const response = await fetch(test.url, { 
          method: 'HEAD',
          timeout: 10000 
        });
        
        results.push({
          name: test.name,
          success: response.ok,
          responseTime: Date.now() - start,
          status: response.status
        });
      } catch (error) {
        results.push({
          name: test.name,
          success: false,
          error: error.message,
          responseTime: Date.now() - start
        });
      }
    }
    
    return results;
  }
}
Solutions:
  • Implement retry logic with exponential backoff
  • Use redundant network connections
  • Cache data locally when possible
  • Monitor network quality over time

Getting Additional Help

Information to Gather Before Contacting Support

System Details:
  • iOS version
  • GoBlue app version
  • Shortcuts app version
  • Device model
Error Information:
  • Exact error messages
  • Screenshots of issues
  • Steps to reproduce
  • Frequency of occurrence
Configuration Details:
  • Form IDs experiencing issues
  • API key (last 4 characters only)
  • Webhook URLs being used
  • Message templates causing problems
Volume Information:
  • Number of forms
  • Daily message volume
  • Number of contacts
  • Peak usage times
Integration Details:
  • External systems connected
  • Zapier workflows
  • Custom API integrations
  • Third-party tools used

Self-Service Resources

Support Escalation Process

1

Self-Diagnosis

Use this troubleshooting guide and check status page
2

Community Support

Ask questions in Discord community for peer help
3

Email Support

Contact [email protected] with detailed information
4

Priority Support

Available for Pro and Enterprise plan subscribers

Prevention and Best Practices

Monitoring and Alerting

Set Up Monitoring

  • Track message delivery rates
  • Monitor API response times
  • Watch for error patterns
  • Set up automated alerts

Regular Maintenance

  • Update iOS and apps regularly
  • Clean up old test data
  • Review and optimize workflows
  • Archive unused forms

Testing Strategy

  • Test changes in sandbox first
  • Validate templates before deploying
  • Monitor new integrations closely
  • Have rollback plans ready

Documentation

  • Document your configurations
  • Keep integration details updated
  • Share knowledge with team
  • Maintain troubleshooting logs

Common Prevention Strategies

// Implement comprehensive error handling
class GoBlueIntegration {
  constructor() {
    this.retryAttempts = 3;
    this.retryDelay = 1000; // 1 second
  }
  
  async sendWebhook(data) {
    for (let attempt = 1; attempt <= this.retryAttempts; attempt++) {
      try {
        const response = await this.makeRequest(data);
        
        if (response.ok) {
          return response.json();
        }
        
        if (response.status >= 400 && response.status < 500) {
          // Client error - don't retry
          throw new Error(`Client error: ${response.status}`);
        }
        
        // Server error - might be temporary, retry
        if (attempt < this.retryAttempts) {
          await this.sleep(this.retryDelay * attempt);
          continue;
        }
        
        throw new Error(`Server error after ${attempt} attempts`);
        
      } catch (error) {
        if (attempt === this.retryAttempts) {
          throw error;
        }
        
        await this.sleep(this.retryDelay * attempt);
      }
    }
  }
  
  sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }
}
The key to avoiding issues is implementing proper error handling, monitoring your integrations, and testing changes thoroughly before deploying to production.