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

# Observability

> Monitor and analyze your VAPI-based voice agents

export const CopyPageButton = () => {
  if (typeof window !== 'undefined') {
    setTimeout(function () {
      if (document.getElementById('ck-tools')) return;
      var anchor = document.getElementById('content-area') || document.querySelector('.mdx-content');
      if (!anchor) return;
      if (!document.getElementById('ck-style')) {
        var s = document.createElement('style');
        s.id = 'ck-style';
        s.textContent = '#ck-tools{position:absolute;top:6px;right:0;z-index:100;font-family:inherit;}' + '.ck-row{display:inline-flex;align-items:stretch;border:1px solid rgba(0,0,0,0.15);border-radius:8px;overflow:hidden;background:#fff;}' + ':root.dark .ck-row{background:rgba(255,255,255,0.06);border-color:rgba(255,255,255,0.12);}' + '.ck-btn{padding:5px 12px;border:none;background:none;cursor:pointer;font-size:13px;font-weight:500;font-family:inherit;color:#374151;}' + ':root.dark .ck-btn{color:#d1d5db;}' + '.ck-btn:hover{background:rgba(0,0,0,0.04);}' + ':root.dark .ck-btn:hover{background:rgba(255,255,255,0.06);}' + '.ck-chevron{padding:5px 8px;border:none;background:none;cursor:pointer;font-size:14px;font-family:inherit;color:#374151;}' + ':root.dark .ck-chevron{color:#d1d5db;}' + '.ck-chevron:hover{background:rgba(0,0,0,0.04);}' + ':root.dark .ck-chevron:hover{background:rgba(255,255,255,0.06);}' + '.ck-divider{width:1px;background:rgba(0,0,0,0.12);flex-shrink:0;}' + ':root.dark .ck-divider{background:rgba(255,255,255,0.12);}' + '.ck-dd{position:absolute;top:calc(100% + 4px);right:0;min-width:180px;background:#fff;border:1px solid rgba(0,0,0,0.12);border-radius:8px;box-shadow:0 4px 12px rgba(0,0,0,0.1);padding:4px;display:none;z-index:200;}' + ':root.dark .ck-dd{background:#1f2937;border-color:rgba(255,255,255,0.1);box-shadow:0 4px 16px rgba(0,0,0,0.35);}' + '.ck-item{display:block;width:100%;padding:7px 12px;border:none;background:none;border-radius:6px;cursor:pointer;font-size:13px;font-family:inherit;text-align:left;color:#374151;}' + ':root.dark .ck-item{color:#d1d5db;}' + '.ck-item:hover{background:rgba(0,0,0,0.05);}' + ':root.dark .ck-item:hover{background:rgba(255,255,255,0.07);}';
        document.head.appendChild(s);
      }
      var wrap = document.createElement('div');
      wrap.id = 'ck-tools';
      var row = document.createElement('div');
      row.className = 'ck-row';
      var mainBtn = document.createElement('button');
      mainBtn.className = 'ck-btn';
      mainBtn.textContent = 'Copy page';
      var divider = document.createElement('span');
      divider.className = 'ck-divider';
      var chevron = document.createElement('button');
      chevron.className = 'ck-chevron';
      chevron.textContent = '▾';
      var dd = document.createElement('div');
      dd.className = 'ck-dd';
      function closeDD() {
        dd.style.display = 'none';
      }
      function openDD() {
        dd.style.display = 'block';
      }
      chevron.onclick = function (e) {
        e.stopPropagation();
        if (dd.style.display === 'block') {
          closeDD();
        } else {
          openDD();
        }
      };
      document.addEventListener('click', function (e) {
        if (!e.target.closest('#ck-tools')) {
          closeDD();
        }
      });
      document.addEventListener('keydown', function (e) {
        if (e.key === 'Escape') {
          closeDD();
        }
      });
      function makeItem(label, fn) {
        var b = document.createElement('button');
        b.className = 'ck-item';
        b.textContent = label;
        b.onclick = function () {
          fn();
          closeDD();
        };
        return b;
      }
      function getMarkdown() {
        var walk = function (node) {
          if (!node) return '';
          if (node.nodeType === 3) return node.textContent || '';
          if (node.nodeType !== 1) return '';
          var tag = node.tagName.toLowerCase();
          var skip = ['script', 'style', 'svg', 'noscript', 'button', 'iframe'];
          if (skip.indexOf(tag) !== -1) return '';
          if (node.id === 'ck-tools') return '';
          var ch = Array.from(node.childNodes).map(walk).join('');
          if (tag === 'h1') return '\n# ' + ch.trim() + '\n\n';
          if (tag === 'h2') return '\n## ' + ch.trim() + '\n\n';
          if (tag === 'h3') return '\n### ' + ch.trim() + '\n\n';
          if (tag === 'p') return '\n' + ch.trim() + '\n\n';
          if (tag === 'pre') return '\n```\n' + node.textContent.trim() + '\n```\n\n';
          if (tag === 'li') return '- ' + ch.trim() + '\n';
          if (tag === 'code') return '`' + ch.trim() + '`';
          return ch;
        };
        var content = document.querySelector('.mdx-content') || document.getElementById('content-area') || document.body;
        return walk(content).replace(/\n\n\n+/g, '\n\n').trim();
      }
      function copyMd() {
        var md = getMarkdown();
        navigator.clipboard.writeText(md).then(function () {
          mainBtn.textContent = 'Copied!';
          setTimeout(function () {
            mainBtn.textContent = 'Copy page';
          }, 2000);
        });
      }
      function viewMd() {
        var md = getMarkdown();
        var safe = md.split('&').join('&amp;').split('<').join('&lt;').split('>').join('&gt;');
        var html = '<!DOCTYPE html><html><head><meta charset="utf-8"><style>body{font-family:monospace;max-width:860px;margin:40px auto;padding:0 24px;line-height:1.7;white-space:pre-wrap;word-wrap:break-word}</style></head><body>' + safe + '</body></html>';
        window.open(URL.createObjectURL(new Blob([html], {
          type: 'text/html'
        })), '_blank');
      }
      function openClaude() {
        var prompt = 'Can you read this Cekura docs page ' + window.location.href + ' so I can ask you questions?';
        window.open('https://claude.ai/new?q=' + encodeURIComponent(prompt), '_blank');
      }
      mainBtn.onclick = copyMd;
      dd.appendChild(makeItem('Copy page', copyMd));
      dd.appendChild(makeItem('View as Markdown', viewMd));
      dd.appendChild(makeItem('Open in Claude', openClaude));
      row.appendChild(mainBtn);
      row.appendChild(divider);
      row.appendChild(chevron);
      wrap.appendChild(row);
      wrap.appendChild(dd);
      anchor.style.position = 'relative';
      anchor.insertBefore(wrap, anchor.firstChild);
    }, 50);
  }
  return null;
};

