Dynamic Call Configuration: Pre-call webhooks allow you to fetch customer data, account information, and contextual details in real-time before each call starts.

Overview

Showing the configuration for pre-call webhook Pre-call webhooks enable bidirectional communication between Openmic and your systems. When a call is about to begin, Openmic sends call details to your webhook endpoint, and your system responds with dynamic variables that customize the call experience.

Real-time Data Injection

Fetch customer details, account status, and contextual information from your systems before the call starts

Personalized Conversations

Use dynamic variables to personalize agent responses and call flows based on caller information

When Pre-call Webhooks Trigger

Pre-call webhooks respect the webhook_direction configuration setting:

Both

Triggered for all inbound and outbound calls

Inbound

Only triggered for incoming calls to your agents

Outbound

Only triggered for calls initiated by your agents
If no webhook URL is configured or the webhook direction doesn’t match the call direction, the call proceeds without dynamic variables.

Request Specification

HTTP Method and Timeout

Openmic sends a POST request to your configured webhook URL with:
  • Content-Type: application/json
  • Timeout: 3 seconds per attempt
  • User-Agent: Openmic-Webhook/1.0
If all webhook attempts fail, the call will end. Please read failure handling for more info.

Request Payload

{
	"event": "call",
	"call": {
		"direction": "outbound",
		"bot_id": "cmdx5w8oc0005q671s3cbg063",
		"from_number": "+16167948654",
		"to_number": "+916297653534",
		"attempt": "2"
	}
}

Payload Fields

FieldTypeRequiredDescription
eventstringYesAlways "call" for pre-call webhooks
call.directionstringYesCall direction: "inbound" or "outbound"
call.bot_idstringYesUnique identifier for the bot/session
call.from_numberstringYesCaller’s phone number in E.164 format
call.to_numberstringYesCallee’s phone number in E.164 format
call.attemptstringYesAttempt number of the webhook

Expected Response

Success Response

Your webhook must return a 200 status code with a JSON response containing dynamic variables:
{
	"call": {
		"dynamic_variables": {
			"customer_name": "John Doe",
			"account_balance": "1,250.50",
			"subscription_status": "premium",
			"last_purchase_date": "2024-07-15",
			"support_tier": "gold",
			"preferred_language": "english"
		}
	}
}

Response Structure

FieldTypeRequiredDescription
callobjectYesContainer for call-related data
call.dynamic_variablesobjectYesKey-value pairs of variables to inject into the call
Variable Usage: Dynamic variables can be referenced in your agent prompts using template syntax like {{ customer_name }}.

Retry Logic and Error Handling

Retry Configuration

Max Attempts

3 total attempts 1 initial request + 2 retries

Timeout

3 seconds Per individual request attempt

Backoff Strategy

Exponential delays 1s, 2s, 3s between retries

Retry Triggers

Openmic retries your webhook in these scenarios:
  • Timeout: No response within 3 seconds
  • HTTP Errors: 4xx or 5xx status codes
  • Network Errors: Connection failures or DNS resolution issues
  • Invalid JSON: Malformed response body

Failure Handling

If all webhook attempts fail, the call will terminate.
To avoid an incomplete or awkward conversation caused by missing dynamic variables, the default behavior is to end the call after all retry attempts are exhausted. If you want the call to proceed even after repeated webhook failures, implement the following safeguard:
  • Track the "attempt" field included in each webhook request payload.
  • On the third attempt (final retry), return an empty JSON object for the dynamic variables.
Example response to allow the call to continue without injected variables:
{
	"call": {
		"dynamic_variables": {}
	}
}
When using this approach, ensure your agent prompts handle missing variables gracefully.

Examples

// Example CRM lookup function
async function getCustomerData(phoneNumber) {
  // Pretend we're calling an internal CRM API or DB
  return {
    customer_name: 'Alice Chen',
    account_balance: '3452.75',
  };
}

app.post('webhook/pre-call', async (req, res) => {
  const { call } = req.body;
  console.log('📞 Pre-call webhook received:', call);
  try {
    // Pull customer data based on from_number
    const customerData = await getCustomerData(call.from_number);
    // Return dynamic variables in correct format
    res.json({
      call: {
        dynamic_variables: customerData
      }
    });
  } catch (err) {
    console.error('❌ Failed to fetch customer data', err);
    // If this is the 3rd attempt, return empty variables to allow call
    if (parseInt(call.attempt, 10) === 3) {
      return res.json({
        call: {
          dynamic_variables: {}
        }
      });
    }
    // Any other attempt = fail (will trigger retry)
    res.status(500).json({ error: 'Failed to fetch call data' });
  }
});

Testing and Debugging