Interfone
Développeurs

API One

Reliez votre CRM ou vos outils métier à votre téléphonie Interfone : utilisateurs, appels en cours, click-to-call, contacts et webhooks.

https://api.interfone.be/v1/{module}/{account_id}/{resource}

Les jetons d'accès se créent dans One, Paramètres › Outils développeurs.

Introduction

L'API One pilote votre compte Interfone depuis vos propres applications : centraux, utilisateurs, téléphones, numéros, contacts, appels en cours, journal et webhooks.

Chaque route commence par un {module} puis par l'identifiant de votre compte client. Le module disponible est magic-ip.

Une liste rend une enveloppe : le compte, le nombre d'éléments et le tableau data. Une liste paginée y ajoute limit et offset. Un détail rend l'objet seul.

Les identifiants rendus sont ceux de la plateforme téléphonique : ils sont stables et vous pouvez les conserver.

URL de base
https://api.interfone.be/v1/{module}/{account_id}/{resource}
Enveloppe d'une liste
{
  "account": {
    "id": "{account_id}",
    "name": "Exemple SRL"
  },
  "count": 2,
  "data": [
    "…"
  ]
}
Enveloppe d'une liste paginée
{
  "account": {
    "id": "{account_id}",
    "name": "Exemple SRL"
  },
  "count": 50,
  "limit": 50,
  "offset": 0,
  "data": [
    "…"
  ]
}

Authentification

Chaque requête porte un jeton Bearer dans l'en-tête Authorization. Les jetons se créent dans le bloc Authentification ci-dessus et ne sont affichés qu'une fois.

Un jeton est lié à un seul compte et a une portée : la liste des modules qu'il peut lire. Un compte ou un module hors portée répond 403.

Un jeton révoqué répond 401 dès la requête suivante.

En-têtes
Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
Réponse · 401
{
  "error": "unauthorized",
  "message": "Missing or malformed Bearer token"
}
Réponse · 403
{
  "error": "forbidden",
  "message": "Token scope does not cover module \"sms\"",
  "scopes": [
    "magic-ip"
  ]
}

Limites

60 requêtes par tranche de 60 secondes et par jeton, tous modules confondus.

Au-delà, la réponse est un 429 avec l'en-tête Retry-After et le champ retry_after : le nombre de secondes à attendre avant que le compteur reparte.

Le compteur est par jeton, pas par point d'entrée. Les pages font 50 éléments par défaut et 500 au maximum.

Réponse · 429
HTTP/1.1 429 Too Many Requests
Retry-After: 37

{
  "error": "rate_limited",
  "message": "Rate limit exceeded: 60 requests per 60 seconds per token",
  "retry_after": 37
}

Codes de réponse

Une erreur rend un objet avec un code error stable et un message.

CodeerrorSignification
200Succès
400bad_requestParamètre manquant ou invalide, le message dit lequel
401unauthorizedJeton manquant, mal formé ou révoqué
403forbiddenCompte ou module hors portée du jeton
404not_foundRessource introuvable
409conflictLa demande contredit l'état actuel : contact d'une autre source, aucun poste enregistré, adresse partagée par plusieurs utilisateurs
429rate_limitedLimite de débit atteinte
500server_errorErreur serveur
501not_implementedPoint d'entrée pas encore disponible
502central_errorLa plateforme téléphonique a refusé la demande, son message est rendu tel quel
503unavailablePlateforme téléphonique injoignable
Réponse · 404
{
  "error": "not_found",
  "message": "User not found"
}

Magic IP

Centraux

Vos centraux téléphoniques : un par site. Un compte en a au moins un.

Lister les centraux

GET/magic-ip/{account_id}/accounts

Le champ id de chaque central est celui que portent ensuite les utilisateurs et les téléphones dans account_id. is_primary désigne le central principal du compte.

Requête
curl --request GET \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/accounts' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx'
Réponse · 200
{
  "account": {
    "id": "{account_id}",
    "name": "Exemple SRL"
  },
  "count": 2,
  "data": [
    {
      "id": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
      "name": "Siège",
      "realm": "siege.exemple.be",
      "enabled": true,
      "parent_id": null,
      "is_primary": true,
      "created_at": "2024-03-12T09:41:00Z"
    },
    {
      "id": "0f1e2d3c4b5a69788796a5b4c3d2e1f0",
      "name": "Atelier",
      "realm": "atelier.exemple.be",
      "enabled": true,
      "parent_id": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
      "is_primary": false,
      "created_at": "2025-01-20T14:05:00Z"
    }
  ]
}

Lire un central

GET/magic-ip/{account_id}/accounts/{id}

Paramètres

idchemin · stringobligatoire
Identifiant du central.
Requête
curl --request GET \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/accounts/a1b2c3d4e5f60718293a4b5c6d7e8f90' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx'
Réponse · 200
{
  "id": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
  "name": "Siège",
  "realm": "siege.exemple.be",
  "enabled": true,
  "parent_id": null,
  "is_primary": true,
  "created_at": "2024-03-12T09:41:00Z"
}

