ExoVoIPDeveloper guide

Conventions

Rules common to all endpoints.

Format

  • Requests and responses in JSON, fields in camelCase, UTF-8 encoding.
  • Dates and times in ISO 8601 UTC (2026-11-04T10:00:00.000Z); plain dates as YYYY-MM-DD.
  • Numeric identifiers, unless stated otherwise (e.g. call linkedid, voicemail message id).
  • PATCH updates only the fields you send; a field set to null is cleared, an omitted field is left unchanged. PUT replaces the specified object or setting.
  • Secrets (trunk passwords, PINs) are never returned: responses include hasSecret / hasPin instead.
  • Values shown only once: the SIP password when an extension is created, the API key on creation and rotation, the webhook secret, the initial administrator password of a new tenant.

Base URL

The default address is https://centralino.exovoip.it/api. In the SDKs it is a constructor option: if the address changes, just update it.

export EXOPBX_BASE_URL="https://centralino.exovoip.it/api"
curl -s "$EXOPBX_BASE_URL/health"

Pagination

Lists use a cursor:

  • limit (1–200, default 50) and cursor query parameters;
  • response { "items": [...], "nextCursor": "..." }; nextCursor is null on the last page;
  • the cursor is opaque: pass it as is, without interpreting it.
# Prima pagina
curl -s "https://centralino.exovoip.it/api/v1/cdr?limit=100" -H "X-API-Key: $EXOPBX_API_KEY"
# Pagina successiva: valore nextCursor della risposta precedente
curl -s "https://centralino.exovoip.it/api/v1/cdr?limit=100&cursor=eyJ2IjoxfQ" -H "X-API-Key: $EXOPBX_API_KEY"

Idempotency

POST requests accept the Idempotency-Key header (up to 255 characters). Repeating the same request with the same key within 24 hours returns the same response without creating duplicates; with a different body you get 409 IDEMPOTENCY_CONFLICT. The SDKs send a random key with every POST, so automatic retries are safe.

curl -s -X POST https://centralino.exovoip.it/api/v1/extensions \
  -H "X-API-Key: $EXOPBX_API_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: crm-utente-4821" \
  -d '{"number":"105","name":"Giulia Verdi"}'

Errors

Every error has the same format:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Dati non validi",
    "details": [{ "path": ["number"], "message": "Obbligatorio" }]
  }
}

code is stable and is what your code should check; message is human-readable text that may change.

StatusMain codesMeaning
400VALIDATION_ERROR, BAD_REQUEST, TENANT_REQUIREDInvalid data or missing tenant
401UNAUTHORIZED, API_KEY_INVALID, API_KEY_EXPIRED, API_KEY_REVOKEDMissing or invalid key
403FORBIDDEN, SCOPE_MISSING, IP_NOT_ALLOWED, TENANT_SUSPENDEDInsufficient permissions
404NOT_FOUNDResource does not exist or belongs to another tenant
409CONFLICT, IN_USE, LIMIT_REACHED, IDEMPOTENCY_CONFLICTDuplicate, resource in use, plan limit
413 / 415PAYLOAD_TOO_LARGE, UNSUPPORTED_MEDIA_TYPEFile too large or unsupported format
429RATE_LIMITEDToo many requests
501NOT_IMPLEMENTEDFeature not yet available
503SERVICE_UNAVAILABLEService temporarily unavailable
curl -s -X POST https://centralino.exovoip.it/api/v1/extensions \
  -H "X-API-Key: $EXOPBX_API_KEY" -H "Content-Type: application/json" -d '{"number":""}'
# {"error":{"code":"VALIDATION_ERROR","message":"Dati non validi","details":[...]}}

Rate limits

Each key can send up to 600 requests per minute (platform default). Beyond the limit you get 429 RATE_LIMITED with the Retry-After header (seconds to wait) and details.retryAfter. The SDKs wait and retry automatically.

# HTTP/1.1 429 Too Many Requests
# Retry-After: 12
# {"error":{"code":"RATE_LIMITED","message":"Limite di richieste superato per questa chiave","details":{"retryAfter":12}}}

Other limits: JSON body up to 1 MB; audio files within the limits listed in the Voice prompts guide; at most 10 webhooks per tenant.

Caching and useful headers

  • API responses are not cached (Cache-Control: no-store).
  • Always send Accept: application/json (the SDKs do this for you).
  • When contacting support, include the date and time of the request, the endpoint and the error code.

Endpoints not yet in the SDK

If the API adds an endpoint before you update the SDK, you can call it with the generic request method:

curl -s "https://centralino.exovoip.it/api/v1/extensions?limit=10" -H "X-API-Key: $EXOPBX_API_KEY"