v1.2.0
OpenAPI 3.0.3

Public OpenAPI contract for the AI4Call client-facing APIs.

The primary service at https://client-api.ai4call.com covers authenticated account management, assistants and their runtime configuration, provider wallet, catalog resources, knowledge, RAG document management, tools and account analytics.

Current Client API authentication flow:

  1. POST /api/v1/auth/portal/login validates email and portalApiKey. It does not issue an access token or create a server-side session.
  2. Business calls accept Authorization: Bearer <portalApiKey> or the legacy pair x-client-email and x-portal-api-key.
  3. Operations on a single assistant use assistantId; legacy assistantApiKey path values remain accepted during the v1 compatibility period.

This document also contains operations hosted by dedicated services. Public RAG operations use their own Bearer authentication and outbound-call operations use their own API-key header; each such operation declares its dedicated server and security scheme.

Server:https://client-api.ai4call.com

Production client API

No authentication selected
Client Libraries

Health

​

Check availability of the API service

Health Operations

Health check of the service

​

Health check of the service

Responses

  • application/json
  • application/json
  • application/json
Request Example for get/health
curl https://client-api.ai4call.com/health
{
  "success": true,
  "message": "Service is healthy.",
  "requestId": "8cb7cd6b-3f55-4226-b4a2-54fd9e90ec99",
  "data": {
    "status": "ok",
    "service": "api-rest-assistant-creator",
    "dataSource": "database"
  }
}

Auth

​

Portal customer authentication via email and portalApiKey

Authenticate a portal customer with email and portalApiKey

​

Validates the static portal credentials and returns customer data. It does not issue a token or create a server-side session.

Body·

required
application/json

Credentials used to verify a portal customer. This request does not create a session or issue an access token.

  • Portal customer email.

  • Static portal API key associated with the customer account.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for post/api/v1/auth/portal/login
curl https://client-api.ai4call.com/api/v1/auth/portal/login \
  --request POST \
  --header 'Content-Type: application/json' \
  --data '{
  "email": "developer@example.com",
  "portalApiKey": "portal_demo_key_123456789"
}'
{
  "success": true,
  "message": "Portal client authenticated successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "client": {
      "clientId": "example-id",
      "email": "developer@example.com",
      "displayName": "Example",
      "companyName": "Example",
      "isActive": true
    }
  }
}

Account

​

Retrieve the allowed IPs of the authenticated account

​

Retrieve the allowed IPs of the authenticated account

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/account/allowed-ips
curl https://client-api.ai4call.com/api/v1/account/allowed-ips \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Account allowed IPs retrieved successfully.",
  "requestId": "9755db58-3e8d-4a09-b3a1-c68fd6f70c8a",
  "data": {
    "configuration": {
      "allowedIps": [
        {
          "ip": "10.10.10.5",
          "description": "Main office"
        },
        {
          "ip": "192.168.1.20",
          "description": null
        }
      ]
    }
  },
  "meta": {
    "count": 2
  }
}

Update the allowed IPs of the authenticated account

​

Updates the account's IP whitelist with PATCH merge semantics.

Editable parameters:

  • allowedIps
  • allowedIps[].ip
  • allowedIps[].description
  • addIps
  • addIps[].ip
  • addIps[].description
  • deleteIps

How to recover current data:

  • use GET /api/v1/account/allowed-ips

Operational rules:

  • allowedIps replaces the entire list
  • addIps adds new IPs or updates the description of IPs already present
  • deleteIps removes the indicated IPs
  • do not combine allowedIps with addIps or deleteIps
  • allowedIps: [] completely clears the list
  • after the DB update, the backend also immediately synchronizes the firewall

Body·

required
application/json

PATCH merge the account's allowed IP configuration.

Operational rules:

  • allowedIps completely replaces the current list
  • addIps adds new IPs or updates the description of an already existing IP
  • deleteIps removes the indicated IPs
  • allowedIps cannot be combined with addIps or deleteIps
  • allowedIps: [] removes all IPs
  • description: null or empty string removes the IP description
  • Value supplied for addIps in the AccountAllowedIpsUpdateRequest request.

    Properties: 2
  • Value supplied for allowedIps in the AccountAllowedIpsUpdateRequest request.

    Properties: 2
  • Value supplied for deleteIps in the AccountAllowedIpsUpdateRequest request.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for patch/api/v1/account/allowed-ips
curl https://client-api.ai4call.com/api/v1/account/allowed-ips \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "allowedIps": [
    {
      "ip": "10.10.10.5",
      "description": "Main office"
    },
    {
      "ip": "192.168.1.20",
      "description": "House"
    }
  ]
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "configuration": {
      "allowedIps": [
        {
          "ip": "203.0.113.10",
          "description": "example"
        }
      ]
    }
  },
  "meta": {
    "count": 1
  }
}

Retrieves the call limits of the authenticated account

​

Returns the account-level concurrent call limits for all customer assistants.

How to use the answer:

  • use assistants[].assistantApiKey in PATCH
  • configuredLimit and the value saved on the tenant side
  • maxConcurrentCalls and the actual value shown on the portal
  • if configuredLimit and null, the backend uses defaultLimit

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/account/call-limits
curl https://client-api.ai4call.com/api/v1/account/call-limits \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Account call limits retrieved successfully.",
  "data": {
    "configuration": {
      "defaultLimit": 10,
      "assistants": [
        {
          "assistantApiKey": "ai4call_sk_abc123",
          "assistantName": "Assistente Demo",
          "description": "Customer support",
          "configuredLimit": 5,
          "maxConcurrentCalls": 5
        },
        {
          "assistantApiKey": "ai4call_sk_sales456",
          "assistantName": "Assistente Vendite",
          "description": null,
          "configuredLimit": null,
          "maxConcurrentCalls": 10
        }
      ]
    }
  },
  "meta": {
    "count": 2
  },
  "requestId": "9755db58-3e8d-4a09-b3a1-c68fd6f70c8a"
}

Update the authenticated account's call limits

​

Update account-level concurrent call limits with PATCH merge semantics.

Editable parameters:

  • assistants
  • assistants[].assistantApiKey
  • assistants[].maxConcurrentCalls

How to recover data:

  • use GET /api/v1/account/call-limits
  • reuse assistants[].assistantApiKey

Operational rules:

  • each item modifies only the indicated assistant
  • maxConcurrentCalls: null removes the configured limit and the assistant returns to defaultLimit
  • if an assistant is not present in the payload, its limit does not change

Body·

required
application/json

PATCH merge the account's simultaneous call limits.

Operational rules:

  • assistants is mandatory
  • each item updates only the indicated assistant
  • maxConcurrentCalls: null removes the limit configured for that assistant
  • if an assistant is not sent, its current limit does not change
  • maxConcurrentCalls must be an integer greater than or equal to 0
  • Value supplied for assistants in the AccountCallLimitsUpdateRequest request.

    Properties: 2

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for patch/api/v1/account/call-limits
curl https://client-api.ai4call.com/api/v1/account/call-limits \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "assistants": [
    {
      "assistantApiKey": "ai4call_sk_abc123",
      "maxConcurrentCalls": 5
    },
    {
      "assistantApiKey": "ai4call_sk_sales456",
      "maxConcurrentCalls": 12
    }
  ]
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "configuration": {
      "defaultLimit": 1,
      "assistants": [
        {
          "assistantApiKey": "ai4call_sk_example",
          "assistantName": "Example",
          "configuredLimit": 1,
          "maxConcurrentCalls": 1
        }
      ]
    }
  },
  "meta": {
    "count": 1
  }
}

Retrieve the routing numbers of the authenticated account

​

Returns the portal account-level routing numbers:

  • assistants
  • demoNumbers
  • purchasedNumbers
  • userNumbers

How to use the answer:

  • use assistants[].assistantApiKey in PATCH payloads
  • use phoneNumber from the respective lists in the PATCH payloads
  • assistantApiKey and assistantName inside each number indicate the assistant currently connected

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/account/number-routing
curl https://client-api.ai4call.com/api/v1/account/number-routing \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Account number routing retrieved successfully.",
  "data": {
    "configuration": {
      "assistants": [
        {
          "assistantApiKey": "ai4call_sk_abc123",
          "assistantName": "Assistente Demo"
        }
      ],
      "demoNumbers": [
        {
          "phoneNumber": "000012345678",
          "assistantApiKey": "ai4call_sk_abc123",
          "assistantName": "Assistente Demo",
          "assignedAt": "2026-04-24T10:00:00.000Z"
        }
      ],
      "purchasedNumbers": [
        {
          "phoneNumber": "+390201234567",
          "prefix": "02",
          "assistantApiKey": null,
          "assistantName": null,
          "acquiredAt": "2026-04-20T09:00:00.000Z"
        }
      ],
      "userNumbers": [
        {
          "phoneNumber": "+390612345678",
          "prefix": "06",
          "assistantApiKey": "ai4call_sk_abc123",
          "assistantName": "Assistente Demo",
          "createdAt": "2026-04-10T09:00:00.000Z"
        }
      ]
    }
  },
  "meta": {
    "assistantCount": 1,
    "demoCount": 1,
    "purchasedCount": 1,
    "userCount": 1,
    "totalCount": 3
  },
  "requestId": "9755db58-3e8d-4a09-b3a1-c68fd6f70c8a"
}

Update the authenticated account's routing numbers

​

Update account-level number routing with PATCH merge semantics.

Editable parameters:

  • demoNumbers
  • demoNumbers[].phoneNumber
  • demoNumbers[].assistantApiKey
  • purchasedNumbers
  • purchasedNumbers[].phoneNumber
  • purchasedNumbers[].assistantApiKey
  • userNumbers
  • userNumbers[].phoneNumber
  • userNumbers[].assistantApiKey

How to recover data:

  • use GET /api/v1/account/number-routing
  • reuse assistants[].assistantApiKey
  • reuse demoNumbers[].phoneNumber, purchasedNumbers[].phoneNumber, userNumbers[].phoneNumber

Operational rules:

  • each item modifies only the indicated number
  • assistantApiKey: null releases the number
  • if the number was already associated with another assistant, it is moved to the new one
  • for demo numbers, by assigning an assistant to a demo number, any other demo already connected to that assistant is released
  • omitted fields are not modified

Body·

required
application/json

PATCH merge of account number routing.

Operational rules:

  • at least one of demoNumbers, purchasedNumbers, userNumbers must be present
  • each item updates only the indicated number
  • assistantApiKey: null releases the number
  • assistantApiKey: "..." connect or move the number to that assistant
  • if a number was connected to another assistant, it is dropped and reconnected to the new one
  • for demo numbers, if the target assistant already had another demo number, the old one is released
  • omitted fields are not modified
  • Value supplied for demoNumbers in the AccountNumberRoutingUpdateRequest request.

    Properties: 2
  • Value supplied for purchasedNumbers in the AccountNumberRoutingUpdateRequest request.

    Properties: 2
  • Value supplied for userNumbers in the AccountNumberRoutingUpdateRequest request.

    Properties: 2

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for patch/api/v1/account/number-routing
curl https://client-api.ai4call.com/api/v1/account/number-routing \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "demoNumbers": [
    {
      "phoneNumber": "000012345678",
      "assistantApiKey": "ai4call_sk_abc123"
    }
  ],
  "purchasedNumbers": [
    {
      "phoneNumber": "+390201234567",
      "assistantApiKey": "ai4call_sk_sales456"
    }
  ],
  "userNumbers": [
    {
      "phoneNumber": "+390612345678",
      "assistantApiKey": null
    }
  ]
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "configuration": {
      "assistants": [
        {
          "assistantApiKey": "ai4call_sk_example",
          "assistantName": "Example"
        }
      ],
      "demoNumbers": [
        {
          "phoneNumber": "+390212345678"
        }
      ],
      "purchasedNumbers": [
        {
          "phoneNumber": "+390212345678"
        }
      ],
      "userNumbers": [
        {
          "phoneNumber": "+390212345678"
        }
      ]
    }
  },
  "meta": {
    "assistantCount": 1,
    "demoCount": 1,
    "purchasedCount": 1,
    "userCount": 1,
    "totalCount": 1
  }
}

Recovers all purchasable plugins of the authenticated account

​

Returns the plugins that can be purchased for the authenticated customer according to his price list.

How to use the data:

  • directly reuse pluginName in the PATCH PATCH /api/v1/account/plugins/purchase
  • no plugin IDs needed

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/account/plugins/available
curl https://client-api.ai4call.com/api/v1/account/plugins/available \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Account purchasable plugins retrieved successfully.",
  "requestId": "99c930a8-4f1f-4c98-8b9b-6af88a3aa7d8",
  "data": {
    "configuration": {
      "plugins": [
        {
          "pluginName": "Google Sheets",
          "pluginCode": "google_sheets",
          "description": "Integration with Google Sheets",
          "category": "data_integrations",
          "pluginType": "paid",
          "purchasePrice": 9.9,
          "monthlyPrice": 4.9,
          "priceListName": "Standard",
          "activeInstanceCount": 1
        }
      ]
    }
  },
  "meta": {
    "count": 1
  }
}

Retrieves all active plugin instances purchased by the authenticated account

​

Returns the active plugin instances of the authenticated client.

Canonical usage:

  • use the stable instanceId with PATCH /api/v1/account/plugins/instances/{instanceId}
  • use the same instanceId with DELETE /api/v1/account/plugins/instances/{instanceId}

The legacy name-based PATCH remains available for compatibility.

Query Parameters

  • Maximum number of items returned in one cursor-paginated page. Omit both limit and cursor to preserve the legacy unpaginated response.

  • Opaque cursor returned in meta.nextCursor by the previous page.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/account/plugins/instances
curl https://client-api.ai4call.com/api/v1/account/plugins/instances \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Account purchased plugin instances retrieved successfully.",
  "requestId": "1f345f1f-53a9-4d87-8a65-f45966c26ef8",
  "data": {
    "configuration": {
      "instances": [
        {
          "pluginName": "Google Sheets",
          "pluginCode": "google_sheets",
          "description": "Integration with Google Sheets",
          "category": "data_integrations",
          "instanceName": "Sheets Produzione",
          "instanceIndex": 1,
          "status": "active",
          "activationDate": "2026-04-24T10:30:00.000Z",
          "nextBillingDate": "2026-05-24T10:30:00.000Z",
          "purchasePrice": 9.9,
          "monthlyPrice": 4.9,
          "instanceId": "1"
        }
      ]
    }
  },
  "meta": {
    "count": 1
  }
}

Create a purchased plugin instance

​

Purchases a plugin and creates a new account plugin instance. The response exposes the stable instanceId used by the canonical instance routes.

Body·

required
application/json

Purchase a plugin using the plugin name returned by GET /api/v1/account/plugins/available.

Operational rules:

  • pluginName must match the value returned from the catalog
  • instanceName and optional
  • if instanceName is not present, the backend automatically generates Istanza N
  • legacy snake_case aliases remain accepted but are deprecated

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for post/api/v1/account/plugins/instances
curl https://client-api.ai4call.com/api/v1/account/plugins/instances \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "pluginName": "Google Sheets",
  "instanceName": "Sheets Produzione"
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "configuration": {
      "pluginName": "Example",
      "pluginCode": "example",
      "instanceName": "Example",
      "instanceIndex": 1,
      "status": "active",
      "activationDate": "2026-09-28T10:30:00.000Z",
      "purchasePriceCharged": 1,
      "monthlyPriceCharged": 1,
      "totalCharged": 1,
      "instanceId": "1"
    }
  }
}

Rename a purchased plugin instance

​

Renames an active plugin instance using its stable instanceId.

Path Parameters

  • Stable plugin subscription identifier returned by the instance list or create operation.

Body·

required
application/json

Rename a purchased plugin instance identified by its stable instanceId.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for patch/api/v1/account/plugins/instances/{instanceId}
curl 'https://client-api.ai4call.com/api/v1/account/plugins/instances/{instanceId}' \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "newInstanceName": "Sheets Marketing"
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "configuration": {
      "pluginName": "Example",
      "pluginCode": "example",
      "instanceName": "Example",
      "previousInstanceName": "Example",
      "status": "active",
      "activationDate": "2026-09-28T10:30:00.000Z",
      "nextBillingDate": "2026-09-28T10:30:00.000Z",
      "instanceId": "1"
    }
  }
}

Cancel a purchased plugin instance

​

Cancels an active plugin instance using its stable instanceId.

Path Parameters

  • Stable plugin subscription identifier returned by the instance list or create operation.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for delete/api/v1/account/plugins/instances/{instanceId}
curl 'https://client-api.ai4call.com/api/v1/account/plugins/instances/{instanceId}' \
  --request DELETE \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "configuration": {
      "pluginName": "Example",
      "pluginCode": "example",
      "instanceName": "Example",
      "previousInstanceName": "Example",
      "status": "cancelled",
      "activationDate": "2026-09-28T10:30:00.000Z",
      "nextBillingDate": null,
      "instanceId": "1"
    }
  }
}

Retrieve an acquired plugin instance configuration

​

Retrieves configuration for an acquired plugin instance. Use the stable instanceId returned by GET /api/v1/account/plugins/instances. The legacy name-based route remains supported.

Path Parameters

  • Stable identifier of the acquired plugin instance.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/account/plugins/instances/{instanceId}/configuration
curl 'https://client-api.ai4call.com/api/v1/account/plugins/instances/{instanceId}/configuration' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "string",
  "requestId": "string",
  "data": {
    "configuration": {
      "pluginName": "string",
      "pluginCode": "string",
      "instanceName": null,
      "supportsConfiguration": true,
      "requiresInstanceName": true,
      "patchMode": "merge",
      "configurableProperties": [
        {
          "key": "string",
          "label": "string",
          "type": "string",
          "required": true,
          "secret": true,
          "description": null,
          "enumValues": [
            "string"
          ],
          "replaceOnPatch": true
        }
      ],
      "configuration": null,
      "availableInstanceNames": [
        "string"
      ],
      "note": null
    }
  }
}

Update an acquired plugin instance configuration

​

Updates configuration using the stable instanceId. Plugin and instance names are resolved server-side, so clients send only the configuration fields to merge.

Path Parameters

  • Stable identifier of the acquired plugin instance.

Body·

required
application/json

Configuration PATCH body addressed by a stable plugin instanceId.

  • Plugin-specific fields to merge into the saved configuration.

    Properties: 1

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for patch/api/v1/account/plugins/instances/{instanceId}/configuration
curl 'https://client-api.ai4call.com/api/v1/account/plugins/instances/{instanceId}/configuration' \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "configuration": {
    "additionalProperty": "anything"
  }
}'
{
  "success": true,
  "message": "string",
  "requestId": "string",
  "data": {
    "configuration": {
      "pluginName": "string",
      "pluginCode": "string",
      "instanceName": null,
      "supportsConfiguration": true,
      "requiresInstanceName": true,
      "patchMode": "merge",
      "configurableProperties": [
        {
          "key": "string",
          "label": "string",
          "type": "string",
          "required": true,
          "secret": true,
          "description": null,
          "enumValues": [
            "string"
          ],
          "replaceOnPatch": true
        }
      ],
      "configuration": null,
      "availableInstanceNames": [
        "string"
      ],
      "note": null
    }
  }
}

Assistants

​

Lists the authenticated client's assistants

