Skip to main content

Overview

Arlo can push real-time notifications to your agent when provider activity occurs. This is optional but strongly recommended — without it, your agent must poll for updates.

register_webhook

Register or update a webhook URL to receive real-time notifications.

Parameters

ParameterTypeRequiredDescription
webhookUrlstringYesURL for notifications (must be publicly accessible)
webhookTokenstringNoBearer token for webhook authentication
deliveryContextobjectNoPlatform-specific context included in webhooks
conversationSessionKeystringNoFor threading webhook notifications
sessionKeystringNoCustom session key (auto-generated if not provided)

Delivery Context

The deliveryContext object is passed through in every webhook payload:
{
  "to": "+15551234567",
  "channel": "whatsapp",
  "deliver": true
}
FieldDescription
toRecipient identifier (e.g., phone number, chat ID)
channelChannel name (e.g., whatsapp, telegram, discord)
deliverWhether to deliver the notification to the user

Validation

Before registration, Arlo validates the webhook URL:
  1. Pattern check — Rejects private IPs, localhost, etc.
  2. Connectivity test — Verifies the URL is reachable
The URL must be publicly accessible. Use ngrok, Cloudflare Tunnel, Tailscale Funnel (.ts.net), or a public server.

Returns

{
  "success": true,
  "webhookUrl": "https://your-agent/hooks/arlo",
  "hasSecret": true,
  "hasDeliveryContext": true,
  "sessionKey": "session_abc123"
}

get_webhook_status

Check webhook status for the authenticated user’s session.

Parameters

ParameterTypeRequiredDescription
sessionKeystringNoCheck a specific session (returns all sessions if omitted)

Returns (Specific Session)

{
  "configured": true,
  "sessionKey": "session_abc123",
  "webhookUrl": "https://your-agent/hooks/arlo",
  "hasSecret": true,
  "hasDeliveryContext": true,
  "conversationSessionKey": "session_xyz",
  "linkedAt": "2025-03-15T10:30:00Z"
}

Returns (All Sessions)

{
  "configured": true,
  "sessionCount": 2,
  "sessions": [
    {
      "sessionKey": "session_abc123",
      "webhookUrl": "https://your-agent/hooks/arlo",
      "hasSecret": true,
      "hasDeliveryContext": true
    },
    {
      "sessionKey": "session_def456",
      "webhookUrl": "https://other-agent/webhooks",
      "hasSecret": false,
      "hasDeliveryContext": false
    }
  ]
}

Webhook Configuration

During init_signup

Webhooks can also be configured during init_signup:
{
  "baseUrl": "https://mcp.arlohealth.ai",
  "webhookUrl": "https://your-agent/hooks/arlo",
  "webhookToken": "your-secret-token",
  "deliveryContext": {
    "to": "+15551234567",
    "channel": "whatsapp",
    "deliver": true
  },
  "conversationSessionKey": "session_xyz"
}

After Authentication

Use register_webhook to configure or update webhooks after the user is authenticated:
{
  "webhookUrl": "https://your-agent/hooks/arlo",
  "webhookToken": "your-secret-token",
  "deliveryContext": {
    "to": "+15551234567",
    "channel": "whatsapp",
    "deliver": true
  },
  "conversationSessionKey": "session_xyz"
}
If init_signup is called without webhookUrl, any existing webhook configuration is preserved.

Webhook Payload

All notifications are sent as POST {webhookUrl} with:

Headers

Authorization: Bearer <webhookToken>
Content-Type: application/json

Body

{
  "text": "[Arlo] You have a new message from your healthcare provider.",
  "mode": "now",
  "conversationId": "conv_abc123",
  "deliveryContext": {
    "to": "+15551234567",
    "channel": "whatsapp",
    "deliver": true
  },
  "conversationSessionKey": "session_xyz"
}
FieldDescription
textHuman-readable notification message
modeAlways now
conversationIdThe conversation ID (when applicable)
deliveryContextYour original delivery context (passed through)
conversationSessionKeyYour session key (for threading)

Notification Types

Eventtext value
Provider sent a message[Arlo] You have a new message from your healthcare provider. Check the consultation for their response.
AI triage responded[Arlo] The AI triage assistant has responded. Check the consultation for updates.
Provider connected[Arlo] Your consultation is now active.
Consultation closed[Arlo] Your consultation has been closed.
Auth completed[Arlo] <UserName> has successfully connected to Arlo Health.
Security note: Notification payloads never include message content. Your agent should fetch the full context from the API after receiving a webhook. This prevents prompt injection from untrusted provider input.

Verifying Requests

Always validate the Authorization header matches your webhookToken:
app.post("/hooks/arlo", (req, res) => {
  const token = req.headers.authorization?.replace("Bearer ", "");

  if (token !== process.env.ARLO_WEBHOOK_SECRET) {
    return res.status(401).json({ error: "Unauthorized" });
  }

  // Process notification
  const { consultationId, text } = req.body;

  // Acknowledge immediately
  res.status(200).json({ received: true });

  // Then fetch full context
  processNotification(consultationId);
});

Handling Notifications

When a notification arrives:
  1. Acknowledge immediately with 200 OK — Arlo does not wait for processing
  2. Fetch the consultation to get the latest messages
  3. Read the most recent message and decide how to respond
  4. Do not include raw provider message text in your agent’s context — fetch it through the API where it is wrapped with safety boundaries

Example Handler

async function processNotification(consultationId) {
  // Fetch full consultation status
  const status = await getConsultationStatus({
    conversationId: consultationId,
    includeMessages: true
  });

  // Get the latest message
  const latestMessage = status.messages[status.messages.length - 1];

  if (latestMessage.sender === "provider") {
    // Provider sent a message - notify user and/or respond
    await notifyUser(latestMessage.content);
  }

  if (status.status === "CLOSED") {
    // Consultation ended - get clinical notes
    const notes = await getConsultationNotes({
      conversationId: consultationId
    });
    await sendSummaryToUser(notes);
  }
}

Re-authentication

If a session expires and the user re-authenticates:
  • init_signup must be called again with webhook params to re-register the URL
  • If init_signup is called without webhookUrl, the existing webhook config is preserved

Troubleshooting

Webhook not receiving notifications

  1. Verify URL is publicly accessible (not localhost or VPN)
  2. Check that HTTPS is enabled
  3. Verify the URL responds with 200 status
  4. Use get_webhook_status to verify the webhook is configured

Invalid signature errors

  1. Verify webhookToken matches what was passed to register_webhook or init_signup
  2. Check for URL encoding issues in the token
  3. Ensure you’re comparing the raw token, not base64 encoded

Missed notifications

  1. Notifications are not retried on failure
  2. Ensure your endpoint responds quickly (< 5 seconds)
  3. Process notifications asynchronously after acknowledging