Skip to content

API

Rendered reference for AdvisoryHub's machine-consumable HTTP surface: the internal /api/ JSON namespace, the GitHub App webhook receiver, the public project picker, and the health probes. Server-rendered HTML/HTMX UI routes are deliberately not part of this contract.

The machine-readable source of truth is openapi.yaml (OpenAPI 3.0.3), kept honest by drift guards in api/tests/test_openapi_spec.py: the document must validate, and every /api/ route must match the Django URLconf bidirectionally — paths and methods. info.version tracks the application version in lockstep (dev/release.sh bumps it, dev/check_release_versions.sh gates it).

Authentication in one line: /api/ uses the OIDC-established session cookie (plus the CSRF header on unsafe methods, no API tokens), the webhook uses an HMAC-SHA256 signature, and the intake picker and health probes are unauthenticated. Details in the rendered description below and in permissions.

AdvisoryHub API 0.1.0

AdvisoryHub is a private application for authoring, reviewing, publishing, and auditing security advisories for Eclipse Foundation projects. This document describes its machine-consumable endpoints only; there is no public anonymous API surface.

Authentication. The /api/ namespace is an internal, same-origin JSON API: it authenticates with the Django session cookie established via the OIDC browser flow (there are no API tokens), and every unsafe method additionally requires the CSRF token header. Unauthenticated requests get a JSON 401 not_authenticated instead of a login redirect. The GitHub webhook authenticates with an HMAC signature; the project picker and health probes are unauthenticated.

Request bodies. /api/ POST endpoints accept either application/json or application/x-www-form-urlencoded bodies (form values arrive as strings — JSON is recommended, and required for non-string semantics such as booleans).

Errors. JSON errors share the Error shape {"error": "<machine_code>", "message": "<human text>"}. Two deliberate exceptions: unknown resources return Django's default HTML 404 page (except where noted), and a request with an HTTP method not listed here returns an empty 405 with an Allow header.


Servers

Description URL
Paths are absolute from the deployment root. /

Advisories


GET /api/advisories/

List advisories visible to the authenticated user

Input parameters

Parameter In Type Default Nullable Description
sessionCookie cookie string N/A No Django session established via the OIDC browser flow. Production uses the `__Host-` prefixed cookie name; dev/test use plain `sessionid`. There are no API tokens — this is an internal, same-origin API.
page query integer 1 No 1-indexed page; values below 1 are coerced to 1.
page_size query integer 25 No Page size, clamped to 1–100.
project query string No Filter to a single project by UUID.
q query string No Case-insensitive substring match over summary, details, advisory_id, and aliases.
review_status query No Filter by review sub-state. Not validated server-side — an unknown value simply matches nothing.
state query No Filter by lifecycle state (validated; unknown values are a 400).

Responses

{
    "results": [
        {
            "advisory_id": "string",
            "project": "string",
            "state": "triage",
            "review_status": "none",
            "summary": "string",
            "modified_at": "2022-04-13T15:42:05.901Z",
            "published_at": "2022-04-13T15:42:05.901Z",
            "republish_required": true
        }
    ],
    "total": 0,
    "page": 0,
    "page_size": 0
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "results",
        "total",
        "page",
        "page_size"
    ],
    "properties": {
        "results": {
            "type": "array",
            "items": {
                "$ref": "#/components/schemas/AdvisorySummary"
            }
        },
        "total": {
            "type": "integer",
            "description": "Total matches across all pages."
        },
        "page": {
            "type": "integer"
        },
        "page_size": {
            "type": "integer"
        }
    }
}

{
    "error": "string",
    "message": "string"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "error",
        "message"
    ],
    "properties": {
        "error": {
            "type": "string",
            "description": "Stable machine-readable code."
        },
        "message": {
            "type": "string",
            "description": "Human-readable explanation."
        }
    },
    "additionalProperties": true,
    "description": "Shared JSON error envelope. Some errors carry extra fields (e.g. `step_up_url` on `step_up_required`)."
}

Refer to the common response description: NotAuthenticated.


GET /api/advisories/{advisory_id}/

Retrieve one advisory

Input parameters

Parameter In Type Default Nullable Description
sessionCookie cookie string N/A No Django session established via the OIDC browser flow. Production uses the `__Host-` prefixed cookie name; dev/test use plain `sessionid`. There are no API tokens — this is an internal, same-origin API.
advisory_id path string No AdvisoryHub identifier (e.g. `ECL-q2f7-38cm-9wrx`). Malformed ids miss the URL pattern entirely and 404 at the resolver.

Responses

