Stitchflow
Github Copilot logo

Github Copilot User Management API Guide

API workflow

How to automate user lifecycle operations through APIs with caveats that matter in production.

UpdatedMar 9, 2026

Summary and recommendation

The GitHub Copilot REST API exposes seat management under /orgs/{org}/copilot/billing/ and enterprise-scope equivalents under /enterprises/{enterprise}/copilot/billing/. Authentication requires either a classic PAT with manage_billing:copilot and read:org scopes, or a GitHub App installation token with the copilot organization permission. All requests must include the X-GitHub-Api-Version: 2022-11-28 header - omitting it can produce silent failures or 404s.

Pagination is offset-style (page / per_page, max 100), with navigation via Link response headers. Standard REST rate limits apply: 5,000 requests/hour per token, with secondary limits on burst writes.

Seat-level data integrates cleanly into an identity graph - login, id, last_activity_at, last_activity_editor, plan_type, and assigning_team are all returned per seat record, enabling cross-system correlation against your IdP or HR source of truth.

API quick reference

Has user APIYes
Auth methodGitHub Personal Access Token (PAT) or GitHub App installation token; OAuth 2.0 app tokens also accepted where the GitHub Apps OAuth flow is used
Base URLOfficial docs
SCIM availableYes
SCIM plan requiredGitHub Enterprise Cloud with Enterprise Managed Users (EMU)

Authentication

Auth method: GitHub Personal Access Token (PAT) or GitHub App installation token; OAuth 2.0 app tokens also accepted where the GitHub Apps OAuth flow is used

Setup steps

  1. Create a GitHub App or generate a fine-grained PAT with the required scopes under Settings > Developer settings.
  2. For GitHub Apps: install the app on the target organization and generate an installation access token via POST /app/installations/{installation_id}/access_tokens.
  3. For PATs: generate a classic PAT with 'manage_billing:copilot' and 'read:org' scopes, or a fine-grained PAT with 'GitHub Copilot Business' organization permissions.
  4. Pass the token in the Authorization header: 'Authorization: Bearer '.
  5. Include the API version header: 'X-GitHub-Api-Version: 2022-11-28'.

Required scopes

Scope Description Required for
manage_billing:copilot Read and write access to Copilot seat assignments and billing Add seats, remove seats, list seats (classic PAT)
read:org Read organization membership and team data Resolving team slugs and org membership for seat operations
copilot (GitHub App permission: organization-level) GitHub App permission granting Copilot seat management All Copilot seat management endpoints when using a GitHub App

User object / data model

Field Type Description On create On update Notes
login string GitHub username of the seat assignee required immutable Used as identifier in add/remove seat payloads
id integer GitHub user numeric ID system-assigned read-only Returned in seat list responses
avatar_url string (URL) URL of the user's GitHub avatar system-assigned read-only Returned in seat list responses
created_at string (ISO 8601) Timestamp when the Copilot seat was assigned system-assigned read-only Seat-level field, not user account creation
updated_at string (ISO 8601) Timestamp of last seat record update system-assigned system-assigned
pending_cancellation_date string (ISO 8601) | null Date seat cancellation takes effect, if scheduled null set on removal Seat remains active until this date after removal request
last_activity_at string (ISO 8601) | null Last recorded Copilot activity timestamp for the user null system-assigned May be null if user has not used Copilot
last_activity_editor string | null Editor/IDE used in the last Copilot activity (e.g., 'vscode') null system-assigned
plan_type string Copilot plan assigned to the seat (e.g., 'business', 'enterprise') inherited from org plan read-only
assigning_team object | null Team object if seat was assigned via a team, null if assigned directly set if team-based assignment read-only Contains team id, name, slug

Core endpoints

List Copilot seats for an organization

  • Method: GET
  • URL: /orgs/{org}/copilot/billing/seats
  • Watch out for: Returns seats for the org plan only. Enterprise-level seat listing requires the enterprise endpoint. Pagination via Link header.

Request example

GET /orgs/my-org/copilot/billing/seats?per_page=50&page=1
Authorization: Bearer <token>
X-GitHub-Api-Version: 2022-11-28

