Développeurs

Intégrez les appels traduits dans vos propres systèmes

Owaa for Business offre une API REST pour passer et examiner les appels traduits, un webhook signé pour le routage entrant, et un serveur MCP qui permet aux assistants IA de travailler avec votre compte sous des limites que vous contrôlez.

Sur cette page

Authentification

Authentification avec une clé API

Chaque requête contient votre clé en tant que jeton Bearer. Créez des clés dans la console Owaa for Business. Une clé n'est affichée qu'une seule fois lors de sa création, alors stockez-la dans votre gestionnaire de secrets.

URL de base

https://b2b.owaa.ai/v1/b2b/admin

curl: GET /billing
curl https://b2b.owaa.ai/v1/b2b/admin/billing \
  -H "Authorization: Bearer $API_KEY"

Envoyez la clé dans l'en-tête Authorization. Les clés ne sont pas acceptées en tant que paramètre de requête.

Les clés API ne peuvent appeler que les points d'intégration listés sur cette page, et le serveur MCP. La gestion des clés API, des membres de l'équipe, des recharges de facturation, des identifiants d'opérateur et des limites de dépenses nécessite une session console connectée.

Faites pivoter une clé depuis la console (page des clés API) : la nouvelle clé est affichée une fois et l'ancienne cesse de fonctionner immédiatement.

Une requête avec une clé manquante ou invalide renvoie 401. Les tentatives échouées répétées depuis une même adresse sont bloquées pendant un certain temps.

API REST

Points d'intégration

Tous les chemins sont relatifs à l'URL de base. Les requêtes et les réponses sont en JSON, sauf les enregistrements, qui diffusent de l'audio.

  • POST/calls/originate

    Démarrez un appel traduit entre le téléphone de votre agent et un tiers, en utilisant votre propre compte Twilio connecté.

  • GET/caller-id/preview?destination=

    Simulez une destination : affiche l'ID de l'appelant qui serait utilisé, afin que les problèmes d'ID d'appelant apparaissent avant que vous ne composiez.

  • GET/calls

    Liste les segments d'appel, du plus récent au plus ancien. Filtrez avec la limite (1 à 200) et le statut, et paginez avec le curseur dans next_cursor.

  • GET/calls/{id}

    Récupère un seul segment d'appel.

  • GET/calls/{id}/recording

    Diffuse l'enregistrement d'un segment en audio Opus. Choisissez le côté avec side=in ou side=out.

  • GET/billing

    Lisez votre solde, le tarif par minute, les minutes restantes et le seuil de solde faible.

  • GET/twilio-numbers

    Listez vos numéros Twilio avec leur identifiant, leurs paramètres de routage et leur statut. Lecture seule : aucune information d'identification n'est renvoyée.

  • PUT/twilio-numbers/{id}/route

    Définissez l'URL de routage entrant et la destination de secours pour l'un de vos numéros Twilio.

Exemple

Passer un appel traduit

Envoyez le numéro de l'agent et le numéro du tiers. Les langues et les identifiants d'appelant sont facultatifs, et les champs inconnus sont rejetés.

POST /calls/originate
curl -X POST https://b2b.owaa.ai/v1/b2b/admin/calls/originate \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_number": "+14165550100",
    "far_number": "+34600000000",
    "agent_language": "en",
    "far_language": "es"
  }'
201 Created
{
  "bridge_id": "...",
  "agent_call_sid": "...",
  "far_call_sid": "...",
  "agent_caller_id": "+14165550101",
  "far_caller_id": "+14165550101",
  "agent_must_confirm": false
}

Une requête réussie renvoie 201 avec les identifiants de l'appel. Exécutez d'abord l'aperçu de l'ID de l'appelant pour éviter les cas 409.

Lister les étapes d'appel récentes. Utilisez le point de terminaison de facturation de la même manière pour lire votre solde.

curl: GET /calls
curl "https://b2b.owaa.ai/v1/b2b/admin/calls?limit=20" \
  -H "Authorization: Bearer $API_KEY"

Pour définir le routage, vous avez besoin de l'identifiant du numéro. Trouvez-le avec GET /twilio-numbers, qui liste vos numéros (affichés ici avec les champs principaux).

curl: GET /twilio-numbers
curl https://b2b.owaa.ai/v1/b2b/admin/twilio-numbers \
  -H "Authorization: Bearer $API_KEY"
200 OK
[
  {
    "id": "<number_id>",
    "phone_number_e164": "+14165550101",
    "friendly_name": "Support line",
    "country_code": "CA",
    "voice_enabled": true,
    "verified": true,
    "routes_to_owaa": true,
    "inbound_destination_e164": "+34600000000",
    "inbound_routing_url": "https://example.com/owaa/route",
    "agent_language": "es",
    "caller_language_hint": "en"
  }
]

