Toegang
Authenticatie
Elk endpoint vraagt een bearer-token, op twee na: de specificatie en de voorwaarden. Een ppl_live_-token werkt op de REST-API en op de MCP-server; een OAuth-token alleen op de MCP-server.
Het token meesturen
Stuur het token mee in de Authorization-header, bij elk verzoek:
Authorization: Bearer ppl_live_...Zonder header, met een onbekend of ingetrokken token krijg je 401 unauthorized. Een geldig token zonder het recht dat het endpoint vraagt krijgt 403 forbidden. Zet een token nooit in een URL of in code die bij gebruikers draait.
Rechten (scopes)
Een token draagt een of meer rechten. Elk endpoint vraagt er precies één; in de referentie staat bij elk endpoint welke.
| Recht | Wie het kan krijgen | Wat het opent |
|---|---|---|
read | Elke organisatie in het portaal; via OAuth iedereen (Alleen lezen). | De openbare agenda, je eigen events en je token. (16 endpoints) |
scan | Organisaties in het portaal; via OAuth de rollen aan de deur. | Tickets valideren en op gebruikt zetten aan de deur. (1 endpoint) |
attendance | Organisaties in het portaal; via OAuth de rollen die events bewerken. | Aantallen gaan, interesse en tickets van je eigen events, en externe verkoop doorgeven. (3 endpoints) |
tickets | Organisaties in het portaal, voor een koppeling met hun eigen ticketshop. Nooit via OAuth. | De ticketlijst van je eigen shop aanleveren, zodat tickets bij de koper in de app komen. (2 endpoints) |
admin | Alleen het platform zelf, in /admin/api of als beheerder via OAuth. | Het werk van het agenda-team. |
OAuth 2.1 met PKCE (voor de MCP-server)
Voor de MCP-server is er OAuth 2.1, zodat een assistent kan koppelen zonder dat iemand een token kopieert. Wat er is geïmplementeerd:
- Authorization code met PKCE, alleen
S256. Geen implicit flow en geen wachtwoorden. - Dynamische registratie van clients (RFC 7591) op
/oauth/register. Een redirect-URI is https, of http op een loopback-adres (localhost,127.0.0.1,[::1]) met elke poort. - Resource indicators (RFC 8707): een token is uitgegeven voor
https://partyppl.nl/mcpen werkt nergens anders, ook niet op de REST-API. - Metadata volgens RFC 8414 en RFC 9728, en
issin het antwoord (RFC 9207). - Een access token (
ppl_oat_) leeft 60 minuten; een refresh token (ppl_ort_) 30 dagen en wordt bij elk gebruik vervangen. Een autorisatiecode is 60 seconden geldig en één keer te gebruiken; het verzoek wacht 10 minuten tot de gebruiker heeft ingelogd en ja gezegd. - Intrekken via
/oauth/revoke(RFC 7009), of door de gebruiker zelf bij Gekoppelde apps in zijn instellingen.
Wat een koppeling mag, beslist de gebruiker op de toestemmingspagina, op basis van zijn rol: Alleen lezen geeft read; een organisatie geeft wat die rol daar mag (read, en attendance en scan voor de rollen die events bewerken of aan de deur staan). Verandert de rol, dan verandert wat het token mag, bij het volgende verzoek. Het recht tickets wordt nooit via OAuth gegeven.
De metadata van de autorisatieserver, zoals deze server hem uitgeeft:
{
"issuer": "https://partyppl.nl",
"authorization_endpoint": "https://partyppl.nl/oauth/authorize",
"token_endpoint": "https://partyppl.nl/oauth/token",
"registration_endpoint": "https://partyppl.nl/oauth/register",
"revocation_endpoint": "https://partyppl.nl/oauth/revoke",
"response_types_supported": [
"code"
],
"response_modes_supported": [
"query"
],
"grant_types_supported": [
"authorization_code",
"refresh_token"
],
"token_endpoint_auth_methods_supported": [
"none",
"client_secret_post",
"client_secret_basic"
],
"revocation_endpoint_auth_methods_supported": [
"none",
"client_secret_post",
"client_secret_basic"
],
"code_challenge_methods_supported": [
"S256"
],
"scopes_supported": [
"read",
"attendance",
"scan",
"admin"
],
"authorization_response_iss_parameter_supported": true,
"service_documentation": "https://partyppl.nl/api",
"ui_locales_supported": [
"nl",
"en"
]
}De flow in stappen
Een MCP-client als Claude doet dit zelf. Bouw je je eigen client, dan zijn dit de stappen:
- Vraag
/mcpzonder token. Het antwoord is401met eenWWW-Authenticate-header die naar de metadata van de resource wijst. - Lees
/.well-known/oauth-protected-resourceen daarna/.well-known/oauth-authorization-server. - Registreer je client met
POST /oauth/registeren bewaar declient_id. - Maak een
code_verifieren de bijbehorendecode_challenge(SHA-256, base64url), en stuur de gebruiker naar/oauth/authorizemetresponse_type=code,client_id,redirect_uri,code_challenge,code_challenge_method=S256,stateenresource. - Na ja komt de gebruiker terug op je
redirect_urimetcode,stateeniss. Controleerstateeniss. - Wissel de code in met
POST /oauth/token(grant_type=authorization_code,code,redirect_uri,client_id,code_verifier), alsapplication/x-www-form-urlencoded. - Stuur het access token mee naar
/mcp. Verlopen? Vraag een nieuw metgrant_type=refresh_token.
# 1. PKCE
verifier=$(openssl rand -base64 48 | tr -d '=+/' | cut -c1-64)
challenge=$(printf %s "$verifier" | openssl dgst -sha256 -binary | openssl base64 | tr '+/' '-_' | tr -d '=')
# 2. Register a client
curl -s -X POST "https://partyppl.nl/oauth/register" \
-H "Content-Type: application/json" \
-d '{"client_name":"My app","redirect_uris":["http://127.0.0.1:8765/callback"]}'
# 3. Send the person to the consent page (in a browser)
# https://partyppl.nl/oauth/authorize?response_type=code&client_id=$CLIENT_ID
# &redirect_uri=http%3A%2F%2F127.0.0.1%3A8765%2Fcallback
# &code_challenge=$challenge&code_challenge_method=S256&state=$STATE
# &resource=https://partyppl.nl/mcp
# 4. Exchange the code
curl -s -X POST "https://partyppl.nl/oauth/token" \
-d grant_type=authorization_code -d code="$CODE" -d client_id="$CLIENT_ID" \
-d redirect_uri=http://127.0.0.1:8765/callback -d code_verifier="$verifier"Bijgewerkt