Book a build call

Embed and Public Agent API

Mrs. NetShow is an AI agent.

Put a live agent on a website with the two-line Alive Kit embed, allow its site for voice, and use the public agent doors.

Guided article

Audience: a developer, or an AI agent, who wants a NetShow agent alive on a website it does not own: a customer site, a WordPress or Shopify store, or a page of its own. Scope: the one embed (the Alive Kit script and its <alive-agent> element), the voice door the element uses on your site, the owner's embed page that hands out the snippet and allows your website, the public agent pages and documents, and the older embed doors that still answer for pages pasted before the kit. How this guide was written: from the code on main. The class and method are named under each door, and the element's attributes are the ones public/alive-kit/alive-kit.js reads. The host is shown as https://app.netshow.ai. A door marked off until your administrator turns it on sits behind a switch that ships off; while it is off the door answers 404, or the element stays a captioned look without a voice.

10 min read 2,185 words Developer reference

Which door do I need?

You want to Use Who sets it up
Put a live agent on any web page The two lines below: alive-kit.js and <alive-agent> You paste them
Let that agent speak on your site in the NetShow voice Your website on the agent's allowed list, with voice on for it The agent's owner, on the embed page
Get the exact snippet for one agent The owner's embed page, GET /dashboard/agents/{agentId}/embed The agent's owner
Read a public agent's face, name and look as data GET /alive-kit/v1/agents/{slug} Nobody: public agents only
Talk to a public agent from your own agent, not a page The public agent's MCP or A2A door See the MCP Integration and A2A Protocol guides

What you can do without a key

The embed needs no key, no token and no account. The element reads public facts only, and its voice is admitted by the website it runs on (the Origin your browser sends), not by a secret in the page.

Door What it gives you Switch
/alive-kit/alive-kit.js The kit: one script that defines <alive-agent>. Always on (a static file)
GET /alive-kit/v1/agents/{slug} The public agent's document the element reads: name, look, character, greeting. ai.features.alive_kit_agent
GET /alive-kit/v1/agents/{slug}/package.alive.json The same agent as a downloadable .alive.json package. ai.features.alive_kit_agent
GET /api/widget/voice/mint-url/{slug} A one-minute signed address that starts a voice session, for an allowed website only. ai.features.widget_voice_door
GET /agents and GET /agent/{slug} The public directory and each public agent's own page. Always on
POST /api/agent/{slug}/mcp and POST /api/agent/{slug}/a2a A public agent's machine doors. ai.features.agent_ready_sites and ai.features.public_agent_answers

A door with a switch is off until your administrator turns it on.

Put a live agent on your site: the two lines

<script src="https://app.netshow.ai/alive-kit/alive-kit.js" defer></script>
<alive-agent agent="your-agent-slug" look="auto" mode="free"></alive-agent>

