Skip to main content

API Implementation Examples (Several Languages)

This guide provides implementation-ready examples for integrating WispHive OAuth APIs in multiple languages.

OAuth process visual guide

Scenario A: Create a hosted OAuth integration

Endpoint: POST /api/v1/oauth/integrations/hosted

Required headers:

  • X-API-Key: <management-api-key>
  • Content-Type: application/json

cURL

curl -X POST "https://auth.samwifi.site/api/v1/oauth/integrations/hosted" \
-H "X-API-Key: <management-api-key>" \
-H "Content-Type: application/json" \
-d '{
"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"
}'

Python (requests)

import requests

url = "https://auth.samwifi.site/api/v1/oauth/integrations/hosted"
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",
"oauth_scope": "openid profile email",
}

response = requests.post(
url,
headers={"X-API-Key": "<management-api-key>"},
json=payload,
timeout=20,
)
response.raise_for_status()
print(response.json())

Node.js (fetch)

const 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",
oauth_scope: "openid profile email"
};

const res = await fetch("https://auth.samwifi.site/api/v1/oauth/integrations/hosted", {
method: "POST",
headers: { "Content-Type": "application/json", "X-API-Key": "<management-api-key>" },
body: JSON.stringify(payload)
});

if (!res.ok) {
throw new Error(`HTTP ${res.status}`);
}

console.log(await res.json());

Go (net/http)

package main

import (
"bytes"
"fmt"
"io"
"net/http"
)

func main() {
body := []byte(`{
"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"
}`)

req, _ := http.NewRequest(http.MethodPost, "https://auth.samwifi.site/api/v1/oauth/integrations/hosted", bytes.NewBuffer(body))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-API-Key", "<management-api-key>")

resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()

out, _ := io.ReadAll(resp.Body)
fmt.Println(string(out))
}

Java (Java 11 HttpClient)

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class HostedOauthExample {
public static void main(String[] args) throws Exception {
String json = """
{
"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"
}
""";

HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://auth.samwifi.site/api/v1/oauth/integrations/hosted"))
.header("Content-Type", "application/json")
.header("X-API-Key", "<management-api-key>")
.POST(HttpRequest.BodyPublishers.ofString(json))
.build();

HttpResponse<String> resp = HttpClient.newHttpClient().send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());
}
}

Scenario B: Submit AAA handoff callback

Endpoint: POST /cp/rdt/{callback_slug}/{callback_token}

Required:

  • Callback API key in X-API-Key header (preferred), or X-WispHive-Token, or wisphive_token body field
  • Idempotency-Key header
  • Derived-only identity fields (derived_username, derived_email, user_session_id)

Python

import uuid
import requests

callback_url = "https://auth.samwifi.site/cp/rdt/cp-6a3e91fa6c1b/A29-U1N7W90A"
headers = {
"Content-Type": "application/json",
"X-API-Key": "WH_Oid-a67d39t78sqcaRedsWte9_Kl90klhgyr37gHgfw-uiDlc35j9yUfa",
"Idempotency-Key": str(uuid.uuid4()),
}
payload = {
"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",
}

res = requests.post(callback_url, headers=headers, json=payload, timeout=10)
res.raise_for_status()
print(res.json())

Node.js

import crypto from "node:crypto";

const callbackUrl = "https://auth.samwifi.site/cp/rdt/cp-6a3e91fa6c1b/A29-U1N7W90A";

const response = await fetch(callbackUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": "WH_Oid-a67d39t78sqcaRedsWte9_Kl90klhgyr37gHgfw-uiDlc35j9yUfa",
"Idempotency-Key": crypto.randomUUID()
},
body: JSON.stringify({
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"
})
});

console.log(await response.json());

C#

using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;

var client = new HttpClient();
var callbackUrl = "https://auth.samwifi.site/cp/rdt/cp-6a3e91fa6c1b/A29-U1N7W90A";

var payload = new
{
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"
};

var req = new HttpRequestMessage(HttpMethod.Post, callbackUrl);
req.Headers.Add("X-API-Key", "WH_Oid-a67d39t78sqcaRedsWte9_Kl90klhgyr37gHgfw-uiDlc35j9yUfa");
req.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString());
req.Content = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");

var resp = await client.SendAsync(req);
resp.EnsureSuccessStatusCode();
Console.WriteLine(await resp.Content.ReadAsStringAsync());

Production implementation checklist

  • If your team prefers no-code onboarding, use the WispHive dashboard UI to configure providers and callback contracts.
  • Treat wisphive_token as a secret and rotate via your security process.
  • Always set an Idempotency-Key for callback POSTs.
  • Apply short HTTP timeouts and retry only safe/idempotent calls.
  • Keep provider client credentials in secure secret storage.
  • Log correlation IDs, not secrets or direct user PII.