{
    "advisory_id": "string",
    "project": {
        "id": "ab597204-159a-4431-b0ca-f5e7aed31190",
        "slug": "string",
        "name": "string",
        "is_mature_publisher": true
    },
    "state": "triage",
    "review_status": "none",
    "summary": "string",
    "details": "string",
    "aliases": [
        "string"
    ],
    "references": [
        {
            "type": "ADVISORY",
            "url": "string"
        }
    ],
    "affected": [
        {
            "package": {
                "name": "string",
                "ecosystem": "string"
            },
            "ranges": [
                {
                    "type": "string",
                    "events": [
                        {
                            "introduced": "string",
                            "fixed": "string",
                            "last_affected": "string",
                            "limit": "string"
                        }
                    ]
                }
            ],
            "versions": [
                "string"
            ]
        }
    ],
    "severity": [
        {
            "type": "CVSS_V2",
            "score": "string"
        }
    ],
    "cwe_ids": [
        "string"
    ],
    "credits": [
        {
            "name": "string",
            "contact": [
                "string"
            ],
            "type": "FINDER"
        }
    ],
    "republish_required": true,
    "withdrawn_reason": "string",
    "dismissed_reason": "string",
    "created_at": "2022-04-13T15:42:05.901Z",
    "modified_at": "2022-04-13T15:42:05.901Z",
    "published_at": "2022-04-13T15:42:05.901Z",
    "submitted_for_review_at": "2022-04-13T15:42:05.901Z",
    "url": "string"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "advisory_id",
        "project",
        "state",
        "review_status",
        "summary",
        "details",
        "aliases",
        "references",
        "affected",
        "severity",
        "cwe_ids",
        "credits",
        "republish_required",
        "withdrawn_reason",
        "dismissed_reason",
        "created_at",
        "modified_at",
        "published_at",
        "submitted_for_review_at",
        "url"
    ],
    "properties": {
        "advisory_id": {
            "type": "string",
            "pattern": "^ECL(-[23456789cfghjmpqrvwx]{4}){3}$"
        },
        "project": {
            "$ref": "#/components/schemas/ProjectRef"
        },
        "state": {
            "$ref": "#/components/schemas/AdvisoryState"
        },
        "review_status": {
            "$ref": "#/components/schemas/ReviewStatus"
        },
        "summary": {
            "type": "string"
        },
        "details": {
            "type": "string"
        },
        "aliases": {
            "type": "array",
            "items": {
                "type": "string"
            },
            "description": "External identifiers (CVE, GHSA, ...)."
        },
        "references": {
            "type": "array",
            "items": {
                "$ref": "#/components/schemas/Reference"
            }
        },
        "affected": {
            "type": "array",
            "items": {
                "$ref": "#/components/schemas/AffectedEntry"
            }
        },
        "severity": {
            "type": "array",
            "items": {
                "$ref": "#/components/schemas/SeverityEntry"
            }
        },
        "cwe_ids": {
            "type": "array",
            "items": {
                "type": "string"
            },
            "description": "CWE identifiers (e.g. `CWE-79`)."
        },
        "credits": {
            "type": "array",
            "items": {
                "$ref": "#/components/schemas/Credit"
            }
        },
        "republish_required": {
            "type": "boolean"
        },
        "withdrawn_reason": {
            "type": "string",
            "description": "Empty unless the advisory was withdrawn."
        },
        "dismissed_reason": {
            "type": "string",
            "description": "Empty unless the advisory was dismissed."
        },
        "created_at": {
            "type": "string",
            "format": "date-time"
        },
        "modified_at": {
            "type": "string",
            "format": "date-time"
        },
        "published_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
        },
        "submitted_for_review_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
        },
        "url": {
            "type": "string",
            "description": "Relative URL of the advisory's HTML detail page."
        }
    }
}

Refer to the common response description: NotAuthenticated.

Refer to the common response description: Forbidden.

Refer to the common response description: NotFoundHtml.

Comments


GET /api/advisories/{advisory_id}/comments/

List comments on an advisory

Description

Comments are never published or disclosed externally; they are visible only to users with access to the advisory inside AdvisoryHub. Internal comments are omitted for users without internal-comment visibility. Author emails are masked unless the caller may see user emails on this advisory (INV-PRIVACY-4).

Input parameters

Parameter In Type Default Nullable Description
sessionCookie cookie string N/A No Django session established via the OIDC browser flow. Production uses the `__Host-` prefixed cookie name; dev/test use plain `sessionid`. There are no API tokens — this is an internal, same-origin API.
advisory_id path string No AdvisoryHub identifier (e.g. `ECL-q2f7-38cm-9wrx`). Malformed ids miss the URL pattern entirely and 404 at the resolver.

Responses

{
    "results": [
        {
            "id": 0,
            "author": "string",
            "body": "string",
            "is_redacted": true,
            "is_internal": true,
            "created_at": "2022-04-13T15:42:05.901Z",
            "edited_at": "2022-04-13T15:42:05.901Z"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "results"
    ],
    "properties": {
        "results": {
            "type": "array",
            "items": {
                "$ref": "#/components/schemas/Comment"
            }
        }
    }
}

Refer to the common response description: NotAuthenticated.

Refer to the common response description: Forbidden.

Refer to the common response description: NotFoundHtml.

Refer to the common response description: RateLimited.


POST /api/advisories/{advisory_id}/comments/

Add a comment

Description

Rate limited to 30 requests/minute per user.

Input parameters

Parameter In Type Default Nullable Description
csrfToken header string N/A No Django CSRF token (double-submit with the `__Host-csrftoken` cookie; `csrftoken` in dev/test). Required alongside the session cookie on every unsafe method of the /api/ namespace.
sessionCookie cookie string N/A No Django session established via the OIDC browser flow. Production uses the `__Host-` prefixed cookie name; dev/test use plain `sessionid`. There are no API tokens — this is an internal, same-origin API.
advisory_id path string No AdvisoryHub identifier (e.g. `ECL-q2f7-38cm-9wrx`). Malformed ids miss the URL pattern entirely and 404 at the resolver.

Request body

{
    "body": "string",
    "is_internal": true
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the request body
{
    "type": "object",
    "required": [
        "body"
    ],
    "properties": {
        "body": {
            "type": "string",
            "minLength": 1,
            "description": "Comment text; surrounding whitespace is stripped."
        },
        "is_internal": {
            "type": "boolean",
            "default": false,
            "description": "When false (the default) the comment is visible to everyone with access to the advisory; when true it is hidden from users without internal-comment visibility. Either way the comment is never published or disclosed externally. With a form-encoded body any non-empty string is truthy — use JSON for reliable boolean semantics."
        }
    }
}

{
    "body": "string",
    "is_internal": true
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the request body
{
    "type": "object",
    "required": [
        "body"
    ],
    "properties": {
        "body": {
            "type": "string",
            "minLength": 1,
            "description": "Comment text; surrounding whitespace is stripped."
        },
        "is_internal": {
            "type": "boolean",
            "default": false,
            "description": "When false (the default) the comment is visible to everyone with access to the advisory; when true it is hidden from users without internal-comment visibility. Either way the comment is never published or disclosed externally. With a form-encoded body any non-empty string is truthy — use JSON for reliable boolean semantics."
        }
    }
}

Responses

{
    "id": 0,
    "author": "string",
    "body": "string",
    "is_redacted": true,
    "is_internal": true,
    "created_at": "2022-04-13T15:42:05.901Z",
    "edited_at": "2022-04-13T15:42:05.901Z"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "id",
        "author",
        "body",
        "is_redacted",
        "is_internal",
        "created_at",
        "edited_at"
    ],
    "properties": {
        "id": {
            "type": "integer"
        },
        "author": {
            "type": "string",
            "nullable": true,
            "description": "Author email, masked unless the caller may see user emails on this advisory (INV-PRIVACY-4); null for authorless comments."
        },
        "body": {
            "type": "string",
            "description": "Redaction-aware text (`is_redacted` replaces the body)."
        },
        "is_redacted": {
            "type": "boolean"
        },
        "is_internal": {
            "type": "boolean"
        },
        "created_at": {
            "type": "string",
            "format": "date-time"
        },
        "edited_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
        }
    }
}

{
    "error": "string",
    "message": "string"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "error",
        "message"
    ],
    "properties": {
        "error": {
            "type": "string",
            "description": "Stable machine-readable code."
        },
        "message": {
            "type": "string",
            "description": "Human-readable explanation."
        }
    },
    "additionalProperties": true,
    "description": "Shared JSON error envelope. Some errors carry extra fields (e.g. `step_up_url` on `step_up_required`)."
}