​

Lists the authenticated client's assistants

Query Parameters

  • Maximum number of items returned in one cursor-paginated page. Omit both limit and cursor to preserve the legacy unpaginated response.

  • Opaque cursor returned in meta.nextCursor by the previous page.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/assistants
curl https://client-api.ai4call.com/api/v1/assistants \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "assistants": [
      {
        "assistantId": "example-id",
        "id": "example-id",
        "clientEmail": "developer@example.com",
        "mode": "text",
        "name": "Example",
        "status": "draft",
        "numbers": {
          "demo": [
            "example"
          ],
          "purchased": [
            "example"
          ]
        },
        "network": {
          "allowedIps": [
            "203.0.113.10"
          ]
        },
        "settings": {
          "model": "example-model",
          "voice": "example-voice",
          "language": "it-IT",
          "timezone": "Europe/Rome",
          "recordingEnabled": true
        },
        "firstMessage": {
          "text": "",
          "callerSpeaksFirst": false,
          "uninterruptible": false
        },
        "metadata": {},
        "createdAt": "2026-09-28T10:30:00.000Z",
        "updatedAt": "2026-09-28T10:30:00.000Z"
      }
    ]
  }
}

Create a new pre-initialized assistant for the authenticated client

​

Creates the assistant by replicating the same logic used by the AI4Call portal.

For a classic assistant only name and description are required. For an audio-to-audio assistant send mode: audio_to_audio and, if you want to override the defaults, the canonical audioToAudio block. The legacy voice_to_voice mode and voiceToVoice field remain accepted for compatibility.

The backend automatically performs:

  • assistantApiKey generation in ai4call_sk_* format
  • progressive jsonFilename allocation in FLLM*.json format
  • demo virtualNumber generation in 0000******** format
  • runtime JSON initialization with portal defaults
  • backend provisioning trigger
  • best-effort attempt to register the assistant on the MCP tenant

Initial defaults applied:

  • TTS tts_live_azure_multi with voice it-IT-ElsaNeural
  • ASR asr_azure_multi
  • LLM openai with model gpt-4o
  • first message not configured (empty firstMessage.text)
  • preconfigured initial prompt
  • initial status draft

If mode is audio_to_audio, the backend initializes a configType: voice-llm JSON with an audio-to-audio root compatible with the portal.

Body·

required
application/json

Minimum creation payload. The backend replicates the portal logic: generates assistantApiKey, virtualNumber and jsonFilename, initializes the runtime JSON with AI4Call defaults and starts provisioning the assistant. The assistant name is normalized by replacing spaces with _.

  • Functional description of the assistant.

  • Assistant name. If it contains spaces, the backend automatically converts them to _.

  • Initial audio-to-audio configuration, used when applicable to the selected mode.

    Properties: 6
  • Runtime mode to use when creating the assistant.

    values
    textaudio_to_audiovoice_to_voice
  • Legacy alias of audioToAudio.

    Properties: 6

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for post/api/v1/assistants
curl https://client-api.ai4call.com/api/v1/assistants \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "name": "Sales Assistant",
  "description": "Demo assistant for inbound commercial campaigns.",
  "mode": "text"
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "assistant": {
      "assistantId": "example-id",
      "id": "example-id",
      "apiKey": "sk_example",
      "clientEmail": "developer@example.com",
      "mode": "text",
      "name": "Example",
      "status": "draft",
      "numbers": {
        "demo": [
          "example"
        ],
        "purchased": [
          "example"
        ]
      },
      "network": {
        "allowedIps": [
          "203.0.113.10"
        ]
      },
      "settings": {
        "model": "example-model",
        "voice": "example-voice",
        "language": "it-IT",
        "timezone": "Europe/Rome",
        "recordingEnabled": true
      },
      "firstMessage": {
        "text": "",
        "callerSpeaksFirst": false,
        "uninterruptible": false
      },
      "metadata": {},
      "createdAt": "2026-09-28T10:30:00.000Z",
      "updatedAt": "2026-09-28T10:30:00.000Z"
    }
  }
}

Retrieves an authenticated customer-specific assistant

​

Retrieves an authenticated customer-specific assistant

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/assistants/{assistantId}
curl https://client-api.ai4call.com/api/v1/assistants/205 \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "assistant": {
      "assistantId": "example-id",
      "id": "example-id",
      "apiKey": "sk_example",
      "clientEmail": "developer@example.com",
      "mode": "text",
      "name": "Example",
      "status": "draft",
      "numbers": {
        "demo": [
          "example"
        ],
        "purchased": [
          "example"
        ]
      },
      "network": {
        "allowedIps": [
          "203.0.113.10"
        ]
      },
      "settings": {
        "model": "example-model",
        "voice": "example-voice",
        "language": "it-IT",
        "timezone": "Europe/Rome",
        "recordingEnabled": true
      },
      "firstMessage": {
        "text": "",
        "callerSpeaksFirst": false,
        "uninterruptible": false
      },
      "metadata": {},
      "createdAt": "2026-09-28T10:30:00.000Z",
      "updatedAt": "2026-09-28T10:30:00.000Z"
    }
  }
}

Update assistant metadata, status and basic configuration

​

Updates the assistant's general fields.

For text assistants, the firstMessage block updates the first static message with PATCH merge semantics. Send firstMessage.text: null or firstMessage.text: "" to delete it.

For audio-to-audio assistants, the canonical audioToAudio block updates the voice-llm JSON with PATCH merge semantics. The legacy voiceToVoice field remains accepted for compatibility.

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Body·

required
application/json

PATCH payload used to update editable assistant fields.

  • Partial update of the audio-to-audio configuration.

    Properties: 6
  • New functional description; null removes the current description.

  • Partial update of the assistant's first-message configuration.

    Properties: 3
  • Free-form metadata to store with the assistant.

    Properties: 1
  • If it contains spaces, the backend automatically converts them to _.

  • Network settings to update on the assistant.

    Properties: 1
  • Replacement values for assistant number lists when supplied.

    Properties: 2
  • High-level assistant settings to update.

    Properties: 5
  • New lifecycle status for the assistant.

  • Legacy alias of audioToAudio.

    Properties: 6

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for patch/api/v1/assistants/{assistantId}
curl https://client-api.ai4call.com/api/v1/assistants/205 \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "status": "active",
  "firstMessage": {
    "text": "Ciao, sono l'\''assistente virtuale. Come posso aiutarti?",
    "callerSpeaksFirst": false,
    "uninterruptible": false
  }
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "assistant": {
      "assistantId": "example-id",
      "id": "example-id",
      "apiKey": "sk_example",
      "clientEmail": "developer@example.com",
      "mode": "text",
      "name": "Example",
      "status": "draft",
      "numbers": {
        "demo": [
          "example"
        ],
        "purchased": [
          "example"
        ]
      },
      "network": {
        "allowedIps": [
          "203.0.113.10"
        ]
      },
      "settings": {
        "model": "example-model",
        "voice": "example-voice",
        "language": "it-IT",
        "timezone": "Europe/Rome",
        "recordingEnabled": true
      },
      "firstMessage": {
        "text": "",
        "callerSpeaksFirst": false,
        "uninterruptible": false
      },
      "metadata": {},
      "createdAt": "2026-09-28T10:30:00.000Z",
      "updatedAt": "2026-09-28T10:30:00.000Z"
    }
  }
}

Delete an assistant

​

Deletes the assistant, releases its assigned phone numbers, removes its runtime JSON and refreshes the routing map. Deletion is rejected while another assistant in the same account uses this assistant as a transfer target.

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for delete/api/v1/assistants/{assistantId}
curl https://client-api.ai4call.com/api/v1/assistants/205 \
  --request DELETE \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Assistant deleted successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "deleted": true
  }
}

Update the numbers routed to the assistant

​

Update the routing of the customer's numbers to this assistant, with PATCH merge semantics between the three lists.

Editable parameters:

  • demoNumbers
  • purchasedNumbers
  • userNumbers

How to recover current data:

  • use GET /api/v1/catalog/assistants/{assistantApiKey}/number-routing for the numbers already assigned and those still available on the account

Operational rules:

  • at least one of the three lists must be present
  • an omitted list retains the current value
  • a list that is present replaces the previous one entirely: send [] to free all numbers of that kind
  • assigning a number already routed to another assistant moves it to this one

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Body·

required
application/json

PATCH merge of the numbers routed to the assistant.

Operational rules:

  • at least one of demoNumbers, purchasedNumbers and userNumbers must be present
  • omitted lists retain the current value
  • each list replaces the previous one entirely: to remove all numbers of a kind, send []
  • only numbers already available on the customer account can be assigned
  • a number assigned to another assistant is moved to this one
  • Demo numbers to route to this assistant

  • Purchased numbers to route to this assistant

  • Customer's own numbers (own PBX) to route to this assistant

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for patch/api/v1/assistants/{assistantId}/runtime/number-routing
curl https://client-api.ai4call.com/api/v1/assistants/205/runtime/number-routing \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "demoNumbers": [
    "+390211223344"
  ]
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "configuration": {
      "demoNumbers": [
        "example"
      ],
      "purchasedNumbers": [
        "example"
      ],
      "userNumbers": [
        "example"
      ]
    }
  }
}

List the customer's numbers with their routing state

​

Returns all the customer's numbers, divided into demo, purchased and own, each with the assistant it is currently routed to.

Use it before PATCH /api/v1/assistants/{assistantApiKey}/runtime/number-routing to know which numbers are free and which are already assigned elsewhere.

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/catalog/assistants/{assistantId}/number-routing
curl https://client-api.ai4call.com/api/v1/catalog/assistants/205/number-routing \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Assistant number routing configuration retrieved successfully.",
  "requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "data": {
    "configuration": {
      "demoNumbers": [
        {
          "phoneNumber": "+390211223344",
          "assistantApiKey": "ak_live_123",
          "assistantName": "Reception",
          "assignedToCurrentAssistant": true,
          "assignedAt": "2026-08-01T09:15:00.000Z"
        }
      ],
      "purchasedNumbers": [],
      "userNumbers": []
    }
  },
  "meta": {
    "demoCount": 1,
    "purchasedCount": 0,
    "userCount": 0,
    "totalCount": 1
  }
}

Assistant Prompt

​

Editable assistant prompt, first message and related options

Retrieve editable prompt and configuration of the assistant's first message

​

Returns the prompt configuration of the assistant in the same conceptual model used by the portal.

What comes back

  • prompt.text: only the editable part of the prompt
  • firstMessage.text: the first static message, if present
  • firstMessage.callerSpeaksFirst: option that indicates whether the caller speaks first
  • firstMessage.uninterruptible: option that indicates whether the first message cannot be interrupted

Important note

Any automatic sections already present in the JSON, such as system blocks or knowledge, are not returned in prompt.text. On voice_to_voice servers, prompt.text corresponds to the root field prompt of the JSON voice-llm; the first message is not used.

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/assistants/{assistantId}/prompt
curl https://client-api.ai4call.com/api/v1/assistants/205/prompt \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "assistantApiKey": "ai4call_sk_6asvqzto",
    "assistantId": "205",
    "configuration": {
      "prompt": {
        "text": "Sei un assistente commerciale cordiale e conciso. Rispondi in italiano."
      },
      "firstMessage": {
        "text": "Ciao, sono l'assistente virtuale di AI4Call. Come posso aiutarti?",
        "callerSpeaksFirst": false,
        "uninterruptible": false
      }
    }
  }
}

Update editable prompt and assistant's first message configuration

​

Update assistant prompt configuration with PATCH merge semantics.

Editable parameters:

  • prompt.text
  • firstMessage.text
  • firstMessage.callerSpeaksFirst
  • firstMessage.uninterruptible

If you update the prompt

  • Send prompt.text
  • The backend updates only the editable part
  • Any automatic sections already present in the JSON, such as system and knowledge, remain preserved

If you update the first message

  • Send firstMessage.text to set or replace it
  • Send firstMessage.text: null or "" to delete it
  • Send firstMessage.callerSpeaksFirst: true if you want the caller to speak first
  • If callerSpeaksFirst=true, the backend deletes the first static message and forces uninterruptible=false

Note on merging

  • Omitted fields retain their current value
  • You can update just the prompt, just the first message, or both in the same call
  • on assistants voice_to_voice, only prompt.text is updated in the JSON root voice-llm; firstMessage fields are ignored by the audio-to-audio runtime

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Body·

required
application/json

Prompt and first message update payload.

Use one of the examples below depending on what you want to change:

  • prompts only
  • first message only
  • switch to callerSpeaksFirst

PATCH merge the assistant prompt configuration.

Operational rules:

  • omitted fields retain their current value
  • prompt.text updates only the editable part of the prompt
  • any automatic sections already present in the JSON, such as system and knowledge, are preserved
  • to delete the first static message, send firstMessage.text: null or firstMessage.text: ""
  • if after the merge firstMessage.callerSpeaksFirst=true, the backend:
    • delete the first static message
    • go firstMessage.uninterruptible=false
  • Value supplied for firstMessage in the AssistantPromptUpdateRequest request.

    Properties: 3
  • Value supplied for prompt in the AssistantPromptUpdateRequest request.

    Properties: 1

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for patch/api/v1/assistants/{assistantId}/prompt
curl https://client-api.ai4call.com/api/v1/assistants/205/prompt \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "prompt": {
    "text": "Sei un assistente commerciale chiaro, breve e orientato alla conversione."
  }
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "assistantApiKey": "ai4call_sk_6asvqzto",
    "assistantId": "205",
    "configuration": {
      "prompt": {
        "text": "Sei un assistente commerciale cordiale e conciso. Rispondi in italiano."
      },
      "firstMessage": {
        "text": "Ciao, sono l'assistente virtuale di AI4Call. Come posso aiutarti?",
        "callerSpeaksFirst": false,
        "uninterruptible": false
      }
    }
  }
}

Provider Wallet

​

List the providers that accept your own credentials

​

Returns the catalog of providers the wallet supports, each with the exact fields required to save a credential.

Read it before POST /api/v1/account/provider-wallet: serviceType, provider and engine of the creation payload must match one of these entries, and config accepts only the keys listed in its fields.

ai4call: true marks a provider also usable through the AI4CALL price list, without your own credentials; byok: true marks one that accepts your credentials.

The catalog is static and does not depend on the authenticated customer.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/account/provider-wallet/catalog
curl https://client-api.ai4call.com/api/v1/account/provider-wallet/catalog \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Provider wallet catalog retrieved successfully.",
  "requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "data": {
    "providers": [
      {
        "id": "llm:openai",
        "serviceType": "llm",
        "serviceLabel": "LLM",
        "provider": "openai",
        "engine": "openai",
        "label": "OpenAI",
        "description": "Flagship models of the GPT family and o series",
        "ai4call": true,
        "byok": true,
        "fields": [
          {
            "key": "apiKey",
            "label": "API key",
            "type": "password",
            "required": true,
            "secret": true
          }
        ]
      }
    ]
  },
  "meta": {
    "count": 29
  }
}

List the credentials saved in the wallet

​

Returns the customer's credentials, ordered by service and provider.

The configuration never comes back in clear text: preview carries the non-secret values plus the secrets truncated to their first characters, enough to tell two credentials apart.

The id of each credential is the value to send as providerWalletId on the assistant runtime endpoints, instead of putting an API key in the payload.

Query Parameters

  • Maximum number of items returned in one cursor-paginated page. Omit both limit and cursor to preserve the legacy unpaginated response.

  • Opaque cursor returned in meta.nextCursor by the previous page.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/account/provider-wallet
curl https://client-api.ai4call.com/api/v1/account/provider-wallet \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Provider wallet credentials retrieved successfully.",
  "requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "data": {
    "credentials": [
      {
        "id": 42,
        "serviceType": "llm",
        "provider": "openai",
        "engine": "openai",
        "name": "OpenAI produzione",
        "isActive": true,
        "preview": {
          "apiKey": "sk-proj-ab**********"
        },
        "createdAt": "2026-08-01T09:15:00.000Z",
        "updatedAt": "2026-08-20T11:02:00.000Z"
      }
    ]
  },
  "meta": {
    "count": 1
  }
}

Save a new credential in the wallet

​

Saves a provider credential. The value is encrypted at rest and never returned in clear text.

How to build the payload:

  • read GET /api/v1/account/provider-wallet/catalog
  • copy serviceType, provider and engine from the chosen entry
  • fill config with the keys listed in that entry's fields

Operational rules:

  • config accepts only the declared keys: any other key returns 400
  • every field marked required must be present and non-empty
  • fields with options accept only the listed values
  • name is free text, used to recognise the credential later

The id in the response is the value to use as providerWalletId on the assistant runtimes.

Body·

required
application/json

Creation of a credential in the wallet.

Operational rules:

  • serviceType, provider and engine must match an entry returned by GET /api/v1/account/provider-wallet/catalog
  • config accepts only the keys declared by that entry's fields; any other key is rejected
  • every field marked required must be present and non-empty
  • Values of the fields declared by the catalog entry

    Properties: 1
  • Engine code selected from the provider-wallet catalog.

  • Customer-defined name for the saved credential.

  • Provider code selected from the provider-wallet catalog.

  • Service category selected from the provider-wallet catalog.

    values
    llmttsasrvoice_llm

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for post/api/v1/account/provider-wallet
curl https://client-api.ai4call.com/api/v1/account/provider-wallet \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "serviceType": "llm",
  "provider": "openai",
  "engine": "openai",
  "name": "OpenAI produzione",
  "config": {
    "apiKey": "sk-proj-example"
  }
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "credential": {
      "id": 42,
      "serviceType": "llm",
      "provider": "openai",
      "engine": "openai",
      "name": "OpenAI produzione",
      "isActive": true,
      "preview": {
        "apiKey": "sk-proj-ab**********"
      },
      "createdAt": "2026-09-28T10:30:00.000Z",
      "updatedAt": "2026-09-28T10:30:00.000Z"
    }
  }
}

List the wallet credentials associated with an assistant

​

Returns which credential each runtime of the assistant is using, one entry per scopeKey (for example the llm, the tts, the asr).

The runtime endpoints report only hasProviderWallet, a boolean: this is where you find out which credential is applied.

Associations are not written here: they are created by sending providerWalletId on the corresponding runtime endpoint, and removed by sending providerWalletId: null.

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/account/provider-wallet/assistants/{assistantId}
curl https://client-api.ai4call.com/api/v1/account/provider-wallet/assistants/205 \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Assistant provider wallet associations retrieved successfully.",
  "requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "data": {
    "associations": [
      {
        "assistantApiKey": "ai4call_sk_abc123",
        "scopeKey": "llm",
        "serviceType": "llm",
        "provider": "openai",
        "engine": "openai",
        "providerWalletId": 42,
        "walletName": "OpenAI produzione",
        "createdAt": "2026-08-01T09:15:00.000Z",
        "updatedAt": "2026-08-20T11:02:00.000Z"
      }
    ]
  },
  "meta": {
    "count": 1
  }
}

Retrieve one credential from the wallet

​

Returns a single credential. As in the list, the configuration comes back only as preview, with the secrets masked.

