Overview
@akapulu/server is the server-side package in the Akapulu Web SDK.
Use it in your backend to call Akapulu APIs from your own server routes.
This is the recommended way to keep your API key on the server while letting your frontend call simple local endpoints.
Installation
Client constructor
The entry point iscreateAkapuluServerClient().
AKAPULU_API_KEY from the environment. If it is missing, client creation throws an error.
Main responsibility
@akapulu/server sits between your application routes and the Akapulu API.
It is responsible for:
- creating the server client
- calling the connect endpoint
- polling conversation updates
- fetching conversation detail data
- fetching conversation recording responses
- mapping your app-specific request body into Akapulu request fields like
scenario_id,avatar_id,runtime_vars, andrecord_conversation
Method reference
connectConversation(body)
ConnectConversationRequest:
Scenario id to launch.
Avatar id to use for the conversation.
Optional runtime variables passed into the scenario.
Optional speech-to-text keyword hints.
Optional recording toggle.
Optional override. The client defaults this to
true before making the request.ConnectConversationResponse:
room_urltokenconversation_session_id
pollConversationUpdates(conversationSessionId)
ConversationUpdatesResponse:
conversation_session_idcall_is_readycompletion_percentlatest_update_text
getConversationDetail(conversationSessionId)
ConversationDetailResponse includes:
idcreated_atcreated_at_textduration_textavatarscenario_idrecordingtranscript_rows
getConversationRecording(conversationSessionId)
ConversationRecordingResponse is a union of:
- redirect response:
{ kind: "redirect", status, location } - json response:
{ kind: "json", status, payload } - binary response:
{ kind: "binary", status, body, contentType, contentDisposition }
Main types
The package also exports the main request and response types used by those methods, including:ConnectConversationRequestConnectConversationResponseConversationUpdatesResponseConversationDetailResponseConversationRecordingResponseAkapuluApiErrorResponse
AkapuluApiError, which is thrown for non-success API responses from connectConversation, pollConversationUpdates, and getConversationDetail.
Typical route pattern
Most apps create local routes like:POST /api/akapulu/connectGET /api/akapulu/updates?conversation_session_id=...GET /api/akapulu/conversation-details?conversation_session_id=...GET /api/akapulu/view-recording?conversation_session_id=...
@akapulu/server.
How it fits with the rest of the SDK
In a typical app:- The browser calls your local backend routes.
- Your backend uses
@akapulu/server. @akapulu/servercalls Akapulu APIs.- Your frontend then uses
@akapulu/reactor@akapulu/react-uito join and render the conversation.
What your local routes return
AkapuluProvider (from @akapulu/react) reads config.endpoints.connectPath and config.endpoints.updatesPath, sends a POST request to the connect URL, then sends GET requests to the updates URL while the session is joining.
Those handlers must respond with snake_case JSON in the same shape Akapulu returns. See Customize Conversation UI. The usual pattern is to return the resolved promise from @akapulu/server so the response types stay aligned.
Connect route → connectConversation
Your POST connect handler should return a body typed as ConnectConversationResponse:
room_url— Daily room URL for mediatoken— join token for that roomconversation_session_id— id used for updates polling
Updates route → pollConversationUpdates
Your GET updates handler should return a body typed as ConversationUpdatesResponse:
conversation_session_id— same session the client is pollingcall_is_ready— whentrue, the client can treat the call as readycompletion_percent—0–100progress from the scenariolatest_update_text— short status string for UI
@akapulu/server. The AkapuluProvider contract for those URLs is summarized under Connect and updates response shape in Customize Conversation UI.
Custom connect payloads
One common pattern is to accept app-specific JSON in your local connect route, then map it into Akapulu request fields likeruntime_vars and record_conversation.

