# Get Shared Thread

Opens a thread **share link** by its slug and returns the shared conversation thread (read-only) plus whether the caller may import-and-fork or join it live. The slug — taken from the share URL — is the capability: knowing the underlying thread id is not enough. The link resolves only for active members of the thread's organization; for `explicit` links, only users explicitly granted access can resolve it. Anyone else gets a `404`. A revoked or expired link returns a validation error (`422`).

### The link's own creator and the thread's owner

Nobody appears in their own grant list, so the person who **created** the link — and the **owner** of the shared thread — resolve it without being in `grant_user_ids`. Opening your own share URL (from a bookmark, a notification, or your own copy of the link) returns the conversation rather than a dead link.

That entitlement is re-checked on every call, not inherited from having made the link: a creator who has since lost access to the underlying thread (their space grant was removed, or they left the organization) gets the same uniform `404` as anyone else, and a creator left with only **view**-level access to the thread's space cannot resolve a `live` or `fork` link. The thread's owner is entitled at any access level. A revoked or expired link still returns `422` for them, exactly as it does for a grantee.

Because the owner already has full access to their own thread, [joining](/api-reference/shared-threads/join-shared-thread) their own live link succeeds but records no join — the thread stays an owned thread, never a joined one.

### Guest members

A **guest** member (a restricted member who can reach only resources explicitly shared with them) is **not** admitted by an organization-wide link on its own — an org-wide link grants "anyone in the org", which a guest is deliberately excluded from. A guest resolves such a link only when they are separately, directly entitled to the underlying thread: they own it, or they belong to a space they can access that contains the thread. In that case the link resolves for them exactly as it would for any member. Access level still applies: a guest reached via a space needs **edit**-level (co-working) access to that space to open a `live` or `fork` link (a write/co-working capability); **view**-level space access resolves only a read-only `view` link. A guest with no such direct entitlement continues to get the uniform `404`.

### When a link stops working

A caller the link was actually given to is told **why** it no longer opens, so the client can show "Dana deleted this chat" instead of a generic dead link. The reason is in the error's `details`, on the status the route has always used for that case:

| `details.unavailable_reason` | Status | Meaning |
|  --- | --- | --- |
| `thread_deleted` | `404` | The thread's owner deleted the conversation. |
| `share_revoked` | `422` | The link was revoked by someone with edit access to the conversation. Who revoked it is not recorded, so do not attribute it to the owner. |
| `share_expired` | `422` | The link passed its expiry time. |
| `org_access_lost` | `404` | The caller is no longer an active member of the thread's organization. |


Who receives a reason:

- `thread_deleted`, `share_revoked` and `share_expired` go to a caller who is otherwise **entitled** to the link: any active member for an organization-wide link (guests excepted, as above), a granted user for an `explicit` link, the link's creator, or the thread's owner.
- `org_access_lost` goes to a caller who is no longer a member of the organization but held a claim on **this** link: they were granted it, joined the live thread through it, created it, or own the thread.


Alongside the reason:

- **owner** `object | null` — The thread owner's display identity, in the same shape as `owner` on a successful response. Always `null` for `org_access_lost`.
- **shared_by** `object | null` — The display identity of the person who created the link, same shape. Always `null` for `org_access_lost`.
- **can_request_access** `boolean` — `true` only when asking the owner could restore access: the reason is `share_revoked` or `share_expired` (the conversation still exists), the owner's account is active and still a member of the organization, and the caller is not the owner. Otherwise `false`.
- **link_id** `string` — On the two `422` reasons only. The slug is never echoed back.
- **access_request** `object | null` — On the two `422` reasons only. The caller's newest [access request](/api-reference/shared-threads/request-access) for this chat, or `null` if they never asked: `id` `string` (`tsar_…`), `status` `string` (`pending`, `granted` or `dismissed`), `created_at` `string`, `decided_at` `string | null`, and `retry_after` `integer | null` (seconds before a `dismissed` caller may ask again; `null` otherwise). Show "Request sent" while it is `pending`.


