OAuth & Sign in with Sporty

MCP and AI clients

Dynamic client registration, and what a self-registered client can and cannot do.

An agent connecting to Sporty has no human available to fill in a registration form first, so Sporty supports RFC 7591 dynamic client registration. A client registers itself, then runs the ordinary authorization code flow.

Dynamic registration is not enabled on every environment. If it is off you get 403 access_denied, and the way in is a client registered by a club administrator instead.

Registering

curl -X POST https://api.sporty.plus/oauth2/register \
  -H 'Content-Type: application/json' \
  -d '{
    "client_name": "My Agent",
    "redirect_uris": ["http://127.0.0.1:8976/callback"],
    "client_uri": "https://myagent.example",
    "contacts": ["you@example.com"]
  }'
{
  "client_id": "01a09ad5-1469-7260-8157-bba3655a2fdf",
  "client_id_issued_at": 1789304059,
  "client_name": "My Agent",
  "redirect_uris": ["http://127.0.0.1:8976/callback"],
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"],
  "token_endpoint_auth_method": "none",
  "scope": "openid profile email me.read me.reservations.read"
}

There is no client_secret: a self-registered client is public, and PKCE is what protects it. Loopback redirect URIs are allowed precisely for this case, and the port is ignored when matching.

Discovery for a plain OAuth client is at https://api.sporty.plus/.well-known/oauth-authorization-server, and the resource you are reaching for is described at /.well-known/oauth-protected-resource.

What a self-registered client is limited to

All of this is deliberate, and none of it is negotiable per client:

  • Public and PKCE-only. No secret exists to leak.
  • authorization_code and refresh_token only. Never client_credentials — an agent never acts with no member present.
  • openid, profile, email and me.* only. It can never ask for a club's data. An integration that needs club.* is one a club administrator registers. All of the me.* scopes are available (on /me):
    • the member's profile;
    • their bookings, and booking or cancelling a court for them;
    • their match results;
    • their clubs and memberships.

    An agent booking for a member should show them the price. When needs_payment is true, it should tell them they pay in the Sporty app.
  • Consent is never skipped, even for a member who has approved it before.
  • Short-lived tokens — fifteen minutes, refreshable for a day.
  • Rate-limited registration, a handful per hour per address.

Pending review

A self-registered client is pending, and a pending client works only for the account that registered it.

That is what makes open registration safe rather than alarming: you can build and test the whole flow immediately, and until we have looked at your application nobody else's account is reachable by it. The member is also told on the consent screen that the application has not been reviewed.

When you want it available to other people, get in touch. Review is a conversation about what your agent does and which scopes it genuinely needs, not a form.