Portfolio Supported AIs Solutions Tasks Email Archive Bring Your Own Code Integrations Pricing

Get Started

ChatGPT

ChatGPT

Start directly →

Ready
Claude

Claude

Directory Connector →

Ready
Mistral

Mistral

Directory Connector →

Ready

Dashboard Always available
Site Assistant

Site Assistant

⚡ Built-in — Platform Built-in

An AI chat assistant for the visitors of your site, using your own AI key (OpenAI, Anthropic, Groq, OpenRouter, Mistral or Cloudflare Workers AI). You set the model, instructions, topic and limits; visitors only send their question and get the answer. Daily cap protects your AI budget. Optional realtime voice (paid plans): visitors talk to the assistant in the browser via OpenAI Realtime, with your key kept server-side and every call ended after max_minutes.

⚡ Built-in — No Setup Required This integration is built into the WebsitePublisher platform. All endpoints are available immediately — no API key needed.

Try it with your AI assistant

Once WebsitePublisher is connected to your AI assistant, paste one of these into the chat. Replace the parts in [brackets] with your own details.

@WebsitePublisher add an AI chat assistant to my site that answers questions about my services
@WebsitePublisher limit the chat assistant on my site to questions about [your topic] and cap it at [50] answers a day
With WebsitePublisher, add an AI chat assistant to my site that answers questions about my services
With WebsitePublisher, limit the chat assistant on my site to questions about [your topic] and cap it at [50] answers a day
With WebsitePublisher, add an AI chat assistant to my site that answers questions about my services
With WebsitePublisher, limit the chat assistant on my site to questions about [your topic] and cap it at [50] answers a day

Endpoints (10)

POST create-assistant

Create an AI assistant for site visitors. It uses the AI integration of this project, so the key of the chosen provider must be in the vault (openai: openai_api_key, anthropic: aapi_anthropic_key, groq: groq_api_key, openrouter, mistral, cloudflare-workers-ai: see their integration). Visitors can never change the model, instructions or limits. scope sets how broadly it may answer: "strict" (default) only about topic, "related" also briefly about closely related questions, "open" anything. Do NOT put secrets, internal prices or private data in system_prompt: a determined visitor may get the model to reveal it. After creating, call test-assistant once to check it works.

Field Type Required Description
assistant_key string ✓ Yes Short id, lowercase letters, digits, - and _. Example: "help".
label string ✓ Yes Human-readable name.
provider string ✓ Yes "openai", "anthropic", "groq", "openrouter", "mistral" or "cloudflare-workers-ai".
model string ✓ Yes Model id of that provider, e.g. "gpt-4o-mini", "claude-haiku-4-5-20251001", "llama-3.1-8b-instant".
system_prompt string ✓ Yes Instructions for the assistant: who it is, what it knows about the site, tone. Max 8000 characters.
access string ✓ Yes "anonymous" (any visitor) or "verified" (signed-in visitors or tenants only). No default: choose deliberately.
scope string No "strict" (default), "related" or "open".
topic string No What the assistant is about, e.g. "our hiking routes, bookings and opening hours". Required unless scope is "open".
off_topic_reply string No Fixed reply for questions outside the topic. Empty: the assistant politely says in the visitor's language what it can help with.
max_output_tokens integer No Max length of one answer (1-4000). Default 500.
temperature number No 0-1, default 0.7. Not applied for providers "openai" and "anthropic" (their newer models refuse it).
max_input_chars integer No Max characters per visitor message (1-8000). Default 1000.
max_history_messages integer No How many earlier messages are sent along for context (0-40). Default 10. The page sends this history, so a visitor can make up earlier messages; turn on signed_history to leave out answers the assistant never gave, or set 0 so the assistant only sees the current question.
signed_history boolean No Default false. true: an earlier answer in history only counts when the page sends back its reply_sig as sig, with the answer exactly as chat returned it; other answers are left out. Stops a visitor from making up what the assistant said. The page must keep reply_sig (see chat).
per_session_hourly integer No Max messages per visitor (session, or email when verified) per hour (1-1000). Default 30.
per_ip_hourly integer No Anonymous only: max messages per IP address per hour (0 = off, max 1000). Default 60.
per_ip_daily integer No Anonymous only: max messages per IP address per day (UTC), 0 = off, max 10000. Default 100 (assistants created before this setting existed have 0). Stops one visitor or script from using up daily_cap on its own. Visitors who share an IP (office, school, mobile network) count together: raise it or set 0 if they get blocked. Over it the visitor gets reason "network_limit".
daily_cap integer No Budget brake: max answers per day (UTC) for this assistant, all visitors together (1-100000). Default 500. After that visitors see fallback_message.
fallback_message string No What visitors see when a limit is reached or the AI provider fails. Default: "The assistant is not available right now. Please try again later."
POST update-assistant

Change an assistant. Only send what changes. Send an empty string for topic or off_topic_reply to clear it. Set is_active false to pause (visitors then see fallback_message).

