Skip to content

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/oauth

Query:

  • client_id — string with the Facebook app id. Grindr's is 1273378622718674, unchanged from v25.20.0 to v26.15.1
  • redirect_uri — string with the custom-scheme URI the dialog redirects to when it finishes. fb1273378622718674://authorize/ on the Custom Tab path; fbconnect://success on the WebView path, or fbconnect://chrome_os_success on Chrome OS. fbconnect://cct.com.grindrapp.android replaces the first when the fb<app id> scheme resolves to no local activity
  • response_type — string, comma-separated. id_token,token,signed_request,graph_domain on the Custom Tab path; token,signed_request,graph_domain on the WebView path, which requests no OIDC token
  • scope — string, comma-separated permissions. Grindr requests public_profile and email, and openid is added unconditionally, so all three go out on every path, optional
  • state — string with a JSON object round-tripped for CSRF and logging: 0_auth_logger_id (a UUID), 3_method (custom_tab or web_view) and, on the Custom Tab path, 7_challenge (20 random characters, checked on the way back), optional
  • auth_type — string, always rerequest, optional
  • default_audience — string, always friends. Only meaningful for publish permissions, which Grindr does not request, optional
  • login_behavior — string, always NATIVE_WITH_FALLBACK, optional
  • sdk — string identifying the caller, e.g. android-18.1.3, optional
  • e2e — string with a JSON object holding end-to-end timing marks, e.g. {"init":<unix ms>}, optional
  • cbt — string with the client's millisecond timestamp as the dialog is built, optional
  • ies — string flag, 0 for Grindr, which ships with auto app-event logging disabled, optional
  • return_scopes — string, always true; asks the redirect to carry granted_scopes and denied_scopes, optional
  • nonce — string with a UUID, echoed inside the returned id_token. Custom Tab path only, optional
  • code_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, optional
  • code_challenge_method — string, always S256. Custom Tab path only, optional
  • display — string, always touch. WebView path only, optional
  • sso — string, always chrome_custom_tab. Custom Tab path only, optional
  • cct_prefetching — string flag, 1 when Custom Tabs prefetching is enabled, 0 otherwise, optional
  • cct_over_app_switch — string, always 1 when present. Custom Tab path only, and only after a native app-switch handler bailed out with error=logged_out; otherwise the key is absent, optional
  • access_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_token

Query:

  • code — string with the authorization code from the dialog redirect
  • client_id — string with the Facebook app id, 1273378622718674 for Grindr
  • redirect_uri — string, the same redirect URI the dialog was opened with
  • code_verifier — string, the 43-128 character PKCE verifier whose S256 hash was sent as code_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}/me

Query:

  • fields — string, comma-separated. id,name,first_name,middle_name,last_name for a Facebook-domain token; id,name,profile_picture for an Instagram-domain one, which Grindr never requests, optional
  • access_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.

Open Grind is not affiliated with Grindr in any way.