That is the whole embed (the Alive Kit toolbox, docs/alive-kit/TOOLBOX.md section 1, is its owner's manual). Paste the script once, anywhere in the page, and the element where the agent should live. With agent="netshow" you get the house host.

What a visitor sees: the agent is alive as the page loads. It shows its greeting as a caption, blinks and breathes, and morphs with its room: a live ASCII face when it is tiny, the whole character when there is space. Its face is the talk button. Where your site is allowed for voice (next section), it speaks in the NetShow voice at the visitor's first touch of the page; anywhere else it stays a living, captioned look. It never uses a browser voice or a recorded clip, and it always says it is an AI.

The element

These are the attributes public/alive-kit/alive-kit.js reads. Leave out any you do not need.

Attribute Values Default
agent netshow (the house host) or a public agent's slug netshow
look auto, 1 to 9, or a look name: ascii, sketch, svg, toon, 2d, 3d. Look 9 (a paid live human face) is opt-in only. auto
character mrs-netshow, mr-netshow, pip, robo, byte, owl, cat, fox, drake, momo, scout pip on your site
mode container (fills its box), free (rides the page, bottom right), stage (owns the screen; Esc or "Bring me back" returns it) container
lang a language tag (en, es, ...) or auto for the visitor's browser language the page's <html lang>
greeting the caption shown at load; the live voice says its own words the character's greeting
name the host's name the character's name
mint-url the agent's voice door, https://app.netshow.ai/api/widget/voice/mint-url/{slug} with the agent's slug none: captions only
voice-src a same-origin address that answers {sessionUrl, agentId} (NetShow's own pages) none

Size it with CSS: --alive-agent-size (in container mode, default 320px) and --alive-agent-free-size (in free mode, default 120px). In free and stage mode the agent draws no buttons around itself: hovering it (or tapping it on a phone) shows its one menu.

The agent's public document

Class: AliveKitAgentController (methods show and package). The element fetches this for any slug other than the house host. Public agents only; the document carries public facts only, never the agent's instructions, knowledge, owner or visitors. It answers with Access-Control-Allow-Origin: * so it works from any site, and is cached for 60 seconds. 240 requests a minute.

curl --max-time 30 https://app.netshow.ai/alive-kit/v1/agents/your-agent-slug -H 'Accept: application/json'

A private agent, an unknown slug, or the switch ai.features.alive_kit_agent off: 404. The package.alive.json door answers the same file as a download (Content-Disposition: attachment).

Stores and site builders

Where What to do
Any HTML page The two lines above.
WordPress The owner downloads the NetShow Alive plugin for this agent at GET /dashboard/agents/{agentId}/embed/wordpress-plugin.zip (class AgentWordPressPluginController), installs it and ticks "Put the live host on every page". It prints the same two lines.
Shopify The theme section in integrations/shopify/netshow-alive/sections/netshow-alive.liquid, added to the footer group in Customize. Captions and the one menu today.
A sandboxed frame you cannot load modules into See docs/alive-kit/TOOLBOX.md section 1, "A sandboxed frame".

Give it a voice on your site

The element's voice comes only from the signed mint, and the mint answers only a website the agent's owner has allowed and switched voice on for. Nothing in the page is a secret.

  1. The owner allows your website. On the embed page the owner adds the origin (https://your-site.example): POST /dashboard/agents/{agentId}/embed/origins with the field origin. Class: AgentEmbedOriginController (method store). The site starts as pending. Switches: ai.features.embed_selfserve and ai.features.embed_origin_selfserve.
  2. You prove you control the site. Publish the exact token the embed page shows at https://your-site.example/.well-known/netshow-origin.txt (class EmbedOriginVerification), with no redirect. Where ai.features.embed_origin_verify_meta is on, a <meta name="netshow-origin" content="..."> tag inside your home page's <head> also counts.
  3. The owner presses Verify. POST /dashboard/agents/{agentId}/embed/origins/verify fetches the proof once and moves the site to active. POST /dashboard/agents/{agentId}/embed/origins/withdraw takes it off the list again (it is kept as withdrawn, never deleted).
  4. The owner turns voice on for that site. POST /dashboard/agents/{agentId}/embed/origins/voice (class AgentEmbedOriginVoiceController). Switches: ai.features.widget_voice_door and ai.features.widget_voice_owner_switch.
  5. Put mint-url on the element. The owner's snippet already carries it.

GET /api/widget/voice/mint-url/{slug}

Class: WidgetVoiceMintUrlController (method show). The element calls it from the visitor's browser at the visitor's first touch; the Origin header is the website asking. 10 requests a minute. Every answer carries Access-Control-Allow-Origin set to that origin and Cache-Control: private, no-store.

curl --max-time 30 https://app.netshow.ai/api/widget/voice/mint-url/your-agent-slug \
  -H 'Origin: https://your-site.example' -H 'Accept: application/json'

Response 200 (the address lives 60 seconds):

{"mintUrl": "https://app.netshow.ai/api/realtime/session/public?agent_id=...&widget_voice=embed&widget_origin=https%3A%2F%2Fyour-site.example&expires=...&signature=..."}

Where the agent has a voice ladder, the answer also carries voiceLadder, rung and voicePageUrl, the agent's own voice page.

Status Body message Why
403 Voice is not available on this site right now. You can keep typing. The website is not allowed, or voice is not on for it.
404 The agent is not public, the slug is unknown, or ai.features.widget_voice_door is off.
409 Captions are the available lane. Keep typing, or open the voice page. Captions are the agent's voice today.
503 Live voice is awaiting its session budget. You can keep typing. The daily voice ceiling (ai.spend.lanes.realtime_voice_session.daily_ceiling_usd) is not set, or is used up.

POST /api/realtime/session/public

Class: RealtimeSessionController (method createPublic). The element posts to the signed mintUrl it was handed; the signature, the website and the agent are checked again, and the house daily ceilings apply. 10 requests a minute. The answer starts the session on the NetShow proxy voice (gpt-realtime-2.1-mini by default). You never build this request yourself: changing any query parameter breaks the signature and the door answers 403.

The owner's embed page

Class: AgentEmbedController (method show), at GET /dashboard/agents/{agentId}/embed, signed in, the agent's owner only (anyone else gets 404). Switch: ai.features.embed_selfserve. The page is titled "Put on your own website" and carries:

  • The snippet. While ai.features.owner_embed_alive_kit is on, it is the two lines above for this agent, built by AliveEmbedKit::kitSnippet: look="auto", the mode that follows the agent's Own the stage setting, and its mint-url. While it is off, the page shows the older snippet for owners who already pasted it.
  • Your websites. The allowed list from the section above, with each site's state and its voice switch.
  • Checks. POST /dashboard/agents/{agentId}/embed/check (class AgentSnippetCheckerController, switch ai.features.studio_snippet_checker) checks a pasted snippet; POST /dashboard/agents/{agentId}/embed/live-check (class AgentEmbedLiveCheckController, switch ai.features.embed_site_live_check) loads your page once and reports whether the agent is on it.
  • The WordPress plugin download (above).

Publish the agent

The embed, the public document and the public page work only for a public agent. POST /dashboard/agents/{agentId}/publish (class AgentPublishController), signed in as the owner, with a CSRF token: the field make_public (default true) sets the agent public or private. Making it public also needs confirm_publish=1; without it the agent is not changed and the page asks the owner to confirm first. Another owner's agent answers 404.

Public agent pages

Door Class and method What it is
GET /agents AgentProfileController@directory The public directory: 24 a page, ?category= and ?q= to filter.
GET /agent/{slug} AgentProfileController@show The agent's public page, with its live host. Public or marketplace agents only, else 404.
GET /agent/{slug}/voice AgentVoicePageController@show The agent's own voice page (the voicePageUrl the mint hands out).
POST /agent/{slug}/chat AgentProfileController@trialChat The typed turn of the agent's own page.

POST /agent/{slug}/chat is the page's own conversation, not an API for other sites: it is a same-site browser request that needs the page's session and CSRF token. Body message (required, at most 500 characters); 5 requests a minute per visitor; 15 messages a visitor session before the page asks the visitor to sign up. Its answer:

{"reply": "<the agent's answer>", "messagesLeft": 14, "limitReached": false, "tier": "...", "greetTier": "...", "degraded": false}

and, at the cap:

{"reply": null, "limitReached": true, "signupUrl": "/register?agent=your-agent-slug"}

To talk to a public agent from your own software, use its MCP door (POST /api/agent/{slug}/mcp) or A2A door (POST /api/agent/{slug}/a2a): the MCP Integration and A2A Protocol guides show each with a request and a response.

Older embed doors

These still answer for pages that were pasted before the kit. They are not the embed to build on: a new page uses the two lines above.

Door Class What it does now
GET /act/embed/{agentSlug} ActEmbedController@show An iframe target. While ai.features.act_embed_public is off it sends a public agent's visitor on to the logged-out ACT chat; on, it draws the public agent's chat in the frame. 404 for a private agent either way.
GET /embed/agents/{agentId}/chat a closure in routes/web.php An iframe chat widget keyed by the agent's id; 403 for a private agent.
/js/ns-chat-widget.js with data-api set to the agent's door WidgetSnippet The script-tag chat widget the deploy page hands out while ai.features.embed_snippet_live_widget is on; it answers only a website on the allowed list.

How to get a key

The embed needs none. What stands in for a key is the allowed list: the agent's owner adds your website, you publish the proof file, the owner presses Verify and turns voice on. For machine access to an agent (MCP, A2A or the owner's API), see the Authentication and Keys guide.

Was this helpful?

We can turn this into interactive help, search, and guided checklists next.

Previous guide

MCP Integration

Next guide

Authentication and Keys

Ready to meet your AI agent?

New accounts open soon.

Join the opening list Talk to our agent