- 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, andfindings: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.gzarchive and use the source upload flow. No Git remote or website scan is required.
§ 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:§ 04 Check credit balances
Use the service key to read the current balances for its organization before offering scan choices: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, uniqueIdempotency-Key for each intended scan. Reuse it only when retrying the identical request after a transport error, timeout, or 5xx.
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.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
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:
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
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, callapex login, or remain attached while a multi-hour scan completes.
Short prompts for adapter development:
- Using
APEX_SERVICE_KEYfrom 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 itslocal_archivescan 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.