Developer & agent API

Everything needed to build against https://class.withwind.tw: register a client yourself, get a token, call the API. No sales call, no email, no waiting for an API key — see the redirect-URI rule below for what self-serve registration covers.

Get credentials

Clients are created by dynamic client registration (RFC 7591): POST your client metadata to https://class.withwind.tw/api/oauth/register and the response carries your client_id. The authorization server advertises the same endpoint as registration_endpoint in its metadata, which is the source of truth if anything here disagrees.

Registration is open to any client redirecting to a loopback address (http://127.0.0.1:PORT/...), which covers CLI tools, desktop apps and local agents. A fixed HTTPS callback needs a registered integration — registering one is refused with invalid_redirect_uri rather than failing later at https://class.withwind.tw/oauth/authorize, so contact support or see https://docs.loopwise.com before building a hosted web client.

PurposeEndpoint
Client registrationhttps://class.withwind.tw/api/oauth/register
Authorizationhttps://class.withwind.tw/oauth/authorize
Tokenhttps://class.withwind.tw/api/oauth/token
UserInfohttps://class.withwind.tw/api/oauth/userinfo
Revocationhttps://class.withwind.tw/api/oauth/revoke

Authenticate

Authorization Code flow with PKCE (S256). Public clients use the none token-endpoint auth method, confidential clients client_secret_post.

1. Register a client:

curl -X POST https://class.withwind.tw/api/oauth/register \
  -H 'Content-Type: application/json' \
  -d '{"client_name":"My agent","application_type":"native","redirect_uris":["http://127.0.0.1:41234/callback"],"token_endpoint_auth_method":"none"}'

2. Send the person to the authorization endpoint with your PKCE challenge:

https://class.withwind.tw/oauth/authorize?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&scope=openid%20profile%20courses:read&code_challenge=CODE_CHALLENGE&code_challenge_method=S256&state=RANDOM

3. Exchange the returned code for tokens:

curl -X POST https://class.withwind.tw/api/oauth/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'grant_type=authorization_code' \
  -d 'code=AUTHORIZATION_CODE' \
  -d 'redirect_uri=YOUR_REDIRECT_URI' \
  -d 'client_id=YOUR_CLIENT_ID' \
  -d 'code_verifier=CODE_VERIFIER'

4. Call the API:

curl https://class.withwind.tw/api/oauth/userinfo \
  -H 'Authorization: Bearer ACCESS_TOKEN'

Refresh with the refresh_token grant, and revoke at https://class.withwind.tw/api/oauth/revoke (RFC 7009). Errors follow RFC 6749 §5.2: a JSON body with error and error_description; an invalid token is 401 invalid_token and a token missing a scope is 403 insufficient_scope. The full walkthrough is at /auth.md.

Scopes

ScopeGrants
openidOpenID Connect authentication
profileBasic profile information
emailEmail address
courses:readRead access to courses
courses:writeWrite access to courses
students:readRead access to students
students:writeWrite access to students
members:readRead access to members
members:writeWrite access to members
analytics:readRead access to analytics
curriculum:readRead access to curriculum
curriculum:writeWrite access to curriculum
orders:readRead access to orders
school:readRead access to school
school:writeWrite access to school
appearance:readRead access to appearance
appearance:writeWrite access to appearance
events:readRead access to events
events:writeWrite access to events
membership_plans:readRead access to membership plans
membership_plans:writeWrite access to membership plans
coupons:readRead access to coupons
coupons:writeWrite access to coupons
posts:readRead access to posts
posts:writeWrite access to posts
subscriptions:readRead access to subscriptions
subscriptions:writeWrite access to subscriptions
digital_products:readRead access to digital products
digital_products:writeWrite access to digital products
comments:readRead access to comments
lecturers:readRead access to lecturers
lecturers:writeWrite access to lecturers
storage:writeWrite access to storage
forms:readRead access to forms
pages:readRead access to pages
pages:writeWrite access to pages
account:readRead access to account
account:writeWrite access to account

Machine-readable resources

Platform-wide documentation lives at https://docs.loopwise.com. Everything above is specific to https://class.withwind.tw.