GitHub

Connect your client's GitHub with a sign-in, and call its API through Operate As.

Website
github.com
Connects by
Signing in with GitHub
Category
Developer tools
Services
1
Tools
1,202
ServiceKey
GitHubgithub

Connecting

Your client presses Connect on their link and approves on GitHub's own screen. Operate As never sees their password.

Check they're connected
curl https://api.operate.as/v1/me/clients \  -H "Authorization: Bearer $OPERATE_AS_API_KEY"
Response
[  {    "id": "6f1c2a7e-...",    "name": "Miller Dental",    "services": [      "github"    ]  }]

Permissions

What the client readsPermission it asks for
See and change your repositories, issues and pull requestsrepo
See your profileread:user

Tools

Install GitHub's typed package for your language:

pip install operate-as-github
Run github.actions_add_custom_labels_to_self_hosted_runner_for_org
curl -X POST https://api.operate.as/v1/actions/github.actions_add_custom_labels_to_self_hosted_runner_for_org \  -H "Authorization: Bearer $OPERATE_AS_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "clientId": "6f1c2a7e-...",    "input": {      "org": "<org>",      "runner_id": "<runner_id>"    }  }'

Shows the required inputs. Every input, with its JSON Schema: GET /v1/actions/github.actions_add_custom_labels_to_self_hosted_runner_for_org

Response
{  "status": 200,  "data": {    "…": "the service's own response"  },  "encoding": "json"}

Pass-through

Paths continue from https://api.github.com. Your Operate As key goes in Authorization; the client's access is added for you.

See Pass-through requests for the full request and response format.

Call any endpoint
curl "https://api.operate.as/v1/clients/6f1c2a7e-.../github/..." \  -H "Authorization: Bearer $OPERATE_AS_API_KEY"
Response
{  "status": 200,  "data": {    "…": "the service's own response"  },  "encoding": "json"}

When access ends

Operate As renews the sign-in before it runs out and checks it daily. If GitHub refuses to renew it, the service shows Expired, you're alerted, and your client reconnects from the same link.

See Keeping access alive and Removing access.

Calls answer
HTTP/1.1 409 ConflictContent-Type: application/json{  "detail": "Miller Dental's GitHub access ended. Send them their link to reconnect."}
Your webhook receives
{  "id": "evt_3f9a1c…",  "type": "connection.expired",  "createdAt": "2026-10-16T08:00:00+00:00",  "data": {    "clientId": "6f1c2a7e-...",    "clientName": "Miller Dental",    "provider": "github",    "services": [      "github"    ],    "reconnectUrl": "https://…"  }}