Skip to main content
  • Read: 12 min
  • Updated: August 17, 2026
  • Audience: Platform engineers

§ 01 Choose the right integration

Use Apex CLI or MCP when a person or coding agent is working interactively in a repository. Use the service API when a headless process needs HTTP, JSON, and a static organization credential. Set the service key as APEX_SERVICE_KEY and send it as Authorization: Bearer ... or X-API-Key. The CLI does not consume this variable and apex login does not accept service keys. APEX_API_KEY is a legacy integration name; rename it to APEX_SERVICE_KEY when adopting these examples. The machine-readable contract is available at /api/apex/v1/openapi.json.

§ 02 Prerequisites

  • Generate a service key with the smallest required scopes: scans:create, scans:read, and findings:read.
  • Store the key in a secret manager. Apex displays the raw secret once and stores only its hash.
  • For a remote scan, connect the GitHub repository to the organization that owns the key. The first API scan can create and link its workspace automatically.
  • For a remote scan, send a full 40- or 64-character commit SHA. Branch names and moving refs are not accepted.
  • For a local or non-Git directory, create a tar.gz archive and use the source upload flow. No Git remote or website scan is required.
GitLab service-account access is not yet supported by the version-one remote repository flow. Use a local archive for source that Apex cannot materialize through an organization GitHub connection.

§ 03 Generate a service key

Organization managers and Apex administrators can generate a key from Company Settings → Service API keys. Copy the one-time secret directly into a secret manager. You can also create one from your own authenticated terminal:
The commands above use device login only to let an authorized person create the service key. The resulting service key is for REST requests, not later CLI authentication. List metadata or revoke a key without exposing its secret:

§ 04 Check credit balances

Use the service key to read the current balances for its organization before offering scan choices:
The endpoint requires scans:create and never accepts a company identifier; the authenticated service key determines the organization. scanTypes applies the active credit ledger, configured cost, and scansEnabled state. Source compatibility is separate: local archives support only standard, while audit and lite require a provider-backed GitHub source. The response is a point-in-time snapshot. Scan creation can still return 402 if another request consumes the entitlement first; refresh the balances before offering another confirmed choice.

§ 05 Trigger a remote scan

Send a stable, unique Idempotency-Key for each intended scan. Reuse it only when retrying the identical request after a transport error, timeout, or 5xx.
If no active workspace is linked to the canonical repository, Apex creates one and links it before starting the scan. If multiple workspaces match, the API returns a conflict with workspace choices; submit a new intended request with the selected workspaceId and a new idempotency key. When workspaceId is present, useExistingThreatModel defaults to true. Apex validates that a completed model exists before reserving credits. Set generateThreatModel: true for a fresh model, or generateThreatModel: false only when you intentionally want neither generation nor validated reuse. The optional paths array is a focus hint, not a security boundary. Apex may inspect or report code outside those paths.

§ 06 Scan a local directory

Raw filesystem paths cannot cross an HTTP boundary. Package the source, calculate its SHA-256 plus compressed and uncompressed byte counts, then create, upload, complete, and scan the archive.
A newly created local workspace has no completed threat model to reuse. Keep generateThreatModel: true on its first scan; omitting it makes a request with workspaceId default to existing-model reuse and can return THREAT_MODEL_NOT_AVAILABLE. Each archive must be at most 500 MiB compressed and 2 GiB uncompressed. A scan can include at most 20 archives. Signed upload URLs are credentials: do not log or persist them beyond the upload. A successful scan request returns HTTP 202:

§ 07 Poll and cancel scans

Retain scanId and workspaceId. Poll with bounded backoff while status is preparing, queued, or running; stop on completed, failed, or cancelled. Large scans can take hours, so a 20-minute timeout is not suitable for full-codebase benchmarking. Make polling resumable instead of creating a duplicate scan after a client restart. To cancel an active scan:
Cancellation requires scans:create. Repeating a successful cancellation is safe. Apex returns 409 when the scan is already completed or failed, or has not started in Apex yet.

§ 08 Fetch findings

The scan findings response is a GitLab SAST report. Each vulnerability includes the persisted Apex finding ID, title, description, severity, and available source location. IDs remain stable when the same scan is fetched again. A key with findings:read can retrieve unpublished drafts. Treat the payload and credential as privileged data. The first findings request after completion may return 503 with Retry-After while Apex durably synchronizes the terminal finding set. Retry the same GET. To retrieve the same cross-scan set as the workspace findings browser, use a workspace prefix or UUID:
state=open excludes invalid findings, duplicates, and findings marked fixed, false positive, won’t fix, or skipped. Repeat filter to combine facets such as severity:high, review:accepted, repo:example-app, source:lib/auth.ts, or !validation:invalid.

§ 09 Errors and retries

GET and cancellation requests are safe to retry. After a transport error, timeout, or 5xx, retry scan creation only with the original body and original Idempotency-Key. After correcting a definitive 4xx, submit a new intended request with a new key. Never log authorization headers, the service key, or signed upload URLs.

§ 10 Agent-ready environment prompt

Use the API agent environment when a coding agent or orchestration system must choose a source and start one Standard scan, then return the workspace ID, scan ID, and handoff links immediately. It is deliberately REST-only: it does not install Apex CLI, call apex login, or remain attached while a multi-hour scan completes. Short prompts for adapter development:
  • Using APEX_SERVICE_KEY from the environment, fetch the organization’s current Apex Standard credit balance, ask whether to use the exact local archive or a compatible provider-backed commit, start one confirmed Standard scan, and immediately return its workspace ID, scan ID, accepted status, status URL, findings URL, and web link without logging credentials.
  • Package this local directory as tar.gz, create and complete an Apex source upload, then start a standard scan from its local_archive scan source. Keep the service key and signed upload URL secret.
  • Given an Apex scanId, fetch its findings, preserve the raw response, and import each vulnerability once by stable ID. Do not trigger a new scan.