Utilisateurs

Les utilisateurs de vos centraux, avec leur extension et leur rôle.

Lister les utilisateurs

GET/magic-ip/{account_id}/users

Tous les utilisateurs du compte, triés par nom. Le rôle est admin ou user.

Paramètres

account_idrequête · string
Restreint la liste à un seul central, désigné par l'id rendu par la liste des centraux.
emailrequête · string
Adresse e-mail exacte, sans tenir compte de la casse.
Requête
curl --request GET \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/users?email=camille@exemple.be' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx'
Réponse · 200
{
  "account": {
    "id": "{account_id}",
    "name": "Exemple SRL"
  },
  "count": 1,
  "data": [
    {
      "id": "5c6d7e8f90a1b2c3d4e5f60718293a4b",
      "account_id": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
      "first_name": "Camille",
      "last_name": "Dupont",
      "email": "camille@exemple.be",
      "extension": "201",
      "role": "admin",
      "enabled": true
    }
  ]
}

Lire un utilisateur

GET/magic-ip/{account_id}/users/{id}

Paramètres

idchemin · stringobligatoire
Identifiant de l'utilisateur.
Requête
curl --request GET \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/users/5c6d7e8f90a1b2c3d4e5f60718293a4b' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx'
Réponse · 200
{
  "id": "5c6d7e8f90a1b2c3d4e5f60718293a4b",
  "account_id": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
  "first_name": "Camille",
  "last_name": "Dupont",
  "email": "camille@exemple.be",
  "extension": "201",
  "role": "admin",
  "enabled": true
}

Téléphones

Les téléphones déclarés sur vos centraux, avec leur état d'enregistrement en direct.

Lister les téléphones

GET/magic-ip/{account_id}/devices

owner_id porte l'id de l'utilisateur à qui le téléphone est attribué, ou null s'il est libre. registered dit si le téléphone est enregistré sur le central à cet instant. Un combiné DECT n'a pas de mac_address.

Ces données sont lues en direct sur la plateforme téléphonique : comptez quelques centaines de millisecondes de plus, et un 503 si elle est injoignable.

Paramètres

account_idrequête · string
Restreint la liste à un seul central, désigné par l'id rendu par la liste des centraux.
user_idrequête · string
Ne garde que les téléphones de cet utilisateur.
Requête
curl --request GET \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/devices' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx'
Réponse · 200
{
  "account": {
    "id": "{account_id}",
    "name": "Exemple SRL"
  },
  "count": 1,
  "data": [
    {
      "id": "d4e5f60718293a4b5c6d7e8f90a1b2c3",
      "account_id": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
      "name": "SIP-T54W | AABBCCDDEEFF",
      "type": "sip_device",
      "model": "SIP-T54W",
      "mac_address": "AA:BB:CC:DD:EE:FF",
      "owner_id": "5c6d7e8f90a1b2c3d4e5f60718293a4b",
      "enabled": true,
      "registered": true
    }
  ]
}

Lire un téléphone

GET/magic-ip/{account_id}/devices/{id}

Paramètres

idchemin · stringobligatoire
Identifiant du téléphone.
Requête
curl --request GET \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/devices/d4e5f60718293a4b5c6d7e8f90a1b2c3' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx'
Réponse · 200
{
  "id": "d4e5f60718293a4b5c6d7e8f90a1b2c3",
  "account_id": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
  "name": "SIP-T54W | AABBCCDDEEFF",
  "type": "sip_device",
  "model": "SIP-T54W",
  "mac_address": "AA:BB:CC:DD:EE:FF",
  "owner_id": "5c6d7e8f90a1b2c3d4e5f60718293a4b",
  "enabled": true,
  "registered": true
}

Appels en cours

Les appels qui traversent vos centraux à cet instant, lus en direct. Un appel regroupe ses branches : celle qui entre dans le central et celles qui sonnent ou parlent sur vos postes.

Lister les appels en cours

GET/magic-ip/{account_id}/live-calls

state vaut ringing tant que personne n'a décroché, puis answered. user_id, device_id et extension désignent le poste du compte engagé dans l'appel.

Paramètres