When `can_request_access` is `true`, offer an "Ask for access" button that calls [Request Access Through a Dead Share Link](/api-reference/shared-threads/request-access) with the same slug.

The error's `message` is a ready-to-show sentence, for example `Dana Owner deleted this chat.`

Anyone else — an unknown slug, a member who was never given an `explicit` link, a former member of an organization-wide link they never joined, someone who held a different link to the same conversation — gets the uniform `404` with empty `details`, exactly as before, so a link's or thread's existence is never revealed to a caller it was not shared with.

A deleted conversation takes precedence over the link's own state: a revoked or expired link to a conversation that has since been deleted returns `404` with `thread_deleted` (it used to return `422`), so read `details` on a `404` too. The same `details` are returned by every route that opens a link by its slug (messages, import, join, the live stream). If the identities cannot be looked up, the reason is still returned with `owner` and `shared_by` set to `null`.

To read the thread's messages, call [Get Shared Thread Messages](/api-reference/shared-threads/get-shared-thread-messages). To get your own editable copy, [import-and-fork](/api-reference/shared-threads/import-shared-thread) it (when the link allows it).

## Authentication

Requires **user** authentication (Bearer token). A share link is resolved against a recipient user, so API-key authentication is rejected with `403` — an API key has no recipient identity.

## Path Parameters

**`slug`** string required

The share-link slug, taken from the share URL.

## Returns

Returns a `ResolvedShareResponse` object:

- **slug** `string` — The resolved slug.
- **access_level** `string` — The link's access level: `view`, `fork`, or `live`.
- **can_fork** `boolean` — Whether the caller may import-and-fork this conversation.
- **can_live** `boolean` — Whether the caller may join live co-working on this thread (open the real-time stream and post messages to it).
- **thread** `object` — The shared thread (read-only view). Includes `id`, `title`, `status`, `assistant_id`, `organization_id`, `message_count`, `created_at`, `updated_at`, `last_message_at`, and related metadata. The thread's `space_ids` are deliberately omitted for share-link recipients.
- **owner** `object | null` — The thread owner's display identity, so the recipient can render "Owned by {name}" with no extra lookup. Fields: `user_id` `string`, `name` `string | null` (display name; falls back to a name derived from the owner's first/last name, else the email local part), `avatar_url` `string | null`. `null` only if the owner record cannot be loaded.
- **audience** `string` — Who the link is shared with: `grantees` (a finite explicit-grant list — see `grantees`; render non-present grantees as offline) or `anyone_in_org` (open to the whole organization, with no finite roster — show presence-only, do not fabricate an offline list).
- **grantees** `array` — For an `audience: "grantees"` link, the explicit grantees as the finite roster to diff against the present set (who is offline). Each is an object: `user_id` `string`, `name` `string | null`, `avatar_url` `string | null`. Empty for `audience: "anyone_in_org"`.


## Code Examples

### cURL


```bash
curl https://api.aitronos.com/v1/shared-threads/abc123slug \
  -H "Authorization: Bearer YOUR_TOKEN"
```

### Python SDK


```python
from aitronos import Aitronos

client = Aitronos(api_key="", token="YOUR_TOKEN")
resolved = client.threads.shared.resolve(slug="abc123slug")
print(resolved.access_level, resolved.can_fork, resolved.thread.id)
```

### Python (requests)


```python
import requests

response = requests.get(
    "https://api.aitronos.com/v1/shared-threads/abc123slug",
    headers={"Authorization": "Bearer YOUR_TOKEN"},
)
resolved = response.json()
print(resolved["access_level"], resolved["thread"]["id"])
```

### JavaScript


```javascript
const response = await fetch(
  "https://api.aitronos.com/v1/shared-threads/abc123slug",
  {
    headers: { Authorization: "Bearer YOUR_TOKEN" },
  },
);
const resolved = await response.json();
console.log(resolved.access_level, resolved.thread.id);
```

## Response Examples

### Success (200)


