API first success
You can reach a grounded answer without opening the web app once. This path is for teams that already know they want agent behavior but want it behind their own scripts, jobs, or UI. The assistant chat API is how you talk to an agent from that code.
Before you start
Every call below needs a Radioso host to talk to. Use the hosted EU API at https://api.radioso.ai, the hosted US API at https://api-us.radioso.ai, or your own origin if you’re self-hosting — start the stack first with Run locally in 5 minutes, then swap in http://localhost:8080. Pick one host and stay on it for every step below: a workspace token only works against the instance that issued it.
The examples on this page call https://api.radioso.ai.
The happy path
From nothing to a grounded answer takes six calls:
- check whether registration is available
- create or access an account
- establish a session
- reveal a workspace token
- upload one document
- ask one agent question whose answer should obviously come from that document
Check registration availability
Ask the server whether it accepts open registration before showing or using signup.
Create or access an account
Register the first user on an empty open-source server, log in with an existing user, or accept an invitation.
Establish a session
Registration sends a verification email but does not return a session cookie. Login and invitation acceptance establish a session.
Reveal the workspace token
Use the session-authenticated workspace route to get the bearer token.
Upload content and ask a grounded agent question
Use the workspace token for document and chat routes.
One concrete example
Say you upload a document that reads:
Refunds are available within 14 days of purchase with proof of payment.
A good first API test is then:
- upload that exact text
- wait for processing to complete
- ask,
What is the refund window?
If the system is working, the answer comes back grounded in that document rather than sounding generic. That contrast, your text versus a plausible guess, is the thing you’re checking for.
Register
curl -sS https://api.radioso.ai/api/v1/auth/registrationThe response is { "available": true } or { "available": false }. Open-source registration is available only until the first organization has been created. Later users join that organization by invitation. Enterprise Edition keeps registration available.
When registration is available:
curl -sS \
-H 'Content-Type: application/json' \
-d '{"email":"you@example.com","password":"verysecurepassword"}' \
https://api.radioso.ai/api/v1/auth/registerRegistration returns bootstrap data such as workspaceId, sends a verification email, and does not establish a session. Verify the email address before logging in.
If the user already exists, log in and save the session cookie:
curl -sS -c cookies.txt \
-H 'Content-Type: application/json' \
-d '{"email":"you@example.com","password":"verysecurepassword"}' \
https://api.radioso.ai/api/v1/auth/loginReveal the workspace token
curl -sS -b cookies.txt \
https://api.radioso.ai/api/v1/account/workspaces/<workspace-id>/tokenIf you need to list workspaces first:
curl -sS -b cookies.txt \
https://api.radioso.ai/api/v1/workspaceThe token response looks like:
{"token":"radioso_..."}The same token is available in the dashboard under Settings, in the API access panel. Reveal it there when you want to copy it into another client, and note that the panel also shows a ready-made curl example against your own host.

If a workspace token, public chat link, or Enterprise embed token is ever exposed, rotate it from the settings screen instead of relying on disable and re-enable toggles.
Upload one document
You can use the SDK:
import { createRadiosoClient } from '@radioso/typescript-sdk'
const client = createRadiosoClient({
apiToken: process.env.RADIOSO_API_TOKEN!,
// baseUrl defaults to https://api.radioso.ai; set it explicitly for
// https://api-us.radioso.ai or a self-hosted origin like http://localhost:8080
})
await client.documents.create({
title: 'Refund policy',
content: 'Refunds are available within 14 days of purchase with proof of payment.',
source: { kind: 'website', url: 'https://example.com/docs' },
})When the source of truth is a file, import it instead:
import { readFile } from 'node:fs/promises'
const file = await readFile('./refund-policy.pdf')
await client.documents.importFile({
file,
filename: 'refund-policy.pdf',
title: 'Refund policy',
mimeType: 'application/pdf',
})You can also use the raw HTTP document routes directly, including the multipart POST /api/v1/document/import path.
Ask one question that should have an obvious answer
curl -sS -X POST https://api.radioso.ai/api/v1/assistant/chat \
-H "Authorization: Bearer $RADIOSO_API_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"message":"What is the refund window?","stream":false}'client.chat.create wraps the same route:
const response = await client.chat.create({
message: 'What is the refund window?',
stream: false,
})
console.log(response.answer)Either way, the response is the grounded answer plus the citations that support it — here is the exact shape:
{
"conversationId": "5b1b6e9e-2b0a-4f1d-9c4a-7e8f2a6c9d31",
"assistantMessageId": "8f2c5a3e-9d1b-4a7c-b6e2-1f4d8c0a5b93",
"agentId": "3a9d7c5e-1b2f-4e8a-9c6d-5f0e3a7b2c14",
"agentName": "Support",
"answer": "Refunds are available within 14 days of purchase with proof of payment.",
"citations": [
{
"documentId": "c1d2e3f4-5678-4abc-9def-0123456789ab",
"chunkId": "d2e3f4a5-6789-4bcd-8ef0-123456789abc",
"title": "Refund policy",
"sourceUrl": "https://example.com/docs"
}
],
"answerSegments": [
{
"text": "Refunds are available within 14 days of purchase with proof of payment.",
"citationIndices": [0]
}
],
"suggestions": []
}citations[].sourceUrl only shows up when the source document carries one — the document you uploaded above does, because you passed source: { kind: "website", url: "https://example.com/docs" }. A plain inline document without a source still cites documentId and title. (The full response can also carry ownership and debug fields; see the API Reference for the complete schema.)
What success looks like
- you can establish a session and reveal a workspace token
- the document is accepted and processed
- the answer is about your uploaded document, not a generic policy guess
- if citations are enabled for the workspace, the answer points back to the supporting content
Common failure mode
If upload works but chat doesn’t, one of these is usually true:
- document processing is still running
- the backend does not have a valid provider key
- the session cookie was not saved by the client
What to do next
- If the API behavior looks right, continue with TypeScript SDK getting started.
- If the answer quality is weak, review Document upload and Agents and skills.