Skip to content

REST and GraphQL APIs

ONEKEY provides comprehensive APIs for accessing firmware analysis capabilities. The API consists of two complementary parts designed to support different use cases:

  • REST API - Authentication and file operations (uploads/downloads).
  • GraphQL API - Access the full platform functionality with flexible querying and mutation capabilities.

Important

The GraphQL API requires authentication. Authenticate using either the REST API flow or an API Token.

All authenticated API requests must include the Authorization header with your tenant token1 or API token2:

Authorization: Bearer <your-tenant-token>

Full API documentation is available at:

An interactive GraphQL Playground is accessible on the platform by enabling GraphQL console access:

  1. Click on your profile in the top-right corner:
    Select profile
  2. Enable GraphQL console access.
  3. Click GQL next to the Upload firmware button.

For help writing GraphQL queries, see Writing GraphQL queries.

REST API

The REST API provides endpoints for:

  • Authentication - User login and token management.
  • Firmware operations - Upload, download, metadata management.
  • File operations - Download extracted files, binaries, and analysis artifacts.
  • Reports - Generate and download .pdf and .csv reports.
  • Version information - Query API and platform versions.

Key REST endpoints:

Endpoint Method Purpose
/login POST Query authentication provider for email
/authorize POST Authenticate and receive ID token
/token POST Exchange ID token for tenant token
/upload-firmware/{metadata_id} POST Upload firmware binary for analysis
/firmwares/{firmware_id}/download-file/{file_path} GET Download file from analyzed firmware
/firmwares/{firmware_id}/sbom GET Download SBOM (CycloneDX or SPDX)
/version GET Get API version information

Authentication

One of the main workflows for the REST API is authentication. ONEKEY supports two authentication methods: email and password login and creating an API token on the platform. The REST API handles the email and password flow. It consists of three steps: login, authorization, and getting the tenant token.

Step 1: Login (/login)

Query the authentication configuration for a given email address:

curl -X POST https://app.eu.onekey.com/api/login \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com"}'

Response:

{
  "mode": "local"
}

The mode field indicates the authentication provider (e.g., local for local authentication, or SSO provider details).

Step 2: Authorize (/authorize)

Authenticate with credentials and receive an ID token:

curl -X POST https://app.eu.onekey.com/api/authorize \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "your-password",
    "nonce": "your-generated-nonce",
    "client_id": "web"
  }'

Response:

{
  "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "policies_accepted_at": "2023-06-15T18:17:41Z"
}

The id_token is a JWT token containing user identity and tenant information. Use this token to request tenant-specific access.

Nonce

The nonce is a random string you generate to protect against replay attacks. Use the same value in both /authorize and /token.

Step 3: Get tenant token (/token)

Exchange the ID token for a tenant-specific access token:

curl -X POST https://app.eu.onekey.com/api/token \
  -H "Content-Type: application/json" \
  -d '{
    "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
    "tenant_id": "your-tenant-id",
    "client_id": "web",
    "nonce": "your-generated-nonce"
  }'

Response:

{
  "tenant_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user_email": "user@example.com",
  "roles": ["editor"],
  "user_groups": [{ "id": "550e8400-e29b-41d4-a716-446655440000", "name": "My Team" }],
  "product_groups": [{ "id": "660e8400-e29b-41d4-a716-446655440001", "name": "Default" }]
}

The tenant_token is a Bearer token used for all subsequent API requests. It contains tenant-specific permissions and product group access. The token is short-lived – once it expires, you must repeat the full authentication flow to obtain a new one. For long-running automation, consider using an API token instead.

Downloading files

Download extracted files

curl -X GET "https://app.eu.onekey.com/api/firmwares/<firmware-id>/download-file/bin/busybox" \
  -H "Authorization: Bearer <your-token>" \
  -o busybox

Download SBOM

Generate and download a Software Bill of Materials. You can select the format via the Accept header:

curl -X GET "https://app.eu.onekey.com/api/firmwares/<firmware-id>/sbom" \
  -H "Authorization: Bearer <your-token>" \
  -H "Accept: application/vnd.cyclonedx+json; version=1.6" \
  -o sbom.cdx.json
curl -X GET "https://app.eu.onekey.com/api/firmwares/<firmware-id>/sbom" \
  -H "Authorization: Bearer <your-token>" \
  -H "Accept: application/vnd.cyclonedx+xml; version=1.6" \
  -o sbom.cdx.xml
curl -X GET "https://app.eu.onekey.com/api/firmwares/<firmware-id>/sbom" \
  -H "Authorization: Bearer <your-token>" \
  -H "Accept: application/spdx+json; version=2.3" \
  -o sbom.spdx.json
curl -X GET "https://app.eu.onekey.com/api/firmwares/<firmware-id>/sbom" \
  -H "Authorization: Bearer <your-token>" \
  -H "Accept: application/spdx+xml; version=2.3" \
  -o sbom.spdx.xml