account_idrequête · string
Restreint la liste à un seul central, désigné par l'id rendu par la liste des centraux.
user_idrequête · string
Ne garde que les appels où cet utilisateur est engagé.
Requête
curl --request GET \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/live-calls' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx'
Réponse · 200
{
  "account": {
    "id": "{account_id}",
    "name": "Exemple SRL"
  },
  "count": 1,
  "data": [
    {
      "id": "c0ffee00-1111-4222-8333-444455556666",
      "account_id": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
      "direction": "inbound",
      "state": "answered",
      "from": "32470123456",
      "to": "3221234567",
      "started_at": "2026-09-13T09:41:12Z",
      "duration_sec": 84,
      "user_id": "5c6d7e8f90a1b2c3d4e5f60718293a4b",
      "device_id": "d4e5f60718293a4b5c6d7e8f90a1b2c3",
      "extension": "201",
      "legs": [
        {
          "id": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
          "call_id": "7a1c2e3f-sip-0001",
          "direction": "inbound",
          "from": "32470123456",
          "to": "3221234567",
          "answered": true,
          "user_id": null,
          "device_id": null,
          "extension": null
        },
        {
          "id": "f6a7b8c9-d0e1-4f2a-9b3c-4d5e6f7a8b9c",
          "call_id": null,
          "direction": "outbound",
          "from": "32470123456",
          "to": "201",
          "answered": true,
          "user_id": null,
          "device_id": "d4e5f60718293a4b5c6d7e8f90a1b2c3",
          "extension": "201"
        }
      ]
    }
  ]
}

Lire un appel en cours

GET/magic-ip/{account_id}/live-calls/{id}

Paramètres

idchemin · stringobligatoire
Identifiant de l'appel en cours, ou d'une de ses branches.
Requête
curl --request GET \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/live-calls/c0ffee00-1111-4222-8333-444455556666' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx'
Réponse · 200
{
  "id": "c0ffee00-1111-4222-8333-444455556666",
  "account_id": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
  "direction": "inbound",
  "state": "answered",
  "from": "32470123456",
  "to": "3221234567",
  "started_at": "2026-09-13T09:41:12Z",
  "duration_sec": 84,
  "user_id": "5c6d7e8f90a1b2c3d4e5f60718293a4b",
  "device_id": "d4e5f60718293a4b5c6d7e8f90a1b2c3",
  "extension": "201",
  "legs": [
    {
      "id": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
      "call_id": "7a1c2e3f-sip-0001",
      "direction": "inbound",
      "from": "32470123456",
      "to": "3221234567",
      "answered": true,
      "user_id": null,
      "device_id": null,
      "extension": null
    },
    {
      "id": "f6a7b8c9-d0e1-4f2a-9b3c-4d5e6f7a8b9c",
      "call_id": null,
      "direction": "outbound",
      "from": "32470123456",
      "to": "201",
      "answered": true,
      "user_id": null,
      "device_id": "d4e5f60718293a4b5c6d7e8f90a1b2c3",
      "extension": "201"
    }
  ]
}

Disponibilité

L'état de chaque utilisateur à cet instant, déduit de ses téléphones enregistrés et des appels en cours.

Lister la disponibilité

GET/magic-ip/{account_id}/availability

status vaut available (un téléphone enregistré, aucun appel), ringing (un appel sonne sur son poste), busy (en communication) ou offline (aucun téléphone enregistré, ou utilisateur désactivé). Un mobile compte comme enregistré.

Paramètres

account_idrequête · string
Restreint la liste à un seul central, désigné par l'id rendu par la liste des centraux.
Requête
curl --request GET \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/availability' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx'
Réponse · 200
{
  "account": {
    "id": "{account_id}",
    "name": "Exemple SRL"
  },
  "count": 2,
  "data": [
    {
      "user_id": "5c6d7e8f90a1b2c3d4e5f60718293a4b",
      "account_id": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
      "extension": "201",
      "status": "busy",
      "registered_devices": 1,
      "call": {
        "id": "c0ffee00-1111-4222-8333-444455556666",
        "direction": "inbound",
        "from": "32470123456",
        "to": "3221234567",
        "since": "2026-09-13T09:41:12Z"
      }
    },
    {
      "user_id": "7e8f90a1b2c3d4e5f60718293a4b5c6d",
      "account_id": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
      "extension": "202",
      "status": "available",
      "registered_devices": 2,
      "call": null
    }
  ]
}

Lire la disponibilité d'un utilisateur

GET/magic-ip/{account_id}/users/{id}/availability

Paramètres

idchemin · stringobligatoire
Identifiant de l'utilisateur, ou son adresse e-mail. 409 si plusieurs utilisateurs du compte partagent l'adresse.
Requête
curl --request GET \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/users/5c6d7e8f90a1b2c3d4e5f60718293a4b/availability' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx'
Réponse · 200
{
  "user_id": "5c6d7e8f90a1b2c3d4e5f60718293a4b",
  "account_id": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
  "extension": "201",
  "status": "busy",
  "registered_devices": 1,
  "call": {
    "id": "c0ffee00-1111-4222-8333-444455556666",
    "direction": "inbound",
    "from": "32470123456",
    "to": "3221234567",
    "since": "2026-09-13T09:41:12Z"
  }
}

Click-to-call

Lancer un appel depuis le poste fixe d'un utilisateur : son téléphone sonne d'abord, puis le central compose le numéro dès qu'il décroche. Jamais le mobile.

Appeler depuis le poste d'un utilisateur

POST/magic-ip/{account_id}/users/{id}/dial