Response example

{
  "total_seats": 2,
  "seats": [
    {
      "created_at": "2024-01-10T00:00:00Z",
      "updated_at": "2024-06-01T00:00:00Z",
      "pending_cancellation_date": null,
      "last_activity_at": "2024-06-10T12:00:00Z",
      "last_activity_editor": "vscode",
      "plan_type": "business",
      "assignee": {"login": "octocat", "id": 1}
    }
  ]
}

Get Copilot seat details for a user

  • Method: GET
  • URL: /orgs/{org}/members/{username}/copilot
  • Watch out for: Returns 404 if the user does not have a Copilot seat in the org.

Request example

GET /orgs/my-org/members/octocat/copilot
Authorization: Bearer <token>
X-GitHub-Api-Version: 2022-11-28

Response example

{
  "created_at": "2024-01-10T00:00:00Z",
  "updated_at": "2024-06-01T00:00:00Z",
  "pending_cancellation_date": null,
  "last_activity_at": "2024-06-10T12:00:00Z",
  "last_activity_editor": "vscode",
  "plan_type": "business",
  "assignee": {"login": "octocat", "id": 1}
}

Add Copilot seats for users

  • Method: POST
  • URL: /orgs/{org}/copilot/billing/selected_users
  • Watch out for: Only works when org Copilot access is set to 'selected users'. If set to 'all members', this endpoint returns an error. Max 100 usernames per request.

Request example

POST /orgs/my-org/copilot/billing/selected_users
Authorization: Bearer <token>
X-GitHub-Api-Version: 2022-11-28
Content-Type: application/json

{"selected_usernames": ["octocat", "monalisa"]}

Response example

{
  "seats_created": 2
}

Remove Copilot seats for users

  • Method: DELETE
  • URL: /orgs/{org}/copilot/billing/selected_users
  • Watch out for: Seat remains active until end of billing cycle (pending_cancellation_date is set). Removal is not immediate.

Request example

DELETE /orgs/my-org/copilot/billing/selected_users
Authorization: Bearer <token>
X-GitHub-Api-Version: 2022-11-28
Content-Type: application/json

{"selected_usernames": ["octocat"]}

Response example

{
  "seats_cancelled": 1
}

Add Copilot seats for a team

  • Method: POST
  • URL: /orgs/{org}/copilot/billing/selected_teams
  • Watch out for: Team slug must match exactly. All current team members receive seats; future members added to the team also receive seats automatically.

Request example

POST /orgs/my-org/copilot/billing/selected_teams
Authorization: Bearer <token>
X-GitHub-Api-Version: 2022-11-28
Content-Type: application/json

{"selected_teams": ["engineering"]}

Response example

{
  "seats_created": 5
}

Remove Copilot seats for a team

  • Method: DELETE
  • URL: /orgs/{org}/copilot/billing/selected_teams
  • Watch out for: Cancels seats for all current team members. Pending cancellation date applies.

Request example

DELETE /orgs/my-org/copilot/billing/selected_teams
Authorization: Bearer <token>
X-GitHub-Api-Version: 2022-11-28
Content-Type: application/json

{"selected_teams": ["engineering"]}

Response example

{
  "seats_cancelled": 5
}

Get Copilot usage metrics for an organization

  • Method: GET
  • URL: /orgs/{org}/copilot/usage
  • Watch out for: Usage data has a ~24-hour lag. Date range max is 28 days per request. Not a per-user breakdown; use seat list for individual last_activity_at.

Request example

GET /orgs/my-org/copilot/usage?since=2024-06-01&until=2024-06-30
Authorization: Bearer <token>
X-GitHub-Api-Version: 2022-11-28

Response example

[
  {
    "day": "2024-06-10",
    "total_suggestions_count": 1200,
    "total_acceptances_count": 800,
    "total_lines_suggested": 4500,
    "total_lines_accepted": 3000,
    "total_active_users": 15
  }
]

List Copilot seats for an enterprise

  • Method: GET
  • URL: /enterprises/{enterprise}/copilot/billing/seats
  • Watch out for: Requires enterprise-level token with manage_billing:copilot. Returns seats across all orgs in the enterprise.

