Skip to main content

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 (or X-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) or X-WispHive-Token
  • Idempotency-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();