number est une extension ou un numéro international sans le +. Sans device_id, l'API prend le seul poste fixe enregistré de l'utilisateur, un poste de bureau avant une application ; s'il en a plusieurs, elle répond 400 avec la liste des candidats ; s'il n'en a aucun, 409.

Si l'utilisateur a plusieurs postes, passez device_id : la réponse 400 liste les candidats avec leur type, et GET /devices?user_id= les donne aussi. La réponse 202 confirme que le poste a été sollicité ; l'appel apparaît ensuite dans les appels en cours avec le call_id rendu.

Paramètres

idchemin · stringobligatoire
Identifiant de l'utilisateur, ou son adresse e-mail. 409 si plusieurs utilisateurs du compte partagent l'adresse.
numbercorps · stringobligatoire
Extension ou numéro international sans le +, par exemple 32470123456.
device_idcorps · string
Poste fixe précis de l'utilisateur. 403 s'il ne lui appartient pas, 400 si c'est un mobile, 409 s'il n'est pas enregistré.
auto_answercorps · boolean
true pour que le poste décroche seul, si le téléphone le permet.
Requête
curl --request POST \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/users/camille@exemple.be/dial' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx' \
  --header 'Content-Type: application/json' \
  --data '{"number":"32470123456"}'
Réponse · 202
{
  "user_id": "5c6d7e8f90a1b2c3d4e5f60718293a4b",
  "account_id": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
  "device_id": "d4e5f60718293a4b5c6d7e8f90a1b2c3",
  "number": "32470123456",
  "call_id": "a1b2c3d4-0000-4000-8000-000000000001",
  "status": "ringing"
}

Journal des appels

Les appels terminés, un par conversation quel que soit le nombre de postes qui ont sonné, avec leur sens réel.

Lister les appels

GET/magic-ip/{account_id}/calls

Par défaut les dernières 24 heures, au plus 31 jours par requête. direction est le sens métier : un poste qui compose un numéro est un appel sortant, même si le central le voit entrer. answered dit si quelqu'un a décroché.

Paramètres

fromrequête · date
Début de la fenêtre, ISO 8601 ou AAAA-MM-JJ (journée entière, UTC).
torequête · date
Fin de la fenêtre, ISO 8601 ou AAAA-MM-JJ. Maintenant par défaut.
directionrequête · string
inbound ou outbound.
numberrequête · string
Numéro ou extension présent d'un côté de l'appel, comparé sur les chiffres.
account_idrequête · string
Restreint la liste à un seul central, désigné par l'id rendu par la liste des centraux.
limitrequête · integer
Nombre d'éléments par page, 50 par défaut, 500 au maximum.
offsetrequête · integer
Nombre d'éléments à sauter, 0 par défaut.
Requête
curl --request GET \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/calls?from=2026-09-13&to=2026-09-13&direction=inbound' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx'
Réponse · 200
{
  "account": {
    "id": "{account_id}",
    "name": "Exemple SRL"
  },
  "count": 2,
  "limit": 50,
  "offset": 0,
  "from": "2026-09-13T00:00:00.000Z",
  "to": "2026-09-13T23:59:59.000Z",
  "data": [
    {
      "id": "c0ffee00-1111-4222-8333-444455556666",
      "account_id": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
      "direction": "inbound",
      "from": "32470123456",
      "to": "3221234567",
      "started_at": "2026-09-13T09:41:12Z",
      "duration_sec": 143,
      "answered": true,
      "hangup_cause": "NORMAL_CLEARING",
      "user_id": "5c6d7e8f90a1b2c3d4e5f60718293a4b",
      "extension": "201",
      "legs": 3
    },
    {
      "id": "deadbeef-2222-4333-8444-555566667777",
      "account_id": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
      "direction": "outbound",
      "from": "202",
      "to": "32470999999",
      "started_at": "2026-09-13T08:15:03Z",
      "duration_sec": 31,
      "answered": true,
      "hangup_cause": "NORMAL_CLEARING",
      "user_id": "7e8f90a1b2c3d4e5f60718293a4b5c6d",
      "extension": "202",
      "legs": 2
    }
  ]
}

Lire un appel

GET/magic-ip/{account_id}/calls/{id}

L'appel doit se trouver dans la fenêtre from / to, les dernières 24 heures par défaut.

Paramètres

idchemin · stringobligatoire
Identifiant de l'appel.
fromrequête · date
Début de la fenêtre, ISO 8601 ou AAAA-MM-JJ (journée entière, UTC).
torequête · date
Fin de la fenêtre, ISO 8601 ou AAAA-MM-JJ. Maintenant par défaut.
Requête
curl --request GET \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/calls/c0ffee00-1111-4222-8333-444455556666?from=2026-09-13' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx'
Réponse · 200
{
  "id": "c0ffee00-1111-4222-8333-444455556666",
  "account_id": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
  "direction": "inbound",
  "from": "32470123456",
  "to": "3221234567",
  "started_at": "2026-09-13T09:41:12Z",
  "duration_sec": 143,
  "answered": true,
  "hangup_cause": "NORMAL_CLEARING",
  "user_id": "5c6d7e8f90a1b2c3d4e5f60718293a4b",
  "extension": "201",
  "legs": 3
}