Définissez ensuite le routage entrant pour ce numéro avec PUT /twilio-numbers/{id}/route : l'URL que Owaa appelle pour chaque appel entrant, la destination de secours, et éventuellement la langue de l'agent et un indice de langue pour l'appelant.

curl: PUT /twilio-numbers/{id}/route
curl -X PUT https://b2b.owaa.ai/v1/b2b/admin/twilio-numbers/<number_id>/route \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "routing_url": "https://example.com/owaa/route",
    "destination_e164": "+34600000000",
    "agent_language": "es",
    "caller_language_hint": "en"
  }'

Routage entrant

Router les appels entrants avec un webhook signé

Pour chaque appel entrant sur un numéro routé vers votre URL, Owaa envoie un POST et attend jusqu'à trois secondes. Si votre point de terminaison échoue, expire ou renvoie un JSON invalide, l'appel est dirigé vers la destination de secours que vous avez configurée et la raison est enregistrée.

Corps de la requête

call.inbound
{
  "event": "call.inbound",
  "call_id": "...",
  "tenant_id": "...",
  "from": "+14165550100",
  "to": "+14165550101",
  "twilio_call_sid": "...",
  "received_at": "..."
}

Répondez avec 200 et connectez ou rejetez. Un caller_id que vous ne possédez pas est ignoré.

response: connect
{ "action": "connect", "destination": "+34600000000", "caller_id": "+14165550101" }
response: reject
{ "action": "reject", "reason": "closed" }

X-Owaa-Signature Chaque requête contient un en-tête X-Owaa-Signature sous la forme t=<secondes unix>,v1=<hex>. La valeur v1 est le HMAC-SHA256 de l'horodatage, un point et le corps de la requête brut, chiffré avec votre secret de routage. Vérifiez-le par rapport au corps brut et rejetez les horodatages de plus de cinq minutes.

Votre secret de routage est affiché une seule fois sur la page Routage de la console.

La fenêtre de temps limite les relectures à cinq minutes. Pour bloquer les relectures à l'intérieur de celle-ci, mémorisez également le call_id de chaque requête que vous avez déjà traitée.

Node.js
import { createHmac, timingSafeEqual } from "node:crypto";

// rawBody: the exact bytes received, as a string or Buffer.
// Never re-serialise parsed JSON: that changes the bytes and the signature.
export function verifyOwaaSignature(rawBody, header, secret) {
  const parts = Object.fromEntries(
    String(header ?? "").split(",").map((p) => p.split("=")),
  );
  const t = parts.t ?? "";
  if (!/^\d+$/.test(t) || !(Math.abs(Date.now() / 1000 - Number(t)) <= 300)) return false;
  const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest();
  const given = Buffer.from(parts.v1 ?? "", "hex");
  return given.length === expected.length && timingSafeEqual(given, expected);
}
Python
import hashlib
import hmac
import time


def verify_owaa_signature(raw_body: bytes, header: str, secret: str) -> bool:
    parts = dict(p.split("=", 1) for p in (header or "").split(",") if "=" in p)
    try:
        t = int(parts["t"])
    except (KeyError, ValueError):
        return False
    if abs(time.time() - t) > 300:
        return False
    signed = f"{t}.".encode() + raw_body
    expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, parts.get("v1", ""))

Limites et erreurs

Limites de débit et réponses d'erreur

Les limites s'appliquent par entreprise, chaque minute. Lorsqu'une limite est dépassée, l'API renvoie 429 avec un en-tête Retry-After.

  • 600 requêtes de lecture par minute
  • 120 requêtes d'écriture par minute
  • 60 téléchargements d'enregistrements par minute
  • 401Clé API manquante ou invalide.
  • 402Solde insuffisant pour démarrer l'appel.
  • 409Aucun identifiant d'appelant utilisable, ou aucun compte Twilio vérifié connecté.
  • 422Twilio a refusé l'appel, ou un identifiant d'appelant que vous avez nommé ne vous appartient pas.
  • 429Limite de débit dépassée : attendez le temps indiqué dans Retry-After. Également renvoyé à une adresse temporairement bloquée après des clés invalides répétées.

L'API n'a pas de clé d'idempotence. Si une requête pour passer un appel expire, listez vos appels récents avant de l'envoyer à nouveau.

Serveur MCP

Laissez les assistants IA travailler avec votre compte

Le serveur MCP d'Owaa permet aux assistants IA compatibles MCP de consulter les coûts d'appel, de passer des appels traduits et de revoir l'activité de votre entreprise, dans les limites de dépenses que vous avez définies.

Disponible sur demande

Le serveur MCP est disponible sur demande. Contactez-nous pour l'activer pour votre entreprise.

Point de terminaison

https://mcp.owaa.ai/business

Transport HTTP en flux.

Se connecter

Avec une clé API : envoyez-la comme un jeton Bearer dans l'en-tête Authorization.