```json
{
  "slug": "abc123slug",
  "access_level": "live",
  "can_fork": true,
  "can_live": true,
  "thread": {
    "id": "thread_5f8c2a1b9d4e4c3f8a7b6c5d4e3f2a1b",
    "object": "thread",
    "title": "Q3 launch plan",
    "status": "active",
    "assistant_id": "asst_2b1c3d4e5f6a7b8c9d0e1f2a3b4c5d6e",
    "organization_id": "org_9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d",
    "message_count": 12,
    "created_at": 1731318600,
    "updated_at": 1731320400,
    "last_message_at": 1731320400
  },
  "owner": {
    "user_id": "usr_9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d",
    "name": "Dana Owner",
    "avatar_url": "https://api.aitronos.com/v1/user/profile/images/profile-images/usr_9a8b.../avatar_full.webp"
  },
  "audience": "grantees",
  "grantees": [
    {
      "user_id": "usr_1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f",
      "name": "Sam Grantee",
      "avatar_url": null
    }
  ]
}
```

### Error — Link not found or not authorized (404)


```json
{
  "success": false,
  "error": {
    "code": "RESOURCE_NOT_FOUND",
    "message": "That share link could not be found.",
    "system_message": "Share link unresolved for user",
    "type": "client_error",
    "status": 404,
    "details": {},
    "trace_id": "...",
    "timestamp": "..."
  }
}
```

### Error — Conversation deleted by its owner (404)

Returned only to a caller the link was given to.


```json
{
  "success": false,
  "error": {
    "code": "RESOURCE_NOT_FOUND",
    "message": "Dana Owner deleted this chat.",
    "system_message": "Share link not found",
    "type": "client_error",
    "status": 404,
    "details": {
      "unavailable_reason": "thread_deleted",
      "owner": {
        "user_id": "usr_9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d",
        "name": "Dana Owner",
        "avatar_url": null
      },
      "shared_by": {
        "user_id": "usr_9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d",
        "name": "Dana Owner",
        "avatar_url": null
      },
      "can_request_access": false
    },
    "trace_id": "...",
    "timestamp": "..."
  }
}
```

### Error — Link revoked (422)

`share_expired` has the same shape with the message `This share link has expired.`


```json
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "This share link was turned off.",
    "system_message": "This share link is no longer available",
    "type": "validation_error",
    "status": 422,
    "details": {
      "unavailable_reason": "share_revoked",
      "owner": {
        "user_id": "usr_9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d",
        "name": "Dana Owner",
        "avatar_url": null
      },
      "shared_by": {
        "user_id": "usr_9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d",
        "name": "Dana Owner",
        "avatar_url": null
      },
      "can_request_access": true,
      "link_id": "tslnk_3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f"
    },
    "trace_id": "...",
    "timestamp": "..."
  }
}
```

### Error — No longer in the organization (404)


```json
{
  "success": false,
  "error": {
    "code": "RESOURCE_NOT_FOUND",
    "message": "You no longer have access to this organization.",
    "system_message": "Share link not found",
    "type": "client_error",
    "status": 404,
    "details": {
      "unavailable_reason": "org_access_lost",
      "owner": null,
      "shared_by": null,
      "can_request_access": false
    },
    "trace_id": "...",
    "timestamp": "..."
  }
}
```

### Error — API-key authentication (403)


```json
{
  "success": false,
  "error": {
    "code": "INSUFFICIENT_PERMISSIONS",
    "message": "Share links can only be opened with user authentication",
    "system_message": "Insufficient permissions",
    "type": "authorization_error",
    "status": 403,
    "details": { "auth_method": "api_key" },
    "trace_id": "...",
    "timestamp": "..."
  }
}
```

## Related Resources

- [Get Shared Thread Messages](/api-reference/shared-threads/get-shared-thread-messages) — Read the shared thread's messages
- [Import Shared Thread](/api-reference/shared-threads/import-shared-thread) — Fork the shared thread into your own
- [Live Shared Thread](/api-reference/shared-threads/live-shared-thread) — Join the real-time co-working stream