Bouton de fermeture

La fermeture exceptionnelle du central, celle que les codes *561 et *562 déclenchent depuis un poste.

Lire l'état

GET/magic-ip/{account_id}/closure

installed dit si le bouton est posé sur ce compte, closed s'il est activé. Tant qu'il est activé, les appels suivent la branche « fermé » du scénario principal.

Requête
curl --request GET \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/closure' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx'
Réponse · 200
{
  "installed": true,
  "closed": false,
  "account_id": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
  "close_code": "*561",
  "open_code": "*562"
}

Fermer ou rouvrir

PUT/magic-ip/{account_id}/closure

closed à true ferme, à false rouvre. La réponse rend le nouvel état lu sur le central. 404 si le bouton n'est pas installé.

Paramètres

closedcorps · booleanobligatoire
true pour fermer, false pour rouvrir.
Requête
curl --request PUT \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/closure' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx' \
  --header 'Content-Type: application/json' \
  --data '{"closed":true}'
Réponse · 200
{
  "installed": true,
  "closed": true,
  "account_id": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
  "close_code": "*561",
  "open_code": "*562"
}

Contacts

Le répertoire du compte, celui que les postes affichent quand un numéro connu appelle. Un contact poussé par l'API apparaît sur les téléphones à leur prochaine lecture du répertoire.

Lister les contacts

GET/magic-ip/{account_id}/contacts

Tous les contacts du compte, quelle que soit leur origine, triés par nom. total est le nombre total, count celui de la page.

Paramètres

searchrequête · string
Texte cherché dans le nom, la société ou l'e-mail.
numberrequête · string
Numéro présent sur le contact, comparé sur les chiffres.
external_idrequête · string
Votre identifiant, tel que donné à la création.
sourcerequête · string
api pour les contacts de l'API, local pour ceux saisis dans One.
limitrequête · integer
Nombre d'éléments par page, 50 par défaut, 500 au maximum.
offsetrequête · integer
Nombre d'éléments à sauter, 0 par défaut.
Requête
curl --request GET \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/contacts?search=dupont' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx'
Réponse · 200
{
  "account": {
    "id": "{account_id}",
    "name": "Exemple SRL"
  },
  "count": 2,
  "total": 2,
  "limit": 50,
  "offset": 0,
  "data": [
    {
      "id": "2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f",
      "external_id": "crm-10421",
      "name": "Camille Dupont",
      "first_name": "Camille",
      "last_name": "Dupont",
      "company": "Exemple SRL",
      "type": "individual",
      "email": "camille@exemple.be",
      "phone": "3221234567",
      "mobile": "32470123456",
      "language": "fr",
      "street": "Rue de l'Exemple 12",
      "zip_code": "1000",
      "city": "Bruxelles",
      "country": "BE",
      "source": "api",
      "created_at": "2026-09-01T10:00:00Z",
      "updated_at": "2026-09-14T08:12:00Z"
    },
    {
      "id": "9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b",
      "external_id": null,
      "name": "Sam Peeters",
      "first_name": "Sam",
      "last_name": "Peeters",
      "company": null,
      "type": "individual",
      "email": null,
      "phone": null,
      "mobile": "32470999999",
      "language": null,
      "street": null,
      "zip_code": null,
      "city": null,
      "country": null,
      "source": "local",
      "created_at": "2026-06-20T09:00:00Z",
      "updated_at": "2026-06-20T09:00:00Z"
    }
  ]
}

Lire un contact

GET/magic-ip/{account_id}/contacts/{id}

Paramètres

idchemin · stringobligatoire
Identifiant du contact.
Requête
curl --request GET \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/contacts/2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx'
Réponse · 200
{
  "id": "2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f",
  "external_id": "crm-10421",
  "name": "Camille Dupont",
  "first_name": "Camille",
  "last_name": "Dupont",
  "company": "Exemple SRL",
  "type": "individual",
  "email": "camille@exemple.be",
  "phone": "3221234567",
  "mobile": "32470123456",
  "language": "fr",
  "street": "Rue de l'Exemple 12",
  "zip_code": "1000",
  "city": "Bruxelles",
  "country": "BE",
  "source": "api",
  "created_at": "2026-09-01T10:00:00Z",
  "updated_at": "2026-09-14T08:12:00Z"
}

Créer un contact

POST/magic-ip/{account_id}/contacts

Il faut un nom, un prénom et nom, ou une société, et au moins un numéro. Les numéros sont acceptés dans les formes courantes et rendus en international sans le +.

Avec un external_id déjà connu, le contact est remplacé au lieu d'être dupliqué, réponse 200 avec created à false. C'est la clé d'une synchronisation depuis votre CRM.

