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
2 weeks ago - last edited a week ago
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
1 Accepted Solution
Re:External Portal API returning -41501 on client authorization — Omada v6.2-Solution
a week ago - last edited a week ago

Hi  @Krade 

 

Thanks for posting here.

Is your idea something like this: configure an External Portal Server that only provides a webpage, and ultimately the Voucher is passed to the Controller via an API call, allowing the Controller to handle authentication and grant access to the device?

This approach differs from the design intent of our External Portal Server. Our design requires all authentication functions to be handled externally, with the final step being a call to extportal/auth to release the client. In short, this interface is intended to be called only after the external system has completed the entire authentication process. The method you are describing is not supported by our system.

We recommend using the Portal Server to perform voucher validation independently, which means using "authType": 4

Recommended Solution
  0  
0
#2
Options
3 Reply
Re:External Portal API returning -41501 on client authorization — Omada v6.2-Solution
a week ago - last edited a week ago

Hi  @Krade 

 

Thanks for posting here.

Is your idea something like this: configure an External Portal Server that only provides a webpage, and ultimately the Voucher is passed to the Controller via an API call, allowing the Controller to handle authentication and grant access to the device?

This approach differs from the design intent of our External Portal Server. Our design requires all authentication functions to be handled externally, with the final step being a call to extportal/auth to release the client. In short, this interface is intended to be called only after the external system has completed the entire authentication process. The method you are describing is not supported by our system.

We recommend using the Portal Server to perform voucher validation independently, which means using "authType": 4

Recommended Solution
  0  
0
#2
Options
Re:External Portal API returning -41501 on client authorization — Omada v6.2
a week ago

  @Vincent-TP Thanks for the reply! Yes, I eventually figured it out after a few hours of troubleshooting and brainstorming with Claude Code. In the end, we decided to use the Open API to authenticate the vouchers instead. Looking back, we basically reinvented the wheel with glitter and unicorns just to use a personalized domain instead of the built-in authentication via the LAN IP 😂

  0  
0
#3
Options
Re:External Portal API returning -41501 on client authorization — Omada v6.2
a week ago

  @Krade 

Glad you found a solution! The journey of adding “glitter and unicorns” to reinvent the wheel does sound familiar. Thanks for the update.

Krade wrote

  @Vincent-TP Thanks for the reply! Yes, I eventually figured it out after a few hours of troubleshooting and brainstorming with Claude Code. In the end, we decided to use the Open API to authenticate the vouchers instead. Looking back, we basically reinvented the wheel with glitter and unicorns just to use a personalized domain instead of the built-in authentication via the LAN IP 😂

 

  0  
0
#4
Options