OAuth and AAA Endpoint Reference
This page documents the externally supported OAuth and AAA integration endpoints. For field-level definitions see Data models.
All API endpoints are HTTPS-only and require API key headers.
- Management provisioning endpoints use
X-API-Key. - AAA callback uses integration callback key via
X-API-Key(orX-WispHive-Token).
If your team does not want to build against API docs, use the WispHive dashboard UI to configure integrations without writing code.
1. Create hosted OAuth integration
POST /api/v1/oauth/integrations/hosted
Creates a WispHive-hosted OAuth integration. This is the mode where your captive portal points to a WispHive auth-domain URL and WispHive manages the browser entry point.
Required header
X-API-Key
Example request
{
"registration_id": "sme_1ab23cd45ef6",
"entity_name": "Acme SME",
"provider_name": "google",
"oauth_authorize_url": "https://accounts.google.com/o/oauth2/v2/auth",
"oauth_token_url": "https://oauth2.googleapis.com/token",
"oauth_jwks_url": "https://www.googleapis.com/oauth2/v3/certs",
"oauth_client_id": "1234567890-abc123.apps.googleusercontent.com",
"oauth_client_secret": "replace-with-real-secret",
"oauth_scope": "openid profile email",
"oauth_audience": "1234567890-abc123.apps.googleusercontent.com",
"third_party_provider_url": "https://console.cloud.google.com"
}
Example response
{
"success": true,
"integration": {
"id": "oi_a83e52a5ffed1d",
"integration_mode": "hosted_oauth",
"callback_url": "https://auth.samwifi.site/oauth/FA2D7/a5e7f-f3a511-2a9fd2",
"hosted_login_url": "https://auth.samwifi.site/oauth/start/sme_1ab23cd45ef6-4fd388b2",
"derived_name": "acme-sme-cd45ef",
"derived_email_domain": "acme-sme-cd45ef.id.wisphive.net",
"derived_username_format": "acme-sme-cd45ef-{alias}"
}
}
2. Create self-hosted OAuth integration
POST /api/v1/oauth/integrations/self-hosted
Uses the same standards-based authorize/token/JWKS request fields as hosted
OAuth, but records integration_mode=self_hosted_oauth for entities that host
their OAuth provider endpoints themselves. WispHive retains the signed state,
callback, and captive-portal redirect orchestration.
The response includes a self_hosted_login_url.
3. Create AAA handoff integration
POST /api/v1/oauth/integrations/aaa-handoff
Creates a signed callback contract for organizations that keep their own OAuth login domain and POST the authenticated user back to WispHive.
Required header
X-API-Key
Example request
{
"registration_id": "edu_1ab23cd45ef6",
"entity_name": "North Campus",
"provider_name": "google",
"client_oauth_entry_url": "https://login.north-campus.example/oauth/start",
"captive_portal_url": "https://portal.north-campus.example"
}
Example response
{
"success": true,
"integration": {
"id": "ah_8fa31d4c1b92d0",
"integration_mode": "aaa_handoff",
"callback_url": "https://auth.samwifi.site/cp/rdt/cp-6a3e91fa6c1b/A29-U1N7W90A",
"wisphive_token": "WH_Oid-a67d39t78sqcaRedsWte9_Kl90klhgyr37gHgfw-uiDlc35j9yUfa",
"idempotency_required": true,
"derived_name": "acme-sme-cd45ef",
"derived_email_domain": "acme-sme-cd45ef.id.wisphive.net",
"derived_username_format": "acme-sme-cd45ef-{alias}"
}
}
4. Start brokered OAuth login
GET /oauth/start/{integration_id}
Starts the browser redirect to the configured provider authorization endpoint
for either hosted_oauth or self_hosted_oauth. This route is intended for
browser navigation from a captive portal.
Optional query parameters
return_to? optional URL used for post-auth redirect orchestration.
5. Submit AAA handoff callback
POST /cp/rdt/{callback_slug}/{callback_token}
Used by your backend after your own OAuth provider authenticates the user. The callback must contain only derived, non-sensitive user identifiers, and those identifiers must use the WispHive-assigned namespace and email domain returned when the integration was created.
Required header
X-API-Key(preferred) orX-WispHive-TokenIdempotency-Key
Example request body
{
"entity_name": "Acme SME",
"userid": "4d57d5f0-b73f-4d84-b5d2-a06d7701f931",
"derived_username": "acme-sme-cd45ef-user-94a7c1",
"derived_email": "acme-sme-cd45ef-user-94a7c1@acme-sme-cd45ef.id.wisphive.net",
"user_session_id": "sess_01J2Y8M92XH6Q3W6C2P9R4A7NN",
"wisphive_token": "WH_Oid-a67d39t78sqcaRedsWte9_Kl90klhgyr37gHgfw-uiDlc35j9yUfa"
}
Example response
{
"success": true,
"integration_id": "ah_8fa31d4c1b92d0",
"event_id": "1722487101867-0",
"redirect_url": "https://auth.samwifi.site/openid/cp/gAAAAABo...",
"expires_in_seconds": 300
}
Language examples
cURL
curl -X POST "https://auth.samwifi.site/api/v1/oauth/integrations/aaa-handoff" \
-H "X-API-Key: <management-api-key>" \
-H "Content-Type: application/json" \
-d '{
"registration_id": "isp_1ab23cd45ef6",
"entity_name": "MetroFiber ISP",
"provider_name": "microsoft-entra",
"client_oauth_entry_url": "https://login.metrofiber.example/oauth2/start",
"captive_portal_url": "https://portal.metrofiber.example"
}'
Python
import requests
payload = {
"registration_id": "sme_1ab23cd45ef6",
"entity_name": "Acme SME",
"provider_name": "google",
"oauth_authorize_url": "https://accounts.google.com/o/oauth2/v2/auth",
"oauth_token_url": "https://oauth2.googleapis.com/token",
"oauth_jwks_url": "https://www.googleapis.com/oauth2/v3/certs",
"oauth_client_id": "1234567890-abc123.apps.googleusercontent.com",
"oauth_client_secret": "replace-with-real-secret",
}
resp = requests.post(
"https://auth.samwifi.site/api/v1/oauth/integrations/hosted",
headers={"X-API-Key": "<management-api-key>"},
json=payload,
timeout=15,
)
resp.raise_for_status()
print(resp.json())
Node.js
const response = await fetch("https://auth.samwifi.site/api/v1/oauth/integrations/aaa-handoff", {
method: "POST",
headers: { "Content-Type": "application/json", "X-API-Key": "<management-api-key>" },
body: JSON.stringify({
registration_id: "edu_1ab23cd45ef6",
entity_name: "North Campus",
provider_name: "google",
client_oauth_entry_url: "https://login.north-campus.example/oauth/start",
captive_portal_url: "https://portal.north-campus.example"
})
});
console.log(await response.json());
Go
payload := []byte(`{"registration_id":"sme_1ab23cd45ef6","provider_name":"google","oauth_authorize_url":"https://accounts.google.com/o/oauth2/v2/auth","oauth_token_url":"https://oauth2.googleapis.com/token","oauth_jwks_url":"https://www.googleapis.com/oauth2/v3/certs","oauth_client_id":"1234567890-abc123.apps.googleusercontent.com","oauth_client_secret":"replace-with-real-secret"}`)
req, _ := http.NewRequest(http.MethodPost, "https://auth.samwifi.site/api/v1/oauth/integrations/hosted", bytes.NewBuffer(payload))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-API-Key", "<management-api-key>")
Java
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://auth.samwifi.site/api/v1/oauth/integrations/aaa-handoff"))
.header("Content-Type", "application/json")
.header("X-API-Key", "<management-api-key>")
.POST(HttpRequest.BodyPublishers.ofString(json))
.build();