> ## Documentation Index
> Fetch the complete documentation index at: https://docs.roark.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Node.js SDK

> Upload calls, run metrics, and execute simulations using Node.js

<Note>
  The Node.js SDK is continually evolving, with new endpoints being added regularly. Stay tuned for updates!
</Note>

### Overview

The Roark Node.js SDK provides a streamlined way to interact with the Roark API. This guide covers the two most common workflows: uploading calls and running metrics, and executing simulation run plans.

### Prerequisites

Before you begin, ensure you have:

* Node.js v12 or higher - [Download Node.js](https://nodejs.org)
* A Roark API Key - [Generate one here](/documentation/getting-started/api-keys)

### Installation

Choose your preferred package manager:

<CodeGroup>
  ```bash npm theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
  npm install @roarkanalytics/sdk
  ```

  ```bash yarn theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
  yarn add @roarkanalytics/sdk
  ```

  ```bash pnpm theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
  pnpm add @roarkanalytics/sdk
  ```

  ```bash bun theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
  bun add @roarkanalytics/sdk
  ```
</CodeGroup>

### Initialize the Client

```typescript theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
import Roark from '@roarkanalytics/sdk'

const client = new Roark({
  bearerToken: process.env.ROARK_API_BEARER_TOKEN,
})
```

<Note>
  Set `ROARK_API_BEARER_TOKEN` in your environment, or replace with your actual API key from Roark.
</Note>

***

### Upload a Call and Run Metrics

Upload a call recording, then run metric definitions against it using a collection job.

<Steps>
  <Step title="Upload a Call">
    ```typescript theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
    const call = await client.call.create({
      recordingUrl: 'https://example.com/recording.mp3',
      startedAt: '2024-01-15T10:00:00Z',
      interfaceType: 'PHONE',
      callDirection: 'INBOUND',
      agent: {
        name: 'Support Agent',
        customId: 'agent-123',
      },
      customer: {
        phoneNumberE164: '+15551234567',
      },
      // Optional: custom properties for filtering
      properties: {
        department: 'sales',
        campaignId: 'summer-2024',
      },
    })
    ```
  </Step>

  <Step title="Get Metric Definitions">
    List available metric definitions to choose which ones to run:

    ```typescript theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
    const definitions = await client.metric.listDefinitions()

    // Find the metrics you want to collect
    const taskCompletion = definitions.data.find(
      (m) => m.metricId === 'task_completion'
    )
    const satisfaction = definitions.data.find(
      (m) => m.metricId === 'customer_satisfaction'
    )
    ```
  </Step>

  <Step title="Create a Metric Collection Job">
    Run the selected metrics against your uploaded call:

    ```typescript theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
    const job = await client.metricCollectionJob.create({
      callIds: [call.data.id],
      metrics: [
        { id: taskCompletion.id },
        { id: satisfaction.id },
      ],
    })
    ```
  </Step>

  <Step title="Poll for Completion">
    ```typescript theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
    let status = 'PENDING'
    while (status !== 'COMPLETED' && status !== 'FAILED') {
      const result = await client.metricCollectionJob.getByID(job.data.id)
      status = result.data.status
      console.log(`Progress: ${result.data.completedItems}/${result.data.totalItems}`)
      if (status !== 'COMPLETED' && status !== 'FAILED') {
        await new Promise((r) => setTimeout(r, 2000))
      }
    }
    ```
  </Step>

  <Step title="Fetch Results">
    ```typescript theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
    const metrics = await client.call.listMetrics(call.data.id)
    console.log(metrics.data)
    ```
  </Step>
</Steps>

<Tip>
  If you have [metric collectors](/documentation/metrics/metric-collectors) configured, metrics are collected automatically when calls are uploaded — no collection job needed.
</Tip>

***

### Run a Simulation Run Plan

Create and execute a simulation run plan to systematically test your voice AI agent.

<Steps>
  <Step title="Create the Run Plan">
    Define scenarios, personas, agent endpoints, and metrics to include:

    ```typescript theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
    const plan = await client.simulationRunPlan.create({
      name: 'Production Regression Suite',
      direction: 'INBOUND',
      maxSimulationDurationSeconds: 300,
      scenarios: [
        { id: 'scenario-uuid-1' },
        { id: 'scenario-uuid-2' },
      ],
      personas: [
        { id: 'persona-uuid-1' },
        { id: 'persona-uuid-2' },
      ],
      agentEndpoints: [
        { id: 'agent-endpoint-uuid' },
      ],
      metrics: [
        { id: 'metric-definition-uuid-1' },
        { id: 'metric-definition-uuid-2' },
      ],
      iterationCount: 1,
      maxConcurrentJobs: 10,
      autoRun: true, // Start immediately after creation
    })

    // plan.data.runPlanJob contains the job if autoRun is true
    ```
  </Step>

  <Step title="Or Start an Existing Plan">
    If you already have a run plan, start a new job for it:

    ```typescript theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
    const job = await client.simulationRunPlanJob.start('plan-uuid')
    ```
  </Step>

  <Step title="Monitor Progress">
    ```typescript theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
    const jobResult = await client.simulationRunPlanJob.getByID(
      job.data.simulationRunPlanJobId
    )

    console.log(`Status: ${jobResult.data.status}`)
    console.log(`Jobs: ${jobResult.data.simulationJobs.length}`)
    ```
  </Step>

  <Step title="View Results">
    Results including metric evaluations are available in the Roark dashboard, or you can fetch metrics for individual simulation calls via the API:

    ```typescript theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
    // Get metrics for a specific simulation call
    const metrics = await client.call.listMetrics('simulation-call-id')
    ```
  </Step>
</Steps>

***

### Additional Examples

<AccordionGroup>
  <Accordion title="Create a call with tool invocations">
    Track function calls and tool usage during the conversation:

    ```typescript theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
    const call = await client.call.create({
      recordingUrl: 'https://example.com/recording.mp3',
      startedAt: '2024-01-15T10:00:00Z',
      interfaceType: 'PHONE',
      callDirection: 'INBOUND',
      agent: {
        name: 'Booking Agent',
        customId: 'booking-agent-1',
      },
      customer: {
        phoneNumberE164: '+15551234567',
      },
      toolInvocations: [
        {
          name: 'checkAvailability',
          description: 'Check available appointment slots',
          startOffsetMs: 5000,
          endOffsetMs: 5500,
          parameters: {
            date: '2024-01-20',
            serviceType: 'consultation',
          },
          result: { slots: ['9:00 AM', '2:00 PM', '4:00 PM'] },
          agent: { customId: 'booking-agent-1' },
        },
        {
          name: 'bookAppointment',
          description: 'Book an appointment for the customer',
          startOffsetMs: 15000,
          endOffsetMs: 15800,
          parameters: {
            date: '2024-01-20',
            time: '2:00 PM',
            customerName: 'John Doe',
          },
          result: 'Appointment confirmed',
          agent: { customId: 'booking-agent-1' },
        },
      ],
    })
    ```
  </Accordion>

  <Accordion title="Create a call with an existing agent">
    Reference an agent by its Roark ID or custom ID:

    ```typescript theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
    // By Roark ID
    const call = await client.call.create({
      recordingUrl: 'https://example.com/recording.mp3',
      startedAt: '2024-01-15T10:00:00Z',
      interfaceType: 'WEB',
      callDirection: 'OUTBOUND',
      agent: {
        roarkId: '550e8400-e29b-41d4-a716-446655440000',
      },
      customer: {
        phoneNumberE164: '+15551234567',
      },
    })

    // By custom ID
    const call2 = await client.call.create({
      recordingUrl: 'https://example.com/recording.mp3',
      startedAt: '2024-01-15T10:00:00Z',
      interfaceType: 'PHONE',
      callDirection: 'INBOUND',
      agent: {
        customId: 'my-agent-id',
      },
      customer: {
        phoneNumberE164: '+15551234567',
      },
    })
    ```
  </Accordion>

  <Accordion title="Create a metric collection job for multiple calls">
    Run metrics across a batch of existing calls:

    ```typescript theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
    const job = await client.metricCollectionJob.create({
      callIds: [
        'call-uuid-1',
        'call-uuid-2',
        'call-uuid-3',
      ],
      metrics: [
        { id: 'metric-definition-uuid-1' },
        { id: 'metric-definition-uuid-2' },
      ],
    })

    // totalItems = callIds.length * metrics.length
    console.log(`Processing ${job.data.totalItems} items`)
    ```
  </Accordion>
</AccordionGroup>

### Additional Resources

<CardGroup cols={2}>
  <Card title="API Reference" icon="book-open" href="/api-reference/introduction">
    Explore our comprehensive API documentation
  </Card>

  <Card title="Example Repository" icon="github" href="https://github.com/roarkhq/sdk-roark-analytics-node/tree/main/examples">
    View example implementations and use cases
  </Card>

  <Card title="NPM Package" icon="npm" href="https://www.npmjs.com/package/@roarkanalytics/sdk">
    View package details and stats on npm
  </Card>

  <Card title="GitHub Repository" icon="github" href="https://github.com/roarkhq/sdk-roark-analytics-node">
    Browse the source code and contribute
  </Card>
</CardGroup>
