message.comDevelopers

AI engagements Planned

AI engagements are the billing primitive for everything AI. One engagement equals one AI interaction across any channel: a chat where the AI drafted at least one reply, a Smart Hold session that engaged the caller, an AI Receptionist call, or an agent-assist suggestion the agent accepted.

This endpoint is on the roadmap. The summary endpoint will ship with the AI substrate; the detailed list endpoint follows shortly after. Shape may change before launch.

Month-to-date summary

GET/api/v1/ai-engagements/summaryAuth: Bearer

Returns the included quota, the used count, the remaining count, and any overage so far this billing period. Broken down by feature.

Code samples

cURL
curl 'https://app.message.com/api/v1/ai-engagements/summary' \
  -H 'Authorization: Bearer YOUR_WORKSPACE_JWT'
JavaScript
const res = await fetch('https://app.message.com/api/v1/ai-engagements/summary', {
  headers: { Authorization: 'Bearer ' + token }
});
const summary = await res.json();
Python
import requests
r = requests.get(
    "https://app.message.com/api/v1/ai-engagements/summary",
    headers={"Authorization": f"Bearer {token}"},
)
summary = r.json()
Ruby
require "net/http"
require "json"
uri = URI("https://app.message.com/api/v1/ai-engagements/summary")
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
  req = Net::HTTP::Get.new(uri)
  req["Authorization"] = "Bearer #{token}"
  http.request(req)
end
summary = JSON.parse(res.body)
PHP
<?php
$ctx = stream_context_create([
  "http" => ["method" => "GET", "header" => "Authorization: Bearer $token"]
]);
$summary = json_decode(file_get_contents("https://app.message.com/api/v1/ai-engagements/summary", false, $ctx), true);
200 OK
{
  "period": { "start": "2026-05-01T00:00:00Z", "end": "2026-05-31T23:59:59Z" },
  "plan": { "includedEngagements": 100, "overagePricePerEngagement": "0.10" },
  "used": 87,
  "remaining": 13,
  "overage": 0,
  "byFeature": {
    "smart_hold": 4,
    "ai_receptionist": 12,
    "agent_assist": 71,
    "ai_chat_reply": 0
  }
}

List engagements

GET/api/v1/ai-engagementsAuth: Bearer

Cursor-paginated list. Filters: feature, billable, conversationId, startedAfter, endedBefore.

Engagement shape

Engagement
{
  "id": "uuid",
  "conversationId": "uuid",
  "kind": "smart_hold",
  "feature": "smart_hold",
  "billable": true,
  "startedAt": "2026-05-13T15:30:00Z",
  "endedAt": "2026-05-13T15:36:00Z",
  "metadata": {
    "callDurationMs": 360000
  }
}

Counted features

FeatureCounts as one engagement when
smart_holdSmart Hold engages a caller waiting on hold above the threshold.
ai_receptionistCaller opts into AI Receptionist (press 1) and the AI handles the call.
ai_chat_replyAI drafted at least one reply on a chat conversation.
agent_assistAgent used at least one AI-generated suggestion in a conversation.

Engagement counts are de-duplicated per conversation per feature. A 10-minute Smart Hold session counts once, not ten times. This is intentional: we charge by interaction, not by token.

Pricing

  • Starter plan: 100 engagements / month included.
  • Overage: $0.10 per engagement, billed at end of cycle.
  • Pro plan: 1000 engagements / month included.
  • Enterprise: custom; usually a flat cap with no overage.

Errors

CodeWhen
403 forbiddenAgent role does not allow viewing billing data (admin or supervisor only).
404 not_foundEngagement does not exist in this workspace.

Common pitfalls

  • Polling the summary endpoint from a public dashboard. The summary changes minute-by-minute under heavy AI use. Cache for 60 seconds on your side.
  • Equating engagements with messages. Engagements are per-feature per-conversation. One conversation with five AI replies is one engagement.
  • Surprise overage. Set up alerts on the summary endpoint to ping ops when remaining drops below 10% of the included quota.