Appearance
Link Tools โ
Single consolidated tool for managing shareable links that open a Gnosari agent. Each link gets a unique URL (joina.chat/l/{slug}) and a downloadable QR code, and renders the agent either as a classic chat or as an immersive full-page conversation.
AgentLink absorbs the legacy QrLink โ every link that used to be a "QR code" is now an AgentLink with presentation="chat". Physical QR codes keep working: printed codes encode joina.chat/q/{slug}, which resolves through a retained legacy alias on the Agent Links REST resource.
Multiple links can point to the same agent with different greetings, topics, themes, and expiry โ one link per channel (poster, email campaign, personal invitation) so each is tracked separately.
gnosari_manage_link โ
Create, get, list, update, or delete shareable agent links.
Annotations: readOnlyHint: false ยท destructiveHint: false ยท idempotentHint: false ยท openWorldHint: false
Parameters โ
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
action | string | Yes | - | create, get, list, update, delete, or check_slug |
link_id | integer | Conditional | - | Link ID. Required for get, update, delete |
agent_id | integer | Conditional | - | Agent this link opens. Required for create; pass on update to point the link at a different agent |
name | string | Conditional | - | Internal display name (e.g. "VIP dinner invitations"). Required for create. Never shown to visitors |
slug | string | No | auto-generated | Custom URL slug โ joina.chat/l/{slug}. Leave unset on create to auto-generate an unguessable 16-character token (recommended for personal invitations). Required for check_slug |
presentation | string | No | chat | How the agent renders when opened: chat = classic chat widget, conversation = immersive full-page conversation with an editorial headline |
greeting | string | No | inherit | First message the visitor sees, for this link only. Unset = the agent's own greeting |
topic | string | No | None | Headline of the conversation page (e.g. "A conversation about your stay"). Ignored when presentation="chat" |
caption | string | No | None | Subtitle shown under the conversation headline before the visitor starts (e.g. "No forms โ just tell us what you need"). Ignored when presentation="chat" |
chat_theme_id | integer | No | inherit | Theme override for this link only. Unset = the agent's theme (or account default) |
expires_at | datetime | No | never | When the link stops working (visitors then see "link expired"). Naive datetimes are treated as UTC |
clear_fields | list of string | No | - | update only: field names to reset to unset/inherit โ one of greeting, topic, caption, chat_theme_id, expires_at. Cannot clear and set the same field in one call. To re-point the link at a different agent, pass a new agent_id value instead (a link always needs an agent, so agent_id is not clearable) |
skip | integer | No | 0 | Pagination offset (list only) |
limit | integer | No | 100 | Maximum records to return (list only) |
Returns โ
Return type depends on the action:
| Action | Return Type |
|---|---|
create | LinkDetail with urls, resolved agent/theme refs, and hints |
get | LinkDetail |
list | PaginatedAgentLinksResponse with .data and .pagination |
update | LinkDetail with updated fields + hints |
delete | dict with message and hints |
check_slug | AgentLinkSlugAvailability (available: bool, reason: str|None) |
LinkDetail fields:
| Field | Type | Description |
|---|---|---|
id | int | Link identifier |
name | str | Internal display name |
slug | str | URL slug (joina.chat/l/{slug}) |
presentation | str | chat or conversation |
greeting | str | None | Resolved override, or None to inherit the agent's greeting |
topic | str | None | Conversation headline |
caption | str | None | Conversation subtitle (under the headline) |
visit_count | int | Number of times the link has been visited (absorbs the old scan_count) |
expires_at | str | None | ISO 8601 timestamp, or None if it never expires |
agent | LinkAgentRef | {id, name} of the linked agent |
theme | LinkThemeRef | None | {id} of the theme override, or None to inherit |
urls | LinkUrls | {public, embed, qr_image} โ see below |
hints | list[str] | Progressive next-step guidance |
LinkUrls fields:
| Field | Description |
|---|---|
public | joina.chat/l/{slug} โ share this |
embed | /embed/l/{slug} on the Gnosari app โ use as an iframe src |
qr_image | Printable QR code image URL encoding public |
Action: create โ
Create a link, optionally in the conversation presentation from the start.
python
# Classic chat link (default presentation)
result = gnosari_manage_link(
action="create",
name="Business Card QR",
agent_id=123
)
print(f"URL: {result.urls.public}") # https://joina.chat/l/<auto-generated-slug>
# Immersive conversation link with a topic and personal vanity slug
result = gnosari_manage_link(
action="create",
name="VIP dinner invitations",
agent_id=123,
slug="vip-dinner",
presentation="conversation",
topic="A conversation about your stay",
greeting="Hi! We'd love to host you next week."
)Slug Rules โ
- 3-50 characters, lowercase alphanumeric + hyphens
- Must start and end with a letter or number
- Globally unique across all accounts
- Reserved words blocked:
create,stats,settings,admin,api,new,list,edit,delete - Leave
slugunset to get a service-generated unguessable 16-character token โ recommended for links shared with a specific person (an invitation credential, not a memorable name)
Action: get โ
Get details of a specific link including visit count and agent info.
python
result = gnosari_manage_link(action="get", link_id=1)
print(f"{result.name}: {result.visit_count} visits")Error: AgentLinkNotFoundError if invalid link_id or the link belongs to another account.
Action: list โ
List all links for the authenticated account.
python
result = gnosari_manage_link(action="list")
for link in result.data:
print(f"{link.name}: {link.visit_count} visits")
# With pagination
result = gnosari_manage_link(action="list", skip=10, limit=20)Action: check_slug โ
Check whether a slug is globally available before creating or updating a link. Always returns an AgentLinkSlugAvailability object โ never raises on taken, reserved, or invalid-format slugs.
python
check = gnosari_manage_link(action="check_slug", slug="vip-dinner")
if check.available:
result = gnosari_manage_link(
action="create", name="VIP dinner invitations", agent_id=123, slug="vip-dinner"
)
else:
print(f"Slug unavailable: {check.reason}")AgentLinkSlugAvailability fields:
| Field | Type | Description |
|---|---|---|
available | bool | True if the slug can be used; False if taken, reserved, or invalid format |
reason | str | None | Human-readable explanation when available is False. None when available |
Action: update โ
Update a link โ rename it, change presentation, remap to a different agent, set conversation overrides, or set an expiry.
python
# Switch a link to the immersive conversation presentation
gnosari_manage_link(
action="update", link_id=1, presentation="conversation", topic="Let's talk about your order"
)
# Remap to a different agent
gnosari_manage_link(action="update", link_id=1, agent_id=456)
# Set an expiry
from datetime import datetime, UTC
gnosari_manage_link(action="update", link_id=1, expires_at=datetime(2026, 12, 31, tzinfo=UTC))
# Reset the greeting override back to inheriting the agent's own greeting
gnosari_manage_link(action="update", link_id=1, clear_fields=["greeting"])Only provide the fields you want to change. A field cannot be set and cleared in the same call โ that raises a validation error.
Note:
agent_idis not aclear_fieldsoption. A link always needs an agent; to re-point it, pass a newagent_idvalue instead of trying to clear it.
Action: delete โ
Delete a link permanently. The joina.chat/l/{slug} URL โ and any printed QR codes encoding it โ will stop working.
python
gnosari_manage_link(action="delete", link_id=1)
# Returns: {"message": "Agent link 1 deleted", "hints": [...]}Warning: This action cannot be undone.
Common Workflows โ
Create a link for physical media โ
python
# 1. Find the right agent
results = gnosari_search(entity="agents", query="support")
agent_id = results.results[0]["id"]
# 2. Create the link
link = gnosari_manage_link(action="create", name="Business Card QR", agent_id=agent_id)
# 3. Print urls.qr_image, or share urls.public directly
print(f"Public URL: {link.urls.public}")
print(f"QR image: {link.urls.qr_image}")Create an immersive personal invitation โ
python
link = gnosari_manage_link(
action="create",
name="Follow-up with Jordan",
agent_id=agent_id,
presentation="conversation",
topic="A conversation about your stay",
greeting="Hi Jordan! Following up on your visit last week.",
)
# Share link.urls.public โ an unguessable slug means only Jordan can reach it.Remap agent without reprinting โ
python
links = gnosari_manage_link(action="list")
gnosari_manage_link(action="update", link_id=links.data[0].id, agent_id=new_agent_id)Track visit performance โ
python
links = gnosari_manage_link(action="list")
for link in links.data:
print(f"{link.name}: {link.visit_count} visits")Next Steps โ
- API Overview - Tool relationships and common patterns
- Agent Management Tools - Create agents with data collection