Path Parameters

  • Id of the credential, returned when it was created or by the list endpoint

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/account/provider-wallet/{providerWalletId}
curl https://client-api.ai4call.com/api/v1/account/provider-wallet/42 \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "credential": {
      "id": 42,
      "serviceType": "llm",
      "provider": "openai",
      "engine": "openai",
      "name": "OpenAI produzione",
      "isActive": true,
      "preview": {
        "apiKey": "sk-proj-ab**********"
      },
      "createdAt": "2026-09-28T10:30:00.000Z",
      "updatedAt": "2026-09-28T10:30:00.000Z"
    }
  }
}

Update a credential in the wallet

​

Updates a credential with PATCH merge semantics.

Editable parameters:

  • name
  • isActive
  • config

Operational rules:

  • at least one of the three must be present
  • serviceType, provider and engine cannot be changed: to switch provider, create a new credential
  • inside config, an omitted or empty field keeps the value already saved. This is what makes it possible to rename a credential without resending an API key the client can never read back
  • deactivating with isActive: false keeps the credential but stops applying it to the runtimes

Path Parameters

  • Id of the credential, returned when it was created or by the list endpoint

Body·

required
application/json

PATCH merge of a credential.

Operational rules:

  • at least one of name, isActive and config must be present
  • serviceType, provider and engine cannot be changed: to switch provider, create a new credential
  • inside config, an omitted or empty field keeps the value already saved — useful for secrets, which the client can never read back
  • Credential fields to merge into the saved configuration.

    Properties: 1
  • Whether the saved credential can be used by assistant runtimes.

  • New customer-defined credential name.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for patch/api/v1/account/provider-wallet/{providerWalletId}
curl https://client-api.ai4call.com/api/v1/account/provider-wallet/42 \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "name": "OpenAI produzione (rinnovata)"
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "credential": {
      "id": 42,
      "serviceType": "llm",
      "provider": "openai",
      "engine": "openai",
      "name": "OpenAI produzione",
      "isActive": true,
      "preview": {
        "apiKey": "sk-proj-ab**********"
      },
      "createdAt": "2026-09-28T10:30:00.000Z",
      "updatedAt": "2026-09-28T10:30:00.000Z"
    }
  }
}

Delete a credential from the wallet

​

Permanently deletes the credential and every association with the customer's assistants.

The affected assistants go back to using the values written directly in their own configuration; they are not stopped. Check the associations first with GET /api/v1/account/provider-wallet/assistants/{assistantApiKey} if you need to know which assistants are involved.

Path Parameters

  • Id of the credential, returned when it was created or by the list endpoint

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for delete/api/v1/account/provider-wallet/{providerWalletId}
curl https://client-api.ai4call.com/api/v1/account/provider-wallet/42 \
  --request DELETE \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "deleted": true
  }
}

Catalog TTS

​

Update the assistant's TTS runtime configuration

​

Update the assistant's TTS runtime configuration with PATCH merge semantics.

Editable parameters:

  • sourceMode
  • engineCode
  • voiceCode
  • API key
  • region

If you use ai4call

  • Send sourceMode: ai4call
  • Send voiceCode
  • engineCode and optional
  • Do not send API key
  • Do not send region

If you use customer

  • Send sourceMode: customer
  • Send engineCode
  • Send voiceCode
  • Send API key
  • If you use Azure, also send region

Note on merging

  • Omitted fields retain the current value, if already present
  • The response returns the resulting final configuration

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Body·

required
application/json

Choose one of the examples below based on the mode you want to set.

  • ai4call: selection of an item from the AI4Call catalogue
  • customer: direct configuration with customer provider parameters

PATCH merge of the assistant's TTS configuration.

Operational rules:

  • sourceMode and always mandatory
  • omitted fields retain the current value already saved, if present
  • in ai4call the backend resolves the configuration starting from voiceCode
  • in customer the configuration uses direct customer parameters

Application constraints:

  • customer: engineCode, voiceCode and API key must be completed after the merge
  • customer with Azure: region must be completed after the merge
  • ai4call: use voiceCode; engineCode is optional and serves only as a consistency check
  • Runtime sourcing mode.

    • ai4call: uses a provider/model present in the customer's AI4Call price lists
    • customer: Use direct customer credentials and configuration
  • API key of the customer's TTS provider. It should only be sent in customer. In ai4call it should be omitted.

  • TTS engine/provider code. In customer identifies the engine to use. In ai4call it is optional and, if sent, is only used to verify that the voiceCode belongs to that engine.

  • Id of a credential saved in the customer's provider wallet, used instead of sending apiKey in clear text.

    When present, the credentials are read from the wallet, applied to the runtime and the association is stored on the assistant. null removes the association and falls back to the values sent explicitly.

    Wallet credentials are created and managed from the AI4CALL portal.

  • Region/provider area requested by some engine customers, in particular Azure. Required for Azure in customer. In ai4call it should be omitted.

  • TTS voice code. In ai4call is the main parameter to select the entry from the AI4Call catalog. In customer it must identify the valid entry for the chosen provider/engine.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for patch/api/v1/assistants/{assistantId}/runtime/tts
curl https://client-api.ai4call.com/api/v1/assistants/205/runtime/tts \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "sourceMode": "ai4call",
  "voiceCode": "it-IT-DiegoNeural"
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "assistantApiKey": "ai4call_sk_example",
    "assistantId": "example-id",
    "service": "tts",
    "configuration": {
      "sourceMode": "ai4call",
      "hasApiKey": true
    },
    "runtimeBinding": {
      "configured": true,
      "sourceMode": "ai4call"
    }
  }
}

Lists the TTS providers available to the customer

​

Lists the TTS providers available to the customer

Responses

  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/catalog/providers/tts
curl https://client-api.ai4call.com/api/v1/catalog/providers/tts \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "TTS providers retrieved successfully.",
  "requestId": "5f6ca30b-7046-416e-b4da-e149833885e2",
  "meta": {
    "count": 3
  },
  "data": {
    "providers": [
      {
        "providerId": "azure",
        "providerLabel": "Azure",
        "engineCode": "tts_live_azure_multi",
        "serviceType": "tts",
        "availableModes": [
          "ai4call",
          "customer"
        ],
        "itemCount": 530
      },
      {
        "providerId": "elevenlabs",
        "providerLabel": "ElevenLabs",
        "engineCode": "tts_live_eleven_multi",
        "serviceType": "tts",
        "availableModes": [
          "customer"
        ],
        "itemCount": 2793
      }
    ]
  }
}

Lists the TTS entries resolved by the assistant runtime configuration

​

Lists the TTS entries resolved by the assistant runtime configuration

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/catalog/assistants/{assistantId}/tts/voices
curl https://client-api.ai4call.com/api/v1/catalog/assistants/205/tts/voices \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Assistant TTS voices retrieved successfully.",
  "requestId": "00421620-08b4-473d-b703-2d7df18d0f5a",
  "meta": {
    "count": 530
  },
  "data": {
    "voices": [
      {
        "voiceId": "1",
        "voiceCode": "it-IT-DiegoNeural",
        "voiceLabel": "Diego - Italian (Italy)",
        "providerId": "azure",
        "providerLabel": "Azure",
        "engineCode": "tts_live_azure_multi",
        "language": "it-IT",
        "region": null,
        "price": 0.008,
        "sourceMode": "ai4call",
        "catalogOrigin": "ai4call_pricing",
        "previewUrl": null
      }
    ]
  }
}

Catalog ASR

​

Update the assistant's ASR runtime configuration

​

Update the assistant's ASR runtime configuration with PATCH merge semantics.

Editable parameters:

  • sourceMode
  • engineCode
  • API key

If you use ai4call

  • Send sourceMode: ai4call
  • Send engineCode
  • Do not send API key

If you use customer

  • Send sourceMode: customer
  • Send engineCode
  • Send API key

Note on merging

  • Omitted fields retain the current value, if already present
  • The response returns the resulting final configuration

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Body·

required
application/json

Choose one of the examples below based on the mode you want to set.

  • ai4call: selection of an ASR engine from the AI4Call catalog
  • customer: direct configuration with the customer's engine and API key

PATCH merge the assistant's ASR configuration.

Operational rules:

  • sourceMode and always mandatory
  • omitted fields retain the current value already saved, if present
  • in ai4call the backend selects an available engine from the customer's AI4Call price lists
  • in customer the configuration uses direct customer parameters

Application constraints:

  • customer: engineCode and API key must be completed after the merge
  • ai4call: engineCode must identify an engine available in the customer's AI4Call catalog
  • Runtime sourcing mode.

    • ai4call: uses an ASR engine present in the customer's AI4Call price lists
    • customer: Use direct customer credentials and configuration
  • API key of the customer's ASR provider. It should only be sent in customer. In ai4call it should be omitted.

  • ASR engine/provider code. In ai4call identifies the AI4Call engine to associate. In customer identifies the customer's provider engine.

  • Id of a credential saved in the customer's provider wallet, used instead of sending apiKey in clear text.

    When present, the credentials are read from the wallet, applied to the runtime and the association is stored on the assistant. null removes the association and falls back to the values sent explicitly.

    Wallet credentials are created and managed from the AI4CALL portal.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for patch/api/v1/assistants/{assistantId}/runtime/asr
curl https://client-api.ai4call.com/api/v1/assistants/205/runtime/asr \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "sourceMode": "ai4call",
  "engineCode": "asr_azure_multi"
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "assistantApiKey": "ai4call_sk_example",
    "assistantId": "example-id",
    "service": "asr",
    "configuration": {
      "sourceMode": "ai4call",
      "hasApiKey": true
    },
    "runtimeBinding": {
      "configured": true,
      "sourceMode": "ai4call"
    }
  }
}

Lists the ASR providers available to the customer

​

Lists the ASR providers available to the customer

Responses

  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/catalog/providers/asr
curl https://client-api.ai4call.com/api/v1/catalog/providers/asr \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "providers": [
      {
        "providerId": "openai",
        "providerLabel": "openai",
        "serviceType": "tts",
        "availableModes": [
          "ai4call"
        ]
      }
    ]
  }
}

Lists the ASR patterns resolved by the assistant runtime configuration

​

Lists the ASR patterns resolved by the assistant runtime configuration

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/catalog/assistants/{assistantId}/asr/models
curl https://client-api.ai4call.com/api/v1/catalog/assistants/205/asr/models \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Assistant ASR models retrieved successfully.",
  "requestId": "cbdebd8b-8904-4463-bbef-3c5751dc2087",
  "meta": {
    "count": 1
  },
  "data": {
    "models": [
      {
        "modelId": "1",
        "modelCode": "asr_azure_multi",
        "modelLabel": "asr_azure_multi",
        "providerId": "azure",
        "providerLabel": "AZURE",
        "supportedLanguages": [
          "it-IT"
        ],
        "price": 0.005,
        "sourceMode": "ai4call",
        "catalogOrigin": "ai4call_pricing"
      }
    ]
  }
}

Catalog LLM

​

Update the assistant's LLM runtime configuration

​

Update the assistant's LLM runtime configuration with PATCH merge semantics.

Editable parameters:

  • sourceMode
  • engineCode
  • modelCode
  • API key
  • baseUrl

If you use ai4call

  • Send sourceMode: ai4call
  • Send modelCode
  • engineCode and optional
  • Do not send API key
  • Do not send baseUrl

If you use customer

  • Send sourceMode: customer
  • Send engineCode
  • Send modelCode
  • If engineCode = ollama, send baseUrl
  • For all other engines, send API key

Note on merging

  • Omitted fields retain the current value, if already present
  • The response returns the resulting final configuration

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Body·

required
application/json

Choose one of the examples below based on the mode you want to set.

  • ai4call: selection of a model from the AI4Call catalogue
  • customer: direct configuration with the customer's provider

PATCH merge the assistant's LLM configuration.

Operational rules:

  • sourceMode and always mandatory
  • omitted fields retain the current value already saved, if present
  • in ai4call the backend resolves the configuration starting from modelCode
  • in customer the configuration uses direct customer parameters

Application constraints:

  • customer: engineCode and modelCode must be completed after the merge
  • customer with ollama: baseUrl must be completed after the merge
  • customer with engines other than ollama: API key must be completed after the merge
  • ai4call: use modelCode; engineCode is optional and serves only as a consistency check
  • Runtime sourcing mode.

    • ai4call: uses a model present in the customer's AI4Call price lists
    • customer: Use direct customer credentials and configuration
  • API key of the customer's LLM provider. It must be sent in customer for providers who request it. For ollama it is normally not needed. In ai4call it should be omitted.

  • Base custom URL of the LLM provider. Typically used for ollama or self-hosted OpenAI compatible endpoints. In customer with ollama and mandatory. In ai4call it should be omitted.

  • LLM engine/provider code. In customer identifies the provider to use. In ai4call it is optional and, if sent, is only used to verify that the modelCode belongs to that engine.

  • LLM model code. In ai4call is the main parameter to select the model from the AI4Call catalog. In customer it must identify the valid model for the chosen provider.

  • Id of a credential saved in the customer's provider wallet, used instead of sending apiKey in clear text.

    When present, the credentials are read from the wallet, applied to the runtime and the association is stored on the assistant. null removes the association and falls back to the values sent explicitly.

    Wallet credentials are created and managed from the AI4CALL portal.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for patch/api/v1/assistants/{assistantId}/runtime/llm
curl https://client-api.ai4call.com/api/v1/assistants/205/runtime/llm \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "sourceMode": "ai4call",
  "modelCode": "gpt-4.1-mini"
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "assistantApiKey": "ai4call_sk_example",
    "assistantId": "example-id",
    "service": "llm",
    "configuration": {
      "sourceMode": "ai4call",
      "hasApiKey": true
    },
    "runtimeBinding": {
      "configured": true,
      "sourceMode": "ai4call"
    }
  }
}

Lists the LLM providers available to the client

​

Lists the LLM providers available to the client

Responses

  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/catalog/providers/llm
curl https://client-api.ai4call.com/api/v1/catalog/providers/llm \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "providers": [
      {
        "providerId": "openai",
        "providerLabel": "openai",
        "serviceType": "tts",
        "availableModes": [
          "ai4call"
        ]
      }
    ]
  }
}

Lists the LLM models resolved by the assistant runtime configuration

​

Lists the LLM models resolved by the assistant runtime configuration

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/catalog/assistants/{assistantId}/llm/models
curl https://client-api.ai4call.com/api/v1/catalog/assistants/205/llm/models \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Assistant LLM models retrieved successfully.",
  "requestId": "dc4d2d62-0fd3-4b4f-8bf7-1c1d9509966d",
  "meta": {
    "count": 2
  },
  "data": {
    "models": [
      {
        "modelId": "16",
        "modelCode": "gpt-4.1-mini",
        "modelLabel": "GPT-4.1 mini",
        "providerId": "openai",
        "providerLabel": "openai",
        "inputPrice": 0.15,
        "outputPrice": 0.6,
        "sourceMode": "ai4call",
        "catalogOrigin": "ai4call_pricing"
      }
    ]
  }
}

Catalog Audio-to-Audio

​

Update the assistant's audio-to-audio runtime configuration

​

Canonical route for realtime audio-to-audio assistants.

PATCH /api/v1/assistants/{assistantApiKey}/runtime/voice-to-voice is kept as a legacy alias: same handler, same payload, same response.

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Body·

required
application/json

PATCH merge of the audio-to-audio runtime configuration.

Update the server's JSON configType: voice-llm. At least one field between engineCode, modelCode, voiceCode, providerWalletId, apiKey, baseUrl or prompt must be present.

  • Customer key provider API. Send null to remove it from the JSON.

  • Base custom URL. Send null to remove it from the JSON.

  • Provider/engine voice LLM.

  • LLM voice model code.

  • Main prompt of the audio-to-audio runtime.

  • Id of a credential saved in the customer's provider wallet, used instead of sending apiKey in clear text.

    When present, the credentials are read from the wallet, applied to the runtime and the association is stored on the assistant. null removes the association and falls back to the values sent explicitly.

    Wallet credentials are created and managed from the AI4CALL portal.

  • Model item code.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for patch/api/v1/assistants/{assistantId}/runtime/audio-to-audio
curl https://client-api.ai4call.com/api/v1/assistants/205/runtime/audio-to-audio \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "engineCode": "openai",
  "modelCode": "gpt-4o-realtime-preview",
  "voiceCode": "alloy"
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "assistantApiKey": "ai4call_sk_example",
    "assistantId": "example-id",
    "service": "audio-to-audio",
    "configuration": {
      "engineCode": "openai",
      "modelCode": "example-model",
      "voiceCode": "example-voice",
      "baseUrl": "https://example.com",
      "hasApiKey": true,
      "prompt": "example"
    }
  }
}

Lists LLM voice providers available to the customer

​

Lists LLM voice providers available to the customer

Responses

  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/catalog/providers/audio-to-audio
curl https://client-api.ai4call.com/api/v1/catalog/providers/audio-to-audio \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "providers": [
      {
        "providerId": "openai",
        "providerLabel": "openai",
        "serviceType": "tts",
        "availableModes": [
          "ai4call"
        ]
      }
    ]
  }
}

Lists voice LLM models

​

Lists voice LLM models

Query Parameters

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/catalog/audio-to-audio/models
curl 'https://client-api.ai4call.com/api/v1/catalog/audio-to-audio/models?provider=openai&sourceMode=ai4call' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "models": [
      {
        "modelId": "example-model",
        "modelCode": "example-model",
        "modelLabel": "example-model",
        "providerId": "openai",
        "providerLabel": "openai",
        "sourceMode": "ai4call",
        "catalogOrigin": "ai4call_pricing"
      }
    ]
  }
}

Lists the voices available for an LLM voice model

​

Lists the voices available for an LLM voice model

Query Parameters

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/catalog/audio-to-audio/voices
curl 'https://client-api.ai4call.com/api/v1/catalog/audio-to-audio/voices?modelCode=gpt-4o-realtime-preview' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "voices": [
      {
        "voiceId": "example-voice",
        "voiceCode": "example-voice",
        "voiceLabel": "example-voice",
        "modelCode": "example-model",
        "providerId": "openai",
        "providerLabel": "openai"
      }
    ]
  }
}

Lists voice LLM models consistent with the assistant

​

Lists voice LLM models consistent with the assistant

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/catalog/assistants/{assistantId}/audio-to-audio/models
curl https://client-api.ai4call.com/api/v1/catalog/assistants/205/audio-to-audio/models \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "models": [
      {
        "modelId": "example-model",
        "modelCode": "example-model",
        "modelLabel": "example-model",
        "providerId": "openai",
        "providerLabel": "openai",
        "sourceMode": "ai4call",
        "catalogOrigin": "ai4call_pricing"
      }
    ]
  }
}

Lists LLM voice entries available to an assistant

​

Lists LLM voice entries available to an assistant

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Query Parameters

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/catalog/assistants/{assistantId}/audio-to-audio/voices
curl 'https://client-api.ai4call.com/api/v1/catalog/assistants/205/audio-to-audio/voices?modelCode=gpt-4o-realtime-preview' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "voices": [
      {
        "voiceId": "example-voice",
        "voiceCode": "example-voice",
        "voiceLabel": "example-voice",
        "modelCode": "example-model",
        "providerId": "openai",
        "providerLabel": "openai"
      }
    ]
  }
}

Catalog DTMF

​

DTMF assistant configuration and DTMF runtime update

Update the assistant's DTMF runtime configuration