Refer to the common response description: NotAuthenticated.

Refer to the common response description: Forbidden.

Refer to the common response description: NotFoundHtml.

Refer to the common response description: RateLimited.

Access grants


GET /api/advisories/{advisory_id}/grants/

List active grants and pending invitations

Description

Owner-gated (requires grant-management permission).

Input parameters

Parameter In Type Default Nullable Description
sessionCookie cookie string N/A No Django session established via the OIDC browser flow. Production uses the `__Host-` prefixed cookie name; dev/test use plain `sessionid`. There are no API tokens — this is an internal, same-origin API.
advisory_id path string No AdvisoryHub identifier (e.g. `ECL-q2f7-38cm-9wrx`). Malformed ids miss the URL pattern entirely and 404 at the resolver.

Responses

{
    "grants": [
        {
            "id": 0,
            "principal_type": "user",
            "principal_id": 0,
            "principal_label": "string",
            "permission": "viewer",
            "created_at": "2022-04-13T15:42:05.901Z"
        }
    ],
    "pending": [
        {
            "id": 0,
            "email": "string",
            "permission": "viewer",
            "expires_at": "2022-04-13T15:42:05.901Z",
            "redeemed_at": "2022-04-13T15:42:05.901Z"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "grants",
        "pending"
    ],
    "properties": {
        "grants": {
            "type": "array",
            "items": {
                "$ref": "#/components/schemas/Grant"
            }
        },
        "pending": {
            "type": "array",
            "items": {
                "$ref": "#/components/schemas/Invitation"
            }
        }
    }
}

Refer to the common response description: NotAuthenticated.

Refer to the common response description: Forbidden.

Refer to the common response description: NotFoundHtml.

Refer to the common response description: RateLimited.


POST /api/advisories/{advisory_id}/grants/

Grant access or invite by email

Description

Grants viewer or collaborator to a user (by email) or a group (by name). An email with no matching account creates a pending invitation redeemed on the recipient's first login. owner is never grantable (INV-AUTH-3). Rate limited to 20 requests/hour per user.

Input parameters

Parameter In Type Default Nullable Description
csrfToken header string N/A No Django CSRF token (double-submit with the `__Host-csrftoken` cookie; `csrftoken` in dev/test). Required alongside the session cookie on every unsafe method of the /api/ namespace.
sessionCookie cookie string N/A No Django session established via the OIDC browser flow. Production uses the `__Host-` prefixed cookie name; dev/test use plain `sessionid`. There are no API tokens — this is an internal, same-origin API.
advisory_id path string No AdvisoryHub identifier (e.g. `ECL-q2f7-38cm-9wrx`). Malformed ids miss the URL pattern entirely and 404 at the resolver.

Request body

{
    "principal": "user",
    "permission": "viewer",
    "email": "derp@meme.org",
    "group": "string"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the request body
{
    "type": "object",
    "required": [
        "principal",
        "permission"
    ],
    "properties": {
        "principal": {
            "type": "string",
            "enum": [
                "user",
                "group"
            ]
        },
        "permission": {
            "type": "string",
            "enum": [
                "viewer",
                "collaborator"
            ],
            "description": "`owner` is rejected with `invalid_permission` (INV-AUTH-3)."
        },
        "email": {
            "type": "string",
            "format": "email",
            "description": "Required when `principal=user`."
        },
        "group": {
            "type": "string",
            "description": "Required when `principal=group` (exact group name)."
        }
    }
}

{
    "principal": "user",
    "permission": "viewer",
    "email": "derp@meme.org",
    "group": "string"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the request body
{
    "type": "object",
    "required": [
        "principal",
        "permission"
    ],
    "properties": {
        "principal": {
            "type": "string",
            "enum": [
                "user",
                "group"
            ]
        },
        "permission": {
            "type": "string",
            "enum": [
                "viewer",
                "collaborator"
            ],
            "description": "`owner` is rejected with `invalid_permission` (INV-AUTH-3)."
        },
        "email": {
            "type": "string",
            "format": "email",
            "description": "Required when `principal=user`."
        },
        "group": {
            "type": "string",
            "description": "Required when `principal=group` (exact group name)."
        }
    }
}

Responses

{
    "created": "grant",
    "grant": {
        "id": 0,
        "principal_type": "user",
        "principal_id": 0,
        "principal_label": "string",
        "permission": "viewer",
        "created_at": "2022-04-13T15:42:05.901Z"
    },
    "invitation": {
        "id": 0,
        "email": "string",
        "permission": "viewer",
        "expires_at": "2022-04-13T15:42:05.901Z",
        "redeemed_at": "2022-04-13T15:42:05.901Z"
    }
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "created"
    ],
    "properties": {
        "created": {
            "type": "string",
            "enum": [
                "grant",
                "invitation"
            ]
        },
        "grant": {
            "$ref": "#/components/schemas/Grant"
        },
        "invitation": {
            "$ref": "#/components/schemas/Invitation"
        }
    },
    "description": "Exactly one of `grant` / `invitation` is present, matching the `created` discriminator."
}

{
    "error": "string",
    "message": "string"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "error",
        "message"
    ],
    "properties": {
        "error": {
            "type": "string",
            "description": "Stable machine-readable code."
        },
        "message": {
            "type": "string",
            "description": "Human-readable explanation."
        }
    },
    "additionalProperties": true,
    "description": "Shared JSON error envelope. Some errors carry extra fields (e.g. `step_up_url` on `step_up_required`)."
}

Refer to the common response description: NotAuthenticated.

Refer to the common response description: Forbidden.

{
    "error": "string",
    "message": "string"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "error",
        "message"
    ],
    "properties": {
        "error": {
            "type": "string",
            "description": "Stable machine-readable code."
        },
        "message": {
            "type": "string",
            "description": "Human-readable explanation."
        }
    },
    "additionalProperties": true,
    "description": "Shared JSON error envelope. Some errors carry extra fields (e.g. `step_up_url` on `step_up_required`)."
}

