External Portal API returning -41501 on client authorization — Omada v6.2

External Portal API returning -41501 on client authorization — Omada v6.2

External Portal API returning -41501 on client authorization — Omada v6.2
External Portal API returning -41501 on client authorization — Omada v6.2
Sunday - last edited Sunday
Hardware Version:
Firmware Version: 6.2

I'm building a custom external captive portal for a resort using Omada Controller v6.2 (Docker, mbentley/omada-controller:6.2). The portal is hosted on a Node.js server and exposed via Cloudflare Tunnel. Guests connect to a WiFi SSID configured as "External Portal" and are redirected to our custom page where they enter a voucher code.

I've followed FAQ 13080 (API and Code Sample for External Portal Server, updated 2024-09-20) and I'm stuck on step 2. Here is exactly what I'm doing:

Step 1 — Operator login ✅ Working

 

POST https://{controller}:8043/{omadacId}/api/v2/hotspot/login
Body: { "name": "operator_user", "password": "operator_pass" }
Response: { "errorCode": 0, "msg": "Hotspot log in successfully.", "result": { "token": "..." } }
Set-Cookie: TPOMADA_SESSIONID=...

Note: The FAQ says to use extPortal/auth for operator login, but on v6.2 that endpoint returns HTTP 302. I found that hotspot/login is the correct operator login endpoint on v6.2 — is this documented anywhere?

Step 2 — Client authorization ❌ Always returns -41501

 

POST https://{controller}:8043/{omadacId}/api/v2/hotspot/extPortal/auth
Headers: Csrf-Token: {token}, Cookie: TPOMADA_SESSIONID={cookie}
Body:
{
  "clientMac": "B2-50-D6-64-DB-81",
  "apMac": "B0-19-21-04-1E-12",
  "ssidName": "TEST",
  "radioId": 1,
  "site": "69bca1d3470cf665361476f0",
  "authType": 3,
  "voucherCode": "7898789"
}
Response: { "errorCode": -41501, "msg": "Failed to authenticate." }

What I have verified:

  • The client MAC is actively pending on the captive portal (phone is sitting on the portal page)
  • The voucher code is valid (unlimited use, no expiry, created in Hotspot Manager)
  • The site value 69bca1d3470cf665361476f0 comes directly from Omada's own redirect URL (?site=...)
  • The CSRF token and session cookie are fresh (from the login call immediately before)
  • The same -41501 also occurs when calling http://localhost:8088/portal/auth directly with the same params
  • Tested with and without timeclientIpgatewayMacvid fields — all return -41501
  • The operator account is Admin-level, assigned to the correct site

My questions:

  1. Is extPortal/auth the correct endpoint for client authorization in v6.2, or has it changed?
  2. Does the site field in the body expect the site ID (hex), the site name, or something else?
  3. Is there a known issue with the FAQ 13080 documentation being incorrect for v6.x?
  4. Does Omada v6.2 require the client browser to be redirected back to the controller to complete auth, rather than the server calling the API directly?

Any working example or correction to the docs for v6.x would be very appreciated.

Environment:

  • Omada Controller: v6.2 (Docker, mbentley image)
  • Gateway: ER707-M2 (Gateway mode)
  • SSID configured as: External Portal → custom URL
  • Auth type: Voucher (authType 3)
  0      
0
#1
Options