Request example

GET /enterprises/my-enterprise/copilot/billing/seats?per_page=100
Authorization: Bearer <token>
X-GitHub-Api-Version: 2022-11-28

Response example

{
  "total_seats": 50,
  "seats": [
    {
      "assignee": {"login": "octocat"},
      "assigning_team": null,
      "plan_type": "enterprise",
      "last_activity_at": "2024-06-09T08:00:00Z"
    }
  ]
}

Rate limits, pagination, and events

  • Rate limits: GitHub REST API standard rate limits apply. Authenticated requests are limited per token. Copilot endpoints share the global REST quota.
  • Rate-limit headers: Yes
  • Retry-After header: Yes
  • Rate-limit notes: Headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset (Unix timestamp), Retry-After (on 429). Secondary rate limits may apply for burst writes.
  • Pagination method: cursor
  • Default page size: 50
  • Max page size: 100
  • Pagination pointer: page / per_page (offset-style integers); Link header provides next/prev/last URLs
Plan Limit Concurrent
Authenticated (PAT/App token) 5,000 requests/hour per token 0
GitHub App installation token 5,000 requests/hour per installation (scales with org size for large orgs) 0
  • Webhooks available: Yes
  • Webhook notes: GitHub organization and enterprise webhooks fire events related to Copilot seat changes. No dedicated Copilot-specific webhook event type exists; seat changes are surfaced via audit log streaming rather than real-time webhooks.
  • Alternative event strategy: Use GitHub Audit Log Streaming (Enterprise feature) to stream audit events to an external SIEM or storage. Poll /orgs/{org}/copilot/billing/seats for near-real-time seat state.
  • Webhook events: business.add_seats (audit log event), business.remove_seats (audit log event), copilot.seat_assignment_created (audit log), copilot.seat_assignment_cancelled (audit log), copilot.seat_assignment_updated (audit log)

SCIM API status

  • SCIM available: Yes

  • SCIM version: 2.0

  • Plan required: GitHub Enterprise Cloud with Enterprise Managed Users (EMU)

  • Endpoint: https://api.github.com/scim/v2/enterprises/{enterprise}/

  • Supported operations: GET /Users (list provisioned users), GET /Users/{scim_user_id} (get user), POST /Users (provision user), PATCH /Users/{scim_user_id} (update user attributes), DELETE /Users/{scim_user_id} (deprovision user), GET /Groups (list teams as groups), POST /Groups (create team), PATCH /Groups/{scim_group_id} (update team membership), DELETE /Groups/{scim_group_id} (delete team)

Limitations:

  • Only available for Enterprise Managed User (EMU) organizations; not available for standard GitHub orgs.
  • SCIM provisions GitHub user accounts and org membership, not Copilot seats directly - seat assignment still requires the Copilot billing API or org policy.
  • Requires SAML SSO or OIDC to be configured before SCIM provisioning.
  • Supported IdPs: Okta, Microsoft Entra ID (Azure AD). Google Workspace and OneLogin not officially supported.
  • EMU usernames are managed by the IdP and follow the pattern {shortcode}_{username}.
  • SCIM tokens must be generated by the enterprise owner using a special setup user account.

Common scenarios

Provisioning a new employee requires a sequential flow: for EMU orgs, the IdP triggers SCIM POST /Users first to create the managed account, then a separate POST /orgs/{org}/copilot/billing/selected_users call assigns the Copilot seat. SCIM and seat assignment are decoupled - SCIM provisions GitHub identity and org membership but does not automatically grant a Copilot seat.

Deprovisioning sets a pending_cancellation_date on the seat record; the seat remains active and billable until that date regardless of when the API call is made. For EMU, SCIM DELETE /Users/{scim_user_id} suspends the managed account but does not cancel Copilot billing immediately - both steps are required and must be sequenced deliberately.

For idle-seat auditing, paginate GET /orgs/{org}/copilot/billing/seats and filter on last_activity_at - null values or dates beyond a 30-day threshold are reclamation candidates. Note that last_activity_at reflects Copilot suggestion activity only; a user with the extension installed but no triggered suggestions will appear null even if actively employed. Batch removals via DELETE /orgs/{org}/copilot/billing/selected_users accept a maximum of 100 usernames per request.

