--- title: "Let your users sign in from the chat | Busymate AI" description: "Give customers a sign-in card inside the chat, using the accounts you already run: what they get, how to switch it on, and what stays with you." last_updated: "2026-09-15T15:11:29+03:00" --- # Let your users sign in from the chat | Busymate AI Source: https://busymate.ai/zh-Hans/docs/guides/in-chat-sign-in Last modified: 2026-09-15T15:11:29+03:00 Busymate AI lets a customer sign in without leaving the conversation, with the account they already have with you. You implement one tool; your sign-in card opens in the thread the moment a question needs their account, the credentials go to your own site, and the same conversation carries on signed in. No platform account is created for them, and nothing about their login reaches the assistant. Diagram: A question needs an account; a sign-in card opens in the thread; the same conversation continues signed in, vouched for by a short-lived proof your site signs ## Yours end to end - **Sign-in and sign-up are your product's.** The card, the login page and the account creation flow are the ones you already run — the form you return is drawn verbatim, not adapted to a template of ours. Busymate AI never stores a password or creates a customer account; it only verifies the short-lived proof your site signs afterwards. - **What the assistant learns** is an unchanging customer id and, if you allow it, a few display claims such as a name or plan. Everything else stays behind your API and is fetched per request. ## 1. Register your accounts as the identity provider Open [Console → End-user identity](https://busymate.ai/console/identity), or call `upsert_tenant_identity_provider`. Enter your issuer, JWKS URL, audience, workspace and subject claims, the maximum proof age and the mint endpoint described in [Recognize signed-in customers](https://busymate.ai/zh-Hans/docs/guides/identified-visitors). Add your **customer login URL** as well — the hosted chat and the silent connect in step 4 use it. Save, press **Test identified launch**, then publish. The check is standards-only: an ES256 (or RS256) JWT verified against your published JWKS for issuer, audience, subject, workspace claim, the nonce the launch asked for, a one-time `jti`, age and expiry. A failed check names the claim, never the value. {{snippet:identity-endpoint}} ## 2. Put a sign-in card in the chat Sign-in is a **standard widget tool you implement**. Register a tool named `sign_in` — as a page tool on any page where the chat is embedded, or on your [connected MCP server](https://busymate.ai/zh-Hans/docs/guides/connect-mcp-server) — and return a form card from it: {{snippet:page-tools-sign-in}} Whatever you return is rendered as you wrote it: your fields, your labels, your order, your wording, your links. Nothing of ours is added to your form, and there is no platform styling of your login to design around. Two companion names complete the set and both are optional — `sign_up` to create an account, `sign_out` to end the session — on the identical contract. The fields are yours: email and password, an emailed code, or a single button that starts the sign-in you already offer. A `password` field is accepted only on a card that submits back into your own page, so the value goes from the input to your `execute` and nowhere else, and the settled card shows `•••••`. When your tool answers `{ signedIn: true }`, the widget asks your page for a fresh proof through `getIdentity` and re-mints the session in place — same thread, now identified, the earlier question answered. The full field vocabulary and its limits are in [Forms and sign-in inside the chat](https://busymate.ai/zh-Hans/docs/guides/form-cards). ### As many steps as your login has A form may answer with a form: whatever your submit tool returns is drawn next, in the same card. A choice of *Email* or *Phone*, then your fields, a display-name field, a consent checkbox, links to your own terms and privacy, then a one-time code — each step posting to your own endpoint — is still the one `sign_in` tool and nothing new to wire. Hold anything a step needs to remember in your own page, the way the snippet below keeps the contact it just sent a code to. The form has no hidden field, and one invented would simply be dropped. ### No passwords? Use a one-time code If you sign customers in with a code to a phone or an email, the card is two steps: ask where to send the code, then ask for the code. {{snippet:page-tools-sign-in-otp}} Give the code field `autocomplete: "one-time-code"` and leave its type as `text`: a one-time code is not a stored credential, and `text` is what lets a phone offer the SMS it just received. Do not answer a sign-in request with a tool that returns an explanation of how to log in — the chat will say a card is coming and then read your customer a paragraph instead. ### If you implement nothing Both snippets above are starting points, not the contract — a tool of your own that returns the same form is exactly as good, and a login neither of them fits is a reason to write your own, not a reason to skip it. If you register no tool at all, nothing is invented on your behalf. There is no card, and the assistant will not promise one: it answers with your real sign-in link, or sends the visitor to your login URL at the top level (step 3). Publish neither and it offers nothing rather than an errand with nowhere to go. ## 3. Know what happens where | Where the chat runs | What the Sign in control does | |---|---| | Embedded on your page, `sign_in` registered | The card opens in the thread. Nothing leaves the page. | | Embedded on your page, no `sign_in` tool | Your page navigates to your login URL with `return_to` and a one-time `bmai_nonce`, then returns and hands the proof to the widget. | | Your hosted chat address | The same redirect: to your login URL and back to the exact `return_to`, proof in the URL fragment. | | Your iOS or Android app | The app receives the request over the native bridge and runs its own login. | | No `sign_in` tool and no login URL published | Nothing is offered. The assistant does not announce a card it cannot show. | A credential is never typed into a frame that is not yours. The card submits into your page, and a redirect always happens at the top level, on your origin. ## 4. Connect a customer who is already signed in If the customer already has a session with your product, the chat can inherit it without showing a form. On the hosted address and in the embed, the widget opens your login URL once per tab in a hidden frame with `bmai_prompt=none` — the `prompt=none` meaning every identity stack knows: answer only from an existing session, never render a form. Your login redirects straight back with the proof in the fragment, and the session is re-minted signed in. It works when: - your customer login URL is published on the current revision; - your login honours `bmai_prompt=none` — an existing session answers, a signed-out visitor is sent back with nothing; - the probe finishes within three seconds; it runs once per tab and fails silently, so the visitor simply stays a guest with the Sign in control still there. This can only add an identity. It never blocks the chat, never redirects the visible page, never traps anyone in a login form, and is not attempted inside a native app, which passes identity over its own bridge. ## 5. Choose what a signed-in customer can do Each connected tool carries an access level. **Public** tools answer anyone. **Identified** tools run only after the proof was verified and receive your customer id. **Delegated** tools also need *Allow delegated customer account access* on the provider and act through a signed actor token or a per-customer consent. Set the levels in [Connect your MCP server as assistant tools](https://busymate.ai/zh-Hans/docs/guides/connect-mcp-server). The sites at [demo.busymate.ai](https://demo.busymate.ai) each include a demo customer to sign in as: the same card, then orders, bookings or balances for that one person. ## Verify 1. Signed out, ask something that needs an account: the card appears in the thread, not a link away. 2. Sign in from the card: the same conversation continues and your earlier question is answered. 3. Open the tool call's details: the password shows as `•••••`. 4. Sign in to your product in another tab, then open the hosted chat: it is signed in with no form shown. 5. A second customer cannot see the first one's history or account. ### Do my customers need an account with Busymate AI? No. They sign in to your product. Your site signs a short-lived proof, the assistant verifies it against your public key, and the subject is your own customer id. ### Where do sign-ups happen? In your product, the way they do today. The card or the login page you return is yours, so a new customer creates an account with you and comes back to the chat signed in. ### Can the assistant read the password? No. A password field is accepted only on a card that submits into your own page. The value never enters a tool argument, the transcript or a log. ### What if the silent connect is not answered? Nothing visible happens. The probe expires after three seconds, the visitor stays a guest and the Sign in control is still there. ### What happens if I never add the `sign_in` tool? There is no card, and the assistant says so plainly instead of promising one: it gives your real sign-in link, or sends the visitor to your login URL at the top level. Nothing of ours stands in for your login. ## Next - **[Recognize signed-in customers](https://busymate.ai/zh-Hans/docs/guides/identified-visitors)** — the keys, the claims and the mint endpoint. - **[Forms and sign-in inside the chat](https://busymate.ai/zh-Hans/docs/guides/form-cards)** — the card contract in detail. - **[Connect your MCP server as assistant tools](https://busymate.ai/zh-Hans/docs/guides/connect-mcp-server)** — the identified tools it unlocks.