Omitting or sending an unsupported Accept header returns 406 Not Acceptable.

Available SBOM formats for download
  • CycloneDX JSON (versions 1.2 - 1.7)
  • CycloneDX XML (versions 1.1 - 1.7)
  • SPDX JSON (version 2.3)
  • SPDX XML (version 2.3)

GraphQL API

The GraphQL API provides comprehensive access to all platform functionality:

  • Queries - Retrieve firmware, products, analysis results, issues, CVEs.
  • Mutations - Create/update/delete resources, trigger analyses, manage settings.
  • Subscriptions - Real-time updates for analysis progress and report generation.

Firmware upload workflow

Uploading firmware for analysis requires two steps: creating metadata and uploading the binary.

Step 1: Create firmware metadata

Use the GraphQL createFirmwareUpload mutation to prepare for upload:

mutation {
  createFirmwareUpload(input: {
    firmware: {
      name: "MyRouter 1.2.3"
      version: "1.2.3"
    }
    product: {
      name: "MyRouter"
      vendor: "MyVendor"
    }
    productGroup: {
      id: "<product-group-id>"
    }
  }) {
    ... on FirmwareUploadMetadata {
      id
      uploadUrl
    }
  }
}

Tip

Query allProductGroups to find the ID of the product group you want to upload to:

query {
  allProductGroups {
    id
    name
  }
}

Execute with curl:

curl -X POST https://app.eu.onekey.com/api/graphql \
  -H "Authorization: Bearer <your-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation { createFirmwareUpload(input: { firmware: { name: \"MyRouter 1.2.3\", version: \"1.2.3\" }, product: { name: \"MyRouter\", vendor: \"MyVendor\" }, productGroup: { id: \"<product-group-id>\" } }) { ... on FirmwareUploadMetadata { id uploadUrl } } }"
  }'

Response:

{
  "data": {
    "createFirmwareUpload": {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "uploadUrl": "https://app.eu.onekey.com/api/upload-firmware/550e8400-e29b-41d4-a716-446655440000"
    }
  }
}

Info

If you receive an error, make sure you have the Upload permission for the target product group.

Step 2: Upload firmware binary

Upload the firmware file using the uploadUrl from Step 1:

curl -X POST <uploadUrl> \
  -H "Authorization: Bearer <your-token>" \
  -F "firmware=@path/to/firmware.bin"

With optional SBOM:

curl -X POST <uploadUrl> \
  -H "Authorization: Bearer <your-token>" \
  -F "firmware=@path/to/firmware.bin" \
  -F "sbom=@path/to/sbom.json"

Response:

{
  "firmware_id": "660e8400-e29b-41d4-a716-446655440001"
}

The firmware_id identifies your uploaded firmware. Save this UUID to query analysis progress and retrieve results.

Querying analysis results

Once firmware is uploaded, analysis begins automatically. Query the analysis status and results using GraphQL.

Check analysis status

query {
  firmware(id: "abc123") {
    id
    name
    processing {
      ... on ProcessingInProgress {
        state
      }
      ... on ProcessingFailed {
        reason
      }
      ... on ProcessingFinished {
        finishTime
      }
    }
  }
}

Execute:

curl -X POST https://app.eu.onekey.com/api/graphql \
  -H "Authorization: Bearer <your-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query { firmware(id: \"abc123\") { id name processing { ... on ProcessingInProgress { state } ... on ProcessingFailed { reason } ... on ProcessingFinished { finishTime } } } }"
  }'

The processing field indicates the current status:

  • ProcessingInProgress — analysis is running, with state: WAITING | ANALYZING
  • ProcessingFailed — analysis failed; the reason field describes what went wrong
  • ProcessingFinished — analysis completed, with a finishTime timestamp

Retrieve analysis results

After analysis completes query the results:

query {
  firmware(id: "abc123") {
    id
    name
    latestAnalysisTime

    # Security issues
    latestIssues {
      id
      type
      summary
      severity
    }

    # CVEs
    cveMatches {
      id
      cve {
        id
        description
        severity
      }
      component {
        name
        version
      }
    }

    # Components
    components {
      name
      version
      licenses
    }
  }
}

For more specific query examples, see Writing GraphQL queries.


  1. A tenant token is a short-lived JWT obtained through the three-step REST API authentication flow (/login/authorize/token). It is scoped to a specific tenant and carries the user's roles and product group permissions. Suitable for interactive sessions and applications that perform the full login handshake. 

  2. An API token is a long-lived token created in the ONEKEY platform UI under Profile → API tokens. It uses the format {tenant-id}/{secret} and is designed for automation, CI/CD pipelines, and scripts where storing user credentials is not desirable. See API tokens for details.