Approval API

Request user confirmation before performing sensitive actions.

⚠️ Required for: messages.send(), calendar.createEvent(), and other write operations.

approval.request()

Request user approval for an action. Returns after user approves or denies.

Parameters

ParameterTypeRequiredDescription
actionstringYesAction type (e.g., "send_message")
titlestringYesShort approval title
descriptionstringYesDetailed explanation of action
detailsobjectNoAdditional context (recipients, etc.)

Returns

{
  approved: true,        // or false if denied
  approvalId: "appr_abc123",
  timestamp: "2024-03-15T14:30:00Z"
}

Example: Message Approval

const approval = await tools.approval.request({
  action: "send_message",
  title: "Send quarterly report",
  description: "Send Q4 report to team@company.com",
  details: {
    to: ["team@company.com"],
    subject: "Q4 2024 Report",
    preview: "Attached is the quarterly report for review..."
  }
});

if (!approval.approved) {
  return {
    type: "error",
    title: "Message not sent",
    description: "You declined the approval."
  };
}

// Proceed with action
await tools.messages.send({ ... });

Example: Calendar Event Approval

const approval = await tools.approval.request({
  action: "create_calendar_event",
  title: "Schedule team meeting",
  description: "Create recurring weekly standup meeting",
  details: {
    title: "Team Standup",
    start: "2024-03-20T09:00:00Z",
    end: "2024-03-20T09:30:00Z",
    attendees: ["team@company.com"],
    recurrence: "weekly"
  }
});

if (approval.approved) {
  await tools.calendar.createEvent({ ... });
}

User Interface

When you call approval.request(), METAOS shows the user a modal with:

📋

Title

Your approval title

📝

Description

Detailed explanation of what will happen

🔍

Details

Formatted preview of action parameters

Best Practices

✓ Be Specific

Clearly describe what the action will do and who it will affect.

❌ "Send email"
✅ "Send Q4 report to 3 team members"

✓ Include Preview

Show message content, event details, or file previews in details object.

details: { preview: "Message: Hey team, here's...", to: ["alice@company.com"] }

✓ Handle Denials

Always check approval.approved and return gracefully if false.

if (!approval.approved) { return { type: "error", title: "Action cancelled" }; }

✓ One Approval Per Action

Don't request approval for every individual step. Batch related actions into a single approval request.

Complete Example

export async function handleIntent({ intent, context, tools }) {
  if (intent.action === "schedule_and_notify") {
    // Step 1: Find available time
    const events = await tools.calendar.listEvents({
      start: context.now,
      end: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString()
    });

    // Step 2: Request approval for BOTH actions
    const approval = await tools.approval.request({
      action: "schedule_and_notify",
      title: "Schedule meeting and notify team",
      description: "Create calendar event and send email to 3 attendees",
      details: {
        event: {
          title: "Product Review",
          start: "2024-03-22T14:00:00Z",
          attendees: ["alice@co.com", "bob@co.com", "carol@co.com"]
        },
        notification: {
          subject: "Product Review - Friday 2pm",
          body: "Please join us for the product review..."
        }
      }
    });

    if (!approval.approved) {
      return {
        type: "error",
        title: "Cancelled",
        description: "Meeting not created."
      };
    }

    // Step 3: Execute both actions
    try {
      await tools.calendar.createEvent({
        title: "Product Review",
        start: "2024-03-22T14:00:00Z",
        end: "2024-03-22T15:00:00Z",
        attendees: ["alice@co.com", "bob@co.com", "carol@co.com"]
      });

      await tools.messages.send({
        to: ["alice@co.com", "bob@co.com", "carol@co.com"],
        subject: "Product Review - Friday 2pm",
        body: "Please join us for the product review on Friday at 2pm."
      });

      return {
        type: "result",
        title: "✅ All done",
        description: "Meeting scheduled and team notified"
      };
    } catch (error) {
      return {
        type: "error",
        title: "Failed",
        description: error.message
      };
    }
  }
}

🔐 Security Note

Approval requests are logged and auditable. METAOS tracks which agent requested which approvals, and users can review their approval history in Settings → Privacy & Security.