​

Update the assistant's DTMF configuration with PATCH merge semantics.

Editable parameters:

  • enabled
  • playEnabled
  • acceptTimeout
  • minLength
  • maxLength
  • terminationChars

How to recover current data:

  • use GET /api/v1/catalog/assistants/{assistantApiKey}/dtmf

Operational rules:

  • if you want to modify only one field, send only that field
  • enabled: false resets all DTMF settings
  • playEnabled remains independent of the DTMF toggle received
  • on assistants voice_to_voice the backend updates dtmf and pbxTools.dtmf/playDtmf in the JSON voice-llm

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Body·

required
application/json

PATCH merge of the assistant's DTMF configuration.

Operational rules:

  • at least one of enabled, playEnabled, acceptTimeout, minLength, maxLength, terminationChars must be present
  • omitted fields retain the current value
  • by sending one of the DTMF settings with enabled omitted, DTMF is considered enabled
  • enabled: false resets acceptTimeout, minLength, maxLength and terminationChars
  • playEnabled controls DTMF sending during the call
  • Value supplied for acceptTimeout in the AssistantDtmfRuntimeUpdateRequest request.

  • Enable or disable DTMF reception.

  • Value supplied for maxLength in the AssistantDtmfRuntimeUpdateRequest request.

  • Value supplied for minLength in the AssistantDtmfRuntimeUpdateRequest request.

  • Enable or disable DTMF sending during the call.

  • Value supplied for terminationChars in the AssistantDtmfRuntimeUpdateRequest request.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for patch/api/v1/assistants/{assistantId}/runtime/dtmf
curl https://client-api.ai4call.com/api/v1/assistants/205/runtime/dtmf \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "enabled": true,
  "acceptTimeout": 3000,
  "minLength": 1,
  "maxLength": 6,
  "terminationChars": "#"
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "assistantApiKey": "ai4call_sk_example",
    "assistantId": "example-id",
    "service": "dtmf",
    "configuration": {
      "enabled": true,
      "playEnabled": true,
      "acceptTimeout": 1,
      "minLength": 1,
      "maxLength": 1,
      "terminationChars": "example"
    }
  }
}

Retrieve the assistant's DTMF configuration

​

Retrieve the assistant's DTMF configuration

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/catalog/assistants/{assistantId}/dtmf
curl https://client-api.ai4call.com/api/v1/catalog/assistants/205/dtmf \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Assistant DTMF configuration retrieved successfully.",
  "requestId": "4d5581dd-efce-440d-92a6-23444e9cd84f",
  "data": {
    "configuration": {
      "enabled": true,
      "playEnabled": false,
      "acceptTimeout": 3000,
      "minLength": 1,
      "maxLength": 6,
      "terminationChars": "#"
    }
  }
}

Catalog Settings

​

Update the assistant settings

​

Update assistant settings with PATCH merge semantics.

Editable parameters:

  • asrSilenceMs
  • asrInitialDelayMs
  • truncateInitialAudio
  • dynamicTimeoutMs
  • vad
  • vadThreshold
  • vadMinVoiceMs
  • ttsInterruptionInConversation
  • filler.enabled
  • filler.delayMs
  • filler.waitingListIds
  • filler.toolListIds
  • filler.waiting
  • filler.tool
  • reprompt.enabled
  • reprompt.mode
  • reprompt.text
  • reprompt.repeatMaxLength
  • reprompt.maxRetries
  • maxResponseLength
  • callPermissions.checkVerifyNumber
  • callPermissions.allowForeignNumbers
  • callPermissions.allowInternationalNumbers
  • callPermissions.allowMobileNumbers
  • callPermissions.allowFixedNumbers
  • callPermissions.country
  • callPermissions.prefixMobile
  • callPermissions.prefixFixed

How to recover current data:

  • use GET /api/v1/catalog/assistants/{assistantApiKey}/settings

Operational rules:

  • if you want to modify only one field, send only that field
  • filler, reprompt and callPermissions merge only the fields present
  • country, prefixMobile and prefixFixed can be set to null
  • on voice_to_voice assistants, the conversational settings are written to the JSON root voice-llm; call permissions remain on the DB as in the portal

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Body·

required
application/json

PATCH merge of server settings.

How to recover current data:

  • use GET /api/v1/catalog/assistants/{assistantApiKey}/settings

Operational rules:

  • send only the fields to be modified
  • filler, reprompt and callPermissions use partial merge on sent fields
  • callPermissions uses partial merge on sent fields
  • country, prefixMobile and prefixFixed can be sent to null to remove the saved value
  • Value supplied for asrInitialDelayMs in the AssistantSettingsRuntimeUpdateRequest request.

  • Value supplied for asrSilenceMs in the AssistantSettingsRuntimeUpdateRequest request.

  • Value supplied for callPermissions in the AssistantSettingsRuntimeUpdateRequest request.

    Properties: 8
  • Value supplied for dynamicTimeoutMs in the AssistantSettingsRuntimeUpdateRequest request.

  • Value supplied for filler in the AssistantSettingsRuntimeUpdateRequest request.

    Properties: 6
  • Value supplied for maxResponseLength in the AssistantSettingsRuntimeUpdateRequest request.

  • Value supplied for reprompt in the AssistantSettingsRuntimeUpdateRequest request.

    Properties: 5
  • Value supplied for truncateInitialAudio in the AssistantSettingsRuntimeUpdateRequest request.

  • Value supplied for ttsInterruptionInConversation in the AssistantSettingsRuntimeUpdateRequest request.

  • Value supplied for vad in the AssistantSettingsRuntimeUpdateRequest request.

  • Value supplied for vadMinVoiceMs in the AssistantSettingsRuntimeUpdateRequest request.

  • Value supplied for vadThreshold in the AssistantSettingsRuntimeUpdateRequest request.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for patch/api/v1/assistants/{assistantId}/runtime/settings
curl https://client-api.ai4call.com/api/v1/assistants/205/runtime/settings \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "asrSilenceMs": 750,
  "asrInitialDelayMs": 250,
  "dynamicTimeoutMs": 12000,
  "vad": true,
  "vadThreshold": 0.55,
  "vadMinVoiceMs": 180,
  "truncateInitialAudio": false
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "assistantApiKey": "ai4call_sk_example",
    "assistantId": "example-id",
    "service": "settings",
    "configuration": {
      "asrSilenceMs": 1,
      "asrInitialDelayMs": 1,
      "truncateInitialAudio": true,
      "dynamicTimeoutMs": 1,
      "vad": true,
      "vadThreshold": 1,
      "vadMinVoiceMs": 1,
      "ttsInterruptionInConversation": true,
      "filler": {
        "enabled": true,
        "delayMs": 1,
        "waitingListIds": [
          "example"
        ],
        "toolListIds": [
          "example"
        ],
        "waiting": [
          "example"
        ],
        "tool": [
          "example"
        ]
      },
      "reprompt": {
        "enabled": true,
        "mode": "llm",
        "text": [
          "example"
        ],
        "repeatMaxLength": 1,
        "maxRetries": 1
      },
      "maxResponseLength": 1,
      "callPermissions": {
        "checkVerifyNumber": true,
        "allowForeignNumbers": true,
        "allowInternationalNumbers": true,
        "allowMobileNumbers": true,
        "allowFixedNumbers": true,
        "country": "example",
        "prefixMobile": "example",
        "prefixFixed": "example"
      }
    }
  }
}

Update the assistant's advanced settings

​

Update the advanced settings of the assistant with PATCH merge semantics.

Editable parameters:

  • temperature
  • maxTokens
  • topP
  • topK
  • freqPenalty
  • presencePenalty
  • stopSequences

How to recover current data:

  • use GET /api/v1/catalog/assistants/{assistantApiKey}/advanced-settings

Operational rules:

  • if you want to modify only one field, send only that field
  • numeric fields can be sent to null to be removed
  • stopSequences: null or stopSequences: [] resets the list
  • on assistants voice_to_voice these values are written to the JSON root voice-llm

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Body·

required
application/json

PATCH merge of the assistant's advanced settings.

How to recover current data:

  • use GET /api/v1/catalog/assistants/{assistantApiKey}/advanced-settings

Operational rules:

  • send only the fields to be modified
  • numeric fields can be sent to null to be removed
  • stopSequences: null or stopSequences: [] resets the list
  • Value supplied for freqPenalty in the AssistantAdvancedSettingsRuntimeUpdateRequest request.

  • Value supplied for maxTokens in the AssistantAdvancedSettingsRuntimeUpdateRequest request.

  • Value supplied for presencePenalty in the AssistantAdvancedSettingsRuntimeUpdateRequest request.

  • Value supplied for stopSequences in the AssistantAdvancedSettingsRuntimeUpdateRequest request.

  • Value supplied for temperature in the AssistantAdvancedSettingsRuntimeUpdateRequest request.

  • Value supplied for topK in the AssistantAdvancedSettingsRuntimeUpdateRequest request.

  • Value supplied for topP in the AssistantAdvancedSettingsRuntimeUpdateRequest request.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for patch/api/v1/assistants/{assistantId}/runtime/advanced-settings
curl https://client-api.ai4call.com/api/v1/assistants/205/runtime/advanced-settings \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "temperature": 0.6
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "assistantApiKey": "ai4call_sk_example",
    "assistantId": "example-id",
    "service": "advanced-settings",
    "configuration": {
      "temperature": 1,
      "maxTokens": 1,
      "topP": 1,
      "topK": 1,
      "freqPenalty": 1,
      "presencePenalty": 1,
      "stopSequences": [
        "example"
      ]
    }
  }
}

Recover the assistant settings

​

Recover the assistant settings

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/catalog/assistants/{assistantId}/settings
curl https://client-api.ai4call.com/api/v1/catalog/assistants/205/settings \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Assistant settings configuration retrieved successfully.",
  "requestId": "c3d93c2c-8f89-4a2e-b9ad-67d2746c9d16",
  "data": {
    "configuration": {
      "asrSilenceMs": 500,
      "asrInitialDelayMs": 0,
      "truncateInitialAudio": false,
      "dynamicTimeoutMs": 10000,
      "vad": false,
      "vadThreshold": 0.5,
      "vadMinVoiceMs": 180,
      "ttsInterruptionInConversation": true,
      "filler": {
        "enabled": true,
        "delayMs": 1200,
        "waitingListIds": [],
        "toolListIds": [],
        "waiting": [],
        "tool": []
      },
      "reprompt": {
        "enabled": true,
        "mode": "llm",
        "text": [],
        "repeatMaxLength": 180,
        "maxRetries": 1
      },
      "maxResponseLength": 50000,
      "callPermissions": {
        "checkVerifyNumber": false,
        "allowForeignNumbers": false,
        "allowInternationalNumbers": false,
        "allowMobileNumbers": false,
        "allowFixedNumbers": false,
        "country": "it",
        "prefixMobile": "3",
        "prefixFixed": "0"
      }
    }
  }
}

Recover the assistant's advanced settings

​

Recover the assistant's advanced settings

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/catalog/assistants/{assistantId}/advanced-settings
curl https://client-api.ai4call.com/api/v1/catalog/assistants/205/advanced-settings \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Assistant advanced settings configuration retrieved successfully.",
  "requestId": "d1f31a39-a20c-491b-8551-0b2f6a47bbf8",
  "data": {
    "configuration": {
      "temperature": 0.7,
      "maxTokens": 800,
      "topP": 0.9,
      "topK": 40,
      "freqPenalty": 0,
      "presencePenalty": 0,
      "stopSequences": [
        "END"
      ]
    }
  }
}

Catalog Hangup

​

Update the assistant's hangup runtime configuration

​

Update hangup, redirect and transfer configuration with PATCH merge semantics.

Editable parameters:

  • enableHangup
  • enableRedirect
  • enableTransferAgent
  • transferAgentNotificationText
  • availableAgents
  • availableAgents[].assistantApiKey
  • availableAgents[].description

How to recover current data:

  • use GET /api/v1/catalog/assistants/{assistantApiKey}/hangup
  • use GET /api/v1/assistants to retrieve the assistantApiKeys selectable for transfer

Operational rules:

  • if you want to modify only one parameter, send only that parameter
  • enableTransferAgent: false resets notification and connected assistants
  • if enableTransferAgent is active, at least one assistant with a non-empty description is needed
  • on voice_to_voice assistants the backend updates pbxTools.hangup, pbxTools.redirect and pbxTools.transferAgent

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Body·

required
application/json

PATCH merge of assistant hangup/redirect/transfer configuration.

Operational rules:

  • at least one of enableHangup, enableRedirect, enableTransferAgent, transferAgentNotificationText, availableAgents must be present
  • omitted fields retain the current value
  • use GET /api/v1/catalog/assistants/{assistantApiKey}/hangup to read the current state
  • use GET /api/v1/assistants to retrieve the assistantApiKey selectable for transfer
  • if enableTransferAgent and true, you need at least one availableAgents with a non-empty description
  • if you send availableAgents with enableTransferAgent omitted, the transfer is considered active
  • enableTransferAgent: false resets transferAgentNotificationText and availableAgents
  • Value supplied for availableAgents in the AssistantHangupRuntimeUpdateRequest request.

    Properties: 2
  • Value supplied for enableHangup in the AssistantHangupRuntimeUpdateRequest request.

  • Value supplied for enableRedirect in the AssistantHangupRuntimeUpdateRequest request.

  • Value supplied for enableTransferAgent in the AssistantHangupRuntimeUpdateRequest request.

  • Value supplied for transferAgentNotificationText in the AssistantHangupRuntimeUpdateRequest request.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for patch/api/v1/assistants/{assistantId}/runtime/hangup
curl https://client-api.ai4call.com/api/v1/assistants/205/runtime/hangup \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "enableHangup": true,
  "enableRedirect": true
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "assistantApiKey": "ai4call_sk_example",
    "assistantId": "example-id",
    "service": "hangup",
    "configuration": {
      "enableHangup": true,
      "enableRedirect": true,
      "enableTransferAgent": true,
      "transferAgentNotificationText": "example",
      "availableAgents": [
        {
          "assistantApiKey": "ai4call_sk_example",
          "description": "example"
        }
      ]
    }
  }
}

Retrieve the assistant's conversation saving configuration

​

Returns the current conversation saving status:

  • enabled: if sending the summary via email is active
  • emails: configured recipients (comma separated string)
  • smtpInstanceName: name of the connected SMTP plugin instance

Prerequisite: The customer must have at least one active subscription to an SMTP plugin.

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/assistants/{assistantId}/runtime/hangup/save-conversation
curl https://client-api.ai4call.com/api/v1/assistants/205/runtime/hangup/save-conversation \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Assistant save-conversation configuration retrieved successfully.",
  "requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "data": {
    "configuration": {
      "enabled": true,
      "emails": "admin@example.com, report@example.com",
      "smtpInstanceName": "smtp-principale"
    }
  }
}

Update the assistant's conversation saving configuration

​

Update the conversation saving configuration with PATCH merge semantics.

Editable parameters:

  • enabled
  • emails
  • smtpInstanceName

How to recover current data:

  • use GET /api/v1/assistants/{assistantApiKey}/runtime/hangup/save-conversation

Operational rules:

  • at least one of enabled, emails and smtpInstanceName must be present
  • omitted fields retain the current value
  • smtpInstanceName must match the instanceName of a customer's active SMTP subscription
  • to get the list of available SMTP instances, check the customer's plugin subscriptions
  • emails accepts a string with one or more comma-separated emails
  • setting smtpInstanceName: null removes the connection to the SMTP instance

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Body·

required
application/json

PATCH merge of the assistant conversation saving configuration.

Operational rules:

  • at least one of enabled, emails and smtpInstanceName must be present
  • omitted fields retain the current value
  • smtpInstanceName matches the instanceName of the customer's active SMTP subscription
  • if enabled: true, an active SMTP plugin must be configured
  • emails accepts a string with one or more comma-separated emails
  • One or more recipient emails separated by commas (e.g. email1@example.com, email2@example.com)

  • Enable or disable sending of the conversation summary via email

  • Legacy alias of smtpInstanceName.

  • Name of the SMTP plugin instance to use for sending

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for patch/api/v1/assistants/{assistantId}/runtime/hangup/save-conversation
curl https://client-api.ai4call.com/api/v1/assistants/205/runtime/hangup/save-conversation \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "enabled": true,
  "emails": "admin@example.com, report@example.com",
  "smtpInstanceName": "smtp-principale"
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "configuration": {
      "enabled": true,
      "emails": "developer@example.com",
      "smtpInstanceName": "Example"
    }
  }
}

Retrieve the assistant's end-of-conversation webhook configuration

​

Returns the current configuration of the webhook called at the end of the call:

  • enabled: whether sending is active
  • url: destination endpoint
  • authName: name of the applied authentication, null for an unauthenticated call
  • payloadFields: fields always present in the body sent

This channel is an alternative to email delivery (runtime/hangup/save-conversation) and the two can be active at the same time.

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/assistants/{assistantId}/runtime/hangup/conversation-webhook
curl https://client-api.ai4call.com/api/v1/assistants/205/runtime/hangup/conversation-webhook \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Assistant conversation webhook configuration retrieved successfully.",
  "requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "data": {
    "configuration": {
      "enabled": true,
      "url": "https://example.com/hooks/ai4call",
      "authName": "crm-bearer",
      "payloadFields": [
        "caller",
        "called",
        "callid",
        "conversation"
      ]
    }
  }
}

Update the assistant's end-of-conversation webhook configuration

​

Update the webhook configuration with PATCH merge semantics.

Editable parameters:

  • enabled
  • url
  • authName

How to recover current data:

  • use GET /api/v1/assistants/{assistantApiKey}/runtime/hangup/conversation-webhook

Operational rules:

  • at least one of enabled, url and authName must be present
  • omitted fields retain the current value
  • enabling without a valid http:// or https:// url returns 400
  • authName must match an authentication already saved by the customer; the credentials are resolved server side and never travel in this payload
  • setting authName: null sends the webhook without authentication

Body received by the endpoint: caller, called, callid and conversation.

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Body·

required
application/json

PATCH merge of the assistant end-of-conversation webhook configuration.

Operational rules:

  • at least one of enabled, url and authName must be present
  • omitted fields retain the current value
  • if enabled: true, url must be a valid http:// or https:// address
  • authName matches the name of an authentication already saved by the customer; credentials are resolved server side and never travel in this payload
  • setting authName: null sends the webhook without authentication
  • Name of the saved authentication to apply to the request

  • Enable or disable sending the conversation to the webhook

  • Endpoint that receives the POST at the end of the call

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for patch/api/v1/assistants/{assistantId}/runtime/hangup/conversation-webhook
curl https://client-api.ai4call.com/api/v1/assistants/205/runtime/hangup/conversation-webhook \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "enabled": true,
  "url": "https://example.com/hooks/ai4call",
  "authName": "crm-bearer"
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "configuration": {
      "enabled": true,
      "url": "https://example.com",
      "authName": "Example",
      "payloadFields": [
        "caller",
        "called",
        "callid",
        "conversation"
      ]
    }
  }
}

Retrieve the hangup tool schema configuration

​

Returns the current configuration of the schema sent to the hangup webhook:

  • hangupUrl: URL of the webhook called at the end of the call
  • schema: array of properties that define the JSON body sent to the hangup URL