Field Type Required Description
assistant_key string ✓ Yes
label string No
provider string No
model string No
system_prompt string No
access string No
scope string No
topic string No
off_topic_reply string No
max_output_tokens integer No
temperature number No
max_input_chars integer No
max_history_messages integer No
signed_history boolean No
per_session_hourly integer No
per_ip_hourly integer No
per_ip_daily integer No
daily_cap integer No
fallback_message string No
is_active boolean No
POST delete-assistant

Delete an assistant permanently. Realtime calls that are still open are ended first (counts in realtime_calls). To pause it instead, use update-assistant with is_active false.

Field Type Required Description
assistant_key string ✓ Yes
GET get-config

All assistants of this project with their settings, today's number of answers against daily_cap, whether the provider key is in the vault, and the platform limits. realtime holds the voice settings (null when not set up), today's calls against daily_sessions and open_calls (calls not yet closed by the platform; a call the visitor ended counts until its scheduled end).

No input parameters required.

POST test-assistant

Send one test message with exactly the visitor settings (instructions, scope, limits) and see the answer, or the error from the AI provider. Counts towards daily_cap. Use this after create or update.

Field Type Required Description
assistant_key string ✓ Yes
message string ✓ Yes
history array No Optional earlier messages, same format as chat.
POST set-realtime

Turn on realtime voice (speech-to-speech in the browser) for an assistant, or change its settings. Paid plans only. Uses the OpenAI key of this project (vault: openai_api_key); the key never reaches the browser. The assistant's system_prompt, scope and topic become the voice instructions; the platform adds rules for a spoken conversation (short answers, no made-up details). Spoken answers have their own max_output_tokens (default 1024, about 40 seconds of speech; audio counts as tokens), separate from text chat. The first call needs model; later calls only send what changes. Every call is ended automatically after max_minutes, and daily_sessions caps the number of calls per day (UTC). Once connected, a determined visitor can change the instructions over the browser connection, so never put secrets in system_prompt. For the visitor transcript, transcribe_model and its hints (transcribe_prompt, transcribe_keywords, transcribe_languages, transcribe_delay) set the accuracy; a hint the chosen model does not use is left out of the call and listed in transcription_notes. After setting up, call test-realtime once.

Field Type Required Description
assistant_key string ✓ Yes
model string No OpenAI realtime model, e.g. "gpt-realtime" or "gpt-realtime-mini". Required the first time.
voice string No OpenAI voice, e.g. "marin" (default), "cedar" or "alloy".
max_minutes integer No Each call is ended after this many minutes (1-60). Default 10.
daily_sessions integer No Budget brake: max calls per day (UTC) for this assistant, all visitors together (1-10000). Default 50.
max_open_calls integer No Max calls open at the same time for this assistant (0-1000). 0 = no cap (default). A call counts until its scheduled end (max_minutes) or end-realtime-calls, also when the visitor already left. Over the cap a visitor gets limited with reason "busy".
per_actor_hourly integer No Max calls per visitor (session, or email when verified) per hour (1-100). Default 5.
per_ip_hourly integer No Anonymous only: max calls per IP address per hour (0 = off, max 1000). Default 10.
per_ip_daily integer No Anonymous only: max calls per IP address per day (UTC), 0 = off, max 10000. Default 10 when voice is first set up (voice set up before this setting existed has 0). Stops one visitor or script from using up daily_sessions on its own. Visitors who share an IP count together: raise it or set 0 if they get blocked. Over it the visitor gets reason "network_limit".
max_output_tokens integer No Max length of one spoken answer in tokens (1-4096). Default 1024. Audio counts: about 25 tokens per second of speech.
transcribe_visitor boolean No true: what the visitor says is transcribed and sent to the page as conversation.item.input_audio_transcription.completed events. Default false. The transcript comes from a separate transcription model (transcribe_model, default gpt-4o-mini-transcribe), not from the voice model, so it can differ from what the assistant understood. Billed by OpenAI on your key at the price of that transcription model.
transcribe_language string No Language of the visitors as a two-letter ISO 639-1 code (e.g. "nl"), a hint for transcribe_visitor; without it OpenAI guesses the language per sentence. Empty string clears it.
transcribe_model string No Transcription model for transcribe_visitor. Default "gpt-4o-mini-transcribe" (cheapest). "gpt-4o-transcribe" is more accurate, also for less common languages, names and domain words, and costs more. Also accepted: "gpt-4o-mini-transcribe-2025-12-15", "gpt-transcribe", "gpt-live-transcribe", "gpt-realtime-whisper", "whisper-1". Call test-realtime after a change. Empty string = back to the default.
transcribe_prompt string No Hint for the transcription with the names and terms your visitors use, e.g. "Names: ELMA, Element Marketing. Terms: CRM, Google Meet." Used with gpt-4o-transcribe, gpt-4o-mini-transcribe and whisper-1 (for whisper-1 a plain list of words). Max 1000 characters. Not shown to visitors, but never put secrets in it. Empty string clears it.
transcribe_keywords array No Words or phrases that guide the transcription, e.g. ["ELMA","Element Marketing","CRM"]. Used with gpt-transcribe and gpt-live-transcribe (for the gpt-4o models use transcribe_prompt). Max 100, each max 100 characters. [] clears it.
transcribe_languages array No Possible languages of the visitors as ISO 639-1 codes, e.g. ["uk","ru"]. Used with gpt-transcribe and gpt-live-transcribe instead of transcribe_language. Max 10. [] clears it.
transcribe_delay string No gpt-realtime-whisper only: how long it waits before it emits text, "minimal", "low", "medium", "high" or "xhigh". Longer can be more accurate, but the text comes later. Empty string clears it.
noise_reduction string No "far_field" (default, laptop or phone microphone), "near_field" (headset) or "off".
turn_detection string No When the assistant starts to answer. "semantic_auto" (default), "semantic_low", "semantic_medium" or "semantic_high": waits until the visitor has finished a sentence (low waits longest, calmest with background noise). "server_vad": answers after any sound followed by a short silence (fastest, most sensitive to noise).
enabled boolean No false pauses realtime voice; text chat keeps working.
POST test-realtime