Provision a new employee with a Copilot seat

  1. (EMU only) IdP triggers SCIM POST /Users to create the GitHub managed user account.
  2. Verify org membership via GET /orgs/{org}/members/{username}.
  3. POST /orgs/{org}/copilot/billing/selected_users with body {"selected_usernames": ["username"]} to assign a Copilot seat.
  4. Confirm seat via GET /orgs/{org}/members/{username}/copilot and check created_at is set.

Watch out for: Step 3 fails with 422 if the org Copilot policy is 'all members' (seats are auto-assigned) or if the user is not yet an org member.

Deprovision a departing employee and reclaim Copilot seat

  1. DELETE /orgs/{org}/copilot/billing/selected_users with {"selected_usernames": ["username"]} to cancel the seat.
  2. Note the pending_cancellation_date in the response - seat remains active until that date.
  3. (EMU) IdP triggers SCIM DELETE /Users/{scim_user_id} to suspend/remove the managed user account.
  4. Verify seat is gone after cancellation date via GET /orgs/{org}/copilot/billing/seats.

Watch out for: Billing continues until the pending_cancellation_date. Deleting the user via SCIM does not automatically cancel the Copilot seat billing immediately.

Audit active vs. inactive Copilot seat holders

  1. GET /orgs/{org}/copilot/billing/seats?per_page=100 and paginate through all pages using Link header.
  2. For each seat, inspect last_activity_at - seats with null or dates older than 30 days are candidates for reclamation.
  3. Cross-reference with GET /orgs/{org}/copilot/usage for aggregate active user counts.
  4. Build a removal list and batch DELETE /orgs/{org}/copilot/billing/selected_users (max 100 usernames per call).

Watch out for: last_activity_at reflects Copilot suggestion activity only; a user who has the extension installed but hasn't triggered a suggestion will show null even if actively employed.

Why building this yourself is a trap

The most significant API caveat is policy-state dependency: the POST and DELETE seat endpoints for selected users and teams return 422 if the org's Copilot access policy is set to 'all members' rather than 'selected users/teams'. Any automation pipeline must validate org policy state before attempting seat mutations, or handle 422 responses explicitly.

SCIM is exclusively an EMU feature - Copilot Business organizations have no SCIM endpoint. The SCIM token itself must be generated by the enterprise's setup user (a dedicated bot account), not a standard enterprise owner PAT, which is a non-obvious credential management requirement.

Usage metrics from /orgs/{org}/copilot/usage carry a ~24-hour data lag and provide no per-user granularity, making them unsuitable for real-time seat state; use the seat list endpoint with last_activity_at for individual-level signals instead.

Enterprise-scope endpoints (/enterprises/{enterprise}/...) require a token scoped to the enterprise, not an org-level token - mixing these silently returns incomplete data or auth errors depending on the endpoint.

Automate Github Copilot workflows without one-off scripts

Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.

Every app coverage, including apps without APIs
60+ app integrations plus browser automation for apps without APIs
IT graph reconciliation across apps and your IdP
Less than a week to launch, maintained as APIs and admin consoles change
SOC 2 Type II. ~2 hours of your team's time

UpdatedMar 9, 2026

* Details sourced from official product documentation and admin references.

Keep exploring

Related apps

15Five logo

15Five

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

15Five uses a fixed role-based permission model with six predefined roles: Account Admin, HR Admin, Billing Admin, Group Admin, Manager, and Employee. No custom roles can be constructed. User management lives at Settings gear → People → Manage people p

1Password logo

1Password

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

1Password's admin console at my.1password.com covers the full user lifecycle — invitations, group assignments, vault access, suspension, and deletion — without any third-party tooling. Like every app that mixes role-based and resource-level permissions

8x8 logo

8x8

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

8x8 Admin Console supports full lifecycle user management — create, deactivate, and delete — across its X Series unified communications platform. Every app a user can access (8x8 Work desktop, mobile, web, Agent Workspace) is gated by license assignmen