Use the harness module loader and backend ticket envelope. Old package token-provider examples are superseded; keep server keys on the backend and sessions in memory.
End-user experience
What an end user of your app actually sees and does when the chat is embedded: how answers arrive, what the receipts line looks like, how to file a support ticket, who the chat is for in a family, which memory switches exist, what refusal copy and crisis-helpline card surface in distress, and what the kundli gallery renders.
You are integrating the chat into your own product. The features below are the ones your end users see. Customisations for each item live in the tenant admin pane and are described in onboarding and profile data on this site. The pages linked from each section are the ones to read next; nothing on this page describes how the harness works internally.
Answer sources
Many answers cite a source. The wire emits one
source-document chunk per cited source, between the text
deltas and the terminal finish chunk. Each carries
sourceId, mediaType and title so
your UI can render a “Sources” pill row, a numbered footnote
marker, or an inline link — whichever fits your design system.
The full chunk allowlist is on Stream chunks.
Sources are advisory and may be absent on short or non-factual answers;
the SDKs accept a stream with zero source-document chunks
the same way they accept one with many.
Receipts line
When a turn completes, the chat shows a short receipts line so the user
can see what they were charged. The line is rendered from the settled
receipt inside the terminal finish event; the SDKs parse
it into a typed charge value the SDK consumer can drop
into whatever wording your app uses.
- Format: a money amount plus a currency code, for example charged $0.018 / 1 credit. The widget renders it as one line immediately under the stop or finish indicator.
- What the user sees when they stop early: Stopped · charged $X, where $X is the amount the model had produced up to the stop point. Stop never charges for text the model did not produce.
- What the user does not see: the wholesale cost the platform paid on their behalf, the cost split per token, the internal calculation method, or any provider or upstream model name. The line is end-user facing and uses only the values from your monetisation config (or, when the user is on a “my own billing” tenant, no money at all).
The widget hides the line if your tenant turns receipts off in the admin pane. The line is always present on the underlying chunk (it is just not rendered), so any host that ignores the tenant setting and surfaces the chunk directly will still show it.
Support tickets & Help
Every chat surface has an entry point labelled “Help”. It opens a ticket form (subject, message, contact email, an opt-in to attach the current conversation for context). On submit, the harness creates a ticket and routes it to the destination your tenant has configured in the admin pane — your own helpdesk, or Vedika's own ticket queue as a fallback. The end user sees a status card (Open / In progress / Resolved) and the full thread once an agent replies.
Wire contract for hosts that want to surface their own ticket UI:
POST /api/v1/support/tickets
Authorization: Bearer <server_key>
Content-Type: application/json
Idempotency-Key: <uuid>
{
"subject": "Kundli shows the wrong place",
"message": "The chart for my son uses Mumbai instead of Delhi.",
"requester_email": "[email protected]",
"share_conversation": true,
"conversation": [{ "role": "user", "text": "..." }, { "role": "assistant", "text": "..." }]
}
200 OK
{ "ticket_id": "...", "externalId": "...", "status": "open" }
Hosts that already have a ticket form should call this endpoint
directly and skip the chat-side UI. share_conversation
is the only field that, when true, attaches the message-level context
the agent will see; conversation history beyond the current turn is
never sent.
Family members
Each family member is a separate birth profile distinguished by its
relation. There is no nested “family” object:
the chat picks the right profile from context (a question about
“my son” binds to the profile with
relation: child; “my wife's chart” binds to
relation: spouse; compatibility reads from the saved
pair automatically).
See Profile data — Family members for the full field list, the no-child-profiles stance, and how the kit exposes the family list on each platform.
Memory consent toggles
Three switches govern what the chat recalls and writes. The end user sees them as three toggles on the chat Settings screen. Hosts that need server-side control of these switches use the per-turn headers listed on Profile data — Consent for sensitive data; the chat Settings screen still shows the current effective value to the user.
| Toggle | What it covers | Default |
|---|---|---|
| Old memory | Saved preferences, “remember this” items, and the user's prior chat titles. | true in the app; false on the raw
API. |
| Sensitive info | Identity fields, sensitive profile fields, and free-form health notes. | false everywhere; the app prompts once and
remembers. |
| Faith preferences | Saved notes about religion, sect, and personal practice. | false by default; the chat offers to turn it on
in conversation. |
Saving anything into the chat is opt-in per toggle. There is no silent background write. Forgetting is retention-preserving: the entry leaves recall immediately, the audit log retains the event, and the export flags it.
Safety behaviour and the crisis helpline card
The chat applies one deterministic classifier across text, voice and any future surface. A question that triggers a refusal receives a refusal paragraph that is rendered in the user's locale (English is the fallback; the chat UI never silently swaps refusal text).
On the small set of crisis-exit triggers — explicit distress language such as “kill myself”, “want to die”, “don't want to live”, or equivalent in any supported locale — the refusal is paired with a crisis helpline card. The policy ships only phone numbers it can stand behind:
| Region | Card copy |
|---|---|
| US (English) | 988 — Suicide & Crisis Lifeline,
24×7. |
| UK / AU / other English locales | Befrienders Worldwide directory (befrienders.org). |
| India (English plus 12 Indian locales) | 14416 — Tele-MANAS (Govt. of India),
toll-free 1-800-891-4416, free 24×7 in
English and 20 Indian languages. |
Where the policy does not have a verified local number, the card points to a directory rather than inventing one. Voice rendering is short (the user hears at most 30 words), and the full refusal paragraph plus helpline card is delivered as a follow-up text card so the user can read more on their own time. The voice itself never carries the phone number — prompting the user to look, not auto-dial.
When a topic is allowed but touches medical, legal or financial advice, the answer carries a short disclaimer rendered after the answer body in the user's locale. Ordinary questions never do.
D1 — D60 chart types
The kundli page renders the main birth chart (D1, Rashi) plus 15 varga charts. The full set the gallery exposes:
- D1 — Rashi (the main chart).
- D2 — Hora.
- D3 — Drekkana.
- D4 — Chaturthamsha.
- D7 — Saptamsha.
- D9 — Navamsha.
- D10 — Dashamsha.
- D12 — Dwadashamsha.
- D16 — Shodashamsha.
- D20 — Vimshamsha.
- D24 — Chaturvimshamsha.
- D27 — Bhamsha.
- D30 — Trimshamsha.
- D40 — Khavedamsha.
- D45 — Aksha Vedamsha.
- D60 — Shashtiamsha.
On the wire, every chart is a data-vedika-artifact chunk
whose data.kind names the chart type and
data.payload carries the sanitised SVG. The chart stream
is gated by the same Content-Security-Policy rules as text; the
end-user chat only ever sees safe SVG bytes with no script, iframe or
foreign-object inside.
The widget also renders kundli charts from the saved family profiles, including all chart types above, and presents them on the family member's own page inside the chat Settings dialog.
Backend ticket bootstrap
Your backend authenticates the application user, mints an origin-bound token and keeps that token on the backend. It issues a single-use frame ticket and returns ticket, nonce and signedConfig with Cache-Control: no-store.
The host page uses the harness module loader with getSession and an independently supplied verification-key ring. The loader redeems the ticket from the host Origin, keeps the scoped session in memory and creates a user-owned thread. It renews through the same authenticated backend endpoint. Your application destroys the mounted chat on logout or account change.
Profile fields are separate from the mint body. Published branding and configuration come from the active signed web document. Follow the current backend contract; old package token-props examples do not define this flow.
What stays in the customer channel
By design, the items below are absent from these pages. They live in the host service and in the customer's own support channel:
- Provider or upstream model names, internal model identifiers, or deployment identifiers.
- Billing internals, wholesale cost splits, or per-token arithmetic.
- Prompt text, refusal text, routing tables, retrieval corpus, or grading weights.