I'm trying to integrate with the 3CX Video Conference API to create a web application that allows users to create ad-hoc conferences and schedule video conferences. However, I'm consistently encountering API authentication failures despite trying multiple approaches.
What I've tried
Direct API Call (Using jQuery)
javascript
<span><span>var</span><span> settings</span><span> =</span><span> {</span></span><br><span><span> "url"</span><span>: </span><span>"
https://server.3cx.com.au/webmeeting/api/v1/adhoc?extension=391&subject=Test Meeting"</span><span>,</span></span><br><span><span> "method"</span><span>: </span><span>"POST"</span><span>,</span></span><br><span><span> "timeout"</span><span>: </span><span>0</span><span>,</span></span><br><span><span> "headers"</span><span>: {</span></span><br><span><span> "3CX-ApiKey"</span><span>: </span><span>"***API KEY***"</span><span>,</span></span><br><span><span> "Content-Length"</span><span>: </span><span>"0"</span></span><br><span><span> },</span></span><br><span><span>};</span></span><br><span></span><br><span><span>$</span><span>.</span><span>ajax</span><span>(</span><span>settings</span><span>) .</span><span>done</span><span>(</span><span>function</span><span> (</span><span>response</span><span>) {</span></span><br><span><span> console</span><span>.</span><span>log</span><span>(</span><span>response</span><span>);</span></span><br><span><span>});</span></span><br><span></span>
This approach fails with CORS errors in the browser.
2. Server-Side Proxy Approach (Using Node.js)
javascript
<span><span>// Server-side code (Node.js)</span></span><br><span><span>app</span><span>.</span><span>post</span><span>(</span><span>'/api/adhoc'</span><span>, </span><span>async</span><span> (</span><span>req</span><span>, </span><span>res</span><span>) </span><span>=></span><span> {</span></span><br><span><span> try</span><span> {</span></span><br><span><span> const</span><span> subject</span><span> =</span><span> req</span><span>.</span><span>body</span><span>.</span><span>subject</span><span>;</span></span><br><span><span> </span></span><br><span><span> if</span><span> (</span><span>!</span><span>subject</span><span>) {</span></span><br><span><span> return</span><span> res</span><span>.</span><span>status</span><span>(</span><span>400</span><span>).</span><span>json</span><span>({ </span></span><br><span><span> status</span><span>: </span><span>'error'</span><span>, </span></span><br><span><span> message</span><span>: </span><span>'Subject is required'</span><span> </span></span><br><span><span> });</span></span><br><span><span> }</span></span><br><span><span> </span></span><br><span><span> console</span><span>.</span><span>log</span><span>(</span><span>`Creating ad-hoc conference with extension=</span><span>${</span><span>CONFIG</span><span>.</span><span>defaultExtension</span><span>}</span><span>, subject=</span><span>${</span><span>subject</span><span>}</span><span>`</span><span>);</span></span><br><span><span> </span></span><br><span><span> const</span><span> url</span><span> =</span><span> `</span><span>${</span><span>CONFIG</span><span>.</span><span>baseUrl</span><span>}</span><span>/webmeeting/api/v1/adhoc?extension=</span><span>${</span><span>CONFIG</span><span>.</span><span>defaultExtension</span><span>}</span><span>&subject=</span><span>${</span><span>encodeURIComponent</span><span>(</span><span>subject</span><span>)</span><span>}</span><span>`</span><span>;</span></span><br><span><span> </span></span><br><span><span> console</span><span>.</span><span>log</span><span>(</span><span>'Request URL:'</span><span>, </span><span>url</span><span>);</span></span><br><span><span> </span></span><br><span><span> const</span><span> response</span><span> =</span><span> await</span><span> axios</span><span>({</span></span><br><span><span> method</span><span>: </span><span>'post'</span><span>,</span></span><br><span><span> url</span><span>: </span><span>url</span><span>,</span></span><br><span><span> headers</span><span>: {</span></span><br><span><span> '3CX-ApiKey'</span><span>: </span><span>CONFIG</span><span>.</span><span>apiKey</span><span>,</span></span><br><span><span> 'Content-Length'</span><span>: </span><span>'0'</span><span>,</span></span><br><span><span> 'Accept'</span><span>: </span><span>'application/json'</span></span><br><span><span> }</span></span><br><span><span> });</span></span><br><span><span> </span></span><br><span><span> return</span><span> res</span><span>.</span><span>json</span><span>(</span><span>response</span><span>.</span><span>data</span><span>);</span></span><br><span><span> </span></span><br><span><span> } </span><span>catch</span><span> (</span><span>error</span><span>) {</span></span><br><span><span> console</span><span>.</span><span>error</span><span>(</span><span>'Error creating ad-hoc conference:'</span><span>, </span><span>error</span><span>.</span><span>message</span><span>);</span></span><br><span><span> if</span><span> (</span><span>error</span><span>.</span><span>response</span><span>) {</span></span><br><span><span> console</span><span>.</span><span>error</span><span>(</span><span>'Response data:'</span><span>, </span><span>error</span><span>.</span><span>response</span><span>.</span><span>data</span><span>);</span></span><br><span><span> console</span><span>.</span><span>error</span><span>(</span><span>'Response status:'</span><span>, </span><span>error</span><span>.</span><span>response</span><span>.</span><span>status</span><span>);</span></span><br><span><span> console</span><span>.</span><span>error</span><span>(</span><span>'Response headers:'</span><span>, </span><span>error</span><span>.</span><span>response</span><span>.</span><span>headers</span><span>);</span></span><br><span><span> }</span></span><br><span><span> res</span><span>.</span><span>status</span><span>(</span><span>500</span><span>).</span><span>json</span><span>({ </span></span><br><span><span> status</span><span>: </span><span>'error'</span><span>, </span></span><br><span><span> message</span><span>: </span><span>error</span><span>.</span><span>message</span><span>,</span></span><br><span><span> details</span><span>: </span><span>error</span><span>.</span><span>response</span><span>?.</span><span>data</span></span><br><span><span> });</span></span><br><span><span> }</span></span><br><span><span>});</span></span><br><span></span>
3. Direct curl Command
bash
<span><span>curl</span><span> -v</span><span> -X</span><span> GET</span><span> "
https://server.3cx.com.au/webmeeting/api/v1/meetings/list"</span><span> -H</span><span> "3CX-ApiKey: ***API KEY***"</span><span> -H</span><span> "Accept: application/json"</span></span><br><span></span>
Error MEssages
All approaches result in the same error:
json
<span><span>{</span></span><br><span><span> "status"</span><span>: </span><span>"error"</span><span>,</span></span><br><span><span> "errorInformation"</span><span>: </span><span>"API Authentication Failed"</span></span><br><span><span>}</span></span><br><span></span>
I've tried:
- Multiple API keys
- Different URL formats (with/without port 443)
- Multiple authentication formats (standard header, bearer token, basic auth)
- Both server-side and client-side approaches
- Different endpoints (/webmeeting/api/v1/adhoc, /webmeeting/api/v1/meetings/list)
I'm at a loss.
Are there any specific configuration requirements in the 3CX system to enable API access?
Is there a specific authentication format required beyond the "3CX-ApiKey" header?