Paramètres

external_idcorps · string
Votre identifiant du contact dans votre CRM. Permet de le retrouver et de le remplacer sans doublon.
first_namecorps · string
Prénom.
last_namecorps · string
Nom.
companycorps · string
Société. Seule, elle fait un contact de type business.
phonecorps · string
Numéro fixe, par exemple 02 123 45 67 ou 3221234567.
mobilecorps · string
Numéro mobile, par exemple 0470 12 34 56.
emailcorps · string
Adresse e-mail.
typecorps · string
individual ou business. Déduit si absent.
languagecorps · string
Code langue à deux lettres, fr ou nl.
street, zip_code, city, countrycorps · string
Adresse postale, facultative.
Requête
curl --request POST \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/contacts' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx' \
  --header 'Content-Type: application/json' \
  --data '{"external_id":"crm-10421","first_name":"Camille","last_name":"Dupont","company":"Exemple SRL","phone":"02 123 45 67","mobile":"+32 470 12 34 56","email":"camille@exemple.be","language":"fr"}'
Réponse · 201
{
  "id": "2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f",
  "external_id": "crm-10421",
  "name": "Camille Dupont",
  "first_name": "Camille",
  "last_name": "Dupont",
  "company": "Exemple SRL",
  "type": "individual",
  "email": "camille@exemple.be",
  "phone": "3221234567",
  "mobile": "32470123456",
  "language": "fr",
  "street": "Rue de l'Exemple 12",
  "zip_code": "1000",
  "city": "Bruxelles",
  "country": "BE",
  "source": "api",
  "created_at": "2026-09-01T10:00:00Z",
  "updated_at": "2026-09-14T08:12:00Z",
  "created": true
}

Modifier un contact

PATCH/magic-ip/{account_id}/contacts/{id}

Seuls les champs envoyés changent ; null efface. Un contact créé ailleurs que par l'API répond 409 : il appartient à sa source.

Paramètres

idchemin · stringobligatoire
Identifiant du contact.
Requête
curl --request PATCH \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/contacts/2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx' \
  --header 'Content-Type: application/json' \
  --data '{"mobile":"0470 99 99 99","city":"Namur"}'
Réponse · 200
{
  "id": "2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f",
  "external_id": "crm-10421",
  "name": "Camille Dupont",
  "first_name": "Camille",
  "last_name": "Dupont",
  "company": "Exemple SRL",
  "type": "individual",
  "email": "camille@exemple.be",
  "phone": "3221234567",
  "mobile": "32470999999",
  "language": "fr",
  "street": "Rue de l'Exemple 12",
  "zip_code": "1000",
  "city": "Namur",
  "country": "BE",
  "source": "api",
  "created_at": "2026-09-01T10:00:00Z",
  "updated_at": "2026-09-14T09:30:00Z"
}

Supprimer un contact

DELETE/magic-ip/{account_id}/contacts/{id}

Seulement un contact créé par l'API ; 409 sinon.

Paramètres

idchemin · stringobligatoire
Identifiant du contact.
Requête
curl --request DELETE \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/contacts/2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx'
Réponse · 200
{
  "id": "2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f",
  "deleted": true
}

Importer un lot

POST/magic-ip/{account_id}/contacts/batch

Jusqu'à 1 000 contacts par appel, chacun avec un external_id : créés s'ils sont nouveaux, remplacés sinon. La réponse détaille ce qui a échoué, ligne par ligne, sans bloquer le reste.

Le répertoire des postes est régénéré une fois à la fin du lot. Pour une première synchronisation complète, enchaînez les lots de 1 000.

Paramètres

contactscorps · arrayobligatoire
Liste de contacts, mêmes champs que la création, external_id obligatoire.
Requête
curl --request POST \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/contacts/batch' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx' \
  --header 'Content-Type: application/json' \
  --data '{"contacts":[{"external_id":"crm-10421","first_name":"Camille","last_name":"Dupont","phone":"3221234567"},{"external_id":"crm-10422","company":"Atelier Exemple","phone":"3281234567"}]}'
Réponse · 200
{
  "received": 2,
  "created": 1,
  "updated": 1,
  "failed": []
}

Webhooks

One prévient votre serveur à la seconde où un appel sonne, est décroché ou se termine, pour afficher un pop-up dans votre CRM ou y journaliser l'appel. Un abonnement par compte : chaque événement porte l'utilisateur concerné, avec son e-mail et son extension, et c'est votre CRM qui route le pop-up au bon agent. call_id est le même sur tous les événements d'un appel ; c'est l'identifiant de sa branche d'origine, celui que porte cette branche dans les appels en cours. Les numéros sont en international sans le +.

