N AgentNavaKit
Why this is Freelancer-only

Test URLs, prod URLs, the embed snippet, hosted chat pages: these all describe how you publish an agent so end users can reach it. That shape only applies to role: 'freelancer' agents, bots you host on a website to serve many users. Teammates aren't published; they live inside your workspace and you converse with them through the console (or the workspace API). No test URL, no prod URL, no embed step. See Roles → Teammates for what Teammates do instead.

Deploy to test and to prod

Configure creates an agent version (a snapshot). Deploying that version runs it as a public-facing endpoint. You pick the destination:

// the configure call returned:
//   const v = { agentId: 'agt_2b8e', versionId: 'ver_3c5f' }

// dev-only URL — no end-user traffic, ephemeral
const test = await an.agents.deployToTest(v.versionId);
// → { url: 'https://<temp>.test.agents.agentnava.com', expiresAt: '…' }

// production URL — end users hit this
const prod = await an.agents.deployToProd(v.versionId);
// → { url: 'https://<agent-name>.agents.agentnava.com', versionNumber: 4 }

Both calls are idempotent on the version ID. deployToProd promotes the version atomically and keeps the previous one warm until the new one passes a health check. Skip deployToTest if you don't need a dev-only environment.

Versions & rollback

// list every version of this agent (newest first)
const versions = await an.agents.versions('agt_2b8e');
// → [{ id: 'ver_3c5f', number: 4, deployedAt: '…', isProd: true }, …]

// instant rollback to a previous version
await an.agents.rollback('agt_2b8e', 'ver_9a1b');

Rollback is instant. Every version's spec content and configuration is preserved as long as the agent exists.

Custom domain

Map agent.yourdomain.com to the agent's public URL via CNAME, then attach it in code:

await an.domains.add({
  domain:  'agent.yourdomain.com',
  agentId: 'agt_2b8e',
});

The runtime provisions a managed TLS cert and serves the agent at that domain within a minute.

The whole thing: one script tag

Paste this anywhere in the HTML of the page where you want the chat bubble to appear. The token comes pre-filled in your Deploy panel; click Copy there.

<script src="https://agentnava.com/embed/v1.js"
        data-token="agt_pk_xxxxxxxxxxxxxxxx" defer></script>

That’s it. A floating chat bubble appears bottom-right. Visitors click it, a panel opens, they chat with your agent. Reload the page and the same visitor sees their conversation continue. Anonymous visitors are identified by a uuid stored in localStorage.

Optional knobs

All optional. Sensible defaults if you skip them.

AttributeDefaultNotes
data-tokenrequiredThe publishable token from your Deploy panel. Starts with agt_pk_.
data-positionbottom-rightOr bottom-left.
data-color#059669Bubble background colour (any CSS colour).
data-titleagent nameSets the iframe’s title for screen readers.
data-user-idauto-generatedIf your site already knows the visitor, pass their stable id. Without this, an anonymous uuid is minted and persisted in localStorage.
data-user-nameDisplay name to send to the agent.
data-user-emailEmail to send to the agent.

Telling the agent who the user is

Two paths. Pick whichever fits your stack.

1. Static: data-attrs on the script tag

Simplest. Your server renders the snippet with the user’s id baked in.

<script src="https://agentnava.com/embed/v1.js"
        data-token="agt_pk_xxxx"
        data-user-id="customer-42"
        data-user-name="Jane Smith"
        data-user-email="[email protected]"
        defer></script>

2. Dynamic: JS API after auth

Some apps don’t know the user at page render time (post-login SPA, lazy load). Identify after the embed boots:

// Anywhere on your page, AFTER the embed script has run
window.AgentNava.identify({
  id:    'customer-42',
  name:  'Jane Smith',
  email: '[email protected]'
});

The agent’s session keys to user.id, so the same id on the same agent → continues the same conversation. Different id → a new conversation.

Security note. Identity passed from the browser is self-attested: anyone in the browser console can call identify with any id. For high-trust use cases (showing PII the agent shouldn’t reveal to imposters), the upcoming signed-identity flow has your backend mint a JWT proving the user is yours. Until then, treat the embed identity as a routing hint, not a permission grant.

JS API exposed by the embed

The embed sets window.AgentNava after it boots:

window.AgentNava = {
  open():                         void   // open the chat panel
  close():                        void   // close it
  identify({ id, name?, email? }): void   // set the user (see above)
}

The script tag has a defer attribute so it runs after the HTML parses; if you need to call AgentNava.identify immediately on page load, wait for DOMContentLoaded or use a small poll until window.AgentNava exists.

Hosted chat page (no embed)

If you don’t want to embed at all, the Deploy panel also gives you a direct URL:

https://agentnava.com/embed/<agentId>

Share it like any other link. Anonymous users can chat with the deployed agent. Same per-visitor session continuity (localStorage uuid).

What’s actually happening

For when you need to debug or build your own client.

Public endpoints

EndpointAuthWhat it does
GET /v1/public/agents/by-token/:tokenNoneResolves a publishable token to its agentId + name. The embed bootstrap uses this to derive the iframe URL.
GET /v1/public/agents/:agentIdNonePublic metadata for a prod-deployed agent. Returns 404 for non-deployed agents so private specs don’t leak.
POST /v1/public/chatAuthorization: Bearer agt_pk_*SSE chat stream. Body: { content, user: { id, name?, email? } }. Session keys to (agentId, user.id).

Token semantics

  • Minted on first Deploy to prod. Persists across re-deploys.
  • The token is public; it gets pasted into customer site source. Treat it like a Stripe publishable key.
  • Scoped to a single agent. Leaks affect that agent only; can be rotated independently.
  • Open CORS (*) at the chat endpoint, required for embeds on customer-owned origins.