Packamal / PackGuard Analysis API (1.0.0)

Download OpenAPI specification:

Submit packages (PURL or uploaded archive) for analysis and retrieve task status/results.

This API supports two analysis engines selected by the optional Engine header:

  • dynamic-analysis (default): dynamic analysis pipeline for npm, PyPI, and VS Code extensions
  • lastpymile: LastPyMile analysis pipeline (supports npm and PyPI only)

Two submission modes are supported:

  • Live scan (registry) via POST /api/v1/analyze/purl/
  • Local archive scan via a 3-step flow:
    1. POST /api/v1/archives/upload-url/ to obtain a signed upload URL + gcs_path
    2. PUT the file to the signed URL (Google Cloud Storage)
    3. POST /api/v1/analyze/archive/ with purl + gcs_path (+ optional GitHub URL)

Analysis

Submit a live scan (registry) by PURL

Queues analysis for the given PURL.

The Engine header selects analysis engine:

  • omitted/empty => dynamic-analysis
  • dynamic-analysis => dynamic analysis (npm, pypi, vscode-extension)
  • lastpymile => LastPyMile (npm and pypi only)

Notes:

  • If a matching completed task exists, the backend may return a legacy (non-enveloped) JSON body.
  • If an active task exists, returns an enveloped success response indicating current status.
Authorizations:
bearerAuthapiKeyAuth
header Parameters
Engine
string
Default: dynamic-analysis
Enum: "dynamic-analysis" "lastpymile"

Select analysis engine. Missing/empty defaults to dynamic-analysis. lastpymile supports npm and PyPI only.

Request Body schema: application/json
required
purl
required
string

Package URL (must start with pkg:)

Responses

Request samples

Content type
application/json
Example
{
  • "purl": "pkg:npm/axios@1.14.1"
}

Response samples

Content type
application/json
Example
{
  • "success": true,
  • "request_id": "d96c0c9a-6e3c-44cb-bfb1-1b1c5b3c50b0",
  • "data": {}
}

Submit analysis for an uploaded archive

Queues analysis for an archive previously uploaded to GCS via the signed URL from POST /api/v1/archives/upload-url/.

The Engine header selects analysis engine (same as PURL scan). When using Engine: lastpymile, only npm and PyPI packages are supported.

Optional GitHub URL:

  • You may provide github_url or archive_github_url (alias); backend stores it as archive_github_url.
Authorizations:
bearerAuthapiKeyAuth
header Parameters
Engine
string
Default: dynamic-analysis
Enum: "dynamic-analysis" "lastpymile"

Select analysis engine. Missing/empty defaults to dynamic-analysis. lastpymile supports npm and PyPI only.

Request Body schema: application/json
required
purl
required
string
gcs_path
required
string

GCS object path returned by /api/v1/archives/upload-url/

github_url
string or null <uri>

Optional source repository URL (alias of archive_github_url)

archive_github_url
string or null <uri>

Optional source repository URL (alias of github_url)

Responses

Request samples

Content type
application/json
Example
{
  • "purl": "pkg:npm/axios@1.14.1",
  • "gcs_path": "uploads/uuid/axios-1.14.1.tgz"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "request_id": "string",
  • "data": {
    }
}

Archives

Get a signed upload URL for an archive

Returns a signed URL for direct upload to GCS plus a gcs_path token to pass to POST /api/v1/analyze/archive/.

After receiving the signed URL, upload the file using:

  • PUT {url} with the archive bytes (content-type depends on file type).
Authorizations:
bearerAuthapiKeyAuth
Request Body schema: application/json
required
filename
required
string

Original archive filename (e.g. .tgz, .whl, .tar.gz, .zip, .vsix)

Responses

Request samples

Content type
application/json
Example
{
  • "filename": "axios-1.14.1.tgz"
}

Response samples

Content type
application/json
{
  • "success": true,
  • "request_id": "5a7ffdf8-44a9-4c7f-84b5-68e5a38cb7fb",
  • "data": {}
}

Tasks

Get task status (and report URL if completed)

Returns task metadata. When status is completed and a report is available, the field report_blob_url is included.

Report payload at report_blob_url depends on engine:

  • dynamic-analysis -> DynamicAnalysisReport
  • lastpymile -> LastPyMileReport
path Parameters
task_id
required
integer >= 1

Responses

Response samples

Content type
application/json
Example
{
  • "success": true,
  • "request_id": "0b7d1d7f-6b9c-4e14-9a67-f5f0d2d6b9bf",
  • "data": {
    }
}

Reports

List tasks (reports) for the caller API key

Authorizations:
bearerAuthapiKeyAuth
query Parameters
page
integer >= 1
Default: 1
page_size
integer [ 1 .. 100 ]
Default: 20
status
string (TaskStatus)
Enum: "queued" "processing" "completed" "failed" "timeout"

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "request_id": "string",
  • "data": {
    }
}