Each property can be of type string, number, boolean, enum or object. Properties of type object support nested fields via children. On assistants voice_to_voice, the pattern is read from pbxTools.hangupEndpoint.input_schema.

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/assistants/{assistantId}/runtime/hangup/schema
curl https://client-api.ai4call.com/api/v1/assistants/205/runtime/hangup/schema \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Assistant hangup schema configuration retrieved successfully.",
  "requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "data": {
    "configuration": {
      "hangupUrl": "https://webhook.example.com/hangup",
      "schema": [
        {
          "name": "motivo",
          "type": "string",
          "description": "Reason for hangup",
          "required": true
        },
        {
          "name": "esito",
          "type": "enum",
          "description": "Result of the call",
          "required": true,
          "enumValues": [
            "positivo",
            "negativo",
            "richiamata"
          ]
        },
        {
          "name": "dati_cliente",
          "type": "object",
          "description": "Data collected about the customer",
          "children": [
            {
              "name": "nome",
              "type": "string",
              "description": "Customer name"
            },
            {
              "name": "email",
              "type": "string",
              "description": "Customer email"
            }
          ]
        }
      ]
    }
  }
}

Update the hangup tool schema configuration

​

Update hangup schema configuration with PATCH merge semantics.

Editable parameters:

  • hangupUrl
  • schema
  • schema[].name
  • schema[].type
  • schema[].description
  • schema[].required
  • schema[].enumValues
  • schema[].children

How to recover current data:

  • use GET /api/v1/assistants/{assistantApiKey}/runtime/hangup/schema

Operational rules

  • At least one between hangupUrl and schema must be present in the bodysuit
  • Omitted fields retain the current value
  • Sending schema completely replaces the current schema (it is not a merge)
  • Sending hangupUrl: null removes the URL webhook, disables the hangup tool and also automatically clears the schema
  • Sending schema: [] clears the scheme keeping the current URL

  • On assistants voice_to_voice, the backend updates pbxTools.hangupEndpoint.endpoint and pbxTools.hangupEndpoint.input_schema

How to build the schema body

The schema is an array of properties that define the fields of the sent JSON body to hangupUrl at the end of the call. Each property has the following structure:

Field Type Required Description
name string yes Field name in JSON body
type string yes Field Type: string, number, boolean, enum, object
description string no Field Description (helps the LLM model understand what to enter)
required boolean no If true, the field is required in the body hangup
enumValues string[] only for enum List of allowed values ​​(only if type: enum)
children Property[] only for object Nested fields (only if type: object)

Supported types and how to use them

string — free text field:

{ "name": "motivo", "type": "string", "description": "Motivo del termine della chiamata", "required": true }

number — numeric field:

{ "name": "durata_secondi", "type": "number", "description": "Durata della chiamata in secondi" }

boolean — boolean field:

{ "name": "cliente_soddisfatto", "type": "boolean", "description": "Il cliente si è dichiarato soddisfatto" }

enum — multiple choice field, requires enumValues:

{ "name": "esito", "type": "enum", "description": "Esito della chiamata", "required": true, "enumValues": ["positivo", "negativo", "richiamata"] }

object — nested field group, requires children:

{
  "name": "dati_cliente",
  "type": "object",
  "description": "Dati raccolti durante la chiamata",
  "children": [
    { "name": "nome", "type": "string", "description": "Nome del cliente" },
    { "name": "email", "type": "string", "description": "Email del cliente" }
  ]
}

Example of resulting JSON body

With the above scheme, the webhook will receive a body similar to:

{
  "motivo": "Cliente ha chiesto informazioni sul prodotto X",
  "esito": "positivo",
  "cliente_soddisfatto": true,
  "durata_secondi": 182,
  "dati_cliente": {
    "nome": "Mario Rossi",
    "email": "mario@example.com"
  }
}

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Body·

required
application/json
  • Hangup webhook URL (null to remove)

  • Defining body fields (overrides the current schema)

    Properties: 6

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for patch/api/v1/assistants/{assistantId}/runtime/hangup/schema
curl https://client-api.ai4call.com/api/v1/assistants/205/runtime/hangup/schema \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "hangupUrl": "https://webhook.example.com/hangup",
  "schema": [
    {
      "name": "motivo",
      "type": "string",
      "description": "Reason for hangup",
      "required": true
    },
    {
      "name": "esito",
      "type": "enum",
      "description": "Result of the call",
      "required": true,
      "enumValues": [
        "positivo",
        "negativo",
        "richiamata"
      ]
    },
    {
      "name": "dati_cliente",
      "type": "object",
      "description": "Data collected about the customer",
      "children": [
        {
          "name": "nome",
          "type": "string",
          "description": "Customer name"
        },
        {
          "name": "email",
          "type": "string",
          "description": "Customer email"
        }
      ]
    }
  ]
}'
{
  "success": true,
  "data": {
    "configuration": {
      "hangupUrl": "https://example.com",
      "schema": [
        {
          "name": "Example",
          "type": "string"
        }
      ]
    }
  }
}

Retrieve the assistant's hangup configuration

​

Retrieve the assistant's hangup configuration

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/catalog/assistants/{assistantId}/hangup
curl https://client-api.ai4call.com/api/v1/catalog/assistants/205/hangup \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Assistant hangup configuration retrieved successfully.",
  "requestId": "55e4ea0f-21d2-4d28-b6e1-8f47b18b7d44",
  "data": {
    "configuration": {
      "enableHangup": true,
      "enableRedirect": false,
      "enableTransferAgent": true,
      "transferAgentNotificationText": "Avvisa il cliente prima del passaggio.",
      "availableAgents": [
        {
          "assistantApiKey": "ai4call_sk_transfer_1",
          "assistantName": "Assistente Amministrativo",
          "description": "Transfer when customer requests administrative support."
        }
      ]
    }
  }
}

Catalog Pre-Call

​

Retrieve the calling number verification configuration

​

Returns the current configuration of the webhook used to verify the number caller before the call is connected to the assistant.

If no configuration has been created yet, data.configuration will be null.

How number verification works

When a call arrives, the system makes an HTTP request to the configured webhook, passing the calling number into the indicated field (numberParamName), in the position indicated (numberLocation). The webhook should respond with:

{ "enabled": true }
  • If enabled is true (or absent): the call continues normally
  • If enabled is false: the call is blocked

The webhook can also return an callerInfo object with additional data that will be made available to the assistant during the call.

Safety note

Sensitive fields (authToken, authPassword) are never returned in clear text. In their place there are the flags hasAuthToken and hasAuthPassword.

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/assistants/{assistantId}/runtime/precall/number-validation
curl https://client-api.ai4call.com/api/v1/assistants/205/runtime/precall/number-validation \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
Configuration present
{
  "success": true,
  "message": "Assistant precall validation configuration retrieved successfully.",
  "requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "data": {
    "configuration": {
      "name": "Verifica CRM",
      "method": "POST",
      "url": "https://api.example.com/validate-caller",
      "numberLocation": "body",
      "numberParamName": "caller_id",
      "headersJson": {
        "X-Api-Version": "2"
      },
      "authType": "bearer",
      "hasAuthToken": true,
      "hasAuthPassword": false,
      "authUsername": null,
      "timeoutMs": 5000,
      "isActive": true
    }
  }
}

Create or update the calling number verification configuration

​

Create the configuration if it does not exist, otherwise update the fields provided with PATCH merge semantics (omitted fields retain the current value).

Editable parameters:

  • name
  • method
  • url
  • numberLocation
  • numberParamName
  • headersJson
  • authType
  • authToken
  • authUsername
  • authPassword
  • timeoutMs
  • isActive

How to recover current data:

  • use GET /api/v1/assistants/{assistantApiKey}/runtime/precall/number-validation

Operational rules

  • At least one field must be present in the body
  • Omitted fields retain the current value (or the default if it is the first creation)
  • Send isActive: false completely deletes the configuration — data.configuration will be null
  • The configuration is always active (isActive: true) when it is created or updated
  • Sending authToken: null removes the configured token
  • Sending authPassword: null removes the configured password
  • Sending headersJson: null removes all custom headers
  • authToken and authPassword are never returned — use hasAuthToken/hasAuthPassword

How to configure numberLocation

Value Where the number is sent Example
query URL query string GET /validate?caller_id=0391234567
body Body JSON of the request POST /validate with leotard { "caller_id": "0391234567" }
params URL segment GET /validate/0391234567 (the number replaces :numberParamName in the URL)

Authentication supported

authType Required fields Header generated
none — none
bearer authToken Authorization: Bearer <token>
api_key authToken X-Api-Key: <token>
basic authUsername + authPassword Authorization: Basic <base64>

Expected response from webhook

The webhook must respond with HTTP 200 and a JSON body containing at least:

{ "enabled": true }

May include additional data:

{
  "enabled": true,
  "callerInfo": {
    "nome": "Mario Rossi",
    "cliente_id": "C-001",
    "piano": "premium"
  }
}

If enabled is false, the call is blocked before reaching the assistant.

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Body·

required
application/json
  • Basic auth password (null to remove it)

  • Bearer token or API key (null to remove it)

  • values
    nonebearerapi_keybasic
  • Value supplied for authUsername in the AssistantPrecallValidationRuntimeUpdateRequest request.

  • Value supplied for headersJson in the AssistantPrecallValidationRuntimeUpdateRequest request.

    Properties: 1
  • Value supplied for isActive in the AssistantPrecallValidationRuntimeUpdateRequest request.

  • values
    GETPOSTPUTPATCHDELETE
  • Value supplied for name in the AssistantPrecallValidationRuntimeUpdateRequest request.

  • Where to insert the calling number in the HTTP request:

    • query — added as a query string (e.g. ?number=0391234567)
    • body — inserted in the JSON body (e.g. { "number": "0391234567" })
    • params — replaces a segment of the URL (e.g. /validate/0391234567)
    values
    bodyqueryparams
  • Value supplied for numberParamName in the AssistantPrecallValidationRuntimeUpdateRequest request.

  • Value supplied for timeoutMs in the AssistantPrecallValidationRuntimeUpdateRequest request.

  • Value supplied for url in the AssistantPrecallValidationRuntimeUpdateRequest request.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for patch/api/v1/assistants/{assistantId}/runtime/precall/number-validation
curl https://client-api.ai4call.com/api/v1/assistants/205/runtime/precall/number-validation \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "name": "Verifica CRM",
  "method": "POST",
  "url": "https://api.example.com/validate-caller",
  "numberLocation": "body",
  "numberParamName": "caller_id",
  "headersJson": {
    "X-Api-Version": "2",
    "Accept-Language": "it"
  },
  "authType": "bearer",
  "authToken": "eyJhbGciOiJIUzI1NiJ9...",
  "timeoutMs": 5000,
  "isActive": true
}'
{
  "success": true,
  "data": {
    "configuration": {
      "name": "Example",
      "method": "GET",
      "url": "https://example.com",
      "numberLocation": "body",
      "numberParamName": "Example",
      "headersJson": {},
      "authType": "none",
      "hasAuthToken": true,
      "hasAuthPassword": true,
      "authUsername": "Example",
      "timeoutMs": 500,
      "isActive": true
    }
  }
}

Retrieve the assistant's pre-call configuration

​

Returns the current configuration of the pre-call phase: general settings (configuration) and associated tools (tools).

How the pre-call phase works

Before the call is connected to the assistant, the system performs sequentially the configured tools (in the order defined by order). The tools can be:

  • custom tools (defined in the server JSON, subscriptionName: null)
  • tool MCP plugin or custom MCP (with subscriptionName enhanced)

The tools can retrieve caller information, perform validation or enrich the context, and end the call early if earlyTerminationEnabled is true.

If waitingAudioText is configured, it is played to the caller during execution. voiceConfig controls the voice used to generate wait/terminate audio, while modelConfig controls the model used to interpret the results of the tools.

How to read tools

The fields toolName and subscriptionName returned match the fields toolName and subscriptionName to send in the PATCH. The pre-call tools can only be chosen from those already associated with the assistant:

  • GET /api/v1/catalog/assistants/{assistantApiKey}/tools

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/assistants/{assistantId}/runtime/precall/mcp-config
curl https://client-api.ai4call.com/api/v1/assistants/205/runtime/precall/mcp-config \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
Custom tools and associated MCP plugins
{
  "success": true,
  "message": "Assistant precall MCP configuration retrieved successfully.",
  "requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "data": {
    "configuration": {
      "enabled": true,
      "globalPrompt": "Usa le informazioni recuperate per personalizzare la risposta.",
      "waitingAudioText": "Sto verificando la tua identità, un momento...",
      "earlyTerminationEnabled": true,
      "terminationMessage": "Non sei autorizzato a procedere. Arrivederci.",
      "waitingAudioNonInterruptible": true,
      "modelConfig": {
        "mode": "assistant"
      },
      "voiceConfig": {
        "mode": "assistant"
      },
      "outputVariables": [
        {
          "name": "customer_tier",
          "type": "string",
          "required": true
        }
      ],
      "outputSchema": null
    },
    "tools": [
      {
        "toolName": "verifica_cliente",
        "server": "custom",
        "subscriptionName": null,
        "order": 1
      },
      {
        "toolName": "get_customer_info",
        "server": "crm_plugin",
        "subscriptionName": "CRM Principale",
        "order": 2
      }
    ]
  }
}

Update the assistant's pre-call configuration

​

Update pre-call configuration with PATCH merge semantics. At least one field must be present in the bodysuit.

Editable parameters:

  • tools
  • tools[].toolName
  • tools[].subscriptionName
  • tools[].order
  • globalPrompt
  • waitingAudioText
  • earlyTerminationEnabled
  • terminationMessage
  • waitingAudioNonInterruptible
  • modelConfig
  • voiceConfig

How to retrieve the current configuration:

  • GET /api/v1/assistants/{assistantApiKey}/runtime/precall/mcp-config

Tool management

The tools field completely replaces the current pre-call tools:

Body posted Effect
tools omitted keeps current tools unchanged
tools: [] removes all pre-call tools and resets all pre-call configuration
tools: [{...}] replaces with the sent list

For sorting:

  • if each item includes order, order is used
  • if order is omitted, array order is used

How to build the tools list

Use the records of GET /api/v1/catalog/assistants/{assistantApiKey}/tools to get toolName and instanceName. The pre-call only accepts tools already associated with the assistant:

Tool type toolName subscriptionName
custom_tool (custom JSON tool) toolName null
plugin_tool (MCP plugin) toolName instanceName
custom_mcp_tool (MCP custom) toolName instanceName

The custom tools (subscriptionName: null) are those defined in the assistant's JSON and they do not require subscriptions.


General configuration

Field Effect
globalPrompt: null removes the global prompt
waitingAudioText: null removes hold audio
earlyTerminationEnabled: true enable early termination
terminationMessage: null removes termination message
waitingAudioNonInterruptible: false makes hold audio interruptible
modelConfig set default/assistant/managed/custom for pre-call model
voiceConfig set default/assistant/custom for pre-call TTS

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Body·

required
application/json

Update pre-call configuration with PATCH merge semantics. At least one field must be present.

Tool management

The tools field completely replaces the pre-call tool list.

  • tools: [] removes all pre-call tools and resets globalPrompt, waitingAudioText, earlyTerminationEnabled, terminationMessage, waitingAudioNonInterruptible, modelConfig and voiceConfig
  • tools omitted: keep current tools unchanged
  • If order is present, the execution order follows order
  • If order is omitted, the execution order follows the order of the sent array

To build the list use the records of GET /api/v1/catalog/assistants/{assistantApiKey}/tools. The pre-call only accepts tools already associated with the assistant.

  • Enable/disable early termination.

  • Enable or disable the whole pre-call phase without losing its configuration. Omitted, it retains the current value.

  • Global pre-call prompt. null to remove it.

  • Model configuration used by the MCP phase. The API keys are not returned in clear text: hasApiKey is exposed in the responses.

    Properties: 5
  • JSON schema of the expected pre-call output, as an alternative to outputVariables.

    Properties: 1
  • Variables to extract from the pre-call result. Replaces the current list entirely.

    Properties: 4
  • Early termination audio message. null to remove it.

  • Complete list of pre-call tools to set (replaces the current ones).

  • Voice/TTS configuration used to generate pre-call hold and termination audio. The API keys are not returned in clear text: hasApiKey is exposed in the responses.

    Properties: 8
  • true plays all on-hold audio, false allows the customer to speak over the audio.

  • Audio text on hold. null to remove it.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for patch/api/v1/assistants/{assistantId}/runtime/precall/mcp-config
curl https://client-api.ai4call.com/api/v1/assistants/205/runtime/precall/mcp-config \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "tools": [
    {
      "toolName": "verifica_cliente",
      "subscriptionName": null,
      "order": 0
    },
    {
      "toolName": "get_customer_info",
      "subscriptionName": "CRM Principale",
      "order": 1
    }
  ],
  "globalPrompt": "Usa le informazioni recuperate per personalizzare la risposta.",
  "waitingAudioText": "Sto verificando la tua identità, un momento...",
  "earlyTerminationEnabled": true,
  "terminationMessage": "Non sei autorizzato a procedere. Arrivederci.",
  "waitingAudioNonInterruptible": true,
  "modelConfig": {
    "mode": "assistant"
  },
  "voiceConfig": {
    "mode": "assistant"
  }
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "configuration": {
      "enabled": true,
      "globalPrompt": "example",
      "waitingAudioText": "example",
      "earlyTerminationEnabled": true,
      "terminationMessage": "Operation completed successfully.",
      "waitingAudioNonInterruptible": true,
      "modelConfig": {
        "mode": "default"
      },
      "voiceConfig": {
        "mode": "default"
      },
      "outputVariables": [
        {
          "name": "customer_tier",
          "type": "string"
        }
      ],
      "outputSchema": {}
    },
    "tools": [
      {
        "toolName": "Example",
        "server": "example",
        "subscriptionName": "Example",
        "order": 1
      }
    ]
  }
}

Retrieve the assistant's pre-call configuration

​

Retrieve the assistant's pre-call configuration

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/catalog/assistants/{assistantId}/pre-call
curl https://client-api.ai4call.com/api/v1/catalog/assistants/205/pre-call \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Assistant pre-call configuration retrieved successfully.",
  "requestId": "03a61d48-929d-4e18-80d6-2af9da9b1493",
  "data": {
    "configuration": {
      "tools": [
        {
          "server": "google_sheets",
          "method": "sheets_search_rows",
          "executeBeforeCall": true,
          "required": [
            "caller_id",
            "company_name"
          ],
          "metadata": {
            "spreadsheetId": "1AbCdEf"
          }
        }
      ],
      "globalPrompt": "Recupera informazioni utili prima del passaggio all'assistente.",
      "waitingAudioText": "Attendi in linea mentre recupero le informazioni.",
      "earlyTerminationEnabled": false,
      "terminationMessage": "",
      "terminationAudioFile": null
    }
  }
}

Catalog Post-Call

​

Retrieve the assistant's MCP post-call configuration

​

Returns the current configuration of the MCP post-call phase: general settings (configuration) and associated tools (tools).

