Facebook
Facebook endpoints reached while signing in. Served by Meta, not Grindr — documented because the resulting access token is what Login via third party consumes as thirdPartyToken.
Facebook login dialog
Facebook's OAuth authorization dialog — the only step of Sign in with Facebook served by Meta over HTTP, and the source of the thirdPartyToken that Grindr's backend consumes.
{graphApiVersion} tracks the Graph API version of the bundled Facebook SDK: v16.0 with SDK 18.1.3 (app v26.9.2), v14.0 with 14.1.1 (v25.20.0).
Two variants reach this URL and their parameter sets differ; parameters specific to one say so below, everything else is sent by both. The Custom Tab variant redirects to fb1273378622718674://authorize/ and uses PKCE. The WebView variant redirects to the app-independent constant fbconnect://success (fbconnect://chrome_os_success on Chrome OS) and uses no PKCE.
On completion the browser is redirected to redirect_uri with the result in the fragment (or query): access_token, expires_in, data_access_expiration_time, granted_scopes, denied_scopes, expired_scopes, graph_domain and signed_request on success, or error/error_type, error_msg/error_message/error_description and error_code on failure. A redirect carrying a code and no access_token is exchanged at Exchange Facebook auth code. Only the access-token string is needed for the Grindr sign-in that follows.
Two further Graph calls precede any login and are not documented as operations here, because neither is on the path of obtaining a token: GET /{graphApiVersion}/app?fields=… (app settings, which supply the cct_prefetching value and the dialog configs) and GET /{graphApiVersion}/app/mobile_sdk_gk?platform=android&sdk_version=…&fields=gatekeepers. Both carry the app access token and are cached on the device.
No key hash, package name or app signature is computed or transmitted anywhere in this flow.
GET https://m.facebook.com/{graphApiVersion}/dialog/oauthQuery:
client_id— string with the Facebook app id. Grindr's is1273378622718674, unchanged from v25.20.0 to v26.15.1redirect_uri— string with the custom-scheme URI the dialog redirects to when it finishes.fb1273378622718674://authorize/on the Custom Tab path;fbconnect://successon the WebView path, orfbconnect://chrome_os_successon Chrome OS.fbconnect://cct.com.grindrapp.androidreplaces the first when thefb<app id>scheme resolves to no local activityresponse_type— string, comma-separated.id_token,token,signed_request,graph_domainon the Custom Tab path;token,signed_request,graph_domainon the WebView path, which requests no OIDC tokenscope— string, comma-separated permissions. Grindr requestspublic_profileandemail, andopenidis added unconditionally, so all three go out on every path, optionalstate— string with a JSON object round-tripped for CSRF and logging:0_auth_logger_id(a UUID),3_method(custom_taborweb_view) and, on the Custom Tab path,7_challenge(20 random characters, checked on the way back), optionalauth_type— string, alwaysrerequest, optionaldefault_audience— string, alwaysfriends. Only meaningful for publish permissions, which Grindr does not request, optionallogin_behavior— string, alwaysNATIVE_WITH_FALLBACK, optionalsdk— string identifying the caller, e.g.android-18.1.3, optionale2e— string with a JSON object holding end-to-end timing marks, e.g.{"init":<unix ms>}, optionalcbt— string with the client's millisecond timestamp as the dialog is built, optionalies— string flag,0for Grindr, which ships with auto app-event logging disabled, optionalreturn_scopes— string, alwaystrue; asks the redirect to carrygranted_scopesanddenied_scopes, optionalnonce— string with a UUID, echoed inside the returnedid_token. Custom Tab path only, optionalcode_challenge— string, the S256 PKCE challenge derived from a 43-128 character verifier. Custom Tab path only; the WebView path sends no PKCE at all, optionalcode_challenge_method— string, alwaysS256. Custom Tab path only, optionaldisplay— string, alwaystouch. WebView path only, optionalsso— string, alwayschrome_custom_tab. Custom Tab path only, optionalcct_prefetching— string flag,1when Custom Tabs prefetching is enabled,0otherwise, optionalcct_over_app_switch— string, always1when present. Custom Tab path only, and only after a native app-switch handler bailed out witherror=logged_out; otherwise the key is absent, optionalaccess_token— string with a cached Facebook access token, sent to let Facebook skip re-authentication when it is still valid, optional
Response:
Facebook's login and consent page. The result is read from the redirect_uri navigation, not from this body.
Exchange Facebook auth code, WIP
NOTE
This endpoint hasn't been researched yet
PKCE authorization-code exchange, reached whenever a redirect comes back with a code and no access_token — from Facebook login dialog on the Custom Tab path, or from a native app-switch handler, which forwards a code challenge of its own without ever loading that URL. The WebView path carries no PKCE and so never reaches here.
Being a Graph call it also carries sdk=android, format=json and an app access token access_token=<app id>|<client token> — for Grindr 1273378622718674|5524d0b5439620826256ca48978b95a3, both halves shipped in the APK's string resources and unchanged from v25.20.0 to v26.15.1.
The access_token from the response is what ends up in thirdPartyToken on Login via third party.
Response type: FacebookAccessTokenResponse (undocumented).
GET https://graph.facebook.com/{graphApiVersion}/oauth/access_tokenQuery:
code— string with the authorization code from the dialog redirectclient_id— string with the Facebook app id,1273378622718674for Grindrredirect_uri— string, the same redirect URI the dialog was opened withcode_verifier— string, the 43-128 character PKCE verifier whose S256 hash was sent ascode_challenge
Response:
Standard Facebook OAuth token payload carrying access_token and its lifetime.
Fetch Facebook profile, WIP
NOTE
This endpoint hasn't been researched yet
Fetched after every successful login: the freshly minted user access token is sent here and the profile cached.
Nothing in the Grindr sign-in path reads the result — the identity Grindr uses is the thirdPartyUserInfo its own backend returns from Login via third party — so a re-implementation that only needs the access token can skip this call.
GET https://graph.facebook.com/{graphApiVersion}/meQuery:
fields— string, comma-separated.id,name,first_name,middle_name,last_namefor a Facebook-domain token;id,name,profile_picturefor an Instagram-domain one, which Grindr never requests, optionalaccess_token— string, the user access token just obtained
Response:
Facebook profile JSON for the fields requested.
Facebook OIDC keys, WIP
NOTE
This endpoint hasn't been researched yet
OIDC JSON Web Key Set, fetched to verify the id_token that Facebook login dialog returns on the Custom Tab and native app-switch paths: the signature is checked against the key matching the JWT header's kid.
Unversioned and unauthenticated — no app id, client token or user token is sent. The WebView path asks for no id_token and never reaches it, and Grindr never reads the id_token.
GET https://www.facebook.com/.well-known/oauth/openid/keys/Response:
JWKS document.