Summary and recommendation
Dependabot has no independent user management API. All access control is inherited from GitHub repository and organization permissions, making it a natural fit for identity graph traversal - user identity, org membership, repository role, and Dependabot alert visibility are all resolvable through the GitHub REST API without any Dependabot-specific provisioning surface.
The base URL is https://api.github.com. Authentication uses a Personal Access Token (classic or fine-grained) or a GitHub App installation token passed as a Bearer token. The `security_events` scope is required for alert read/write operations; `repo` scope alone is insufficient for private repositories in some configurations.
Org-level alert listing additionally requires the caller to hold an org owner or `security manager` role.
API quick reference
| Has user API | No |
| Auth method | GitHub Personal Access Token (classic or fine-grained) or GitHub App installation token passed as Bearer token in Authorization header |
| Base URL | Official docs |
| SCIM available | No |
| SCIM plan required | N/A |
Authentication
Auth method: GitHub Personal Access Token (classic or fine-grained) or GitHub App installation token passed as Bearer token in Authorization header
Setup steps
- Generate a Personal Access Token (classic) at GitHub Settings > Developer settings > Personal access tokens, or create a fine-grained PAT scoped to the target repo/org.
- For GitHub Apps: register an app, install it on the org/repo, and exchange the installation ID for an installation access token via POST /app/installations/{installation_id}/access_tokens.
- Pass the token in the Authorization header: 'Authorization: Bearer
'. - Ensure the token has the required scopes listed below for the specific Dependabot API operations needed.
Required scopes
| Scope | Description | Required for |
|---|---|---|
| security_events | Read and write Dependabot alerts on repositories. | GET/PATCH Dependabot alert endpoints |
| repo | Full repository access; required for private repo Dependabot secret management. | Dependabot secrets CRUD on private repos |
| admin:org | Manage organization-level Dependabot secrets and settings. | Org-level Dependabot secrets endpoints |
| read:org | Read organization membership; used to determine who has access to Dependabot features. | Listing org members with Dependabot access |
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| number | integer | Alert number unique within the repository. | auto-assigned | immutable | Used as path parameter in alert endpoints. |
| state | string | Alert state: 'open', 'dismissed', 'fixed', 'auto_dismissed'. | set by GitHub | PATCH to 'dismissed' | Only 'dismissed' is writable via API. |
| dismissed_reason | string|null | Reason for dismissal: 'fix_started', 'inaccurate', 'no_bandwidth', 'not_used', 'tolerable_risk'. | null | required when dismissing | Must be provided alongside state=dismissed. |
| dismissed_comment | string|null | Free-text comment explaining dismissal (max 280 chars). | null | optional | |
| dismissed_at | string (ISO 8601)|null | Timestamp when alert was dismissed. | null | set by GitHub on dismiss | |
| dismissed_by | object|null | GitHub user object of the person who dismissed the alert. | null | set by GitHub | Contains login, id, avatar_url, type fields. |
| created_at | string (ISO 8601) | Timestamp when alert was created. | auto | immutable | |
| updated_at | string (ISO 8601) | Timestamp of last alert update. | auto | auto | |
| auto_dismissed_at | string (ISO 8601)|null | Timestamp when alert was auto-dismissed. | null | set by GitHub | |
| url | string | REST API URL for the alert. | auto | immutable | |
| html_url | string | GitHub web UI URL for the alert. | auto | immutable | |
| dependency | object | Affected dependency: package (ecosystem, name), manifest_path, scope. | auto | immutable | |
| security_advisory | object | Advisory details: ghsa_id, cve_id, summary, severity, cvss, cwes, identifiers. | auto | immutable | |
| security_vulnerability | object | Vulnerability details: package, severity, vulnerable_version_range, first_patched_version. | auto | immutable | |
| severity | string | Filter parameter: 'low', 'medium', 'high', 'critical'. | n/a | n/a | Query parameter for list endpoints, not a writable field on the alert object. |
Core endpoints
List Dependabot alerts for a repository
- Method: GET
- URL:
https://api.github.com/repos/{owner}/{repo}/dependabot/alerts - Watch out for: Requires 'security_events' scope or repo admin. Returns 404 if Dependabot alerts are not enabled on the repo.
Request example
GET /repos/octocat/hello-world/dependabot/alerts?state=open&severity=high&per_page=30
Authorization: Bearer <token>
Accept: application/vnd.github+json
Response example
[
{
"number": 1,
"state": "open",
"dependency": {"package": {"ecosystem": "npm", "name": "lodash"}},
"security_advisory": {"ghsa_id": "GHSA-xxxx", "severity": "high"},
"created_at": "2024-01-15T10:00:00Z"
}
]
Get a Dependabot alert
- Method: GET
- URL:
https://api.github.com/repos/{owner}/{repo}/dependabot/alerts/{alert_number} - Watch out for: Alert numbers are repo-scoped integers, not globally unique.
Request example
GET /repos/octocat/hello-world/dependabot/alerts/1
Authorization: Bearer <token>
Accept: application/vnd.github+json
Response example
{
"number": 1,
"state": "open",
"dismissed_reason": null,
"dismissed_by": null,
"security_advisory": {"ghsa_id": "GHSA-xxxx"},
"created_at": "2024-01-15T10:00:00Z"
}
Update (dismiss/reopen) a Dependabot alert
- Method: PATCH
- URL:
https://api.github.com/repos/{owner}/{repo}/dependabot/alerts/{alert_number} - Watch out for: dismissed_reason is required when setting state=dismissed. Only 'dismissed' and 'open' are valid writable states.
Request example
PATCH /repos/octocat/hello-world/dependabot/alerts/1
Authorization: Bearer <token>
Content-Type: application/json
{"state":"dismissed","dismissed_reason":"tolerable_risk","dismissed_comment":"Reviewed."}
Response example
{
"number": 1,
"state": "dismissed",
"dismissed_reason": "tolerable_risk",
"dismissed_by": {"login": "monalisa"},
"dismissed_at": "2024-06-01T12:00:00Z"
}
List Dependabot alerts for an organization
- Method: GET
- URL:
https://api.github.com/orgs/{org}/dependabot/alerts - Watch out for: Requires org admin or security manager role. Results include repository context per alert.
Request example
GET /orgs/github/dependabot/alerts?state=open&per_page=100
Authorization: Bearer <token>
Accept: application/vnd.github+json
Response example
[
{
"number": 42,
"repository": {"full_name": "github/repo-a"},
"state": "open",
"security_advisory": {"severity": "critical"}
}
]
List repository Dependabot secrets
- Method: GET
- URL:
https://api.github.com/repos/{owner}/{repo}/dependabot/secrets - Watch out for: Secret values are never returned; only metadata (name, timestamps) is exposed.
Request example
GET /repos/octocat/hello-world/dependabot/secrets
Authorization: Bearer <token>
Accept: application/vnd.github+json
Response example
{
"total_count": 2,
"secrets": [
{"name": "NPM_TOKEN", "created_at": "2023-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z"}
]
}
Create or update a repository Dependabot secret
- Method: PUT
- URL:
https://api.github.com/repos/{owner}/{repo}/dependabot/secrets/{secret_name} - Watch out for: Secret value must be encrypted with the repo's Dependabot public key using libsodium (crypto_box_seal). Fetch the public key first via GET /repos/{owner}/{repo}/dependabot/secrets/public-key.
Request example
PUT /repos/octocat/hello-world/dependabot/secrets/NPM_TOKEN
Authorization: Bearer <token>
Content-Type: application/json
{"encrypted_value":"<libsodium-encrypted-base64>","key_id":"012345678912345678"}
Response example
HTTP 201 Created
(empty body on create; 204 No Content on update)
Delete a repository Dependabot secret
- Method: DELETE
- URL:
https://api.github.com/repos/{owner}/{repo}/dependabot/secrets/{secret_name} - Watch out for: Requires repo 'admin' permission or org owner. Deletion is immediate and irreversible.
Request example
DELETE /repos/octocat/hello-world/dependabot/secrets/NPM_TOKEN
Authorization: Bearer <token>
Accept: application/vnd.github+json
Response example
HTTP 204 No Content
List org-level Dependabot secrets
- Method: GET
- URL:
https://api.github.com/orgs/{org}/dependabot/secrets - Watch out for: Visibility can be 'all', 'private', or 'selected'. For 'selected', use the separate endpoint to manage which repos have access.
Request example
GET /orgs/github/dependabot/secrets?per_page=30
Authorization: Bearer <token>
Accept: application/vnd.github+json
Response example
{
"total_count": 1,
"secrets": [
{"name": "ORG_NPM_TOKEN", "visibility": "selected", "created_at": "2023-06-01T00:00:00Z"}
]
}
Rate limits, pagination, and events
- Rate limits: Dependabot API endpoints follow GitHub REST API rate limits. Authenticated requests: 5,000 requests/hour per user token. GitHub App installation tokens: up to 15,000 requests/hour for orgs with 20+ seats. Secondary rate limits apply to concurrent requests and rapid successive writes.
- Rate-limit headers: Yes
- Retry-After header: Yes
- Rate-limit notes: Headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, Retry-After (on 429). Secondary rate limits return HTTP 403 with a Retry-After header.
- Pagination method: cursor
- Default page size: 30
- Max page size: 100
- Pagination pointer: per_page / page (offset-style integers); Link header provides next/prev/last URLs
| Plan | Limit | Concurrent |
|---|---|---|
| Authenticated user (PAT) | 5,000 requests/hour | 0 |
| GitHub App installation token (large org) | 15,000 requests/hour | 0 |
| Unauthenticated | 60 requests/hour | 0 |
- Webhooks available: Yes
- Webhook notes: GitHub webhooks fire Dependabot-related events at the repository or organization level. Configure via GitHub UI or the REST API (POST /repos/{owner}/{repo}/hooks).
- Alternative event strategy: Poll GET /repos/{owner}/{repo}/dependabot/alerts with updated_at sort for near-real-time detection without webhooks.
- Webhook events: dependabot_alert.created, dependabot_alert.dismissed, dependabot_alert.fixed, dependabot_alert.reintroduced, dependabot_alert.reopened, dependabot_alert.auto_dismissed, dependabot_alert.auto_reopened
SCIM API status
- SCIM available: No
- SCIM version: Not documented
- Plan required: N/A
- Endpoint: Not documented
Limitations:
- Dependabot is a GitHub-native feature with no standalone SCIM endpoint.
- User access to Dependabot is governed entirely by GitHub repository/org membership and role permissions.
- GitHub Enterprise Cloud supports SCIM for org membership provisioning (via /scim/v2/organizations/{org}/Users), which indirectly controls who can access Dependabot features.
Common scenarios
Three automation patterns cover the primary operational use cases.
First, bulk-dismissing low-severity alerts: paginate GET /repos/{owner}/{repo}/dependabot/alerts with state=open and severity=low (max per_page=100), then issue individual PATCH requests per alert - there is no bulk-dismiss endpoint, and omitting dismissed_reason returns HTTP 422.
Second, rotating a Dependabot secret: always fetch a fresh public key via GET /repos/{owner}/{repo}/dependabot/secrets/public-key immediately before encrypting, since a stale key_id returns HTTP 422. encrypt the new value using libsodium crypto_box_seal, then PUT to the secret endpoint.
Third, real-time alert monitoring via webhook: register the dependabot_alert event, validate every inbound request against the X-Hub-Signature-256 header, and respond HTTP 200 within 10 seconds - GitHub retries failed deliveries up to three times with exponential backoff.
For teams that cannot use webhooks, polling GET /repos/{owner}/{repo}/dependabot/alerts sorted by updated_at provides near-real-time detection.
Bulk dismiss low-severity Dependabot alerts across a repo
- GET /repos/{owner}/{repo}/dependabot/alerts?state=open&severity=low&per_page=100 to retrieve open low-severity alerts.
- Iterate through paginated results using the Link header 'next' URL.
- For each alert, PATCH /repos/{owner}/{repo}/dependabot/alerts/{number} with body {"state":"dismissed","dismissed_reason":"tolerable_risk","dismissed_comment":"Bulk dismiss: low severity."}.
- Respect rate limits; check X-RateLimit-Remaining header and pause if approaching 0.
Watch out for: dismissed_reason is mandatory; omitting it returns HTTP 422. There is no bulk-dismiss endpoint; each alert requires an individual PATCH request.
Rotate a Dependabot secret across a repository
- GET /repos/{owner}/{repo}/dependabot/secrets/public-key to retrieve the current key_id and public_key.
- Encrypt the new secret value using libsodium crypto_box_seal with the retrieved public key.
- PUT /repos/{owner}/{repo}/dependabot/secrets/{secret_name} with {"encrypted_value":"
","key_id":" "} to overwrite the existing secret. - Verify the updated_at timestamp via GET /repos/{owner}/{repo}/dependabot/secrets/{secret_name}.
Watch out for: The public key changes periodically; always fetch a fresh key_id immediately before encrypting. Using a stale key_id returns HTTP 422.
Monitor new critical Dependabot alerts via webhook
- Register a webhook on the repo or org via POST /repos/{owner}/{repo}/hooks with events: ["dependabot_alert"] and a secret for HMAC validation.
- In the webhook handler, filter payload where action='created' and alert.security_advisory.severity='critical'.
- Parse alert.html_url and alert.dependency.package.name from the payload for notification routing.
- Respond HTTP 200 within 10 seconds; process asynchronously to avoid GitHub webhook timeouts.
Watch out for: GitHub retries failed webhook deliveries up to 3 times with exponential backoff. Validate the X-Hub-Signature-256 header on every request to prevent spoofing.
Why building this yourself is a trap
The most common integration mistake is assuming Dependabot alert endpoints are always available. They return 404 if Dependabot alerts are not explicitly enabled on the target repository - callers must handle this gracefully rather than treating it as an auth failure.
Secret values are write-only: the API never returns plaintext or encrypted secret content, only metadata (name, timestamps). Auto-dismissed alerts (state=auto_dismissed) have different reopen behavior than manually dismissed alerts - verify current GitHub documentation before building reopen logic.
Pagination uses Link headers (RFC 5988) for next/prev/last navigation alongside offset-based page and per_page integers; cursor and offset semantics are mixed here and callers should follow the Link header rather than constructing page URLs manually.
Rate limits are 5,000 requests/hour for PATs and up to 15,000/hour for GitHub App installation tokens on large organizations - monitor X-RateLimit-Remaining on every response when running bulk alert operations.
Automate Dependabot 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.