Skip to content

Integrations

Queria is designed to be integrated within proprietary applications. This guide outlines the available integration methods, from the embeddable widget to server-to-server communication.

Embeddable widget

The fastest way to add Queria to a website or company portal.

Basic install

Add the following HTML code before the closing </body> tag:

html
<script src="https://cdn.queria.pro/widget.js"></script>
<script>
  Queria.init({
    apiKey: 'qk_live_abc123def456ghi789jkl012',
    theme: 'light',
    position: 'bottom-right',
    language: 'en'
  });
</script>

Configuration options

OptionTypeDefaultDescription
apiKeystring-Domain-restricted API Key (required)
themestringlightTheme: light, dark, auto
positionstringbottom-rightPosition: bottom-right, bottom-left
languagestringitInterface language: it, en
primaryColorstring#2563ebPrimary color (hex)
titlestringAI AssistantTitle shown in the header
placeholderstringType a question...Input field placeholder
topicIdstring-Limits search to a specific topic
widthnumber400Widget width in pixels
heightnumber600Widget height in pixels

Advanced customization

html
<script>
  Queria.init({
    apiKey: 'qk_live_abc123def456ghi789jkl012',
    theme: 'dark',
    position: 'bottom-right',
    primaryColor: '#059669',
    title: 'Document Support',
    placeholder: 'Search company documents...',
    topicId: 'topic_contracts',
    onReady: function() {
      console.log('Queria widget loaded');
    },
    onMessage: function(message) {
      // Callback for every received message
      analytics.track('queria_response', { query: message.query });
    }
  });
</script>

Programmatic control

javascript
// Open the widget
Queria.open();

// Close the widget
Queria.close();

// Send a message programmatically
Queria.send('What is the return policy?');

// Destroy the instance
Queria.destroy();

REST API integration

For deeper integrations, use the REST API directly with server-to-server authentication.

+-----------------+     +------------------+     +-----------------+
|  Your App       |---->|  Your Backend    |---->|  Queria API     |
|  (Frontend)     |     |  (Server)        |     |                 |
+-----------------+     +------------------+     +-----------------+

The API Key must live exclusively on your backend. Your app's frontend communicates with your server, which in turn forwards requests to Queria.

Node.js example

javascript
const express = require('express');
const app = express();

const QUERIA_API_KEY = process.env.QUERIA_API_KEY; // qk_live_abc123...
const QUERIA_BASE_URL = 'https://api.queria.pro';

app.post('/api/ask', async (req, res) => {
  const { question, sessionId } = req.body;

  const response = await fetch(`${QUERIA_BASE_URL}/api/public/chat`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': QUERIA_API_KEY
    },
    body: JSON.stringify({
      message: question,
      sessionId: sessionId
    })
  });

  const data = await response.json();
  res.json({
    answer: data.data.response,
    sources: data.data.sources
  });
});

Python example

python
import requests
import os

QUERIA_API_KEY = os.environ['QUERIA_API_KEY']
QUERIA_BASE_URL = 'https://api.queria.pro'

def ask_queria(question: str, session_id: str = None) -> dict:
    response = requests.post(
        f'{QUERIA_BASE_URL}/api/public/chat',
        headers={
            'Content-Type': 'application/json',
            'X-API-Key': QUERIA_API_KEY
        },
        json={
            'message': question,
            'sessionId': session_id
        }
    )
    response.raise_for_status()
    result = response.json()
    return {
        'answer': result['data']['response'],
        'sources': result['data']['sources']
    }

Use cases

CRM integration

Embed document search in your CRM to let operators find contracts, offers and customer documentation directly from the management UI.

javascript
// Search documents for a specific customer
const results = await fetch(`${QUERIA_BASE_URL}/api/public/chat`, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': QUERIA_API_KEY
  },
  body: JSON.stringify({
    message: `Find active contracts for customer ${customerName}`,
    sessionId: `crm_${customerId}`
  })
});

ERP integration

Connect financial documents (invoices, orders, delivery notes) to enable intelligent searches on accounting and warehouse data.

Company portal

Add an AI assistant to the company intranet for internal knowledge base consultation: manuals, operating procedures, HR policies.

Customer support

Automate answers to frequently asked questions with precise citations from official documents, reducing response time and improving support quality.

Authentication for integrations

ScenarioMethodNotes
Widget on public siteAPI Key + domain restrictionThe domain must match
Backend-to-backendAPI KeyKeep the key on the server
App with user loginJWTEach user has their own token
Mobile appJWT + refresh tokenHandle automatic refresh

Best practices

Error handling

Implement a retry strategy with exponential backoff to handle transient errors:

javascript
async function queriaRequest(payload, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      const response = await fetch(`${QUERIA_BASE_URL}/api/public/chat`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'X-API-Key': QUERIA_API_KEY
        },
        body: JSON.stringify(payload)
      });

      if (response.status === 429) {
        const retryAfter = response.headers.get('Retry-After') || 5;
        await sleep(retryAfter * 1000);
        continue;
      }

      if (!response.ok) throw new Error(`HTTP ${response.status}`);
      return await response.json();
    } catch (error) {
      if (attempt === maxRetries - 1) throw error;
      await sleep(Math.pow(2, attempt) * 1000);
    }
  }
}

Rate limit handling

Monitor X-RateLimit-Remaining headers and slow down requests when the budget approaches zero. For high loads, contact support for custom limits.

Streaming for real-time responses

For interactive UIs, always use the streaming endpoint (/api/public/chat/stream) to show the answer progressively, improving the perception of responsiveness.

Caching

Implement an application-side cache for repeated queries. Queria already applies internal caching, but a local cache reduces latency and quota usage:

javascript
const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes

async function cachedQuery(question) {
  const key = question.toLowerCase().trim();
  const cached = cache.get(key);

  if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
    return cached.data;
  }

  const result = await queriaRequest({ message: question });
  cache.set(key, { data: result, timestamp: Date.now() });
  return result;
}

Queria - Document Intelligence con Cog-RAG