Événement call.ringing
{
  "id": "c8f1e2d3-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
  "type": "call.ringing",
  "created_at": "2026-09-14T09:41:12Z",
  "account_id": "{account_id}",
  "data": {
    "call_id": "2a9455565c7627856719a8f0530a0101",
    "direction": "inbound",
    "from": "32470123456",
    "to": "3221234567",
    "user": {
      "id": "5c6d7e8f90a1b2c3d4e5f60718293a4b",
      "email": "camille@exemple.be",
      "first_name": "Camille",
      "last_name": "Dupont",
      "extension": "201"
    },
    "device_id": "d4e5f60718293a4b5c6d7e8f90a1b2c3",
    "account_id": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
    "timestamp": "2026-09-14T09:41:12Z"
  }
}
Événement call.ended
{
  "id": "d9a2f3e4-5b6c-4d7e-9f0a-1b2c3d4e5f6a",
  "type": "call.ended",
  "created_at": "2026-09-14T09:43:40Z",
  "account_id": "{account_id}",
  "data": {
    "call_id": "2a9455565c7627856719a8f0530a0101",
    "direction": "inbound",
    "from": "32470123456",
    "to": "3221234567",
    "user": {
      "id": "5c6d7e8f90a1b2c3d4e5f60718293a4b",
      "email": "camille@exemple.be",
      "first_name": "Camille",
      "last_name": "Dupont",
      "extension": "201"
    },
    "device_id": "d4e5f60718293a4b5c6d7e8f90a1b2c3",
    "account_id": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
    "timestamp": "2026-09-14T09:43:40Z",
    "answered": true,
    "duration_sec": 148,
    "hangup_cause": "NORMAL_CLEARING"
  }
}
En-têtes de chaque livraison
X-One-Event: call.ringing
X-One-Delivery: c8f1e2d3-4a5b-4c6d-8e9f-0a1b2c3d4e5f
X-One-Timestamp: 1789378872
X-One-Signature: sha256=<HMAC-SHA256(secret, timestamp + "." + body)>

Lister les abonnements

GET/magic-ip/{account_id}/webhooks
Requête
curl --request GET \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/webhooks' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx'
Réponse · 200
{
  "account": {
    "id": "{account_id}",
    "name": "Exemple SRL"
  },
  "count": 1,
  "data": [
    {
      "id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
      "name": "CRM Exemple",
      "url": "https://crm.exemple.be/hooks/one",
      "events": [
        "call.ringing",
        "call.answered",
        "call.ended"
      ],
      "enabled": true,
      "secret_prefix": "whsec_3f9a1c",
      "failure_count": 0,
      "last_delivery_at": "2026-09-14T09:41:14Z",
      "last_status_code": 200,
      "created_at": "2026-09-14T08:00:00Z",
      "updated_at": "2026-09-14T08:00:00Z"
    }
  ]
}

Créer un abonnement

POST/magic-ip/{account_id}/webhooks