The fields toolName and subscriptionName returned match the fields toolName and subscriptionName to send in the PATCH. The post-call tools can only be chosen from those already associated with the assistant:

  • GET /api/v1/catalog/assistants/{assistantApiKey}/tools

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/assistants/{assistantId}/runtime/postcall/mcp-config
curl https://client-api.ai4call.com/api/v1/assistants/205/runtime/postcall/mcp-config \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
Associated post-call tools
{
  "success": true,
  "message": "Assistant postcall MCP configuration retrieved successfully.",
  "requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "data": {
    "configuration": {
      "enabled": true,
      "globalPrompt": "Usa i risultati dei tool per aggiornare il CRM.",
      "modelConfig": {
        "mode": "assistant"
      }
    },
    "tools": [
      {
        "toolName": "create_ticket",
        "server": "crm_plugin",
        "subscriptionName": "CRM Principale",
        "order": 0
      }
    ]
  }
}

Update the assistant's MCP post-call configuration

​

Update post-call configuration with PATCH merge semantics. At least one field must be present in the bodysuit.

Editable parameters:

  • tools
  • tools[].toolName
  • tools[].subscriptionName
  • tools[].order
  • globalPrompt
  • modelConfig

How to retrieve the current configuration:

  • GET /api/v1/assistants/{assistantApiKey}/runtime/postcall/mcp-config

The tools field completely replaces current post-call tools:

Body posted Effect
tools omitted keeps current tools unchanged
tools: [] removes all post-call tools and resets globalPrompt and modelConfig
tools: [{...}] replaces with the sent list

Use records from GET /api/v1/catalog/assistants/{assistantApiKey}/tools to get toolName and instanceName.

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Body·

required
application/json

Update post-call configuration with PATCH merge semantics. At least one field must be present.

The tools field completely replaces the list of post-call tools.

  • tools: [] removes all post-call tools and resets globalPrompt and modelConfig
  • tools omitted: keep current tools unchanged
  • Enable or disable the whole post-call phase without losing its configuration. When false the end-of-call webhook is not sent. Omitted, it retains the current value.

  • Global post-call prompt. null to remove it.

  • Model configuration used by the MCP phase. The API keys are not returned in clear text: hasApiKey is exposed in the responses.

    Properties: 5
  • Complete list of post-call tools to set up.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for patch/api/v1/assistants/{assistantId}/runtime/postcall/mcp-config
curl https://client-api.ai4call.com/api/v1/assistants/205/runtime/postcall/mcp-config \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "tools": [
    {
      "toolName": "create_ticket",
      "subscriptionName": "CRM Principale",
      "order": 0
    }
  ],
  "globalPrompt": "Usa i risultati dei tool per aggiornare il CRM.",
  "modelConfig": {
    "mode": "assistant"
  }
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "configuration": {
      "enabled": true,
      "globalPrompt": "example",
      "modelConfig": {
        "mode": "default"
      }
    },
    "tools": [
      {
        "toolName": "Example",
        "server": "example",
        "subscriptionName": "Example",
        "order": 1
      }
    ]
  }
}

Catalog Runtime Bindings

​

Runtime binding of the assistant to real pricing and providers

Retrieves the assistant runtime bindings to TTS, ASR, and LLM

​

Retrieves the assistant runtime bindings to TTS, ASR, and LLM

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/catalog/assistants/{assistantId}/runtime-bindings
curl https://client-api.ai4call.com/api/v1/catalog/assistants/205/runtime-bindings \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Assistant runtime bindings retrieved successfully.",
  "requestId": "6ce3ab94-4041-4429-86ef-5522dc80c4c4",
  "data": {
    "assistantApiKey": "ast_demo_sales_001",
    "assistantId": "188",
    "runtimeBindings": {
      "tts": {
        "configured": false,
        "sourceMode": "customer",
        "pricingId": null,
        "priceListId": null,
        "providerId": null,
        "providerLabel": null,
        "engineCode": null,
        "modelCode": null,
        "modelLabel": null
      },
      "asr": {
        "configured": true,
        "sourceMode": "ai4call",
        "pricingId": 9,
        "priceListId": 3,
        "providerId": "azure",
        "providerLabel": "AZURE",
        "engineCode": "asr_azure_multi",
        "modelCode": "asr_azure_multi",
        "modelLabel": "asr_azure_multi"
      },
      "llm": {
        "configured": true,
        "sourceMode": "ai4call",
        "pricingId": 16,
        "priceListId": 2,
        "providerId": "openai",
        "providerLabel": "openai",
        "engineCode": "gpt-4.1-mini",
        "modelCode": "gpt-4.1-mini",
        "modelLabel": "GPT-4.1 mini"
      }
    }
  }
}

Knowledge

​

List the customer's knowledge items

​

Returns the customer's own knowledge items plus the ones provided by AI4CALL, most recently updated first. The shared ones carry isShared: true: they can be associated with your assistants but not modified.

Each item comes back complete with its triggers, ordered by sortOrder.

Query Parameters

  • Maximum number of items returned in one cursor-paginated page. Omit both limit and cursor to preserve the legacy unpaginated response.

  • Opaque cursor returned in meta.nextCursor by the previous page.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/knowledge
curl https://client-api.ai4call.com/api/v1/knowledge \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Knowledge items retrieved successfully.",
  "requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "data": {
    "knowledges": [
      {
        "id": 7,
        "title": "Orari e sedi",
        "defaultResponse": "Siamo aperti dal lunedì al venerdì, dalle 9 alle 18.",
        "rules": null,
        "defaultPostAction": "ask_if_needs_more",
        "isShared": false,
        "triggers": [
          {
            "id": 21,
            "query": "Quali sono gli orari di apertura?",
            "aiInstructions": null,
            "specificResponse": null,
            "postAction": null,
            "sortOrder": 1
          }
        ],
        "createdAt": "2026-08-01T09:15:00.000Z",
        "updatedAt": "2026-08-20T11:02:00.000Z"
      }
    ]
  },
  "meta": {
    "count": 1
  }
}

Create a knowledge item

​

Creates a knowledge item owned by the customer.

A knowledge item is a set of recognised requests, the triggers, with what the assistant should answer. It is folded into the prompt of every assistant it is associated with, so creating it is not enough: associate it with PUT /api/v1/catalog/assistants/{assistantApiKey}/knowledge.

Operational rules:

  • triggers may be omitted or empty: the item then always answers with defaultResponse
  • a trigger without specificResponse falls back to the item's defaultResponse
  • a trigger without postAction falls back to the item's defaultPostAction
  • aiInstructions steers how the model uses the answer, without rewriting the answer itself
  • sortOrder is optional: when omitted, the order of the array is used

Body·

required
application/json

Creation of a knowledge item.

triggers may be omitted or empty: the item then always answers with defaultResponse.

  • Default answer used when a trigger has no specific response.

  • Human-readable title of the new knowledge item.

  • Defaults to ask_if_needs_more when omitted

  • Optional constraints applied to the whole knowledge item.

  • Initial trigger list for the knowledge item.

    Properties: 5

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for post/api/v1/knowledge
curl https://client-api.ai4call.com/api/v1/knowledge \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "title": "Orari e sedi",
  "defaultResponse": "Siamo aperti dal lunedì al venerdì, dalle 9 alle 18.",
  "defaultPostAction": "ask_if_needs_more",
  "triggers": [
    {
      "query": "Quali sono gli orari di apertura?"
    },
    {
      "query": "Siete aperti il sabato?",
      "specificResponse": "Il sabato siamo chiusi."
    }
  ]
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "knowledge": {
      "id": 1,
      "title": "Orari e sedi",
      "defaultResponse": "example",
      "rules": "example",
      "defaultPostAction": "ask_if_needs_more",
      "isShared": true,
      "triggers": [
        {
          "id": 1,
          "query": "Quali sono gli orari di apertura?",
          "aiInstructions": "example",
          "specificResponse": "example",
          "postAction": "example",
          "sortOrder": 1
        }
      ],
      "createdAt": "2026-09-28T10:30:00.000Z",
      "updatedAt": "2026-09-28T10:30:00.000Z"
    }
  }
}

Retrieve one knowledge item

​

Returns a single item complete with its triggers. Works for the customer's own items and for the shared ones.

Path Parameters

  • Id of the knowledge item

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/knowledge/{knowledgeId}
curl https://client-api.ai4call.com/api/v1/knowledge/7 \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "knowledge": {
      "id": 1,
      "title": "Orari e sedi",
      "defaultResponse": "example",
      "rules": "example",
      "defaultPostAction": "ask_if_needs_more",
      "isShared": true,
      "triggers": [
        {
          "id": 1,
          "query": "Quali sono gli orari di apertura?",
          "aiInstructions": "example",
          "specificResponse": "example",
          "postAction": "example",
          "sortOrder": 1
        }
      ],
      "createdAt": "2026-09-28T10:30:00.000Z",
      "updatedAt": "2026-09-28T10:30:00.000Z"
    }
  }
}

Update a knowledge item

​

Updates an item with PATCH merge semantics.

Operational rules:

  • at least one field must be present, omitted fields keep their current value
  • triggers, when present, replaces the whole list: send it complete, or omit it to leave the triggers untouched. Sending [] removes them all
  • the items provided by AI4CALL (isShared: true) are not editable and answer 404

Changes take effect on every assistant the item is associated with, without reassociating it.

Path Parameters

  • Id of the knowledge item

Body·

required
application/json

PATCH merge of a knowledge item.

Operational rules:

  • at least one field must be present
  • omitted fields keep their current value
  • triggers, when present, replaces the whole list: send it complete, or omit it to leave the triggers untouched. Sending [] removes them all
  • items with isShared: true cannot be modified
  • New default post-action for triggers without their own value.

  • New default response for the knowledge item.

  • New optional constraints for the knowledge item.

  • New title for the knowledge item.

  • Complete replacement trigger list when this field is supplied.

    Properties: 5

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for patch/api/v1/knowledge/{knowledgeId}
curl https://client-api.ai4call.com/api/v1/knowledge/7 \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "defaultResponse": "Siamo aperti dal lunedì al venerdì, dalle 9 alle 19."
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "knowledge": {
      "id": 1,
      "title": "Orari e sedi",
      "defaultResponse": "example",
      "rules": "example",
      "defaultPostAction": "ask_if_needs_more",
      "isShared": true,
      "triggers": [
        {
          "id": 1,
          "query": "Quali sono gli orari di apertura?",
          "aiInstructions": "example",
          "specificResponse": "example",
          "postAction": "example",
          "sortOrder": 1
        }
      ],
      "createdAt": "2026-09-28T10:30:00.000Z",
      "updatedAt": "2026-09-28T10:30:00.000Z"
    }
  }
}

Delete a knowledge item

​

Permanently deletes the item, its triggers and every association with the customer's assistants. The affected assistants simply stop carrying it in their prompt.

The items provided by AI4CALL are not deletable and answer 404.

Path Parameters

  • Id of the knowledge item

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for delete/api/v1/knowledge/{knowledgeId}
curl https://client-api.ai4call.com/api/v1/knowledge/7 \
  --request DELETE \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "deleted": true
  }
}

List the knowledge items associated with an assistant

​

Returns the items folded into this assistant's prompt, in the order they are applied, together with their full content so a second call is not needed.

An association pointing to a deleted item is dropped from the response.

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/assistants/{assistantId}/knowledge
curl https://client-api.ai4call.com/api/v1/assistants/205/knowledge \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Assistant knowledge associations retrieved successfully.",
  "requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "data": {
    "assistantApiKey": "ai4call_sk_abc123",
    "associations": [
      {
        "knowledgeId": 7,
        "sortOrder": 1
      }
    ],
    "knowledges": [
      {
        "id": 7,
        "title": "Orari e sedi",
        "defaultResponse": "Siamo aperti dal lunedì al venerdì, dalle 9 alle 18.",
        "rules": null,
        "defaultPostAction": "ask_if_needs_more",
        "isShared": false,
        "triggers": [],
        "createdAt": "2026-08-01T09:15:00.000Z",
        "updatedAt": "2026-08-20T11:02:00.000Z"
      }
    ]
  },
  "meta": {
    "count": 1
  }
}

Set the knowledge items associated with an assistant

​

Replaces the assistant's associations entirely: what you send becomes the complete list.

Two accepted shapes:

  • associations, when the order matters and you want to state it
  • knowledgeIds, when the order of the array is enough

They are mutually exclusive. An empty list detaches every item.

Both your own items and the shared ones can be associated; an id that is neither yours nor shared makes the whole call fail with 400, without partial changes.

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Body·

required
application/json

Replaces the assistant's knowledge associations entirely.

Send associations when the order matters, knowledgeIds when the order of the array is enough. The two are mutually exclusive; an empty list detaches everything.

Both your own items and the shared ones can be associated.

  • Value supplied for associations in the AssistantKnowledgeAssociationsRequest request.

    Properties: 2
  • Value supplied for knowledgeIds in the AssistantKnowledgeAssociationsRequest request.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for put/api/v1/assistants/{assistantId}/knowledge
curl https://client-api.ai4call.com/api/v1/assistants/205/knowledge \
  --request PUT \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "knowledgeIds": [
    7,
    12
  ]
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "assistantApiKey": "ai4call_sk_example",
    "associations": [
      {
        "knowledgeId": 1,
        "sortOrder": 1
      }
    ],
    "knowledges": [
      {
        "id": 1,
        "title": "Orari e sedi",
        "defaultResponse": "example",
        "rules": "example",
        "defaultPostAction": "ask_if_needs_more",
        "isShared": true,
        "triggers": [
          {
            "id": 1,
            "query": "Quali sono gli orari di apertura?",
            "aiInstructions": "example",
            "specificResponse": "example",
            "postAction": "example",
            "sortOrder": 1
          }
        ],
        "createdAt": "2026-09-28T10:30:00.000Z",
        "updatedAt": "2026-09-28T10:30:00.000Z"
      }
    ]
  }
}

Filler Phrase Lists

​

List the client's filler lists

​

List the client's filler lists

Query Parameters

  • Maximum number of items returned in one cursor-paginated page. Omit both limit and cursor to preserve the legacy unpaginated response.

  • Opaque cursor returned in meta.nextCursor by the previous page.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/filler-phrase-lists
curl https://client-api.ai4call.com/api/v1/filler-phrase-lists \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "lists": [
      {
        "id": "example-id",
        "name": "Example",
        "phrases": [
          "example"
        ],
        "isDefault": true,
        "createdAt": "2026-09-28T10:30:00.000Z",
        "updatedAt": "2026-09-28T10:30:00.000Z"
      }
    ]
  }
}

Create a filler list

​

Create a filler list

Body·

required
application/json
  • Value supplied for id in the FillerPhraseListCreateRequest request.

  • Value supplied for name in the FillerPhraseListCreateRequest request.

  • Value supplied for phrases in the FillerPhraseListCreateRequest request.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for post/api/v1/filler-phrase-lists
curl https://client-api.ai4call.com/api/v1/filler-phrase-lists \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "id": "support_waiting",
  "name": "Attesa supporto",
  "phrases": [
    "Un attimo, sto verificando.",
    "Rimanga in linea, controllo subito."
  ]
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "list": {
      "id": "example-id",
      "name": "Example",
      "phrases": [
        "example"
      ],
      "isDefault": true,
      "createdAt": "2026-09-28T10:30:00.000Z",
      "updatedAt": "2026-09-28T10:30:00.000Z"
    }
  }
}

Update a filler list

​

Update a filler list

Path Parameters

Body·

required
application/json
  • Value supplied for name in the FillerPhraseListUpdateRequest request.

  • Value supplied for phrases in the FillerPhraseListUpdateRequest request.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for put/api/v1/filler-phrase-lists/{listId}
curl 'https://client-api.ai4call.com/api/v1/filler-phrase-lists/{listId}' \
  --request PUT \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "name": "Attesa supporto aggiornata",
  "phrases": [
    "Un attimo, sto verificando."
  ]
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "list": {
      "id": "example-id",
      "name": "Example",
      "phrases": [
        "example"
      ],
      "isDefault": true,
      "createdAt": "2026-09-28T10:30:00.000Z",
      "updatedAt": "2026-09-28T10:30:00.000Z"
    }
  }
}

Delete a filler list

​

Delete a filler list

Path Parameters

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for delete/api/v1/filler-phrase-lists/{listId}
curl 'https://client-api.ai4call.com/api/v1/filler-phrase-lists/{listId}' \
  --request DELETE \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "deleted": true
  }
}

Retrieve a filler list

​

Retrieves one filler phrase list owned by the authenticated customer.

Path Parameters

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/filler-phrase-lists/{listId}
curl 'https://client-api.ai4call.com/api/v1/filler-phrase-lists/{listId}' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "list": {
      "id": "example-id",
      "name": "Example",
      "phrases": [
        "example"
      ],
      "isDefault": true,
      "createdAt": "2026-09-28T10:30:00.000Z",
      "updatedAt": "2026-09-28T10:30:00.000Z"
    }
  }
}

Retrieves the filler lists associated with the assistant

​

Retrieves the filler lists associated with the assistant

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/assistants/{assistantId}/filler-phrase-lists
curl https://client-api.ai4call.com/api/v1/assistants/205/filler-phrase-lists \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Assistant filler phrase list associations retrieved successfully.",
  "requestId": "c3d93c2c-8f89-4a2e-b9ad-67d2746c9d16",
  "data": {
    "associations": {
      "waitingListIds": [
        "default_waiting",
        "support_waiting"
      ],
      "toolListIds": [
        "default_tool"
      ]
    }
  }
}

Save the filler lists associated with the assistant

​

Save the filler lists associated with the assistant

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Body·

required
application/json

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for put/api/v1/assistants/{assistantId}/filler-phrase-lists
curl https://client-api.ai4call.com/api/v1/assistants/205/filler-phrase-lists \
  --request PUT \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "waitingListIds": [
    "default_waiting",
    "support_waiting"
  ],
  "toolListIds": [
    "default_tool"
  ]
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "associations": {
      "waitingListIds": [
        "example"
      ],
      "toolListIds": [
        "example"
      ]
    }
  }
}

RAG

​

Lists all customer RAG collections

​

Returns all RAG collections available to the authenticated client.

Use this answer to fill in name in the PATCH /api/v1/assistants/{assistantApiKey}/runtime/rag.

Query Parameters

  • Maximum number of items returned in one cursor-paginated page. Omit both limit and cursor to preserve the legacy unpaginated response.

  • Opaque cursor returned in meta.nextCursor by the previous page.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/rag/collections
curl https://client-api.ai4call.com/api/v1/rag/collections \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "All client RAG collections retrieved successfully.",
  "requestId": "6cd7751e-0d03-4228-b607-c0e1e3c7c6be",
  "meta": {
    "count": 2
  },
  "data": {
    "collections": [
      {
        "id": "42",
        "name": "Listino AI4Call",
        "description": "Product documentation demo collection",
        "collectionName": "ai4call-listino",
        "isActive": true,
        "maxChunkSize": 5000,
        "maxChunksPerFile": null,
        "createdAt": "2026-04-21T12:00:00.000Z",
        "updatedAt": "2026-04-21T12:00:00.000Z",
        "publicRagId": "rag_8K2mP9zQ4xL7"
      },
      {
        "id": "43",
        "name": "FAQ Globale",
        "description": "Collection not yet attached to an assistant",
        "collectionName": "faq-global",
        "isActive": true,
        "maxChunkSize": 5000,
        "maxChunksPerFile": null,
        "createdAt": "2026-04-21T12:05:00.000Z",
        "updatedAt": "2026-04-21T12:05:00.000Z",
        "publicRagId": "rag_4FaQ2zX8mN6"
      }
    ]
  }
}

