Orova API Documentation

Connect your CRM and leverage AI-powered customer interactions

API Overview

Everything you need to integrate your CRM with Orova

Connect External CRM

Push contacts from your CRM to Orova's database with our simple API integration.

Retrieve History Data

Access detailed interaction history, including call recordings, transcripts, and outcomes.

Real-time Integration

Set up webhooks for real-time data exchange between your systems and Orova.

Authentication

Secure your API requests with JWT authentication

Obtaining an Access Token

All requests to the Orova API require authentication using JWT (JSON Web Tokens). To obtain an access token, make a POST request to the login endpoint.

Endpoint

POST /api/auth/login

Request Body

{
  "username": "your_username",
  "password": "your_password"
}

Response

{
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

For all subsequent requests, include the access token in the Authorization header:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Authentication Example
// Example: Obtaining an access token
        const axios = require('axios');

        async function getAccessToken(username, password) {
        try {
            const response = await axios.post(
            'https://app.orova.ai/api/auth/login',
            {
                username: username,
                password: password
            }
            );
            
            return response.data.accessToken;
        } catch (error) {
            console.error('Authentication failed:', error);
            throw error;
        }
        }

        // Usage
        getAccessToken('your_username', 'your_password')
        .then(token => {
            console.log('Access token:', token);
            // Use this token for subsequent API calls
        });

CRM Integration

Connect your external CRM to push contacts to Orova

Webhook Integration

For real-time integration, you can set up a webhook to receive contacts from your CRM system.

Endpoint

POST /api/contacts/webhook-contacts

Request Headers

Content-Type: application/json
                    Authorization: Bearer {your_access_token}

Request Body

The request body should follow the same structure as the direct API integration method. You can send a single contact or an array of contacts:


{
  "value": 
    [
      {
        "contactName": "John Doe",
        "phoneNumber": "+12345678901",
        "campaign": "Sales",
        "region": "Asia/Dubai",
        "customerId":"1234567"
      },
      {
        "contactName": "Jane Smith",
        "phoneNumber": "+12345678902",
        "campaign": "Client",
        "region": "Asia/Dubai",
        "customerId":"1234567"
      }
    ]
  }

Contact Data Structure

The following table describes the fields supported when pushing contacts to Orova:

Field Type Required Description
customerId String Yes CustomerId is required for existing customers to enable proper webhook updates
contactName String Yes Full name of the contact
phoneNumber String Yes Phone number with international format (e.g., "+12345678901")
campaign String Yes List of campaign names the contact belongs to
region String No Geographic region of the contact (e.g., "Asia/Dubai")

History Data

Receive call history data from Orova

Webhook Integration for History Data

Orova automatically sends call history data to your system via webhooks after each call is completed. You don't need to retrieve history records manually - instead, you provide us with your webhook endpoint.

Setup Required: Contact Orova support to configure your webhook endpoint. We will send all call history data to your specified URL in real-time as calls are completed.

Your Webhook Endpoint

Your webhook should be able to receive POST requests with call history data. When you provide a contact with a customerId, we will send a PUT request to update that specific customer.

POST https://your-domain.com/webhook

For new customers without customerId:

PUT https://your-domain.com/webhook/{customerId}

For existing customers with customerId (updates the specific customer record):

Webhook Authentication

We recommend securing your webhook endpoint with authentication headers or API keys. During setup, provide us with any required authentication details.

Important: When pushing contacts to Orova, include the customerId field for existing customers. This ensures we can update the correct record in your system via PUT requests to your webhook.

Webhook Handler Example
// Example: Webhook endpoint handler
const express = require('express');
const app = express();

app.use(express.json());

// Handle new call history data
app.post('/webhook', async (req, res) => {
  try {
    const historyData = req.body;
    
    // Process new call history
    console.log('New call history received:', historyData);
    
    // Save to your database
    await saveCallHistory(historyData);
    
    res.status(200).json({ success: true });
  } catch (error) {
    console.error('Webhook error:', error);
    res.status(500).json({ error: 'Internal server error' });
  }
});

// Handle customer updates (when customerId provided)
app.put('/webhook/:customerId', async (req, res) => {
  try {
    const customerId = req.params.customerId;
    const historyData = req.body;
    
    // Update existing customer record
    console.log(`Updating customer ${customerId}:`, historyData);
    
    // Update your database
    await updateCustomerHistory(customerId, historyData);
    
    res.status(200).json({ success: true });
  } catch (error) {
    console.error('Customer update error:', error);
    res.status(500).json({ error: 'Internal server error' });
  }
});

app.listen(3000, () => {
  console.log('Webhook server running on port 3000');
});

History Data Structure

The following is an example of the call history data that will be sent to your webhook:

{
  "fullName": "John Doe",
  "mobileNumber": "+12345678901",
  "callStartTime": "2024-06-05T10:30:00.000Z",
  "callEndTime": "2024-06-05T10:35:45.000Z",
  "callDuration": 345000,
  "callEndReason": "customer-ended-call",
  "callCost": "1.75",
  "recordingUrl": "https://storage.orova.ai/recordings/call.mp3",
  "callTranscript": "Agent: Hello, this is Sales Agent from Orova...",
  "callSummary": "The contact expressed interest in Project Alpha and agreed to schedule a property viewing.",
  "emotions": "positive",
  "timezone": "Asia/Dubai",
}

Code Examples

Implementation examples in different programming languages

Node.js Example

Example of pushing a contact to Orova API using Node.js:

const axios = require('axios');

async function pushContactToOrova(contact, accessToken) {
  try {
    const response = await axios.post(
      'https://app.orova.ai/api/contacts',
      contact,
      {
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${accessToken}`
        }
      }
    );

    console.log('Contact pushed successfully:', response.data);
    return response.data;
  } catch (error) {
    console.error('Error pushing contact to Orova:', error.response?.data || error.message);
    throw error;
  }
}

const contact = {
  "contactName": "John Doe",
  "phoneNumber": "+12345678901",
  "campaigns": ["sales"],
  "region": "Asia/Dubai",
};

const accessToken = 'your_access_token_here';
pushContactToOrova(contact, accessToken);

Python Example

Example of retrieving history records using Python:

import requests
import json

def get_history_records(access_token, page=1, limit=20, search=None, filter_type=None):
    url = 'https://app.orova.ai/api/history'

    params = {
        'page': page,
        'limit': limit
    }

    if search:
        params['search'] = search

    if filter_type:
        params['filterType'] = filter_type

    headers = {
        'Authorization': f'Bearer {access_token}'
    }

    response = requests.get(url, params=params, headers=headers)

    if response.status_code == 200:
        return response.json()
    else:
        raise Exception(f"Error retrieving history records: {response.text}")

access_token = 'your_access_token_here'
history_data = get_history_records(access_token, page=1, limit=10)
print(json.dumps(history_data, indent=2))

Golang Example

Example of pushing a contact to Orova API using Golang:

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"
)

func main() {
    contact := map[string]interface{}{
        "contactName": "John Doe",
        "phoneNumber": "+12345678901",
        "campaigns":   []string{"sales"},
        "region":      "Asia/Dubai",
    }

    jsonData, err := json.Marshal(contact)
    if err != nil {
        panic(err)
    }

    req, err := http.NewRequest("POST", "https://app.orova.ai/api/contacts", bytes.NewBuffer(jsonData))
    if err != nil {
        panic(err)
    }

    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("Authorization", "Bearer your_access_token_here")

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    fmt.Println("Response Status:", resp.Status)
}

Troubleshooting

Common issues and solutions

Authentication Issues

+

Issue: "Invalid credentials" error when trying to obtain an access token

Solution:

  • Verify that you're using the correct username and password
  • Ensure you're using the correct endpoint for authentication (/api/auth/login)
  • Check if your account has been locked due to too many failed attempts

Issue: "Token expired" or "Invalid token" errors

Solution:

  • Your access token has expired. Use the refresh token to obtain a new access token
  • If the refresh token is also expired, you'll need to log in again
  • Ensure you're including the token in the correct format: Bearer {token}

Contact Integration Issues

+

Issue: "Phone number format invalid" error when pushing contacts

Solution:

  • Ensure phone numbers are in international format with the country code (e.g., "+12345678901")
  • Remove any spaces, dashes, or other non-digit characters from the phone number
  • If you're unsure about the format, use a phone number validation library

Issue: Duplicate contacts being created

Solution:

  • The API identifies contacts by phone number
  • If you're seeing duplicates, check if there are slight variations in the phone number format
  • Consider implementing a pre-processing step to standardize phone numbers before pushing to Orova

History Data Issues

+

Issue: Unable to retrieve history records

Solution:

  • Verify that you have the correct permissions to access history data
  • Check if you're using the correct endpoint (/api/history)
  • Ensure your access token is valid and has not expired

Issue: Missing fields in history records

Solution:

  • Some fields may be optional and only present in certain types of interactions
  • Check the documentation for the specific field to understand when it's included
  • If you believe a required field is missing, contact Orova support