daimon.email
Api referenceAccount

Notify Operator

Request operator intervention with a magic action link

Authentication

Account API Key required via Authorization: Bearer {api_key} header.

Overview

This endpoint allows AI agents to autonomously request help from their human operator for any issue - not just upgrades. It generates a JWT-signed magic link that takes the operator to a pre-filled action page.

Request Body

issuestringbodyrequired

Description of the issue or request (1-1000 characters)

contextobjectbody

Optional structured context about the issue. Can include any JSON-serializable data.

action_labelstringbody

Custom button text for the action link (default: "Review Request")

curl -X POST https://api.daimon.email/v1/notify-operator \
  -H "Authorization: Bearer dm_free_7d8a9b0c1d2e3f4g5h6i7j8k9l0m1n2o" \
  -H "Content-Type: application/json" \
  -d '{
    "issue": "Unable to send confirmation email - sending requires paid tier",
    "context": {
      "attempted_action": "send_email",
      "recipient": "user@example.com",
      "blocked_by": "SEND_REQUIRES_PAID"
    },
    "action_label": "Upgrade to Enable Sending"
  }'
import { DaimonClient } from 'daimon-email';

const client = new DaimonClient({
  apiKey: 'dm_free_7d8a9b0c1d2e3f4g5h6i7j8k9l0m1n2o'
});

const notification = await client.account.notifyOperator({
  issue: 'Unable to send confirmation email - sending requires paid tier',
  context: {
    attempted_action: 'send_email',
    recipient: 'user@example.com',
    blocked_by: 'SEND_REQUIRES_PAID'
  },
  actionLabel: 'Upgrade to Enable Sending'
});

console.log('Operator notification created:');
console.log(notification.agent_script);
// Output: "Tell your operator: Unable to send confirmation email..."
from daimon_email import DaimonClient

client = DaimonClient(api_key='dm_free_7d8a9b0c1d2e3f4g5h6i7j8k9l0m1n2o')

notification = client.account.notify_operator(
    issue='Unable to send confirmation email - sending requires paid tier',
    context={
        'attempted_action': 'send_email',
        'recipient': 'user@example.com',
        'blocked_by': 'SEND_REQUIRES_PAID'
    },
    action_label='Upgrade to Enable Sending'
)

print('Operator notification created:')
print(notification.agent_script)
# Output: "Tell your operator: Unable to send confirmation email..."

Response

{
  "result": {
    "operator_action_url": "https://daimon.email/operator/action?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "operator_action_label": "Upgrade to Enable Sending",
    "agent_script": "Tell your operator: Unable to send confirmation email - sending requires paid tier. Here's a direct action link: https://daimon.email/operator/action?token=eyJhbGc...",
    "notification_id": "not_xyz789",
    "expires_at": "2024-03-18T14:23:45Z"
  },
  "next_steps": [
    "Share operator_action_url with your operator via Slack, email, or UI",
    "Use agent_script as a ready-made message template",
    "Link is valid for 7 days",
    "Operator can view issue details and take action without logging in"
  ]
}

Response Fields

operator_action_urlstring

JWT-signed magic link for the operator. Takes them to a page with issue details and suggested actions.

operator_action_labelstring

Button text for the action (from request or default)

agent_scriptstring

Ready-made message the agent can use to notify the operator. Includes the issue description and action URL.

notification_idstring

Unique notification identifier (prefix: not_)

expires_atstring

ISO 8601 timestamp when link expires (7 days from creation)

Use Cases

Request Tier Upgrade

await client.account.notifyOperator({
  issue: 'I need sending access to complete the onboarding flow',
  context: { required_feature: 'send_messages' },
  actionLabel: 'Upgrade to Developer Tier'
});

Report Webhook Failure

await client.account.notifyOperator({
  issue: 'Webhook endpoint has been unhealthy for 2 hours',
  context: {
    webhook_id: 'wh_xyz789',
    failure_count: 12,
    last_error: 'Connection timeout'
  },
  actionLabel: 'View Webhook Settings'
});

Request Custom Domain

await client.account.notifyOperator({
  issue: 'I need to use emails@example.com instead of @daimon.email',
  context: {
    requested_domain: 'example.com',
    reason: 'Brand consistency for customer communications'
  },
  actionLabel: 'Set Up Custom Domain'
});

Account Under Review

await client.account.notifyOperator({
  issue: 'Account is under review - operations are restricted',
  context: {
    account_status: 'under_review',
    bounce_rate: 6.2,
    review_reason: 'High bounce rate'
  },
  actionLabel: 'Contact Support'
});

Agent Integration Pattern

Use this endpoint whenever the agent encounters an issue that requires human intervention:

async function handleOperatorIntervention(
  client: DaimonClient,
  issue: string,
  context?: any
): Promise<void> {
  const notification = await client.account.notifyOperator({
    issue,
    context
  });

  // Send to Slack
  await slack.postMessage({
    channel: '#agent-alerts',
    text: notification.agent_script
  });

  // Or display in UI
  console.log(notification.agent_script);

  // Throw to halt agent execution
  throw new Error('Operator intervention required');
}

// Example usage
try {
  await client.inboxes.send(messageData);
} catch (error) {
  if (error.code === 'SEND_REQUIRES_PAID') {
    await handleOperatorIntervention(client, error.message, {
      error_code: error.code,
      attempted_action: 'send_email'
    });
  }
}

When the operator clicks the link, they see:

  • Issue description from the issue field
  • Context data displayed as formatted JSON
  • Suggested actions based on the issue type
    • For tier limits: Direct Stripe checkout link
    • For webhook issues: Link to webhook settings
    • For account review: Contact support form
  • Account details (tier, usage, status)

Security

  • Links are JWT-signed and expire after 7 days
  • Links are account-specific and cannot be transferred
  • Context data is encrypted at rest
  • No sensitive data (API keys, passwords) should be included in context

Error Responses

400error

Invalid request - issue must be 1-1000 characters

401error

Invalid or missing API key

Warning

Do not include secrets: Never put API keys, passwords, or other sensitive data in the issue or context fields. These are displayed to the operator in plaintext.

Info

Rate limiting: This endpoint is rate-limited to 10 requests per hour per account to prevent spam. Use it for genuine operator intervention needs.

  • POST /v1/upgrade-link - Specialized endpoint for tier upgrades
  • GET /v1/capabilities - Check what the agent can/cannot do
  • GET /v1/account - View account status and health