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

# Primeros Pasos

> Guía para desarrolladores que integran Neuracall

## Requisitos Previos

Antes de comenzar necesitas:

<Steps>
  <Step title="Credenciales de API">
    Solicita tu `client_id` y `client_secret` a [support@neuracall.com](mailto:support@neuracall.com).
  </Step>

  <Step title="Modelo de Análisis">
    Ten al menos un modelo configurado (puede ser el default).
  </Step>

  <Step title="Archivos de Audio">
    Grabaciones en formato soportado (MP3, WAV, etc.).
  </Step>
</Steps>

## Paso 1: Configurar Entorno

### Variables de Entorno

```bash theme={null}
export NEURACALL_CLIENT_ID="tu_client_id"
export NEURACALL_CLIENT_SECRET="tu_client_secret"
export NEURACALL_API_URL="https://api.neuracall.com"
```

### Dependencias

<CodeGroup>
  ```bash Python theme={null}
  pip install requests
  ```

  ```bash Node.js theme={null}
  npm install node-fetch form-data
  ```
</CodeGroup>

## Paso 2: Implementar Autenticación

Crea una clase o modulo para manejar tokens:

<CodeGroup>
  ```python Python theme={null}
  import os
  import time
  import requests

  class NeuracallClient:
      def __init__(self):
          self.base_url = os.environ.get("NEURACALL_API_URL", "https://api.neuracall.com")
          self.client_id = os.environ["NEURACALL_CLIENT_ID"]
          self.client_secret = os.environ["NEURACALL_CLIENT_SECRET"]
          self.token = None
          self.expires_at = 0

      def get_token(self):
          # Renovar si expira en menos de 5 minutos
          if time.time() > self.expires_at - 300:
              response = requests.post(
                  f"{self.base_url}/v1/auth",
                  json={
                      "client_id": self.client_id,
                      "client_secret": self.client_secret
                  }
              )
              response.raise_for_status()
              data = response.json()
              self.token = data["access_token"]
              self.expires_at = data["expires_at"]
          return self.token

      def _headers(self):
          return {"Authorization": f"Bearer {self.get_token()}"}
  ```

  ```javascript Node.js theme={null}
  class NeuracallClient {
    constructor() {
      this.baseUrl = process.env.NEURACALL_API_URL || "https://api.neuracall.com";
      this.clientId = process.env.NEURACALL_CLIENT_ID;
      this.clientSecret = process.env.NEURACALL_CLIENT_SECRET;
      this.token = null;
      this.expiresAt = 0;
    }

    async getToken() {
      if (Date.now() / 1000 > this.expiresAt - 300) {
        const response = await fetch(`${this.baseUrl}/v1/auth`, {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            client_id: this.clientId,
            client_secret: this.clientSecret
          })
        });
        const data = await response.json();
        this.token = data.access_token;
        this.expiresAt = data.expires_at;
      }
      return this.token;
    }

    async headers() {
      return { "Authorization": `Bearer ${await this.getToken()}` };
    }
  }
  ```
</CodeGroup>

## Paso 3: Crear Análisis

Agrega el método para enviar llamadas:

<CodeGroup>
  ```python Python theme={null}
  def create_analysis(self, audio_path, external_id, agent_id, agent_name, model_name, additional_params=None):
      with open(audio_path, "rb") as audio_file:
          files = {"audio_file": audio_file}
          data = {
              "external_id": external_id,
              "agent_id": agent_id,
              "agent_name": agent_name,
              "model_name": model_name
          }
          if additional_params:
              data["additional_parameters"] = json.dumps(additional_params)

          response = requests.post(
              f"{self.base_url}/v1/call-analysis",
              headers=self._headers(),
              files=files,
              data=data
          )
          response.raise_for_status()
          return response.json()
  ```

  ```javascript Node.js theme={null}
  async createAnalysis(audioPath, externalId, agentId, agentName, modelName, additionalParams = null) {
    const FormData = require("form-data");
    const fs = require("fs");

    const form = new FormData();
    form.append("audio_file", fs.createReadStream(audioPath));
    form.append("external_id", externalId);
    form.append("agent_id", agentId);
    form.append("agent_name", agentName);
    form.append("model_name", modelName);
    if (additionalParams) {
      form.append("additional_parameters", JSON.stringify(additionalParams));
    }

    const response = await fetch(`${this.baseUrl}/v1/call-analysis`, {
      method: "POST",
      headers: await this.headers(),
      body: form
    });
    return response.json();
  }
  ```
