# API

Un appel sortant depuis votre système — un événement CRM, un formulaire, un rappel d'appel manqué. Une liste selon un calendrier est [Campaigns](https://docs.voicelogica.ai/fr/outbound-calls/campaigns/), pas ce point de terminaison.

Les paramètres [Outgoing](https://docs.voicelogica.ai/fr/outbound-calls/outgoing/) de l'agent s'appliquent toujours. Cette requête choisit le numéro, l'agent et le contexte supplémentaire facultatif pour *cet* appel.

## Avant d'appeler

1. Le plan inclut **Allow Outbound Calls**.
2. [Clé API](https://docs.voicelogica.ai/fr/getting-started/api-keys/) avec le groupe **Calls**.
3. Un trunk (ou téléphone VoIP) pour appeler depuis — [Votre propre opérateur](https://docs.voicelogica.ai/fr/telephony/your-own-carrier/) / [Numéros Voice Logica](https://docs.voicelogica.ai/fr/telephony/voice-logica-numbers/).
4. L'**id de l'agent** — depuis l'URL de l'agent sur **My Agents**, ou **Copy** sur une ligne de campagne.

## Première configuration — un appel, puis Calls

```
POST https://api.voicelogica.ai/api/v1/phones/calls/initiate-call
```

```http
x-api-key: YOUR_API_KEY
Content-Type: application/json
```

Revendeurs : `x-company-id` facultatif pour agir sur une filiale. Sans lui, la propre entreprise de la clé est utilisée.

Envoyez **`destinationNumber`** et **`agentId`**. Envoyez **`sipTrunkId`** ou **`voipPhoneId`** sauf si l'entreprise a déjà une route sortante / un trunk par défaut qui peut porter l'appel — si aucun n'est envoyé et qu'aucun trunk ne peut être résolu, l'API retourne qu'aucun trunk SIP actif ou téléphone VoIP n'a été spécifié.

**Trunk (habituel) :**

```bash
curl -X POST https://api.voicelogica.ai/api/v1/phones/calls/initiate-call \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sipTrunkId": "your_sip_trunk_id",
    "destinationNumber": "+14155552671",
    "agentId": "your_agent_id"
  }'
```

**VoIP phone id** fonctionne toujours — le serveur le résout en trunk.

Le succès est `{ "callId": "..." }`. Si la destination est en dehors de 09h00–21h00 heure locale, vous pouvez obtenir `"scheduled": true` plus `scheduleTime` et `reason`. Ouvrez **Calls** et écoutez.

`destinationNumber` en E.164 (`+14155552671`).

## Ce que vous pouvez envoyer

**Requis pour un appel sortant IA**

| Champ | Ce qu'il fait |
|-------|----------------|
| `destinationNumber` | Numéro à appeler. |
| `agentId` | Agent qui parle. Requis pour les appels sortants IA ; facultatif uniquement pour `isInternalCall`. |

**Source de l'appel — envoyez-en un, ou comptez sur le défaut sortant de l'entreprise**

| Champ | Ce qu'il fait |
|-------|----------------|
| `sipTrunkId` | Trunk depuis **Telephony → Trunks**. Préférez celui-ci. |
| `voipPhoneId` | Id de ligne hérité. Résolu en trunk. |
| `callerId` | E.164 ou URI SIP montré au destinataire. Doit être un numéro que ce trunk est autorisé à présenter. |

**Cet appel uniquement**

| Champ | Ce qu'il fait |
|-------|----------------|
| `contextForAi` | Ajouté au prompt système pour cet appel. |
| `dynamicVariables` | Paires clé/valeur de chaînes que le prompt peut utiliser (`{{customer_name}}`). |
| `superVariables` | Valeurs typées : `{ placeholder, value, type }` — `text` / `number` / `boolean` / `date` / `time`. |
| `metadata` | Votre suivi. Stocké sur l'appel. Les clés commençant par `scenario_` sont supprimées. |
| `emailAddress` | Où envoyer le résumé / l'enregistrement. |
| `welcomeMessageOverride` | Énoncé à la place du message d'accueil de l'agent. |
| `isWelcomeMessageAIGenerated` | L'IA écrit le message d'accueil pour cet appel. |
| `scheduledAt` | Date ISO. Appeler plus tard au lieu de maintenant. |
| `maxRetries` | 1–3 si occupé / pas de réponse / messagerie vocale. Défaut 3. |
| `retryDelayMinutes` | 30–1440. Défaut 30. |
| `additionalPhoneNumbers` | Numéros supplémentaires sur la même requête. |

N'envoyez pas `fromNumber`. Le contrat public est `sipTrunkId` / `voipPhoneId`.

## Protections (sortant uniquement)

L'entrant n'est jamais restreint.

- **Time** (activé) — 09h00–21h00 dans l'heure locale du pays de *destination*. En dehors de cela, l'appel est bloqué ou programmé. Contournement : `overrideTimeRestriction: true`.
- **Day** (activé) — les week-ends / jours fériés peuvent être bloqués par le pays de destination. Contournement : `overrideDayRestriction: true`.
- **Anti-harcèlement** (désactivé sauf si vous envoyez `useAntiHarassmentProtection: true`) — max 3 appels réussis et 3 échecs par numéro par jour, 1 heure entre les appels réussis, max 5 réussis par semaine, pas d'appel actif/programmé en double. **Allowed test numbers** de la campagne contourne cela.

Contourner les règles de temps ou de jour peut enfreindre la loi locale. Activez l'anti-harcèlement pour tout travail de contact répété.

## Si cela échoue

Le corps est `{ "error": "<code>", "reason": "<message>" }`.

| Code | Signification |
|------|---------|
| `call_already_in_progress` | Un appel en direct ou programmé vers ce numéro existe déjà. |
| `agent_not_found` / `voip_phone_not_found` | Mauvais id. |
| `daily_call_limit_reached` | 3 appels réussis vers ce numéro aujourd'hui (anti-harcèlement). |
| `failed_call_limit_reached` | 3 tentatives échouées aujourd'hui. |
| `cooldown_period_active` | Attendez 1 heure après un appel réussi vers ce numéro. |
| `weekly_call_limit_reached` | 5 appels réussis cette semaine. |
| `call_already_scheduled` / `failed_to_schedule_call` | Conflit de calendrier. |
| `callee_opted_out` | Ce numéro a demandé à ne plus être appelé. |
| `insufficient_credits` / `no_seconds_available` / `no_channels_available` / `no_concurrent_calls_available` | Plan / crédits. |
| `maximum_authentication_attempts_exceeded` | Téléphone désactivé après des échecs d'authentification répétés. |

402 est facturation. 400 est une mauvaise requête ou une protection. 500 est le serveur d'appels — réessayez plus tard.

## Exemple

```typescript
const response = await fetch('https://api.voicelogica.ai/api/v1/phones/calls/initiate-call', {
  method: 'POST',
  headers: { 'x-api-key': 'YOUR_API_KEY', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    destinationNumber: '+14155552671',
    agentId: 'your_agent_id',
    sipTrunkId: 'your_sip_trunk_id',
    contextForAi: 'Le client a posé une question sur la commande ORD123',
    dynamicVariables: { customer_name: 'Ada', order_id: 'ORD123' },
    useAntiHarassmentProtection: true,
  }),
});
const result = await response.json();
if (result.callId) console.log(result.callId);
else console.error(result.error, result.reason);
```

Calendrier + tentatives :

```json
{
  "destinationNumber": "+14155552671",
  "agentId": "your_agent_id",
  "sipTrunkId": "your_sip_trunk_id",
  "scheduledAt": "2026-09-16T14:30:00Z",
  "maxRetries": 2,
  "retryDelayMinutes": 120
}
```

`scheduledAt` est converti dans le fuseau du pays de destination. Les protections s'appliquent toujours sauf si vous les contournez.

## À quoi ressemble "cassé"

- 400 "no active SIP trunk" — envoyez `sipTrunkId`, ou ajoutez un trunk avec des numéros et un défaut sortant.
- `scheduled: true` quand vous attendiez maintenant — l'heure locale de la destination est en dehors de 09h00–21h00.
- L'agent parle par-dessus "bonjour" — [Outgoing](https://docs.voicelogica.ai/fr/outbound-calls/outgoing/) **Who speaks first**, pas cette charge utile.
- Appel manquant sur **Calls** — mauvaise entreprise (`x-company-id`), ou la requête n'a jamais retourné de `callId`.

## Dépannage

**fromNumber fonctionnait avant**

Le corps public est `sipTrunkId` ou `voipPhoneId`. Envoyez l'id de trunk depuis **Telephony → Trunks**.

**J'ai posté maintenant et j'ai obtenu scheduled: true**

Restriction de temps ou de jour. Attendez la fenêtre, ou définissez `overrideTimeRestriction` / `overrideDayRestriction` seulement si vous êtes autorisé à le faire.

## Vous construisez quelque chose ?

Écrivez à [developers@voicelogica.ai](mailto:developers@voicelogica.ai) — crédits de test supplémentaires et aide sur l'intégration.

- RÉFÉRENCE API [api.voicelogica.ai/api-docs](https://api.voicelogica.ai/api-docs)
- DÉVELOPPEURS [developers@voicelogica.ai](mailto:developers@voicelogica.ai)
- SUPPORT [support@voicelogica.ai](mailto:support@voicelogica.ai)