Create a RAG collection

​

Creates a customer-owned RAG collection and provisions its vector-store collection.

Body·

required
application/json

Create a customer-owned RAG collection and provision the corresponding vector-store collection.

  • Value supplied for name in the RagCollectionCreateRequest request.

  • Value supplied for description in the RagCollectionCreateRequest request.

  • Value supplied for maxChunkSize in the RagCollectionCreateRequest request.

  • Value supplied for maxChunksPerFile in the RagCollectionCreateRequest request.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for post/api/v1/rag/collections
curl https://client-api.ai4call.com/api/v1/rag/collections \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "name": "Product Knowledge",
  "description": "Product documentation",
  "maxChunkSize": 5000,
  "maxChunksPerFile": null
}'
{
  "success": true,
  "message": "RAG collection created successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "collection": {
      "id": "42",
      "publicRagId": "rag_8K2mP9zQ4xL7",
      "name": "Product Knowledge",
      "description": "Product documentation",
      "collectionName": "collection_clNe_abC1234",
      "isActive": true,
      "maxChunkSize": 5000,
      "maxChunksPerFile": null,
      "createdAt": "2026-09-28T10:30:00.000Z",
      "updatedAt": "2026-09-28T10:30:00.000Z"
    }
  }
}

Delete a RAG collection

​

Deletes an unused customer-owned RAG collection and its stored document metadata.

Path Parameters

  • Stable publicRagId of the RAG collection. Legacy collectionName and name values remain accepted.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for delete/api/v1/rag/collections/{ragId}
curl 'https://client-api.ai4call.com/api/v1/rag/collections/{ragId}' \
  --request DELETE \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "RAG collection deleted successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "id": "42",
    "name": "Product Knowledge",
    "collectionName": "collection_clNe_abC1234",
    "deleted": true
  }
}

Estimate token and cost of RAG files before uploading

​

Estimate token and cost of files to upload, using the same calculation shown from the portal before confirming the upload.

Submit files as multipart/form-data in repeatable field files.

Body

required
application/json

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for post/api/v1/rag/documents/estimate
curl https://client-api.ai4call.com/api/v1/rag/documents/estimate \
  --request POST \
  --header 'Content-Type: multipart/form-data' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --form 'files=listino.pdf' \
  --form 'files=faq.txt'
{
  "success": true,
  "message": "RAG document upload token estimate retrieved successfully.",
  "requestId": "41d1c282-d1e4-48ff-b783-eb0c870e32b1",
  "data": {
    "totalTokens": 1200,
    "estimatedCost": 0.00042,
    "fileCount": 2,
    "processingTime": 34,
    "fileDetails": [
      {
        "name": "listino.pdf",
        "tokens": 1000
      }
    ],
    "raw": {
      "success": true
    }
  }
}

Retrieve the status of a RAG upload

​

Use uploadId returned from the upload POST to follow the status of the vectorization, as in the portal.

Path Parameters

Responses

  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/rag/uploads/{uploadId}
curl 'https://client-api.ai4call.com/api/v1/rag/uploads/{uploadId}' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "RAG document upload status retrieved successfully.",
  "requestId": "4801b93d-fac5-4a31-af92-f220ef3bb566",
  "data": {
    "uploadId": "upl_01HTZK",
    "status": "processing",
    "progress": 65,
    "processedFiles": 1,
    "totalFiles": 2,
    "currentFile": "faq.txt",
    "errors": [],
    "totalCost": 0.00042,
    "totalTokens": 1200,
    "results": [],
    "raw": {
      "status": "processing",
      "progress": 65
    }
  }
}

Lists files loaded into a RAG collection

​

Retrieves the authenticated client's RAG collection files.

ragId is the stable publicRagId returned by the collection list. Legacy collectionName and name values remain accepted.

Path Parameters

  • Stable publicRagId of the RAG collection. Legacy collectionName and name values remain accepted.

Query Parameters

  • Maximum number of items returned in one cursor-paginated page. Omit both limit and cursor to preserve the legacy unpaginated response.

  • Opaque cursor returned in meta.nextCursor by the previous page.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/rag/collections/{ragId}/documents
curl 'https://client-api.ai4call.com/api/v1/rag/collections/{ragId}/documents' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "RAG collection documents retrieved successfully.",
  "requestId": "7a70be67-5988-4986-b082-d54a64cc6b01",
  "meta": {
    "count": 1
  },
  "data": {
    "documents": [
      {
        "id": "138",
        "collectionName": "collection_clNe_xvk6bab",
        "fileName": "listino.pdf",
        "fileSize": 245760,
        "uploadDate": "2026-04-21T12:00:00.000Z"
      }
    ]
  }
}

Load files into a RAG collection

​

Load one or more files into the RAG collection, start vectorization on Chroma and save the file detail to make it visible in subsequent GETs.

Submit files as multipart/form-data in repeatable field files. ragId is the stable publicRagId returned by the collection list. Legacy collectionName and name values remain accepted.

Path Parameters

  • Stable publicRagId of the RAG collection. Legacy collectionName and name values remain accepted.

Body

required
application/json

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for post/api/v1/rag/collections/{ragId}/documents
curl 'https://client-api.ai4call.com/api/v1/rag/collections/{ragId}/documents' \
  --request POST \
  --header 'Content-Type: multipart/form-data' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --form 'files=listino.pdf' \
  --form 'files=faq.txt'
{
  "success": true,
  "message": "RAG collection documents upload started successfully.",
  "requestId": "9bb4c2e8-676a-4a86-93f0-c7ce53b43ac2",
  "meta": {
    "count": 2
  },
  "data": {
    "collectionName": "collection_clNe_xvk6bab",
    "name": "Listino AI4Call",
    "uploadId": "upl_01HTZK",
    "backupFiles": [
      "listino.pdf_124",
      "faq.txt_124"
    ],
    "documents": [
      {
        "id": "138",
        "collectionName": "collection_clNe_xvk6bab",
        "fileName": "listino.pdf",
        "fileSize": 245760,
        "uploadDate": "2026-04-21T12:00:00.000Z"
      },
      {
        "id": "139",
        "collectionName": "collection_clNe_xvk6bab",
        "fileName": "faq.txt",
        "fileSize": 8192,
        "uploadDate": "2026-04-21T12:00:01.000Z"
      }
    ],
    "upstream": {
      "success": true,
      "uploadId": "upl_01HTZK"
    }
  }
}

Delete a file from a RAG collection

​

Deletes the document from the Chroma vector store and removes the file detail from the list of the collection.

ragId is the stable publicRagId returned by the collection list. Legacy collectionName and name values remain accepted.

Path Parameters

  • Stable publicRagId of the RAG collection. Legacy collectionName and name values remain accepted.

  • File name to delete, taken from data.documents[].fileName.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for delete/api/v1/rag/collections/{ragId}/documents/{fileName}
curl 'https://client-api.ai4call.com/api/v1/rag/collections/{ragId}/documents/{fileName}' \
  --request DELETE \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "RAG collection document deleted successfully.",
  "requestId": "93f5bcd1-625b-4a7c-a653-1fb742ef80cf",
  "data": {
    "collectionName": "collection_clNe_xvk6bab",
    "name": "Listino AI4Call",
    "fileName": "listino.pdf",
    "metadataDeleted": true,
    "backupFilesDeleted": [
      "listino.pdf_124"
    ],
    "upstream": {
      "success": true,
      "message": "Documento eliminato"
    }
  }
}

Returns the current RAG configuration of a specific assistant

​

Returns the runtime RAG state of the assistant.

If enabled is true, use the name field in this response to fill in the PATCH /api/v1/assistants/{assistantApiKey}/runtime/rag when you want to keep, replace or disable the current collection.

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/assistants/{assistantId}/rag/collections
curl https://client-api.ai4call.com/api/v1/assistants/205/rag/collections \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Assistant RAG configuration retrieved successfully.",
  "data": {
    "enabled": true,
    "name": "Listino AI4Call",
    "returnedChunks": 4,
    "kbPrompt": "Usa la knowledge base come fonte prioritaria."
  },
  "requestId": "7f0d2f4a-c9a8-4f8d-8cbb-4e55c4e0f6bd"
}

Catalog Tools

​

Runtime tools available on the client side and tools associated with the assistant

Update assistant tool bindings

​

Updates the assistant tool associations with PATCH merge semantics, replicating the portal behavior.

Editable parameters:

  • tools
  • tools[].toolName
  • tools[].subscriptionName
  • deleteTools
  • deleteTools[].toolName
  • deleteTools[].subscriptionName
  • toolIds
  • mcpToolsBySubscription
  • mcpToolsBySubscription.{subscription}.{plugin}.tools
  • mcpToolsBySubscription.{subscription}.{plugin}.description
  • mcpToolsBySubscription.{subscription}.{plugin}.subscriptionName

The recommended payload is the high-level by-name one:

  • tools: list of { toolName, subscriptionName } to add
  • deleteTools: list of { toolName, subscriptionName } to remove
  • if you add a custom_tool, use toolName = toolName and subscriptionName = null
  • if you add or remove a plugin_tool, use toolName = toolName and subscriptionName = instanceName
  • if you add or remove a custom_mcp_tool, use toolName = toolName and subscriptionName = instanceName

How to retrieve values:

  • to add tool parts from GET /api/v1/catalog/tools
  • to remove tool parts from GET /api/v1/catalog/assistants/{assistantApiKey}/tools
  • always reuse toolName as toolName
  • always reuse instanceName as subscriptionName for MCP targets
  • if instanceName and null, the tool is a classic custom_tool and must be sent with subscriptionName: null

The portal low-level payload (toolIds + mcpToolsBySubscription) remains supported for enhanced compatibility. On voice_to_voice assistants, HTTP tools are written in endpointTools and the MCP tools in mcpServers in the JSON root voice-llm.

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Body·

required
application/json

Tool association update payload.

You can update just the classic tools, just the MCP tools, or both in the same call. If you use shape by-name, the values ​​should always be taken from the GET catalogs documented above.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for patch/api/v1/assistants/{assistantId}/runtime/tools
curl https://client-api.ai4call.com/api/v1/assistants/205/runtime/tools \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "tools": [
    {
      "toolName": "send_email",
      "subscriptionName": null
    },
    {
      "toolName": "create_ticket",
      "subscriptionName": "Webhook CRM"
    },
    {
      "toolName": "sheets_append_row",
      "subscriptionName": "Google Sheets Produzione"
    }
  ],
  "deleteTools": [
    {
      "toolName": "send_sms",
      "subscriptionName": null
    },
    {
      "toolName": "sheets_search_rows",
      "subscriptionName": "Google Sheets Produzione"
    }
  ]
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "assistantApiKey": "ai4call_sk_example",
    "assistantId": "example-id",
    "service": "tools",
    "configuration": {
      "toolIds": [
        "example"
      ],
      "mcpToolsBySubscription": {},
      "hasMcpTools": true
    }
  }
}

Lists all available customer runtime tools

​

Returns the complete catalog of tools that the customer can associate with an assistant.

Use this response to compile tools into PATCH /api/v1/assistants/{assistantApiKey}/runtime/tools:

  • reuse toolName as toolName
  • if toolType and custom_tool, send subscriptionName: null
  • if toolType and plugin_tool, send subscriptionName equal to instanceName
  • if toolType and custom_mcp_tool, send subscriptionName equal to instanceName

Query Parameters

  • Maximum number of items returned in one cursor-paginated page. Omit both limit and cursor to preserve the legacy unpaginated response.

  • Opaque cursor returned in meta.nextCursor by the previous page.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/catalog/tools
curl https://client-api.ai4call.com/api/v1/catalog/tools \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Available tools retrieved successfully.",
  "requestId": "21715377-4492-44af-91a7-af50058a4bac",
  "meta": {
    "count": 4,
    "customToolCount": 1,
    "pluginToolCount": 2,
    "customMcpToolCount": 1
  },
  "data": {
    "tools": [
      {
        "toolType": "custom_tool",
        "toolName": "crm-search",
        "instanceName": null,
        "pluginName": null,
        "description": "Search for a lead in the company CRM",
        "parameters": null,
        "method": "POST",
        "endpoint": "https://crm.example.com/api/search"
      },
      {
        "toolType": "plugin_tool",
        "toolName": "list_workflows",
        "instanceName": "Marketing",
        "pluginName": "n8n",
        "description": "Lists available workflows",
        "parameters": {
          "type": "object"
        },
        "method": null,
        "endpoint": null
      },
      {
        "toolType": "plugin_tool",
        "toolName": "execute_workflow",
        "instanceName": "Marketing",
        "pluginName": "n8n",
        "description": "Runs an n8n workflow",
        "parameters": {
          "type": "object"
        },
        "method": null,
        "endpoint": null
      },
      {
        "toolType": "custom_mcp_tool",
        "toolName": "search_contact",
        "instanceName": "CRM Custom",
        "pluginName": "CRM Custom",
        "description": "Search for a contact in the CRM",
        "parameters": {
          "type": "object"
        },
        "method": null,
        "endpoint": null
      }
    ]
  }
}

Lists the runtime tools associated with the assistant

​

Returns the tools currently associated with the assistant.

Use this response to compile deleteTools into PATCH /api/v1/assistants/{assistantApiKey}/runtime/tools:

  • reuse toolName as toolName
  • if toolType and custom_tool, send subscriptionName: null
  • if toolType and plugin_tool, send subscriptionName equal to instanceName
  • if toolType and custom_mcp_tool, send subscriptionName equal to instanceName

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/catalog/assistants/{assistantId}/tools
curl https://client-api.ai4call.com/api/v1/catalog/assistants/205/tools \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Assistant associated tools retrieved successfully.",
  "requestId": "5e6fe40d-8f7f-4406-95c0-d3a5c4c90fd3",
  "meta": {
    "count": 3,
    "customToolCount": 1,
    "pluginToolCount": 1,
    "customMcpToolCount": 1
  },
  "data": {
    "tools": [
      {
        "toolType": "custom_tool",
        "toolName": "crm-search",
        "instanceName": null,
        "pluginName": null,
        "description": "Search for a lead in the company CRM",
        "parameters": null,
        "method": "POST",
        "endpoint": "https://crm.example.com/api/search"
      },
      {
        "toolType": "plugin_tool",
        "toolName": "execute_workflow",
        "instanceName": "Marketing",
        "pluginName": "n8n",
        "description": "Runs an n8n workflow",
        "parameters": {
          "type": "object"
        },
        "method": null,
        "endpoint": null
      },
      {
        "toolType": "custom_mcp_tool",
        "toolName": "search_contact",
        "instanceName": "CRM Custom",
        "pluginName": "CRM Custom",
        "description": "Search for a contact in the CRM",
        "parameters": {
          "type": "object"
        },
        "method": null,
        "endpoint": null
      }
    ]
  }
}

Catalog RAG

​

Legacy catalog aliases for customer and assistant RAG collections. Kept for v1 compatibility only.

Update the assistant's RAG runtime configuration

​

Update the assistant's RAG configuration with PATCH merge semantics, aligned to the portal.

Editable parameters:

  • enabled
  • name
  • returnedChunks
  • kbPrompt

How to recover data:

  • use GET /api/v1/catalog/rag/collections to get available RAG collections
  • reuse name from the collection as name

Operational rules:

  • enabled: true enables RAG and requires a valid collection
  • enabled: false removes the RAG knowledge base from the assistant
  • returnedChunks replicates the portal setting
  • kbPrompt updates assistant knowledge base instructions
  • omitted fields retain the current value, if present
  • on assistants voice_to_voice the backend updates knowledgeBases in the JSON root voice-llm

Path Parameters

  • Public assistant identifier. The current numeric assistantId is canonical; the legacy assistantApiKey value remains accepted during the v1 compatibility period.

Body·

required
application/json

PATCH merge of the assistant's RAG configuration, aligned with the portal behavior.

Operational rules:

  • at least one of enabled, name, returnedChunks, kbPrompt must be present
  • use GET /api/v1/catalog/rag/collections to recover the name
  • enabled: true requires a valid and active collection
  • by sending name with a valid collection, the RAG is activated if it is not explicitly disabled
  • enabled: false removes RAG knowledge base from assistant and cleans returnedChunks and kbPrompt
  • returnedChunks follows the portal setting and must be between 1 and 10
  • kbPrompt: null removes assistant knowledge base instructions
  • omitted fields retain the current value, if already present
  • Enable or disable RAG for the assistant. If false, the RAG knowledge base is removed.

  • Assistant knowledge base instructions. If null, the field is removed from the LLM runtime.

  • Name of the RAG collection to associate. It must be recovered from GET /api/v1/catalog/rag/collections. If null, the selection is reset.

  • Number of relevant fragments to return from the knowledge base.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for patch/api/v1/assistants/{assistantId}/runtime/rag
curl https://client-api.ai4call.com/api/v1/assistants/205/runtime/rag \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN' \
  --data '{
  "enabled": true,
  "name": "Listino AI4Call",
  "returnedChunks": 4,
  "kbPrompt": "Usa la knowledge base come fonte prioritaria."
}'
{
  "success": true,
  "message": "Operation completed successfully.",
  "requestId": "00000000-0000-4000-8000-000000000000",
  "data": {
    "assistantApiKey": "ai4call_sk_example",
    "assistantId": "example-id",
    "service": "rag",
    "configuration": {
      "enabled": true,
      "returnedChunks": 1
    }
  }
}

Account Analytics

​

Retrieves the inbound call history of the authenticated customer

​

Returns the customer's inbound calls with details of costs and tokens for each session.

Available filters:

  • startDate and endDate filter by creation date (createdAt)
  • both are optional; if omitted, the backend returns all available history

How to read the costs:

  • all costs are in EUR
  • totalCost = llmInputCost + llmOutputCost + ttsCost + asrCost + ragCost + trafficCost + trafficCostOutbound

Query Parameters

  • Filter start date (YYYY-MM-DD, included)

  • Filter end date (YYYY-MM-DD, included)

  • Maximum number of records. If omitted along with cursor, retains legacy non-paged behavior.

  • Opaque cursor returned in meta.nextCursor to read the next page.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/account/analytics/calls
curl 'https://client-api.ai4call.com/api/v1/account/analytics/calls?startDate=2026-04-01&endDate=2026-04-24&limit=50' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Account analytics calls retrieved successfully.",
  "requestId": "9755db58-3e8d-4a09-b3a1-c68fd6f70c8a",
  "data": {
    "records": [
      {
        "cdrId": 1042,
        "assistantApiKey": "ai4call_sk_abc123",
        "assistantName": "Assistente Demo",
        "callerNumber": "+393331234567",
        "uuid": "7e4c2a91-1234-5678-abcd-ef0123456789",
        "billsec": 92,
        "dialstatus": "ANSWERED",
        "inputTokens": 320,
        "outputTokens": 180,
        "ragTokens": 0,
        "llmInputCost": 0.0003,
        "llmOutputCost": 0.0002,
        "ttsCost": 0.0015,
        "asrCost": 0.001,
        "ragCost": 0,
        "trafficCost": 0.0046,
        "trafficCostOutbound": 0,
        "totalCost": 0.0076,
        "createdAt": "2026-04-24T10:15:00.000Z"
      }
    ]
  },
  "meta": {
    "count": 1
  }
}