</CodeGroup>

## Paso 4: Obtener Resultados

Agrega métodos para consultar el estado:

<CodeGroup>
  ```python Python theme={null}
  def get_analysis(self, analysis_id):
      response = requests.get(
          f"{self.base_url}/v1/call-analysis/{analysis_id}",
          headers=self._headers()
      )
      response.raise_for_status()
      return response.json()

  def wait_for_completion(self, analysis_id, timeout=600, poll_interval=5):
      start = time.time()
      while time.time() - start < timeout:
          result = self.get_analysis(analysis_id)
          if result["status"] == "PROCESS_COMPLETED":
              return result
          elif result["status"] == "ERROR":
              raise Exception(f"Analysis failed: {result.get('error_message')}")
          time.sleep(poll_interval)
      raise TimeoutError("Analysis did not complete in time")
  ```

  ```javascript Node.js theme={null}
  async getAnalysis(analysisId) {
    const response = await fetch(
      `${this.baseUrl}/v1/call-analysis/${analysisId}`,
      { headers: await this.headers() }
    );
    return response.json();
  }

  async waitForCompletion(analysisId, timeout = 600000, pollInterval = 5000) {
    const start = Date.now();
    while (Date.now() - start < timeout) {
      const result = await this.getAnalysis(analysisId);
      if (result.status === "PROCESS_COMPLETED") return result;
      if (result.status === "ERROR") {
        throw new Error(`Analysis failed: ${result.error_message}`);
      }
      await new Promise(r => setTimeout(r, pollInterval));
    }
    throw new Error("Analysis did not complete in time");
  }
  ```
</CodeGroup>

## Paso 5: Uso Completo

<CodeGroup>
  ```python Python theme={null}
  # Ejemplo de uso completo
  client = NeuracallClient()

  # Crear análisis
  analysis = client.create_analysis(
      audio_path="llamada.mp3",
      external_id="CALL-2024-001",
      agent_id="AGT-001",
      agent_name="Juan Perez",
      model_name="Evaluación Servicio Cliente"
  )
  print(f"Análisis creado: {analysis['id']}")

  # Esperar resultado
  result = client.wait_for_completion(analysis["id"])
  print(f"NeuraScore: {result['score_percentage']}%")
  print(f"Resumen: {result['summary']}")
  ```

  ```javascript Node.js theme={null}
  // Ejemplo de uso completo
  const client = new NeuracallClient();

  // Crear análisis
  const analysis = await client.createAnalysis(
    "llamada.mp3",
    "CALL-2024-001",
    "AGT-001",
    "Juan Perez",
    "Evaluación Servicio Cliente"
  );
  console.log(`Análisis creado: ${analysis.id}`);

  // Esperar resultado
  const result = await client.waitForCompletion(analysis.id);
  console.log(`NeuraScore: ${result.score_percentage}%`);
  console.log(`Resumen: ${result.summary}`);
  ```
</CodeGroup>

## Siguientes Pasos

<CardGroup cols={2}>
  <Card title="Ejemplo Python" icon="python" href="/integrations/examples/python">
    Código completo en Python
  </Card>

  <Card title="Ejemplo Node.js" icon="node-js" href="/integrations/examples/nodejs">
    Código completo en Node.js
  </Card>

  <Card title="API Reference" icon="book" href="/api-reference/introduction">
    Documentación completa
  </Card>

  <Card title="Ejemplos cURL" icon="terminal" href="/integrations/examples/curl">
    Pruebas rapidas
  </Card>
</CardGroup>