Check that the OpenAI key, model, voice and the other voice settings work for realtime: sends the same session a call gets, without starting a call or using audio. Does not count towards daily_sessions. Returns {ok, model, voice, error, transcription_model, transcription_notes}; transcription_model is null when transcribe_visitor is off.

Field Type Required Description
assistant_key string ✓ Yes
POST end-realtime-calls

Emergency stop: end every realtime call of this assistant that is still open. Works on every plan. To stop new calls as well, use set-realtime with enabled false. Returns counts: ended, already_ended, unconfirmed (OpenAI answered 503, which it does for a call the visitor already ended; the call is closed) and failed.

Field Type Required Description
assistant_key string ✓ Yes
POST chat

The current visitor asks the assistant a question. Returns {reply, limited, reply_sig}. When limited is true, reply holds the fallback message, reason says why ("daily_limit", "visitor_limit", "network_limit", "inactive", "unavailable") and there is no reply_sig. For a conversation, the page keeps the earlier messages itself and sends them as history; nothing is stored on the server. Keep reply_sig with each answer and send it back as sig in history. With signed_history on, earlier answers without a valid sig are left out, so a visitor cannot make up what the assistant said.

Field Type Required Description
assistant_key string ✓ Yes
message string ✓ Yes The visitor's question. The assistant's own max_input_chars applies.
history array No Earlier messages of this conversation, oldest first: [{"role":"user","content":"..."},{"role":"assistant","content":"...","sig":"<reply_sig>"}]. Only user and assistant roles are used. Send each answer exactly as chat returned it, with its reply_sig as sig.
POST realtime-call

Start a realtime voice call for the current visitor (set up first with set-realtime). The page creates an RTCPeerConnection with the microphone track and a data channel "oai-events", sends its SDP offer here and gets the SDP answer back: {sdp, max_minutes, limited:false}. Audio then flows directly between the browser and OpenAI; the data channel carries the events: the assistant's words as response.output_audio_transcript.delta/done and, with transcribe_visitor on, what the visitor said as conversation.item.input_audio_transcription.completed. When limited is true there is no sdp: message holds the fallback text and reason says why ("daily_limit", "visitor_limit", "network_limit", "busy", "inactive", "not_enabled", "plan", "unavailable"). sapi.execute resolves to {ok, status, data}: the result is in data.result; a refusal has data.success false and data.error. Example: const pc = new RTCPeerConnection(); const audio = new Audio(); audio.autoplay = true; pc.ontrack = e => { audio.srcObject = e.streams[0]; }; const mic = await navigator.mediaDevices.getUserMedia({audio: {echoCancellation: true, noiseSuppression: true}}); pc.addTrack(mic.getTracks()[0]); pc.createDataChannel("oai-events"); await pc.setLocalDescription(await pc.createOffer()); const res = await sapi.execute("site-assistant", "realtime-call", {assistant_key: "tutor", sdp: pc.localDescription.sdp}); const r = res.data && res.data.success ? res.data.result : null; if (!r || r.limited) { pc.close(); /* show r ? r.message : res.data.error */ } else { await pc.setRemoteDescription({type: "answer", sdp: r.sdp}); } Start the call from a user click (browsers require a gesture for the microphone and audio playback).

Field Type Required Description
assistant_key string ✓ Yes
sdp string ✓ Yes pc.localDescription.sdp after setLocalDescription(await pc.createOffer()).

MCP Tool Names

When using this integration through an AI assistant (Claude, ChatGPT, Cursor, etc.), the endpoints are available as MCP tools:

EndpointMCP Tool Name
create-assistant site-assistant_create_assistant
update-assistant site-assistant_update_assistant
delete-assistant site-assistant_delete_assistant
get-config site-assistant_get_config
test-assistant site-assistant_test_assistant
set-realtime site-assistant_set_realtime
test-realtime site-assistant_test_realtime
end-realtime-calls site-assistant_end_realtime_calls
chat site-assistant_chat
realtime-call site-assistant_realtime_call
← Back to all integrations