"string"
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "string"
}

Refer to the common response description: RateLimited.


DELETE /api/advisories/{advisory_id}/grants/{grant_id}/

Revoke a grant

Input parameters

Parameter In Type Default Nullable Description
csrfToken header string N/A No Django CSRF token (double-submit with the `__Host-csrftoken` cookie; `csrftoken` in dev/test). Required alongside the session cookie on every unsafe method of the /api/ namespace.
sessionCookie cookie string N/A No Django session established via the OIDC browser flow. Production uses the `__Host-` prefixed cookie name; dev/test use plain `sessionid`. There are no API tokens — this is an internal, same-origin API.
advisory_id path string No AdvisoryHub identifier (e.g. `ECL-q2f7-38cm-9wrx`). Malformed ids miss the URL pattern entirely and 404 at the resolver.
grant_id path integer No

Responses

{
    "revoked": 0
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "revoked"
    ],
    "properties": {
        "revoked": {
            "type": "integer",
            "description": "Id of the revoked grant."
        }
    }
}

Refer to the common response description: NotAuthenticated.

Refer to the common response description: Forbidden.

Refer to the common response description: NotFoundHtml.

Publication


GET /api/advisories/{advisory_id}/publication/

List publication tasks for an advisory

Input parameters

Parameter In Type Default Nullable Description
sessionCookie cookie string N/A No Django session established via the OIDC browser flow. Production uses the `__Host-` prefixed cookie name; dev/test use plain `sessionid`. There are no API tokens — this is an internal, same-origin API.
advisory_id path string No AdvisoryHub identifier (e.g. `ECL-q2f7-38cm-9wrx`). Malformed ids miss the URL pattern entirely and 404 at the resolver.

Responses

{
    "tasks": [
        {
            "id": 0,
            "advisory_id": "string",
            "status": "queued",
            "attempts": 0,
            "commit_sha": "string",
            "last_error": "string",
            "created_at": "2022-04-13T15:42:05.901Z",
            "started_at": "2022-04-13T15:42:05.901Z",
            "finished_at": "2022-04-13T15:42:05.901Z",
            "artifacts": [
                {
                    "kind": "osv",
                    "path": "string"
                }
            ]
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "tasks"
    ],
    "properties": {
        "tasks": {
            "type": "array",
            "items": {
                "$ref": "#/components/schemas/PublicationTask"
            }
        }
    }
}

Refer to the common response description: NotAuthenticated.

Refer to the common response description: Forbidden.

Refer to the common response description: NotFoundHtml.


POST /api/advisories/{advisory_id}/publish/

Queue publication of an advisory

Description

Pins the latest AdvisoryVersion on a new PublicationTask and enqueues the async OSV+CSAF export. The advisory's state flips to published only after the Git push succeeds (INV-LIFECYCLE-3). Requires a fresh step-up authentication when STEP_UP_REQUIRED is enabled. Rate limited to 10 requests/hour per user. No request body. For GHSA-linked advisories publication is system-driven (INV-GHSA-3): owners receive 403 (the EF feed mirrors the GHSA automatically); only global admins may call this as a break-glass, still gated on the linked GHSA being published upstream.

Input parameters

Parameter In Type Default Nullable Description
csrfToken header string N/A No Django CSRF token (double-submit with the `__Host-csrftoken` cookie; `csrftoken` in dev/test). Required alongside the session cookie on every unsafe method of the /api/ namespace.
sessionCookie cookie string N/A No Django session established via the OIDC browser flow. Production uses the `__Host-` prefixed cookie name; dev/test use plain `sessionid`. There are no API tokens — this is an internal, same-origin API.
advisory_id path string No AdvisoryHub identifier (e.g. `ECL-q2f7-38cm-9wrx`). Malformed ids miss the URL pattern entirely and 404 at the resolver.

Responses

{
    "id": 0,
    "advisory_id": "string",
    "status": "queued",
    "attempts": 0,
    "commit_sha": "string",
    "last_error": "string",
    "created_at": "2022-04-13T15:42:05.901Z",
    "started_at": "2022-04-13T15:42:05.901Z",
    "finished_at": "2022-04-13T15:42:05.901Z",
    "artifacts": [
        {
            "kind": "osv",
            "path": "string"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "id",
        "advisory_id",
        "status",
        "attempts",
        "commit_sha",
        "last_error",
        "created_at",
        "started_at",
        "finished_at",
        "artifacts"
    ],
    "properties": {
        "id": {
            "type": "integer"
        },
        "advisory_id": {
            "type": "string"
        },
        "status": {
            "type": "string",
            "enum": [
                "queued",
                "running",
                "succeeded",
                "failed"
            ]
        },
        "attempts": {
            "type": "integer"
        },
        "commit_sha": {
            "type": "string",
            "description": "Empty until a push succeeded."
        },
        "last_error": {
            "type": "string",
            "description": "Redacted failure summary; empty unless failed."
        },
        "created_at": {
            "type": "string",
            "format": "date-time"
        },
        "started_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
        },
        "finished_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
        },
        "artifacts": {
            "type": "array",
            "items": {
                "type": "object",
                "required": [
                    "kind",
                    "path"
                ],
                "properties": {
                    "kind": {
                        "type": "string",
                        "enum": [
                            "osv",
                            "csaf",
                            "cve"
                        ]
                    },
                    "path": {
                        "type": "string"
                    }
                }
            }
        }
    }
}
{
    "error": "step_up_required",
    "message": "Re-authenticate before publishing.",
    "step_up_url": "/oidc/step-up/"
}
Schema of the response body
{
    "type": "object",
    "required": [
        "error",
        "message"
    ],
    "properties": {
        "error": {
            "type": "string",
            "description": "Stable machine-readable code."
        },
        "message": {
            "type": "string",
            "description": "Human-readable explanation."
        }
    },
    "additionalProperties": true,
    "description": "Shared JSON error envelope. Some errors carry extra fields (e.g. `step_up_url` on `step_up_required`)."
}

