Atlas
Guides

Sharing Conversations

Share Atlas conversations via public or org-scoped links with configurable expiry.

Atlas lets you share conversations via links with configurable expiry and access controls. Public shares are visible to anyone with the link. Organization-scoped shares require authentication. Shared conversations include rich OpenGraph metadata for social previews.

Prerequisites

  • Internal database (DATABASE_URL) — conversation history and sharing are unavailable without it

From the UI

  1. Open a conversation in the Atlas chat interface.
  2. Click the Share button in the conversation header.
  3. Choose an expiry duration (1 hour, 24 hours, 7 days, 30 days, or never).
  4. Optionally toggle Organization only to restrict access to authenticated users.
  5. Click Create share link — Atlas generates a unique share link. Copy it to your clipboard.

The share dialog also provides an iframe embed snippet for embedding the conversation in other pages.

To revoke a shared link, open the share dialog again and click Remove share link. The public link will immediately stop working.

From the API

Create and revoke share links programmatically:

# Share a conversation (with expiry and share mode)
curl -X POST https://your-atlas-api.example.com/api/v1/conversations/{id}/share \
  -H "Authorization: Bearer your-api-key" \
  -H "Content-Type: application/json" \
  -d '{"expiresIn": "7d", "shareMode": "public"}'

# Response:
# {
#   "token": "abc123...",
#   "url": "https://your-atlas-api.example.com/shared/abc123...",
#   "expiresAt": "2026-03-19T00:00:00.000Z",
#   "shareMode": "public"
# }

Available expiresIn values: "1h", "24h", "7d", "30d", "never" (default: "never").

Available shareMode values: "public" (anyone with link), "org" (authenticated users only).

# Revoke sharing
curl -X DELETE https://your-atlas-api.example.com/api/v1/conversations/{id}/share \
  -H "Authorization: Bearer your-api-key"

From the SDK

import { createAtlasClient } from "@useatlas/sdk";

const atlas = createAtlasClient({
  baseUrl: "https://your-atlas-api.example.com",
  apiKey: "your-api-key",
});

// Generate a share link (options like expiresIn and shareMode are available via the REST API)
const { token, url } = await atlas.conversations.share("conversation-id");

// Revoke the share link — it stops working immediately
await atlas.conversations.unshare("conversation-id");

Public View

Shared conversations are visible at /shared/{token}. The page displays:

  • Header — Atlas branding, "Shared conversation" label, and creation date
  • Conversation title — derived from the first user message
  • Messages — user and assistant messages rendered in a clean, read-only format (system and tool messages are hidden)

No authentication is required to view a shared conversation. The public endpoint has its own rate limiter to prevent abuse. Assistant messages containing only non-text parts (such as tool call results) will appear empty in the shared view.

OpenGraph & Social Previews

Shared conversation pages include OpenGraph and Twitter Card metadata for rich social previews when links are shared on Slack, Twitter, LinkedIn, etc.

Meta TagValue
og:titleFirst user message (truncated to 60 characters), e.g. "Atlas: What were our top 10 customers by revenue?"
og:descriptionFirst assistant response (truncated to 160 characters)
og:typearticle
og:site_nameAtlas
twitter:cardsummary

When the conversation has no user messages, the title falls back to the conversation title or "Atlas — Shared Conversation". When the assistant response is only tool calls (no text), the description uses a generic fallback.

Iframe Embedding

Embed a shared conversation in another page using the /embed variant:

<iframe
  src="https://your-atlas-app.example.com/shared/{token}/embed"
  title="Atlas Conversation"
  style="width: 100%; height: 500px; border: 1px solid #e4e4e7; border-radius: 8px;"
></iframe>

The embed view is a compact, chromeless version of the shared conversation — no header, smaller avatars, and a "Powered by Atlas" footer. It supports both light and dark modes (follows system preference).

This is ideal for embedding conversation transcripts in documentation, blog posts, or dashboards.

API Reference

Share

POST /api/v1/conversations/:id/share

Generates a cryptographically random share token and returns the public URL. Requires authentication. If the conversation is already shared, a new token replaces the old one.

Request body (optional):

{
  "expiresIn": "7d",
  "shareMode": "public"
}
FieldTypeDefaultDescription
expiresIn"1h" | "24h" | "7d" | "30d" | "never""never"When the link expires
shareMode"public" | "org""public"public = anyone with link; org = authenticated users only

Response:

{
  "token": "abc123...",
  "url": "https://your-atlas-api.example.com/shared/abc123...",
  "expiresAt": "2026-03-19T00:00:00.000Z",
  "shareMode": "public"
}

Unshare

DELETE /api/v1/conversations/:id/share

Revokes the share token. The public link stops working immediately. Returns 204 No Content on success.

View Shared Conversation

GET /api/public/conversations/:token

Returns the conversation with messages. Public shares require no authentication. Organization-scoped shares (shareMode: "org") require authentication — unauthenticated requests receive 403. Expired links return 410 Gone. Rate-limited per IP (60 requests per minute).

Response:

{
  "title": "Revenue Analysis",
  "surface": "web",
  "createdAt": "2026-03-12T00:00:00Z",
  "messages": [
    {
      "role": "user",
      "content": "What was last month's revenue?",
      "createdAt": "2026-03-12T00:00:01Z"
    },
    {
      "role": "assistant",
      "content": "Last month's revenue was $1.2M...",
      "createdAt": "2026-03-12T00:00:02Z"
    }
  ]
}

Security

  • Tokens are random — share tokens are 28-character base64url strings generated with crypto.randomBytes(21). They cannot be guessed.
  • Expiry enforcement — expired links are checked on every access (not just at creation). Expired tokens return 410 Gone. A background cleanup task also removes expired tokens from the database hourly.
  • Organization-scoped sharing — links with shareMode: "org" require the viewer to be authenticated. Unauthenticated requests receive 403.
  • Revocation is instant — unsharing clears the token from the database. Cached responses (Next.js 60s revalidate) will expire shortly after.
  • No write access — shared conversation views are completely read-only. Viewers cannot modify or interact with the conversation.
  • Rate limited — the public endpoint has a per-IP rate limiter (60 requests per minute, separate from the authenticated rate limiter) to prevent scraping.

Troubleshooting

Share button doesn't appear

Cause: Conversation sharing requires an internal database (DATABASE_URL). Without it, conversation history and sharing are unavailable.

Fix: Set DATABASE_URL to a PostgreSQL connection string and restart the server. The share button appears in the conversation header once the internal database is connected.

Cause: The share link has expired. Links have a configurable expiry (1 hour to 30 days, or never).

Fix: Create a new share link with a longer expiry. When sharing via the API, set expiresIn to "never" for permanent links, or "30d" for longer-lived ones.

Social preview shows generic title

Cause: The conversation has no user messages, or the first assistant response contains only tool calls (no text). OpenGraph metadata falls back to generic values in these cases.

Fix: Ensure the conversation has at least one user message before sharing. The OG title is derived from the first user message (truncated to 60 characters).

For more, see Troubleshooting.

On this page