Getting Started
Quick Start
Connect your first app in 5 minutes
Prerequisites
Before you begin, make sure you have:
- Vocall Engine running locally or accessible at a known URL (default:
ws://localhost:8080) - Node.js 18+ for web SDKs (React, Angular, Vue)
- Flutter 3.10+ for the Flutter SDK
- Kotlin 1.9+ / Android Studio for the Kotlin SDK
- Xcode 15+ / Swift 5.9+ for the Swift SDK
Install the SDK
Pick your platform and install the Vocall SDK:
# React / Next.js
npm install @anthropic/vocall-react
# Angular
npm install @anthropic/vocall-angular
# Vue
npm install @anthropic/vocall-vue
// Kotlin (build.gradle.kts)
dependencies {
implementation("com.primoia:vocall-sdk:1.0.0")
}
// Swift (Package.swift)
dependencies: [
.package(url: "https://github.com/primoia/vocall-swift.git", from: "1.0.0")
]
# Flutter (pubspec.yaml)
dependencies:
vocall_flutter: ^1.0.0
Define Your Manifest
The manifest tells the Vocall Engine what your app looks like -- its screens, fields, actions, and modals. Here is a TypeScript example for a simple invoice form:
const manifest = {
app: "invoicing",
version: "1.0.0",
currentScreen: "create_invoice",
screens: {
create_invoice: {
id: "create_invoice",
label: "Create Invoice",
route: "/invoices/new",
fields: [
{ id: "client_name", type: "autocomplete", label: "Client", required: true },
{ id: "amount", type: "currency", label: "Amount", required: true },
{ id: "due_date", type: "date", label: "Due Date", required: true },
{ id: "description", type: "textarea", label: "Description" },
{ id: "tax_rate", type: "select", label: "Tax Rate", options: [
{ value: "0", label: "Exempt" },
{ value: "5", label: "5%" },
{ value: "10", label: "10%" },
]},
],
actions: [
{ id: "submit_invoice", label: "Submit Invoice", requiresConfirmation: true },
{ id: "save_draft", label: "Save Draft" },
],
},
},
};
Each field needs an id, a type (one of 15 supported types), and a label. Actions need an id and a label. That is the minimum the agent needs to understand your UI.
Register Fields (React Example)
Use the useVocallField hook to bind each form field to the SDK. When the agent sends a fill command targeting a field ID, the hook updates the value automatically:
import { useVocallField } from "@anthropic/vocall-react";
function InvoiceForm() {
const clientName = useVocallField("client_name", "");
const amount = useVocallField("amount", "");
const dueDate = useVocallField("due_date", "");
const description = useVocallField("description", "");
const taxRate = useVocallField("tax_rate", "0");
return (
<form>
<input {...clientName.inputProps} placeholder="Client" />
<input {...amount.inputProps} placeholder="Amount" type="number" />
<input {...dueDate.inputProps} type="date" />
<textarea {...description.inputProps} placeholder="Description" />
<select {...taxRate.inputProps}>
<option value="0">Exempt</option>
<option value="5">5%</option>
<option value="10">10%</option>
</select>
<button type="submit">Submit Invoice</button>
</form>
);
}
The hook returns a value, an onChange handler, and an inputProps spread object. You can also use field.setValue(newValue) programmatically.
Connect to the Engine
Wrap your application with VocallProvider and pass the manifest and engine URL:
import { VocallProvider } from "@anthropic/vocall-react";
function App() {
return (
<VocallProvider
engineUrl="ws://localhost:8080/connect"
manifest={manifest}
>
<InvoiceForm />
<VocallChat />
</VocallProvider>
);
}
The provider establishes the WebSocket connection, sends the manifest on connect, and manages the session lifecycle. The VocallChat component renders the built-in chat interface where users can type or speak to the agent.
Send a Message
Once connected, the user can type something like:
"Create an invoice for Acme Corp, $5,000, due next Friday, 10% tax"
The agent will parse this request and the Engine will send a command with multiple actions:
{
"type": "command",
"seq": 1,
"actions": [
{ "do": "fill", "field": "client_name", "value": "Acme Corp", "animate": "typewriter" },
{ "do": "fill", "field": "amount", "value": "5000", "animate": "count_up" },
{ "do": "fill", "field": "due_date", "value": "2025-01-31" },
{ "do": "select", "field": "tax_rate", "value": "10" },
{ "do": "fill", "field": "description", "value": "Consulting services for Acme Corp" }
]
}
The SDK executes the fill and select actions in parallel, animating the values into the fields. The user sees each field populate as if someone is typing into them.
What Happens Under the Hood
Here is the full sequence of events when a user sends a message:
- Text sent -- The SDK sends a
{ type: "text", message: "..." }to the Engine. - Status: thinking -- The Engine replies with
{ type: "status", status: "thinking" }so the UI can show a loading indicator. - LLM processes -- The Engine forwards the message plus the manifest to the configured LLM. The LLM decides what actions to take.
- Chat streams -- The Engine streams the agent's conversational reply as
chat_tokenmessages, then a finalchatmessage. - Command issued -- The Engine sends a
commandwith an array of UI actions and a sequence number. - SDK executes -- The SDK groups actions by execution mode. Sequential actions (navigate, click, open_modal) run one at a time. Parallel actions (fill, clear, select) run concurrently. Each action retries up to 3 times on failure.
- Result reported -- The SDK sends a
resultmessage with success/failure for each action, plus the current field state. - Status: idle -- The Engine sends
{ type: "status", status: "idle" }to indicate the agent is done.
If any action fails (for example, the field does not exist on the current screen), the agent receives the error in the result and can decide to navigate to the correct screen and retry.
Next Steps
- Read the full ACP Protocol Reference for all message types and action details.
- Explore the Introduction for architecture concepts.