Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Social Graph

Preview Base URL: https://socialgraph.stackwell.tech

Overview

Social Graph keeps the connections between people who use Stackwell apps, and lets an app read a person’s connections once that person approves it.

  1. You register a graph app with Social Graph.
  2. Your app sends the person to Social Graph’s approval page. They sign in with their ChirpAuth account and approve or deny your app.
  3. If they approve, your app exchanges the one-time code it gets back for an access token.
  4. With that token your app reads the person’s profile and connections, checks whether they are connected to someone, and finds which of their connections also use your app.

Your app cannot add or remove anyone’s connections. People appear to your app under ids that belong to your app (psd_...).

It is for developers of apps that want to start from the people a user already knows, instead of asking them to rebuild their contacts.

What preview means here: Social Graph runs in production, and Stackwell’s own services use it. It is not yet open to outside developers:

  • Registering a graph app needs a ChirpAuth developer account and a sign-in from Stackwell’s developer tool. Neither is open to outside developers yet, so there is no self-serve way to register an app.
  • The Social Graph web app only signs people in, shows the approval page, makes invite links for a person to send themselves, and accepts them. There is no screen yet where a person can see their connections or the apps they have approved.

Concepts and Data and privacy mark the other gaps “Not yet”.

Quickstart

This walks one person through approving your app, and reads their connections.

1. Check that Social Graph is reachable

No credentials needed:

curl -fsS https://socialgraph.stackwell.tech/health
{"ok":true}

2. Register your app

Registration takes a ChirpAuth developer token (see Authentication), which outside developers cannot get yet. With one:

curl https://socialgraph.stackwell.tech/api/graph/apps \
  -H "Authorization: Bearer $DEVELOPER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "displayName": "Acme Planner",
    "description": "Plans events with your friends.",
    "platform": "web",
    "redirectUri": "https://acme.example/social-graph/callback"
  }'

The response carries your clientId (graphapp-...), your clientSecret (graphsecret-..., shown only once) and the app’s id. A new app is a draft; nobody can approve it until you make it active:

curl https://socialgraph.stackwell.tech/api/graph/apps/$APP_ID/status \
  -H "Authorization: Bearer $DEVELOPER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"status": "active"}'

3. Send the person to the approval page

Make a random state, and a PKCE verifier and challenge (the challenge is the base64url SHA-256 of the verifier, without padding):

VERIFIER=$(openssl rand -base64 48 | tr '+/' '-_' | tr -d '=\n')
CHALLENGE=$(printf '%s' "$VERIFIER" | openssl dgst -sha256 -binary | base64 | tr '+/' '-_' | tr -d '=\n')

Send the person to:

https://socialgraph.stackwell.tech/graph/authorize?client_id=graphapp-ab6bd084821c471eaab9ef7f83b09bf9&redirect_uri=https%3A%2F%2Facme.example%2Fsocial-graph%2Fcallback&state=xyz&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM

They sign in with ChirpAuth and see your app’s registered name, description, owner and redirect URI, and what it will be able to read. Their browser then returns to your redirect URI:

https://acme.example/social-graph/callback?code=graphcode-nl7_h3Yz90TH_jGjWAnhTz5DFuvra8oIjPG-GCrcjyE&state=xyz

or, if they deny, with ?error=access_denied&state=xyz. Check that state is the one you sent.

4. Exchange the code for an access token

Within 5 minutes, from your server:

curl https://socialgraph.stackwell.tech/api/graph/token \
  -H "Content-Type: application/json" \
  -d '{
    "clientId": "graphapp-ab6bd084821c471eaab9ef7f83b09bf9",
    "authorizationCode": "graphcode-nl7_h3Yz90TH_jGjWAnhTz5DFuvra8oIjPG-GCrcjyE",
    "redirectUri": "https://acme.example/social-graph/callback",
    "clientSecret": "'"$CLIENT_SECRET"'",
    "codeVerifier": "'"$VERIFIER"'"
  }'
{
  "accessToken": "graph-access-LX5hpmIpEI2UphioXi7Luz1n8Y1nBCt5yj5uSJ5bPF0",
  "tokenType": "Bearer",
  "me": { "...": "see API examples" }
}

This app is confidential, so the exchange always needs its clientSecret, and codeVerifier because the approval carried a code_challenge. A public app has no secret and sends only codeVerifier.

5. Read the person’s connections

curl https://socialgraph.stackwell.tech/api/graph-access/connections \
  -H "Authorization: Bearer $ACCESS_TOKEN"
[
  {
    "userId": "psd_4adcf14e44b5495b9e6b7e971d1e3885",
    "displayName": "user-8572fe12",
    "avatarUrl": null
  },
  {
    "userId": "psd_389ff13095374ece90ce63cbd7f7e10e",
    "displayName": "user-9bbce742",
    "avatarUrl": null
  }
]

The token works for 90 days unless it is revoked or replaced first; see Access tokens. See API examples for the other reads.

Authentication

Reads use the person’s access token (Authorization: Bearer graph-access-...), which your app gets by exchanging an approval code. The code exchange itself takes your app’s client id plus either its client secret or a PKCE verifier. Registering and managing an app takes a developer token from ChirpAuth. People approve with their own Social Graph sign-in, which your app cannot use. Authentication has a table of what each credential may do.

API reference

The full endpoint list is in the generated API reference. It also lists the endpoints the Social Graph app uses for people, which take a person’s own sign-in and are not covered here. API examples walks through the endpoints a graph app uses, with real responses, and Concepts explains the rules behind them.

Conventions:

  • Base URL https://socialgraph.stackwell.tech.
  • Request and response bodies are JSON; send Content-Type: application/json. Field names are camelCase. The approval and token fields also accept snake_case (client_id, redirect_uri, code_challenge, authorization_code, code_verifier, client_secret).
  • Times in responses are UTC, written YYYY-MM-DD HH:MM:SS.
  • People are identified by psd_... ids that belong to your app; see Identifiers.
  • Lists are not paged. Connection lists hold at most 100 people.
  • There are no idempotency keys: every POST /api/graph/apps registers a new app.

Errors and limits

Errors are JSON, {"error": "<message>"}, except request parsing errors, which are plain text. A missing or unusable access token is always 401 with {"error":"unauthorized"}. Request bodies are capped at 2 MiB. Errors and limits lists the status codes and the messages worth handling.

Data and privacy

Social Graph learns no email address or name from ChirpAuth. An app a person approved sees their display name and their connections, under ids specific to that app. Nothing is deleted: removing something marks it, and there is no way yet for a person to delete their Social Graph data. Data and privacy says what is stored, who sees what, and what is missing.