Refer to the common response description: Forbidden.

Refer to the common response description: NotFoundHtml.

{
    "error": "string",
    "message": "string"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "error",
        "message"
    ],
    "properties": {
        "error": {
            "type": "string",
            "description": "Stable machine-readable code."
        },
        "message": {
            "type": "string",
            "description": "Human-readable explanation."
        }
    },
    "additionalProperties": true,
    "description": "Shared JSON error envelope. Some errors carry extra fields (e.g. `step_up_url` on `step_up_required`)."
}

Refer to the common response description: RateLimited.


POST /api/publication/tasks/{task_id}/retry/

Retry a failed publication task

Description

Creates a fresh task for the same pinned AdvisoryVersion. Only failed tasks are retryable. Step-up and rate limit as for publish. No request body.

Input parameters

Parameter In Type Default Nullable Description
csrfToken header string N/A No Django CSRF token (double-submit with the `__Host-csrftoken` cookie; `csrftoken` in dev/test). Required alongside the session cookie on every unsafe method of the /api/ namespace.
sessionCookie cookie string N/A No Django session established via the OIDC browser flow. Production uses the `__Host-` prefixed cookie name; dev/test use plain `sessionid`. There are no API tokens — this is an internal, same-origin API.
task_id path integer No

Responses

{
    "id": 0,
    "advisory_id": "string",
    "status": "queued",
    "attempts": 0,
    "commit_sha": "string",
    "last_error": "string",
    "created_at": "2022-04-13T15:42:05.901Z",
    "started_at": "2022-04-13T15:42:05.901Z",
    "finished_at": "2022-04-13T15:42:05.901Z",
    "artifacts": [
        {
            "kind": "osv",
            "path": "string"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "id",
        "advisory_id",
        "status",
        "attempts",
        "commit_sha",
        "last_error",
        "created_at",
        "started_at",
        "finished_at",
        "artifacts"
    ],
    "properties": {
        "id": {
            "type": "integer"
        },
        "advisory_id": {
            "type": "string"
        },
        "status": {
            "type": "string",
            "enum": [
                "queued",
                "running",
                "succeeded",
                "failed"
            ]
        },
        "attempts": {
            "type": "integer"
        },
        "commit_sha": {
            "type": "string",
            "description": "Empty until a push succeeded."
        },
        "last_error": {
            "type": "string",
            "description": "Redacted failure summary; empty unless failed."
        },
        "created_at": {
            "type": "string",
            "format": "date-time"
        },
        "started_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
        },
        "finished_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
        },
        "artifacts": {
            "type": "array",
            "items": {
                "type": "object",
                "required": [
                    "kind",
                    "path"
                ],
                "properties": {
                    "kind": {
                        "type": "string",
                        "enum": [
                            "osv",
                            "csaf",
                            "cve"
                        ]
                    },
                    "path": {
                        "type": "string"
                    }
                }
            }
        }
    }
}

{
    "error": "string",
    "message": "string"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "error",
        "message"
    ],
    "properties": {
        "error": {
            "type": "string",
            "description": "Stable machine-readable code."
        },
        "message": {
            "type": "string",
            "description": "Human-readable explanation."
        }
    },
    "additionalProperties": true,
    "description": "Shared JSON error envelope. Some errors carry extra fields (e.g. `step_up_url` on `step_up_required`)."
}

{
    "error": "string",
    "message": "string"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "error",
        "message"
    ],
    "properties": {
        "error": {
            "type": "string",
            "description": "Stable machine-readable code."
        },
        "message": {
            "type": "string",
            "description": "Human-readable explanation."
        }
    },
    "additionalProperties": true,
    "description": "Shared JSON error envelope. Some errors carry extra fields (e.g. `step_up_url` on `step_up_required`)."
}

Refer to the common response description: Forbidden.

Refer to the common response description: NotFoundHtml.

Refer to the common response description: RateLimited.


GET /api/publication/tasks/{task_id}/artifact/{kind}/

Preview a generated publication artifact

Input parameters