<CopyPageButton />

## Overview

Learn how to monitor, analyze, and optimize your VAPI-based voice agents using Cekura's observability tools. This guide will walk you through setting up and configuring your VAPI integration.

<Tabs>
  <Tab title="Auto-fetch">
    Auto-fetch is the simplest way to get VAPI calls into Cekura. When enabled, Cekura pulls your call data from VAPI every 30 seconds—no webhook configuration required.

    <Steps>
      <Step title="Create or select an agent">
        In your Cekura dashboard, create a new agent or select an existing one with VAPI as the voice provider.
      </Step>

      <Step title="Add VAPI credentials">
        In the Agent Settings page:

        1. Select **VAPI** as the voice integration provider
        2. Add your VAPI API key
        3. Enter your VAPI Assistant ID
      </Step>

      <Step title="Enable auto-fetch">
        Toggle on **Auto-fetch Production Calls** in the voice integration settings.
      </Step>

      <Step title="Test your integration">
        Make a test call from VAPI. Within 30 seconds, your call should appear in the Cekura observability `Calls` section.
      </Step>
    </Steps>

    <Tip>
      Auto-fetch is ideal for getting started quickly or when you can't configure webhooks. For real-time call data, use the webhook-based setup in the other tabs.
    </Tip>
  </Tab>

  <Tab title="No-code VAPI Integration">
    Follow these steps to connect your VAPI agent with Cekura's observability suite:

    <Steps>
      <Step title="Get your Cekura API Key">
        Navigate to the [API keys](https://dashboard.cekura.ai/dashboard/settings/org/api-key) section in your Cekura dashboard settings. If you don't have an API key yet, create a new one. Copy the API key value as you'll need it to authenticate your requests to Cekura's observability API.

        <img src="https://mintcdn.com/vocera/dNswc2jz4aJrHV2E/images/Cekura_credentials.png?fit=max&auto=format&n=dNswc2jz4aJrHV2E&q=85&s=e9f5a070ca5fe1265bf6ed2b8305d041" alt="Cekura API Key Configuration" width="1711" height="334" data-path="images/Cekura_credentials.png" />
      </Step>

      <Step title="Add Cekura credentials to VAPI">
        In your VAPI dashboard, navigate to [integrations](https://dashboard.vapi.ai/settings/integrations/custom-credential) in your account settings and add custom integration with the following details:

        * Auth type: Bearer token
        * Credential name: Cekura API key
        * Token: Your Cekura API key
        * Header name: X-CEKURA-API-KEY
        * Include bearer prefix: No

                  <img src="https://mintcdn.com/vocera/dNswc2jz4aJrHV2E/images/Vapi_custom_credentials.png?fit=max&auto=format&n=dNswc2jz4aJrHV2E&q=85&s=efb74e4e8e93516d2a6d68eb72a152bf" alt="VAPI Cekura Credentials Configuration" width="527" height="649" data-path="images/Vapi_custom_credentials.png" />
      </Step>

      <Step title="Configure Server URL in VAPI">
        In your VAPI dashboard, navigate to your agent settings and configure the Server URL and authorization header you created in the previous step. This URL is used for all communication between your application and VAPI, including context retrieval, function calls, and end-of-call reporting.

        Set the Server URL to:

        ```
        https://api.cekura.ai/observability/v1/vapi/observe/?agent_id=YOUR_AGENT_ID
        ```

        <img src="https://mintcdn.com/vocera/dNswc2jz4aJrHV2E/images/Vapi_observability.png?fit=max&auto=format&n=dNswc2jz4aJrHV2E&q=85&s=8486f7ef0563315ab4ee3cf8e98f9cf6" alt="VAPI Server URL Configuration" width="1239" height="668" data-path="images/Vapi_observability.png" />
      </Step>

      <Step title="Get your Assistant ID">
        Each VAPI agent has a unique Assistant ID that identifies your specific implementation. Copy your Assistant ID from the VAPI dashboard:

        <img src="https://mintcdn.com/vocera/ZbH6QacHNiZbtlBz/images/vapi-assistant-id.png?fit=max&auto=format&n=ZbH6QacHNiZbtlBz&q=85&s=96972b83213891c261720d1281925557" alt="VAPI Assistant ID" width="1846" height="192" data-path="images/vapi-assistant-id.png" />
      </Step>

      <Step title="Add credentials to Cekura">
        In your Cekura Agent Settings page:

        1. Add the API key from VAPI with the tag `webhook`
        2. Copy and add your `agent ID` from VAPI

                   <img src="https://mintcdn.com/vocera/jgU_15-26qRVL6Rl/images/vapi/agent-settings.png?fit=max&auto=format&n=jgU_15-26qRVL6Rl&q=85&s=4f7d709f640a47f3db13b1da487e16e5" alt="Navigate to API Keys" width="1285" height="861" data-path="images/vapi/agent-settings.png" />
      </Step>

      <Step title="Test your integration">
        Make a test call from VAPI (phone number based or webcall). Your calls should now appear in the Cekura observability `Calls` section.
      </Step>
    </Steps>
  </Tab>

  <Tab title="Forwarding VAPI respone">
    If you already have an existing webhook setup and want to forward the VAPI response to Cekura's observability suite:

    <Steps>
      <Step title="Configure forwarding endpoint">
        Set up a forwarding mechanism to send the VAPI webhook response to Cekura's observability endpoint:

        ```
        POST https://api.cekura.ai/observability/v1/observe/
        ```
      </Step>

      <Step title="Add authentication headers">
        Include your Cekura API key in the request headers:

        ```
        X-CEKURA-API-KEY: <your_cekura_api_key>
        Content-Type: application/json
        ```
      </Step>

      <Step title="Forward the request body">
        Forward the VAPI webhook response to Cekura with the following request body structure:

        ```json theme={null}
        {
          "agent": <agent_id_in_cekura>,
          "voice_recording_url": vapi_response["stereoRecordingUrl"],
          "transcript_type": "vapi",
          "transcript_json": vapi_response["messages"],
          "call_id": vapi_response["id"],
          "call_ended_reason": vapi_response["endedReason"]
        }
        ```
      </Step>
    </Steps>
  </Tab>
</Tabs>
