Shared Inbox Links

Shared inbox links let you expose one phone number's inbox to an external user through a public URL, without giving them your organization API key or admin access.

Each link is scoped to exactly one phoneNumberId, can be permanent or expiring, and carries fine-grained permissions for reading and replying.


Typical Flow

  1. Your server creates a shared inbox link with POST /v1/shared-inbox-links
  2. The API returns a publicUrl
  3. You send that URL to the external user
  4. The user opens the URL in the inbox frontend
  5. The frontend exchanges the public token for a short-lived shared session
  6. The user works inside /shared/inbox with only the permissions granted by the link

You do not need to generate tokens manually. Use the publicUrl returned by the API.


Create a Shared Inbox Link

curl -X POST https://api.example.com/v1/shared-inbox-links \
  -H "Authorization: Bearer sk_org_..." \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumberId": "660e8400-e29b-41d4-a716-446655440001",
    "name": "Support vendor access",
    "expiresAt": "2026-04-01T00:00:00.000Z",
    "permissions": {
      "readInbox": true,
      "readDetails": true,
      "markRead": true,
      "sendText": true,
      "sendMedia": false,
      "sendTemplates": true,
      "sendAdvanced": false
    }
  }'

Request Fields

Field Type Required Description
phoneNumberId UUID Yes Internal phone UUID whose inbox will be shared
name string Yes Display name for the shared link
expiresAt ISO datetime or null No When omitted or null, the link does not expire
permissions object Yes Fine-grained permission set for the shared inbox

Permissions

Permission Description
readInbox List conversations and read messages
readDetails View business/profile details and media side panels
markRead Mark inbound messages as read
sendText Send plain text replies
sendMedia Upload and send image, video, audio, document, sticker
sendTemplates List and send WhatsApp templates
sendAdvanced Send interactive, flow, and CTA URL messages

Response

{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "organizationId": "440e8400-e29b-41d4-a716-446655440000",
    "phoneNumberId": "660e8400-e29b-41d4-a716-446655440001",
    "phoneNumber": "+5491155551234",
    "name": "Support vendor access",
    "publicUrl": "https://inbox.example.com/shared/inbox/sil_550e8400-e29b-41d4-a716-446655440999.signature",
    "permissions": {
      "readInbox": true,
      "readDetails": true,
      "markRead": true,
      "sendText": true,
      "sendMedia": false,
      "sendTemplates": true,
      "sendAdvanced": false
    },
    "status": "active",
    "expiresAt": "2026-04-01T00:00:00.000Z",
    "revokedAt": null,
    "lastUsedAt": null,
    "createdAt": "2026-03-24T10:00:00.000Z",
    "updatedAt": "2026-03-24T10:00:00.000Z"
  }
}

Send the returned publicUrl to the person who should access the inbox.


Common Presets

Read-only inbox

{
  "readInbox": true,
  "readDetails": true,
  "markRead": false,
  "sendText": false,
  "sendMedia": false,
  "sendTemplates": false,
  "sendAdvanced": false
}

Standard reply inbox

{
  "readInbox": true,
  "readDetails": true,
  "markRead": true,
  "sendText": true,
  "sendMedia": true,
  "sendTemplates": true,
  "sendAdvanced": false
}

Full composer

{
  "readInbox": true,
  "readDetails": true,
  "markRead": true,
  "sendText": true,
  "sendMedia": true,
  "sendTemplates": true,
  "sendAdvanced": true
}

List Shared Inbox Links

curl "https://api.example.com/v1/shared-inbox-links?phoneNumberId=660e8400-e29b-41d4-a716-446655440001&status=active" \
  -H "Authorization: Bearer sk_org_..."

Supported filters:


Get One Shared Inbox Link

curl https://api.example.com/v1/shared-inbox-links/{sharedInboxLinkId} \
  -H "Authorization: Bearer sk_org_..."

Use this when you need the current publicUrl, permissions, status, or last usage timestamp.


Update a Shared Inbox Link

You can update the display name, expiration date, and permissions.

curl -X PATCH https://api.example.com/v1/shared-inbox-links/{sharedInboxLinkId} \
  -H "Authorization: Bearer sk_org_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Support vendor access - Q2",
    "expiresAt": null,
    "permissions": {
      "readInbox": true,
      "readDetails": true,
      "markRead": true,
      "sendText": true,
      "sendMedia": true,
      "sendTemplates": true,
      "sendAdvanced": false
    }
  }'

Changes apply to future requests immediately. Existing shared sessions are revalidated against the link on every request.


Rotate the Public URL

Rotating a link generates a new publicUrl without changing the link ID.

curl -X POST https://api.example.com/v1/shared-inbox-links/{sharedInboxLinkId}/rotate \
  -H "Authorization: Bearer sk_org_..."

Use this if the old URL was exposed to the wrong person.

Rotation changes the public URL, but existing shared sessions continue working until they expire or the link is revoked.


Revoke a Shared Inbox Link

curl -X DELETE https://api.example.com/v1/shared-inbox-links/{sharedInboxLinkId} \
  -H "Authorization: Bearer sk_org_..."

Revocation is immediate. Existing shared sessions stop working on the next request.

This is a soft revoke, not a hard delete.


Public Access vs API Access

If you are building your own frontend, you can reproduce the same flow:

  1. open the publicUrl
  2. exchange the sil_... token
  3. store the returned shared session token
  4. use that session token as Authorization: Bearer sis_... for shared inbox frontend calls

Related Guides