Parameter In Type Default Nullable Description
sessionCookie cookie string N/A No Django session established via the OIDC browser flow. Production uses the `__Host-` prefixed cookie name; dev/test use plain `sessionid`. There are no API tokens — this is an internal, same-origin API.
kind path string No Artifact kind; only OSV and CSAF artifacts are previewable.
task_id path integer No

Responses

{
    "kind": "osv",
    "path": "string",
    "content": {}
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "kind",
        "path",
        "content"
    ],
    "properties": {
        "kind": {
            "type": "string",
            "enum": [
                "osv",
                "csaf"
            ]
        },
        "path": {
            "type": "string",
            "description": "Path of the file inside the publication repo."
        },
        "content": {
            "type": "object",
            "description": "The OSV or CSAF JSON document."
        }
    }
}

{
    "error": "string",
    "message": "string"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "error",
        "message"
    ],
    "properties": {
        "error": {
            "type": "string",
            "description": "Stable machine-readable code."
        },
        "message": {
            "type": "string",
            "description": "Human-readable explanation."
        }
    },
    "additionalProperties": true,
    "description": "Shared JSON error envelope. Some errors carry extra fields (e.g. `step_up_url` on `step_up_required`)."
}

Refer to the common response description: NotAuthenticated.

Refer to the common response description: Forbidden.

Refer to the common response description: NotFoundHtml.

Dashboard tasks


POST /api/dashboard/cve/{task_id}/transition/

Transition a CVE request task

Description

Admin/security-team only.

Input parameters

Parameter In Type Default Nullable Description
csrfToken header string N/A No Django CSRF token (double-submit with the `__Host-csrftoken` cookie; `csrftoken` in dev/test). Required alongside the session cookie on every unsafe method of the /api/ namespace.
sessionCookie cookie string N/A No Django session established via the OIDC browser flow. Production uses the `__Host-` prefixed cookie name; dev/test use plain `sessionid`. There are no API tokens — this is an internal, same-origin API.
task_id path integer No

Request body

{
    "status": "queued",
    "cve_id": "string",
    "notes": "string"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the request body
{
    "type": "object",
    "required": [
        "status"
    ],
    "properties": {
        "status": {
            "type": "string",
            "enum": [
                "queued",
                "reserved",
                "rejected",
                "cancelled"
            ]
        },
        "cve_id": {
            "type": "string",
            "description": "The reserved CVE id (with `status=reserved`)."
        },
        "notes": {
            "type": "string"
        }
    }
}

{
    "status": "queued",
    "cve_id": "string",
    "notes": "string"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the request body
{
    "type": "object",
    "required": [
        "status"
    ],
    "properties": {
        "status": {
            "type": "string",
            "enum": [
                "queued",
                "reserved",
                "rejected",
                "cancelled"
            ]
        },
        "cve_id": {
            "type": "string",
            "description": "The reserved CVE id (with `status=reserved`)."
        },
        "notes": {
            "type": "string"
        }
    }
}

Responses

{
    "id": 0,
    "advisory_id": "string",
    "status": "queued",
    "cve_id": "string",
    "assignee": "string",
    "requested_by": "string",
    "created_at": "2022-04-13T15:42:05.901Z",
    "finished_at": "2022-04-13T15:42:05.901Z"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "id",
        "advisory_id",
        "status",
        "cve_id",
        "assignee",
        "requested_by",
        "created_at",
        "finished_at"
    ],
    "properties": {
        "id": {
            "type": "integer"
        },
        "advisory_id": {
            "type": "string"
        },
        "status": {
            "type": "string",
            "enum": [
                "queued",
                "reserved",
                "rejected",
                "cancelled"
            ]
        },
        "cve_id": {
            "type": "string",
            "nullable": true
        },
        "assignee": {
            "type": "string",
            "nullable": true,
            "description": "Email; masked for non-admin callers."
        },
        "requested_by": {
            "type": "string",
            "nullable": true,
            "description": "Email; masked for non-admin callers."
        },
        "created_at": {
            "type": "string",
            "format": "date-time"
        },
        "finished_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
        }
    }
}

{
    "error": "string",
    "message": "string"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "error",
        "message"
    ],
    "properties": {
        "error": {
            "type": "string",
            "description": "Stable machine-readable code."
        },
        "message": {
            "type": "string",
            "description": "Human-readable explanation."
        }
    },
    "additionalProperties": true,
    "description": "Shared JSON error envelope. Some errors carry extra fields (e.g. `step_up_url` on `step_up_required`)."
}

Refer to the common response description: NotAuthenticated.

Refer to the common response description: Forbidden.

Refer to the common response description: NotFoundHtml.


POST /api/dashboard/review/{task_id}/decide/

Decide a review task

Description

Admin/security-team only.

Input parameters

Parameter In Type Default Nullable Description
csrfToken header string N/A No Django CSRF token (double-submit with the `__Host-csrftoken` cookie; `csrftoken` in dev/test). Required alongside the session cookie on every unsafe method of the /api/ namespace.
sessionCookie cookie string N/A No Django session established via the OIDC browser flow. Production uses the `__Host-` prefixed cookie name; dev/test use plain `sessionid`. There are no API tokens — this is an internal, same-origin API.
task_id path integer No

Request body