Avec OAuth : les clients qui prennent en charge OAuth 2.1 avec PKCE peuvent se connecter et se voient accorder l'accès depuis la console. Chaque autorisation peut être révoquée.

Configuration du client

Ajoutez le serveur à tout client MCP qui prend en charge les serveurs HTTP distants, et remplacez l'espace réservé par votre clé.

mcp.json
{
  "mcpServers": {
    "owaa": {
      "type": "http",
      "url": "https://mcp.owaa.ai/business",
      "headers": { "Authorization": "Bearer <your-api-key>" }
    }
  }
}
Claude Code
claude mcp add --transport http owaa https://mcp.owaa.ai/business \
  --header "Authorization: Bearer <your-api-key>"

Outils

  • list_languagesLister les langues disponibles pour les appels traduits.
  • check_call_costEstimer le coût d'un appel avant qu'il ne soit passé.
  • get_callObtenir un appel, avec son statut et son coût.
  • list_recent_activityLister l'activité récente sur votre compte.
  • place_translated_callPasser un appel traduit : fait sonner le téléphone de votre opérateur, puis celui de l'interlocuteur distant. Dépense votre solde.
  • delegate_call_taskConfier une tâche téléphonique à l'agent IA d'Owaa, avec un objectif et les champs à collecter. Disponible lorsque activé pour votre entreprise.
  • get_taskVérifier la progression et le résultat d'une tâche déléguée.
  • cancel_taskAnnuler une tâche déléguée.

Portées

  • activity:readRechercher des langues, des coûts, des appels et des tâches. Toujours accordé.
  • calls:translatePasser des appels traduits.
  • tasks:delegateDéléguer des tâches téléphoniques.

Les portées d'une clé API sont définies dans la console. Un outil en dehors des portées de la clé renvoie scope_not_granted.

Le serveur demande aux assistants de vérifier le coût et de confirmer avec l'utilisateur avant tout appel payant.

Les outils renvoient les erreurs sous forme de code et de message, par exemple insufficient_balance, country_not_allowed ou rate_limited. Ne réessayez pas outcome_unknown aveuglément : vérifiez d'abord l'appel.

Sécurité

Comment l'accès est protégé

Chiffré en transit

Tout le trafic API et MCP utilise TLS, avec HSTS.

Clés API

Les clés sont de longs secrets aléatoires, affichés une seule fois lors de leur création et stockés uniquement sous forme de hachage. Révoquez ou faites pivoter une clé à tout moment et l'ancienne cesse de fonctionner immédiatement. Les tentatives échouées répétées sont bloquées.

Limites de débit

600 lectures, 120 écritures et 60 téléchargements d'enregistrements par minute par entreprise, avec 429 et Retry-After en cas de dépassement.

Webhooks signés

Les requêtes de routage entrantes sont signées avec HMAC-SHA256 et un horodatage. Vérifiez la signature et rejetez les requêtes de plus de cinq minutes. Une réponse ne peut pas présenter un identifiant d'appelant que votre entreprise ne possède pas.

Votre compte opérateur

Les appels s'exécutent sur votre propre compte Twilio, et vos identifiants Twilio sont chiffrés au repos.

Autorisation MCP

OAuth 2.1 avec PKCE. Les jetons sont liés à la ressource MCP, les jetons d'accès sont de courte durée, les jetons de rafraîchissement tournent à chaque utilisation, et un jeton de rafraîchissement rejoué révoque l'autorisation. Seuls les digests des jetons sont stockés, et les autorisations peuvent être révoquées depuis la console.

Portées séparées

La lecture et la dépense sont des portées distinctes. Un assistant a besoin de calls:translate ou tasks:delegate avant de pouvoir passer un appel ou démarrer une tâche.

Limites de dépense qu'un assistant ne peut pas augmenter

Chaque clé a une limite de dépense quotidienne et votre entreprise a un plafond quotidien, tous deux avec des valeurs par défaut conservatrices et un maximum de plateforme. Seule une session console connectée peut les modifier, jamais une clé API ou un client IA.

Listes d'autorisation

Les appels sont limités à une liste de pays autorisés, et vous pouvez restreindre les numéros de téléphone d'opérateurs qu'un assistant peut composer. Les deux sont gérés en dehors de la connexion MCP.

Piste d'audit

Chaque appel d'outil MCP est enregistré avec son résultat et le client qui l'a effectué.

Les transcriptions sont optionnelles

Les transcriptions d'appels sont désactivées par défaut et activées par entreprise.

Obtenir l'accès

Parlez-nous de l'accès à l'API et au MCP

Créez des clés API dans la console une fois votre entreprise configurée. Pour activer le serveur MCP ou pour discuter d'une intégration, contactez-nous.

Ouvrir la console
Documentation développeur Owaa — API marchande et serveur MCP