Start with installed API module identity and served path
Record the installed FreePBX branch, PBX API module version and signature state before copying an example request. The release/17.0 metadata currently identifies module version 17.0.9, support for FreePBX 17.0 and a dependency on PM2 17.0.1 or later; those repository values do not prove the running version or service state.
Confirm the exact HTTPS origin, reverse-proxy path and certificate presented to the client. The release/17.0 implementation builds token and GraphQL locations beneath /admin/api/api/, but an observed public URL can differ when a proxy or path prefix is in front of the PBX.
Model the application before handling its secret
The module stores an application name, owner, grant type, client identifier, optional client secret, redirect URI, website, algorithm and allowed scopes as distinct fields. Choose the grant flow for the consumer and record its expected user or service identity before issuing credentials.
Treat the client secret and every access or refresh token as secrets: do not place them in shell history, URLs, screenshots, tickets or source control. Record a fingerprint, application ID and issuance time for correlation, not the secret value.
Grant the smallest operation scopes
FreePBX constructs API scopes from active modules, interface type and operation metadata. GraphQL and REST scopes remain separate, and the release/17.0 implementation validates a requested scope against the flattened active set.
Grant only the exact query or mutation surface the integration needs. A successfully issued token proves authentication and an allowed token request; it does not prove that every resolver, module or mutation is authorized or active.
Separate token issuance from GraphQL execution
The implementation exposes token handling separately from the GraphQL endpoint and uses a Bearer token for GraphQL documentation generation. Capture the token response status, token type, expiry and granted scopes without logging the credential, then issue a minimal read-only query against the intended GraphQL path.
A token request failure belongs to client identity, grant, secret, requested scope, time or token endpoint. A GraphQL failure after token issuance belongs later in the chain: bearer presentation, scope, schema, operation, variables, resolver or downstream module.
Treat schema and module state as runtime evidence
The available GraphQL surface is assembled from active modules. A field visible in source, a generated example or another PBX is not proof that the installed schema exposes it. Capture schema or documentation output from the same authorized environment and version as the request.
Keep parse and validation errors separate from authorization and resolver errors. Do not respond to a missing field by granting all scopes or enabling unrelated modules; first prove the requested operation exists on the active schema.
Validate one application lifecycle without exposing credentials
In an authorized test environment, create a narrowly scoped application, obtain one token, run one non-destructive query, observe expiry or revocation, and verify that the same request fails after the credential is removed. Correlate timestamps, application ID, token fingerprint, scope, HTTP status, GraphQL errors and PBX logs.
Review the installed module changelog and apply supported updates through the established change process. The release/17.0 metadata records fixes for an authentication bypass and GraphQL command-argument sanitization; that history is a reason to verify installed state, not a claim that a running PBX remains vulnerable. No PBX or API request was tested for this guide.
Sources & applicability
Primary references for the technical details above. Operational examples and planning checklists are VoIP.info editorial guidance.
- Sangoma FreePBX PBX API documentation ↗
- FreePBX PBX API module repository ↗
- FreePBX PBX API release/17.0 module metadata ↗
- FreePBX PBX API release/17.0 implementation ↗
Examples require adaptation to your topology. No live PBX or hardware testing is claimed.