{
    "decision": "approved",
    "notes": "string"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the request body
{
    "type": "object",
    "required": [
        "decision"
    ],
    "properties": {
        "decision": {
            "type": "string",
            "enum": [
                "approved",
                "changes_requested"
            ]
        },
        "notes": {
            "type": "string"
        }
    }
}

{
    "decision": "approved",
    "notes": "string"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the request body
{
    "type": "object",
    "required": [
        "decision"
    ],
    "properties": {
        "decision": {
            "type": "string",
            "enum": [
                "approved",
                "changes_requested"
            ]
        },
        "notes": {
            "type": "string"
        }
    }
}

Responses

{
    "id": 0,
    "advisory_id": "string",
    "status": "open",
    "submitted_by": "string",
    "reviewer": "string",
    "decision_notes": "string",
    "created_at": "2022-04-13T15:42:05.901Z",
    "decided_at": "2022-04-13T15:42:05.901Z"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "id",
        "advisory_id",
        "status",
        "submitted_by",
        "reviewer",
        "decision_notes",
        "created_at",
        "decided_at"
    ],
    "properties": {
        "id": {
            "type": "integer"
        },
        "advisory_id": {
            "type": "string"
        },
        "status": {
            "type": "string",
            "enum": [
                "open",
                "approved",
                "changes_requested",
                "withdrawn"
            ]
        },
        "submitted_by": {
            "type": "string",
            "nullable": true,
            "description": "Email; masked for non-admin callers."
        },
        "reviewer": {
            "type": "string",
            "nullable": true,
            "description": "Email; masked for non-admin callers."
        },
        "decision_notes": {
            "type": "string",
            "nullable": true
        },
        "created_at": {
            "type": "string",
            "format": "date-time"
        },
        "decided_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
        }
    }
}

{
    "error": "string",
    "message": "string"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "error",
        "message"
    ],
    "properties": {
        "error": {
            "type": "string",
            "description": "Stable machine-readable code."
        },
        "message": {
            "type": "string",
            "description": "Human-readable explanation."
        }
    },
    "additionalProperties": true,
    "description": "Shared JSON error envelope. Some errors carry extra fields (e.g. `step_up_url` on `step_up_required`)."
}

Refer to the common response description: NotAuthenticated.

Refer to the common response description: Forbidden.

Refer to the common response description: NotFoundHtml.

GHSA webhook


POST /ghsa/webhook/

Receive a GitHub App webhook delivery

Description

CSRF-exempt, session-free receiver authenticated by an HMAC-SHA256 signature over the raw request body (sha256=<hex> in X-Hub-Signature-256, keyed with the app's webhook secret, compared in constant time before any body parsing). Deliveries are idempotent on X-GitHub-Delivery; accepted events are processed asynchronously.

Input parameters

Parameter In Type Default Nullable Description
X-GitHub-Delivery header string No Unique delivery id; replays are detected on this value.
X-GitHub-Event header string No GitHub event name (e.g. `repository_advisory`).
X-Hub-Signature-256 header string No HMAC-SHA256 of the raw body, keyed with the webhook secret.

Request body

Schema of the request body
{
    "type": "object",
    "description": "GitHub webhook event payload (passed through as-is)."
}

Responses

{
    "status": "accepted",
    "delivery_id": "string"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "status",
        "delivery_id"
    ],
    "properties": {
        "status": {
            "type": "string",
            "enum": [
                "accepted"
            ]
        },
        "delivery_id": {
            "type": "string"
        }
    }
}

{
    "status": "already_processed"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "status"
    ],
    "properties": {
        "status": {
            "type": "string",
            "enum": [
                "already_processed"
            ]
        }
    }
}

{
    "error": "string"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "error"
    ],
    "properties": {
        "error": {
            "type": "string"
        }
    },
    "description": "Note — not the shared Error shape: this endpoint emits `{\"error\": \"<text>\"}` with no `message` field."
}

Intake


GET /report/projects.json

Project picker entries for the public report form

Description

Unauthenticated autocomplete data source, capped at 200 entries. Rate limited to 60 requests/minute per client IP.

Input parameters

Parameter In Type Default Nullable Description
q query string No Case-insensitive substring match over slug and name.

Responses

[
    {
        "slug": "string",
        "name": "string"
    }
]
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "array",
    "maxItems": 200,
    "items": {
        "$ref": "#/components/schemas/ProjectPickerEntry"
    }
}

Response headers

Name Description Schema
Cache-Control public, max-age=300 string

Refer to the common response description: RateLimited.

Health


GET /healthz

Liveness probe

Responses

{
    "status": "ok"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "status"
    ],
    "properties": {
        "status": {
            "type": "string",
            "enum": [
                "ok"
            ]
        }
    }
}

GET /readyz

Readiness probe

Description

Checks the database and cache, plus optionally the Celery broker (READYZ_INCLUDE_BROKER) and the publication repository (READYZ_INCLUDE_PUB_REPO).

Responses

{
    "status": "ok"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "status"
    ],
    "properties": {
        "status": {
            "type": "string",
            "enum": [
                "ok"
            ]
        }
    }
}

{
    "status": "fail",
    "failures": {}
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "status",
        "failures"
    ],
    "properties": {
        "status": {
            "type": "string",
            "enum": [
                "fail"
            ]
        },
        "failures": {
            "type": "object",
            "additionalProperties": {
                "type": "string"
            },
            "description": "Failing check name (`db`, `cache`, `broker`, `publication_repo`) to exception class name."
        }
    }
}

Schemas

Advisory

Name Type Description
advisory_id string
affected Array<AffectedEntry>
aliases Array<string> External identifiers (CVE, GHSA, ...).
created_at string(date-time)
credits Array<Credit>
cwe_ids Array<string> CWE identifiers (e.g. `CWE-79`).
details string
dismissed_reason string Empty unless the advisory was dismissed.
modified_at string(date-time)
project ProjectRef
published_at string(date-time) | null
references Array<Reference>
republish_required boolean
review_status ReviewStatus
severity Array<SeverityEntry>
state AdvisoryState
submitted_for_review_at string(date-time) | null
summary string
url string Relative URL of the advisory's HTML detail page.
withdrawn_reason string Empty unless the advisory was withdrawn.

AdvisoryListPage

Name Type Description
page integer
page_size integer
results Array<AdvisorySummary>
total integer Total matches across all pages.

AdvisoryState

Type: string

AdvisorySummary

Name Type Description
advisory_id string
modified_at string(date-time)
project string Project slug.
published_at string(date-time) | null
republish_required boolean A content edit landed after the last publication.
review_status ReviewStatus
state AdvisoryState
summary string

