VitrinaAPI

Check and disconnect channels

Read a workspace's messaging channels, check their health, and disconnect them.

GET /messaging-accounts lists the messaging accounts connected to the workspace, among them a WhatsApp number, a mailbox or an Instagram account. This chapter covers that read half plus disconnect. Connecting a new channel isn't here. Every provider wants an OAuth consent screen, a QR code or a credentials form that no script can fill in by itself, so that half stays an app flow.

Reading needs messaging_accounts:read; disconnecting, messaging_accounts:write. secrets always comes back redacted: the real key survives in the response, with <redacted> standing in for its value.

See the connected channels

curl https://api.vitrinadev.com/api/v1/messaging-accounts \
  -H "Authorization: Bearer $VITRINA_KEY"
{
  "data": [
    {
      "id": "e4e4e4e4-0000-4000-8000-000000000001",
      "tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
      "name": "Sales mailbox",
      "kind": "email_atribu",
      "channels": ["email"],
      "config": { "connected_via": "atribu_partner" },
      "secrets": { "atribu_access_token": "<redacted>" },
      "enabled": true,
      "default_team_id": "cccccccc-0000-4000-8000-000000000001",
      "assignment_mode": "auto_round_robin",
      "assignee_user_ids": [],
      "created_at": "2026-01-10T13:00:00.000Z",
      "updated_at": "2026-09-10T13:00:00.000Z"
    }
  ],
  "meta": { "total": 1 }
}

Live health

curl https://api.vitrinadev.com/api/v1/messaging-accounts/e4e4e4e4-0000-4000-8000-000000000001/health \
  -H "Authorization: Bearer $VITRINA_KEY"

This dials right now and doesn't read the last stored snapshot. stored rides along, with the picture the periodic checker left, so you can compare it against what was already known:

{
  "data": {
    "channel": "email",
    "kind": "email_atribu",
    "connected_via": "atribu_partner",
    "identity": { "display_name": "[email protected]" },
    "webhook": { "status": "delivering", "last_event_at": "2026-09-15T18:20:00.000Z" },
    "whatsapp": null,
    "stored": { "status": "ok", "checked_at": "2026-09-15T18:00:00.000Z" }
  }
}

whatsapp only carries anything (quality_rating, messaging_limit) when kind is whatsapp_cloud; on any other channel it's null. If the check itself fails, with the provider down or the token expired, the answer is still 200, and the failure is reported on identity or on webhook. ?refresh=true forces a fresh probe instead of the provider's cache.

Trap

The response changes with how the channel is connected

The shape of the response isn't uniform across providers. Keep that in mind if you're building something on /health.

connected_viaidentitywebhook
atribu_partner, the managed connectionResolved live against the providerReal
direct, a manual IMAP/SMTP mailboxBuilt from what the connect flow storedAlways null

The managed connection carries WhatsApp, Instagram, Gmail and Outlook email, and Google Calendar. A manual mailbox has no provider webhook to monitor, which is why that field comes back empty. Instagram, Messenger and TikTok work today only through the managed connection; there's no manual-credentials form for them the way there is for IMAP email.

Disconnect

curl -X DELETE https://api.vitrinadev.com/api/v1/messaging-accounts/e4e4e4e4-0000-4000-8000-000000000001 \
  -H "Authorization: Bearer $VITRINA_KEY"

204, no body. The provider-side subscription is torn down first, best-effort, which is a no-op on a channel that has none. Then the local row is deleted. Every conversation, message and lead the channel already produced is untouched.

Per-channel traffic

curl https://api.vitrinadev.com/api/v1/messaging-accounts/stats \
  -H "Authorization: Bearer $VITRINA_KEY"

You get one row per channel with traffic in the last 30 days. A channel with no messages is absent rather than present with zeros:

{
  "data": [
    {
      "messaging_account_id": "e4e4e4e4-0000-4000-8000-000000000001",
      "conversations_total": 128,
      "messages_30d": 640,
      "inbound_30d": 410,
      "outbound_30d": 230,
      "last_message_at": "2026-09-15T18:20:00.000Z"
    }
  ]
}

The Channels reference has the field-by-field contract for this read surface and for disconnect.

On this page