Quatre événements : call.ringing (un appel entrant sonne sur le poste d'un utilisateur, un événement par poste qui sonne), call.started (un utilisateur compose), call.answered (quelqu'un a décroché), call.ended (l'appel est terminé, avec sa durée et son résultat). Tous par défaut.

Le secret n'est rendu qu'à la création. Chaque livraison est signée : X-One-Signature vaut sha256= suivi du HMAC-SHA256 du secret sur timestamp.corps. Votre serveur doit répondre 2xx en moins de 10 secondes ; sinon One réessaie deux fois, à 3 puis 10 secondes. Au plus 5 abonnements par compte.

Paramètres

urlcorps · stringobligatoire
URL https publique de votre serveur.
eventscorps · array
Liste parmi call.ringing, call.started, call.answered, call.ended. Tous si absent.
namecorps · string
Nom libre, pour vous y retrouver.
Requête
curl --request POST \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/webhooks' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx' \
  --header 'Content-Type: application/json' \
  --data '{"url":"https://crm.exemple.be/hooks/one","events":["call.ringing","call.answered","call.ended"],"name":"CRM Exemple"}'
Réponse · 201
{
  "id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
  "name": "CRM Exemple",
  "url": "https://crm.exemple.be/hooks/one",
  "events": [
    "call.ringing",
    "call.answered",
    "call.ended"
  ],
  "enabled": true,
  "secret_prefix": "whsec_3f9a1c",
  "failure_count": 0,
  "last_delivery_at": null,
  "last_status_code": null,
  "created_at": "2026-09-14T08:00:00Z",
  "updated_at": "2026-09-14T08:00:00Z",
  "secret": "whsec_3f9a1c…"
}

Lire un abonnement

GET/magic-ip/{account_id}/webhooks/{id}

Paramètres

idchemin · stringobligatoire
Identifiant de l'abonnement.
Requête
curl --request GET \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/webhooks/5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx'
Réponse · 200
{
  "id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
  "name": "CRM Exemple",
  "url": "https://crm.exemple.be/hooks/one",
  "events": [
    "call.ringing",
    "call.answered",
    "call.ended"
  ],
  "enabled": true,
  "secret_prefix": "whsec_3f9a1c",
  "failure_count": 0,
  "last_delivery_at": "2026-09-14T09:41:14Z",
  "last_status_code": 200,
  "created_at": "2026-09-14T08:00:00Z",
  "updated_at": "2026-09-14T08:00:00Z"
}

Modifier un abonnement

PATCH/magic-ip/{account_id}/webhooks/{id}

Seuls les champs envoyés changent. enabled à false suspend les livraisons sans rien perdre.

Paramètres

idchemin · stringobligatoire
Identifiant de l'abonnement.
enabledcorps · boolean
false suspend les livraisons.
Requête
curl --request PATCH \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/webhooks/5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx' \
  --header 'Content-Type: application/json' \
  --data '{"events":["call.ringing"],"enabled":true}'
Réponse · 200
{
  "id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
  "name": "CRM Exemple",
  "url": "https://crm.exemple.be/hooks/one",
  "events": [
    "call.ringing"
  ],
  "enabled": true,
  "secret_prefix": "whsec_3f9a1c",
  "failure_count": 0,
  "last_delivery_at": "2026-09-14T09:41:14Z",
  "last_status_code": 200,
  "created_at": "2026-09-14T08:00:00Z",
  "updated_at": "2026-09-14T08:00:00Z"
}

Supprimer un abonnement

DELETE/magic-ip/{account_id}/webhooks/{id}

Paramètres

idchemin · stringobligatoire
Identifiant de l'abonnement.
Requête
curl --request DELETE \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/webhooks/5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx'
Réponse · 200
{
  "id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
  "deleted": true
}

Envoyer un événement de test

POST/magic-ip/{account_id}/webhooks/{id}/test

Livre un événement ping signé à l'URL de l'abonnement et rend le résultat : 200 si votre serveur a répondu 2xx, 502 sinon.

Paramètres

idchemin · stringobligatoire
Identifiant de l'abonnement.
Requête
curl --request POST \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/webhooks/5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a/test' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx' \
  --header 'Content-Type: application/json' \
  --data '{}'
Réponse · 200
{
  "subscription_id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
  "delivery_id": "e0b3a4f5-6c7d-4e8f-a0b1-2c3d4e5f6a7b",
  "status": "delivered",
  "attempts": 1,
  "status_code": 200,
  "error": null
}

Lister les livraisons

GET/magic-ip/{account_id}/webhooks/{id}/deliveries

Les dernières livraisons, de la plus récente à la plus ancienne, avec leur statut, le nombre de tentatives et le dernier code reçu.

Paramètres

idchemin · stringobligatoire
Identifiant de l'abonnement.
limitrequête · integer
Nombre de livraisons, 50 par défaut, 100 au maximum.
Requête
curl --request GET \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/webhooks/5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a/deliveries?limit=20' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx'
Réponse · 200
{
  "subscription_id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
  "count": 2,
  "data": [
    {
      "id": "d9a2f3e4-5b6c-4d7e-9f0a-1b2c3d4e5f6a",
      "event_type": "call.ended",
      "call_id": "2a9455565c7627856719a8f0530a0101",
      "status": "delivered",
      "attempts": 1,
      "last_status_code": 200,
      "last_error": null,
      "created_at": "2026-09-14T09:43:40Z",
      "delivered_at": "2026-09-14T09:43:41Z"
    },
    {
      "id": "c8f1e2d3-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
      "event_type": "call.ringing",
      "call_id": "2a9455565c7627856719a8f0530a0101",
      "status": "failed",
      "attempts": 3,
      "last_status_code": 503,
      "last_error": "HTTP 503",
      "created_at": "2026-09-14T09:41:12Z",
      "delivered_at": null
    }
  ]
}

Numéros

Les numéros fixes assignés à vos centraux.

Lister les numéros

GET/magic-ip/{account_id}/numbers
Requête
curl --request GET \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/numbers' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx'
Réponse · 200
{
  "account": {
    "id": "{account_id}",
    "name": "Exemple SRL"
  },
  "count": 1,
  "data": [
    {
      "did_e164": "3221234567",
      "did_national": "021234567",
      "name": "Accueil",
      "status": "assigned",
      "assigned_to_ip_line_id": "9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
      "assigned_at": "2024-03-12T10:02:00Z"
    }
  ]
}

Lire un numéro

GET/magic-ip/{account_id}/numbers/{e164}

Paramètres

e164chemin · stringobligatoire
Numéro au format international sans le +, par exemple 3221234567.
Requête
curl --request GET \
  --url 'https://api.interfone.be/v1/magic-ip/{account_id}/numbers/3221234567' \
  --header 'Authorization: Bearer one_xxxxxxxxxxxxxxxxxxxxxxxx'
Réponse · 200
{
  "did_e164": "3221234567",
  "did_national": "021234567",
  "name": "Accueil",
  "status": "assigned",
  "assigned_to_ip_line_id": "9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
  "assigned_at": "2024-03-12T10:02:00Z",
  "is_private": false
}