AffectedEntry

Name Type Description
package Properties: name, ecosystem
ranges Array<Properties: type, events>
versions Array<string>

Comment

Name Type Description
author string | null Author email, masked unless the caller may see user emails on this advisory (INV-PRIVACY-4); null for authorless comments.
body string Redaction-aware text (`is_redacted` replaces the body).
created_at string(date-time)
edited_at string(date-time) | null
id integer
is_internal boolean
is_redacted boolean

CommentCreate

Name Type Description
body string Comment text; surrounding whitespace is stripped.
is_internal boolean When false (the default) the comment is visible to everyone with access to the advisory; when true it is hidden from users without internal-comment visibility. Either way the comment is never published or disclosed externally. With a form-encoded body any non-empty string is truthy — use JSON for reliable boolean semantics.

Credit

Name Type Description
contact Array<string>
name string
type string

CveTask

Name Type Description
advisory_id string
assignee string | null Email; masked for non-admin callers.
created_at string(date-time)
cve_id string | null
finished_at string(date-time) | null
id integer
requested_by string | null Email; masked for non-admin callers.
status string

CveTransition

Name Type Description
cve_id string The reserved CVE id (with `status=reserved`).
notes string
status string

Error

Name Type Description
error string Stable machine-readable code.
message string Human-readable explanation.

Grant

Name Type Description
created_at string(date-time)
id integer
permission string
principal_id integer
principal_label string | null User email (masked unless the caller may see user emails) or group name; null when the principal no longer exists.
principal_type string

GrantCreate

Name Type Description
email string() Required when `principal=user`.
group string Required when `principal=group` (exact group name).
permission string `owner` is rejected with `invalid_permission` (INV-AUTH-3).
principal string

Invitation

Name Type Description
email string Masked unless the caller may see user emails.
expires_at string(date-time) | null
id integer
permission string
redeemed_at string(date-time) | null

ProjectPickerEntry

Name Type Description
name string
slug string

ProjectRef

Name Type Description
id string(uuid)
is_mature_publisher boolean
name string
slug string

PublicationTask

Name Type Description
advisory_id string
artifacts Array<Properties: kind, path>
attempts integer
commit_sha string Empty until a push succeeded.
created_at string(date-time)
finished_at string(date-time) | null
id integer
last_error string Redacted failure summary; empty unless failed.
started_at string(date-time) | null
status string

Reference

Name Type Description
type string
url string(uri) http/https/ftp/ftps only.

ReviewDecision

Name Type Description
decision string
notes string

ReviewStatus

Type: string

ReviewTask

Name Type Description
advisory_id string
created_at string(date-time)
decided_at string(date-time) | null
decision_notes string | null
id integer
reviewer string | null Email; masked for non-admin callers.
status string
submitted_by string | null Email; masked for non-admin callers.

SeverityEntry

Name Type Description
score string CVSS vector string, or one of negligible/low/medium/high/critical for `Ubuntu`.
type string

Common responses

This section describes common responses that are reused across operations.

NotAuthenticated

No authenticated session (not_authenticated).

{
    "error": "string",
    "message": "string"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "error",
        "message"
    ],
    "properties": {
        "error": {
            "type": "string",
            "description": "Stable machine-readable code."
        },
        "message": {
            "type": "string",
            "description": "Human-readable explanation."
        }
    },
    "additionalProperties": true,
    "description": "Shared JSON error envelope. Some errors carry extra fields (e.g. `step_up_url` on `step_up_required`)."
}

Forbidden

The caller lacks the required permission (forbidden).

{
    "error": "string",
    "message": "string"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "error",
        "message"
    ],
    "properties": {
        "error": {
            "type": "string",
            "description": "Stable machine-readable code."
        },
        "message": {
            "type": "string",
            "description": "Human-readable explanation."
        }
    },
    "additionalProperties": true,
    "description": "Shared JSON error envelope. Some errors carry extra fields (e.g. `step_up_url` on `step_up_required`)."
}

NotFoundHtml

Unknown resource. Django's default error page — text/html, not JSON.

"string"
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "string"
}

RateLimited

Rate limit exceeded (rate_limited).

{
    "error": "string",
    "message": "string"
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "object",
    "required": [
        "error",
        "message"
    ],
    "properties": {
        "error": {
            "type": "string",
            "description": "Stable machine-readable code."
        },
        "message": {
            "type": "string",
            "description": "Human-readable explanation."
        }
    },
    "additionalProperties": true,
    "description": "Shared JSON error envelope. Some errors carry extra fields (e.g. `step_up_url` on `step_up_required`)."
}

Common parameters

This section describes common parameters that are reused across operations.

AdvisoryId

Name In Type Default Nullable Description
advisory_id path string No

TaskId

Name In Type Default Nullable Description
task_id path integer No

Security schemes

Name Type Scheme Description
sessionCookie apiKey Django session established via the OIDC browser flow. Production uses the `__Host-` prefixed cookie name; dev/test use plain `sessionid`. There are no API tokens — this is an internal, same-origin API.
csrfToken apiKey Django CSRF token (double-submit with the `__Host-csrftoken` cookie; `csrftoken` in dev/test). Required alongside the session cookie on every unsafe method of the /api/ namespace.

Tags

Name Description
Advisories Read access to advisories visible to the authenticated user.
Comments Per-advisory discussion threads.
Access grants Per-advisory viewer/collaborator grants and pending email invitations (owner is derived from project security-team membership and is never grantable — INV-AUTH-3).
Publication OSV+CSAF export pipeline status and controls. An advisory's state flips to published only after a successful Git push (INV-LIFECYCLE-3).
Dashboard tasks Admin/security-team task transitions (CVE requests, reviews).
GHSA webhook Inbound GitHub App webhook receiver.
Intake Public report-form support endpoints.
Health Liveness/readiness probes for orchestration.