Retrieves the outbound call history of the authenticated customer

​

Returns the customer's outbound calls with details of traffic costs for each session.

Available filters:

  • startDate and endDate filter by creation date (createdAt)
  • internalId filters a single outbound call using the internal identifier generated by AI4Call
  • the authenticated customer filter is always applied, even when internalId is present
  • if internalId is omitted, the backend returns the available history of the authenticated customer

Query Parameters

  • Filter by the outbound UUID generated by AI4Call.

    UUID generated by AI4Call to correlate the outbound request, callback and final dial-status lookup.

  • Legacy alias of internalId.

    UUID generated by AI4Call to correlate the outbound request, callback and final dial-status lookup.

  • Filter start date (YYYY-MM-DD, included)

  • Filter end date (YYYY-MM-DD, included)

  • Maximum number of records. If omitted along with cursor, retains legacy non-paged behavior.

  • Opaque cursor returned in meta.nextCursor to read the next page.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/account/analytics/calls-outbound
curl 'https://client-api.ai4call.com/api/v1/account/analytics/calls-outbound?internalId=4f9ab147-ef47-4b54-9987-1dd30288c610&internal_id=4f9ab147-ef47-4b54-9987-1dd30288c610&startDate=2026-04-01&endDate=2026-04-24&limit=50' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Account analytics calls outbound retrieved successfully.",
  "requestId": "9755db58-3e8d-4a09-b3a1-c68fd6f70c8b",
  "data": {
    "records": [
      {
        "uuid": "9f1a3b72-5678-1234-dcba-ab9876543210",
        "callId": "CALL-20260424-001",
        "internalId": "4f9ab147-ef47-4b54-9987-1dd30288c610",
        "internal_id": "4f9ab147-ef47-4b54-9987-1dd30288c610",
        "assistantApiKey": "ai4call_sk_abc123",
        "assistantName": "Assistente Demo",
        "destination": "+390212345678",
        "dialstatus": "ANSWERED",
        "process": "outbound_campaign",
        "billsec": 65,
        "listId": "42",
        "listCall": "Campagna Aprile",
        "callResultUrl": "https://example.com/webhooks/ai4call/outbound-result",
        "url_esito_chiamata": "https://example.com/webhooks/ai4call/outbound-result",
        "trafficCostOutbound": 0.0033,
        "createdAt": "2026-04-24T11:00:00.000Z"
      }
    ]
  },
  "meta": {
    "count": 1
  }
}

Retrieves the MCP Pre-Call call history of the authenticated customer

​

Returns the customer's MCP Pre-Call invocations with token details and LLM costs for each request.

The Pre-Call MCP performs numerical validations and MCP configurations before the call is routed to the assistant.

Available filters:

  • startDate and endDate filter by creation date (createdAt)
  • both are optional; if omitted, the backend returns all available history

Query Parameters

  • Filter start date (YYYY-MM-DD, included)

  • Filter end date (YYYY-MM-DD, included)

  • Maximum number of records. If omitted along with cursor, retains legacy non-paged behavior.

  • Opaque cursor returned in meta.nextCursor to read the next page.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/account/analytics/pre-call
curl 'https://client-api.ai4call.com/api/v1/account/analytics/pre-call?startDate=2026-04-01&endDate=2026-04-24&limit=50' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Account analytics pre-call retrieved successfully.",
  "requestId": "9755db58-3e8d-4a09-b3a1-c68fd6f70c8c",
  "data": {
    "records": [
      {
        "cdrId": "501",
        "assistantApiKey": "ai4call_sk_abc123",
        "assistantName": "Assistente Demo",
        "callerId": "+393331234567",
        "uuid": null,
        "inputTokens": 120,
        "outputTokens": 60,
        "inputCost": 0.00012,
        "outputCost": 0.00006,
        "totalCost": 0.00018,
        "createdAt": "2026-04-24T10:14:55.000Z"
      }
    ]
  },
  "meta": {
    "count": 1
  }
}

Retrieves the MCP Post-Call call history of the authenticated customer

​

Returns the customer's Post-Call MCP invocations with token details and LLM costs for each request.

The Post-Call MCP runs tools and automations after the call is closed, using the context of the concluded conversation.

Available filters:

  • startDate and endDate filter by creation date (createdAt)
  • both are optional; if omitted, the backend returns all available history

Query Parameters

  • Filter start date (YYYY-MM-DD, included)

  • Filter end date (YYYY-MM-DD, included)

  • Maximum number of records. If omitted along with cursor, retains legacy non-paged behavior.

  • Opaque cursor returned in meta.nextCursor to read the next page.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/account/analytics/post-call
curl 'https://client-api.ai4call.com/api/v1/account/analytics/post-call?startDate=2026-04-01&endDate=2026-04-24&limit=50' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Account analytics post-call retrieved successfully.",
  "requestId": "9755db58-3e8d-4a09-b3a1-c68fd6f70c8c",
  "data": {
    "records": [
      {
        "cdrId": "501",
        "assistantApiKey": "ai4call_sk_abc123",
        "assistantName": "Assistente Demo",
        "callerId": "+393331234567",
        "uuid": null,
        "inputTokens": 120,
        "outputTokens": 60,
        "inputCost": 0.00012,
        "outputCost": 0.00006,
        "totalCost": 0.00018,
        "createdAt": "2026-04-24T10:14:55.000Z"
      }
    ]
  },
  "meta": {
    "count": 1
  }
}

Retrieve the top-up history of the authenticated customer

​

Returns the customer's credit top-up movements.

Available filters:

  • startDate and endDate filter by creation date (createdAt)
  • both are optional; if omitted, the backend returns all available history

status values:

  • completed — top-up completed and credit credited
  • pending — transaction awaiting confirmation from the gateway
  • failed — transaction failed
  • cancelled — transaction canceled

Query Parameters

  • Filter start date (YYYY-MM-DD, included)

  • Filter end date (YYYY-MM-DD, included)

  • Maximum number of records. If omitted along with cursor, retains legacy non-paged behavior.

  • Opaque cursor returned in meta.nextCursor to read the next page.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/account/analytics/recharges
curl 'https://client-api.ai4call.com/api/v1/account/analytics/recharges?startDate=2026-04-01&endDate=2026-04-24&limit=50' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Account analytics recharges retrieved successfully.",
  "requestId": "9755db58-3e8d-4a09-b3a1-c68fd6f70c8d",
  "data": {
    "records": [
      {
        "id": 301,
        "amount": "50.00",
        "status": "completed",
        "currency": "978",
        "orderId": "ORD-20260424-001",
        "createdAt": "2026-04-24T09:00:00.000Z",
        "updatedAt": "2026-04-24T09:00:05.000Z"
      }
    ]
  },
  "meta": {
    "count": 1
  }
}

Retrieves the RAG consumption history of the authenticated customer

​

Returns the detail of the customer's RAG embedding consumption, aggregated by collection.

Available filters:

  • startDate and endDate filter by creation date of the consumption record (createdAt)
  • both are optional; if omitted, the backend returns all available history

How to read the data:

  • totalToken — total embedding tokens processed for that collection in the period
  • totalCost — total embedding cost in EUR for that collection in the period
  • fileCount — number of files indexed in the collection at the time of the record

Query Parameters

  • Filter start date (YYYY-MM-DD, included)

  • Filter end date (YYYY-MM-DD, included)

  • Maximum number of records. If omitted along with cursor, retains legacy non-paged behavior.

  • Opaque cursor returned in meta.nextCursor to read the next page.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/account/analytics/rag
curl 'https://client-api.ai4call.com/api/v1/account/analytics/rag?startDate=2026-04-01&endDate=2026-04-24&limit=50' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Account analytics RAG retrieved successfully.",
  "requestId": "9755db58-3e8d-4a09-b3a1-c68fd6f70c8e",
  "data": {
    "records": [
      {
        "id": 88,
        "assistantApiKey": "ai4call_sk_abc123",
        "ragId": 12,
        "ragName": "Knowledge Base Prodotti",
        "ragDescription": "Documentazione prodotti aziendali",
        "collectionName": "kb_prodotti_v2",
        "collectionIsActive": true,
        "embeddingProvider": "openai",
        "embeddingModel": "text-embedding-3-small",
        "vectorStoreEngine": "chroma",
        "fileCount": 14,
        "totalToken": 48200,
        "totalCost": "0.0048",
        "collectionCreatedAt": "2026-03-10T08:00:00.000Z",
        "collectionUpdatedAt": "2026-04-20T14:30:00.000Z",
        "createdAt": "2026-04-24T08:00:00.000Z"
      }
    ]
  },
  "meta": {
    "count": 1
  }
}

Retrieves the billed RAG searches of the authenticated customer

​

Returns the detail of the RAG searches charged to the customer, one record per search.

Different from /api/v1/account/analytics/rag, which covers the cost of uploading documents into the collections: this endpoint covers the cost of querying them.

Available filters:

  • startDate and endDate filter by search timestamp (createdAt)
  • both are optional; if omitted, the backend returns all available history

How to read the data:

  • queryTokens — tokens of the query, the quantity the search is billed on
  • pricePerTokenNoVat — unit price applied from the customer price list
  • totalCost — charged amount, VAT included; totalCostNoVat is the same amount before VAT
  • resultCount — chunks returned, at most 10 per search

If the customer has never run a billed search the list is empty.

Query Parameters

  • Filter start date (YYYY-MM-DD, included)

  • Filter end date (YYYY-MM-DD, included)

  • Maximum number of records. If omitted along with cursor, retains legacy non-paged behavior.

  • Opaque cursor returned in meta.nextCursor to read the next page.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/account/analytics/rag-searches
curl 'https://client-api.ai4call.com/api/v1/account/analytics/rag-searches?startDate=2026-08-01&endDate=2026-08-28&limit=50' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Account analytics RAG searches retrieved successfully.",
  "requestId": "9755db58-3e8d-4a09-b3a1-c68fd6f70c8e",
  "data": {
    "records": [
      {
        "id": "6f1c0a1e-6f0e-4a55-9a35-2f6b6d3c1f77",
        "ragId": 12,
        "ragName": "Knowledge Base Prodotti",
        "collectionName": "kb_prodotti_v2",
        "queryTokens": 128,
        "resultCount": 5,
        "ragCost": 0.0000047,
        "totalCost": 0.0000047,
        "totalCostNoVat": 0.0000038,
        "pricePerTokenNoVat": 3e-8,
        "pricePerTokenWithVat": 3.66e-8,
        "source": "call",
        "createdAt": "2026-08-27T10:12:44.000Z"
      }
    ]
  },
  "meta": {
    "count": 1
  }
}

Retrieve the SMS history of the authenticated customer

​

Returns SMS messages sent by the customer via assistants.

Available filters:

  • startDate and endDate filter by sending date (createdAt)
  • both are optional; if omitted, the backend returns all available history

How to read the data:

  • usageSms — number of SMS deducted from the SMS credit for this message (depends on the length of the text)
  • alias — assistant name or label configured for the SMS channel

Query Parameters

  • Filter start date (YYYY-MM-DD, included)

  • Filter end date (YYYY-MM-DD, included)

  • Maximum number of records. If omitted along with cursor, retains legacy non-paged behavior.

  • Opaque cursor returned in meta.nextCursor to read the next page.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/account/analytics/sms
curl 'https://client-api.ai4call.com/api/v1/account/analytics/sms?startDate=2026-04-01&endDate=2026-04-24&limit=50' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Account analytics SMS retrieved successfully.",
  "requestId": "9755db58-3e8d-4a09-b3a1-c68fd6f70c8f",
  "data": {
    "records": [
      {
        "assistantApiKey": "ai4call_sk_abc123",
        "alias": "Assistente Demo",
        "destinationNumber": "+393331234567",
        "text": "Grazie per averci contattato. Le invieremo una conferma via email.",
        "usageSms": 1,
        "createdAt": "2026-04-24T10:20:00.000Z"
      }
    ]
  },
  "meta": {
    "count": 1
  }
}

Retrieves the tool response history of the authenticated customer

​

Returns the responses of the tools invoked by the assistants during calls.

Available filters:

  • startDate and endDate filter by creation date (createdAt)
  • both are optional; if omitted, the backend returns all available history

How to read the data:

  • toolName — name of the invoked tool (corresponds to the name of the tool configured on the assistant)
  • toolCallId — unique identifier of the invocation generated by the LLM
  • callUuid — UUID of the telephone call that originated the invocation
  • toolResponse — response payload returned by the tool; the structure varies for each tool

Query Parameters

  • Filter start date (YYYY-MM-DD, included)

  • Filter end date (YYYY-MM-DD, included)

  • Maximum number of records. If omitted along with cursor, retains legacy non-paged behavior.

  • Opaque cursor returned in meta.nextCursor to read the next page.

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for get/api/v1/account/analytics/tool-responses
curl 'https://client-api.ai4call.com/api/v1/account/analytics/tool-responses?startDate=2026-04-01&endDate=2026-04-24&limit=50' \
  --header 'x-client-email: YOUR_SECRET_TOKEN' \
  --header 'x-portal-api-key: YOUR_SECRET_TOKEN'
{
  "success": true,
  "message": "Account analytics tool responses retrieved successfully.",
  "requestId": "9755db58-3e8d-4a09-b3a1-c68fd6f70c90",
  "data": {
    "records": [
      {
        "id": 4501,
        "callUuid": "7e4c2a91-1234-5678-abcd-ef0123456789",
        "toolName": "get_calendar_availability",
        "toolCallId": "call_abc123xyz",
        "toolResponse": {
          "available": true,
          "slots": [
            {
              "date": "2026-04-25",
              "time": "10:00"
            },
            {
              "date": "2026-04-25",
              "time": "15:00"
            }
          ]
        },
        "createdAt": "2026-04-24T10:15:30.000Z"
      }
    ]
  },
  "meta": {
    "count": 1
  }
}

Public RAG

​

Public RAG search using a customer API key

Public RAG Operations

Search for chunks in a public RAG collection

​

Performs a vector search on a RAG collection using the collection's public API ID.

The endpoint uses the dedicated domain https://rag.ai4call.com and requires a customer API key generated by the AI4Call portal in the Security -> API Key section.

The rag_id field is the public API ID shown in the RAG management UI, not the numeric ID internal database. The search returns a maximum of 4 chunks.

Body·

required
application/json

Public RAG search request accepted by the dedicated RAG service.

  • Text to search semantically in the RAG collection

  • Public API ID of the RAG collection shown in the portal UI

Responses

  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
  • application/json
Request Example for post/public/v1/rag/search
curl https://rag.ai4call.com/public/v1/rag/search \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_SECRET_TOKEN' \
  --data '{
  "rag_id": "rag_8K2mP9zQ4xL7",
  "query": "coca"
}'
{
  "success": true,
  "data": {
    "query": "coca",
    "rag_id": "rag_8K2mP9zQ4xL7",
    "count": 2,
    "results": [
      {
        "content": "1 lattina Coca Cola costa 1,50 EURO",
        "score": 1.4087,
        "metadata": {
          "filename": "Catalogo Prodotti Autorizzati.txt",
          "chunkIndex": "0",
          "totalChunks": "4"
        }
      }
    ]
  }
}

Outbound

​

Webhook to initiate outbound calls with customer PBX or AI4Call trunk

Outgoing call using customer's telephony configuration

​

Initiate an outbound call using the customer's telephony configuration.

Two modes are available:

  • PBX IP mode (default): omit method_uac or set it to false, and provide ip_pbx and sip_port. ip_pbx must be one of the authorized public IPs available in GESTIONE -> Abilita IP.
  • Registered UAC mode: set method_uac to true and omit ip_pbx and sip_port.

The API key in the header must be generated by the portal in the section SICUREZZA -> API key.

Body·

required
application/json

Responses

  • application/json
  • application/json
  • application/json
Request Example for post/webhook/outbound_call_pbx
curl https://outcall.ai4call.com/webhook/outbound_call_pbx \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'X-APIKEY-SECRET-AI4CALL: YOUR_SECRET_TOKEN' \
  --data '{
  "dst": "331XXXXXXXXX",
  "callerId": "02825XXXXX",
  "assistantApiKey": "ai4call_sk_xxxxxxxx",
  "ipPbx": "xxx.xxx.xxx.xxx",
  "sipPort": "5060",
  "addPrompt": "Saluta sempre l'\''utente per nome, si chiama MARIO ROSSI",
  "callResultUrl": "https://example.com/webhooks/ai4call/outbound-result"
}'
{
  "success": true,
  "message": "Outbound call accepted.",
  "requestId": "9755db58-3e8d-4a09-b3a1-c68fd6f70c8b",
  "data": {
    "internalId": "4f9ab147-ef47-4b54-9987-1dd30288c610",
    "status": "accepted",
    "callbackConfigured": true,
    "callId": "CALL-20260504-001"
  }
}

Outgoing call with AI4Call trunk

​

Initiate an outbound call using AI4Call VoIP trunks. Does not require customer PBX configuration.

callerId must be a demo or purchased AI4Call number present in the account. You can see demo and purchased numbers in NUMERI AI4Call -> Routing.

The API key in the header must be generated by the portal in the section SICUREZZA -> API key.

Body·

required
application/json

Responses

  • application/json
  • application/json
  • application/json
Request Example for post/webhook/outbound_call
curl https://outcall.ai4call.com/webhook/outbound_call \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'X-APIKEY-SECRET-AI4CALL: YOUR_SECRET_TOKEN' \
  --data '{
  "dst": "+39331XXXXXXXXX",
  "callerId": "+3902825XXXXX",
  "assistantApiKey": "ai4call_sk_xxxxxxxx",
  "addPrompt": "Saluta sempre l'\''utente per nome, si chiama MARIO ROSSI",
  "callResultUrl": "https://example.com/webhooks/ai4call/outbound-result"
}'
{
  "success": true,
  "message": "Outbound call accepted.",
  "requestId": "9755db58-3e8d-4a09-b3a1-c68fd6f70c8b",
  "data": {
    "internalId": "4f9ab147-ef47-4b54-9987-1dd30288c610",
    "status": "accepted",
    "callbackConfigured": true,
    "callId": "CALL-20260504-001"
  }
}

Retrieve the persisted status of an outbound call

​

Retrieves the final outbound CDR using the internal_id received in the outcome callback.

The callback can arrive while duration is 0; clients can repeat this request until the CDR has been persisted. The API key must belong to the customer that initiated the outbound call.

Path Parameters

  • Outbound internal ID received in the callback.

    UUID generated by AI4Call to correlate the outbound request, callback and final dial-status lookup.

Responses

  • application/json
  • application/json
  • application/json
Request Example for get/getDialstatus/{uuid}
curl https://outcall.ai4call.com/getDialstatus/4f9ab147-ef47-4b54-9987-1dd30288c610 \
  --header 'X-APIKEY-SECRET-AI4CALL: YOUR_SECRET_TOKEN'
{
  "dialStatus": "ANSWER",
  "billSec": 42,
  "trafficCost": "0.003300"
}

Models

​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​