API-referentie
Authenticatie
De Tidal Control API gebruikt Bearer-tokens voor authenticatie. Tokens worden uitgegeven door de Keycloak-realm van je tenant via de OAuth 2.0 Device Authorization Grant (RFC 8628). Deze flow is ontworpen voor scripts en CLI-tools die zelf geen browservenster kunnen openen.
Vereisten
Je hebt je tenantnaam nodig — de Keycloak-realm-identifier van je organisatie. Dit is de organisatie-identifier in je portal-URL:
https://portal.tidalcontrol.com/{jouw-tenant}/
Als je portal-URL bijvoorbeeld https://portal.tidalcontrol.com/demo/ is, is je tenantnaam demo.
Vervang in deze handleiding {jouw-tenant} door je eigen tenantnaam.
De authenticatiestroom
De Device Authorization Grant werkt in drie stappen:
- Je script vraagt een apparaatcode op bij Keycloak
- Jij (of de gebruiker van het script) logt in via een browser-URL
- Je script pollt op het toegangstoken zodra de inlog is voltooid
Stap 1 — Apparaatcode opvragen
curl -X POST \
"https://auth.tidalcontrol.com/realms/{jouw-tenant}/protocol/openid-connect/auth/device" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=portal&scope=openid"
Antwoord:
{
"device_code": "...",
"user_code": "ABCD-1234",
"verification_uri": "https://auth.tidalcontrol.com/realms/{jouw-tenant}/device",
"verification_uri_complete": "https://auth.tidalcontrol.com/realms/{jouw-tenant}/device?user_code=ABCD-1234",
"expires_in": 600,
"interval": 5
}
Stap 2 — Inloggen via browser
Open verification_uri_complete in een browser en log in met je Tidal Control-gegevens. Je script wacht terwijl je dit doet.
Stap 3 — Pollen op het token
Poll het token-endpoint elke interval seconden totdat de inlog is voltooid:
curl -X POST \
"https://auth.tidalcontrol.com/realms/{jouw-tenant}/protocol/openid-connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=urn:ietf:params:oauth:grant-type:device_code&client_id=portal&device_code={device_code}"
Zodra de gebruiker is ingelogd, bevat het antwoord je toegangstoken:
{
"access_token": "eyJhbGci...",
"expires_in": 300,
"refresh_token": "eyJhbGci...",
"refresh_expires_in": 1800,
"token_type": "Bearer"
}
Toegangstokens verlopen na 5 minuten. Gebruik de refresh_token om een nieuw toegangstoken op te halen zonder opnieuw in te loggen (zie hieronder).
API-verzoeken versturen
Voeg het toegangstoken toe als Bearer-header aan elk GraphQL-verzoek:
curl -X POST https://portal.tidalcontrol.com/graphql \
-H "Authorization: Bearer {toegangstoken}" \
-H "Content-Type: application/json" \
-d '{"query": "{ tenant { name displayName } }"}'
Volledig Python-voorbeeld
Dit script doorloopt de volledige authenticatiestroom en hergebruikt het token:
import requests
import time
import json
TENANT = "{jouw-tenant}"
BASE_URL = f"https://auth.tidalcontrol.com/realms/{TENANT}/protocol/openid-connect"
CLIENT_ID = "portal"
GRAPHQL_URL = "https://portal.tidalcontrol.com/graphql"
def get_token():
# Stap 1: Apparaatcode opvragen
r = requests.post(
f"{BASE_URL}/auth/device",
data={"client_id": CLIENT_ID, "scope": "openid"},
)
r.raise_for_status()
device = r.json()
print(f"\nOpen deze URL in je browser om in te loggen:")
print(f" {device['verification_uri_complete']}\n")
# Stap 2: Pollen op token
interval = device.get("interval", 5)
deadline = time.time() + device["expires_in"]
while time.time() < deadline:
time.sleep(interval)
r = requests.post(
f"{BASE_URL}/token",
data={
"grant_type": "urn:ietf:params:oauth:grant-type:device_code",
"client_id": CLIENT_ID,
"device_code": device["device_code"],
},
)
if r.status_code == 200:
print("Authenticatie geslaagd.")
return r.json()
body = r.json()
if body.get("error") == "authorization_pending":
continue
if body.get("error") == "slow_down":
interval += 5
continue
r.raise_for_status()
raise RuntimeError("Authenticatie verlopen.")
def refresh_token(refresh_tok):
r = requests.post(
f"{BASE_URL}/token",
data={
"grant_type": "refresh_token",
"client_id": CLIENT_ID,
"refresh_token": refresh_tok,
},
)
r.raise_for_status()
return r.json()
def graphql(query, variables, access_token):
r = requests.post(
GRAPHQL_URL,
json={"query": query, "variables": variables},
headers={"Authorization": f"Bearer {access_token}"},
)
r.raise_for_status()
result = r.json()
if "errors" in result:
raise RuntimeError(result["errors"])
return result["data"]
if __name__ == "__main__":
token = get_token()
data = graphql("{ tenant { name displayName } }", {}, token["access_token"])
print(json.dumps(data, indent=2))
Token vernieuwen
Wanneer het toegangstoken verloopt, gebruik je het refresh-token in plaats van de volledige inlogstroom opnieuw te doorlopen:
token = refresh_token(token["refresh_token"])
access_token = token["access_token"]
Refresh-tokens verlopen ook (doorgaans na 30 minuten inactiviteit). Als een refresh mislukt, doorloop dan opnieuw de volledige get_token()-stroom.
- Vorige
- Troubleshooting & FAQ
- Volgende
- Data opvragen