Nuance LabsDocs

API keys and session tokens

What each credential can do, how long it lasts, and what revoking does.

Nuance uses two credentials, so the secret one never reaches a browser.

API keySession token
Looks likenk_…st_…
Where it livesYour serverYour page or app
Made byYou, on the platformYour server, with POST /session-tokens
LastsUntil you revoke itOne conversation
CanMint session tokens, list and end your conversations, read transcriptsStart and run one conversation

API keys

Create and revoke API keys on the Nuance platform. A key belongs to your organization, is shown once when you create it, and goes in requests as a bearer token: Authorization: Bearer nk_…. Your plan sets how many live keys you can hold; get your usage shows it as limits.api_keys.

The platform asks you to accept the API Developer Agreement and the Acceptable Use Policy when you first sign in, before you can make a key. Until the account that made your API key has accepted them, starting a conversation answers 403 legal_required (Errors).

Session tokens

Your server mints a token with POST /session-tokens and hands it to the page or app. An endpoint your page calls for one:

// On your server: an endpoint your page or app calls to get a session token
// for a Nuance Live conversation.
// A web-standard handler, so it runs as a Next.js route handler, on Bun,
// Deno or a Cloudflare Worker as written.

const NUANCE_API = process.env.NUANCE_API_URL ?? "https://api.nuancelabs.ai";

/**
 * Your id for the signed-in person making the request, or null. Replace this
 * with your own auth (NextAuth, Clerk, your session cookie): anyone who can
 * call this endpoint can start conversations on your account. Until then it
 * signs in no one, unless you set EXAMPLE_USER_ID to try the example.
 */
async function currentUserId(_request: Request): Promise<string | null> {
  return process.env.EXAMPLE_USER_ID ?? null;
}

export async function POST(request: Request): Promise<Response> {
  const userId = await currentUserId(request);
  if (!userId) {
    return new Response("Sign in to start a conversation", { status: 401 });
  }

  const response = await fetch(`${NUANCE_API}/session-tokens`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.NUANCE_API_KEY}`,
      "Content-Type": "application/json",
    },
    // Your id for the person, so a policy pause stops them, not your whole
    // account. Letters, digits and _ . : - only: hash an email first.
    body: JSON.stringify({ end_user_id: userId }),
  });
  if (!response.ok) {
    // For you, in your server's log: the status and Nuance's reason, such as
    // 401 for a wrong or revoked key. The page gets only the generic message.
    console.error(
      `POST /session-tokens answered ${response.status}: ${await response.text()}`,
    );
    return new Response("Couldn't start a conversation", { status: 502 });
  }

  const { token } = (await response.json()) as { token: string };
  return Response.json({ token });
}

Replace currentUserId with your own sign-in check; until then it signs in no one, and every request gets a 401. Set up a session adds the session's own settings.

  • Start within 60 seconds. A token that hasn't started a conversation by then is refused. Mint one when the person is about to start, not when the page loads.
  • One conversation each. Starting a conversation spends the token. After that it reaches only that conversation, and keeps working until 300 seconds after the conversation ends.
  • Settings are fixed when you mint it. The conversation runs with what your server sends to POST /session-tokens, and the page can't change it:
FieldWhat it sets
personality.system_promptWho the persona is: your own prompt.
personality.persona_idWho the persona looks and sounds like: sam, sonia or mira (see them). Sam and Mira share one voice; Sonia has her own. Left out, sam. Any other id is refused with a 400 whose detail lists the ids you can use.
end_user_idYour id for the person, so a policy pause stops that person, not your whole account.
expressivenessHow much the persona's face and head move, from 0 to 2: lower is calmer, higher more expressive. Left out, 1: the persona's own tuned level.

Leave a field out for the default. interface_setup settles the session itself: see Set up a session. The API reference has every field and its limits.

Revoking a key

Once you revoke a key:

  • requests with the key are refused, including minting new tokens;
  • every session token the key minted is refused, whether or not it has been used.

A conversation that is already connected keeps running until it ends. Its media no longer goes through the Nuance API once it's connected.

On this page