> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cantina.security/llms.txt
> Use this file to discover all available pages before exploring further.

# Apex API agent environment

> A copyable REST-only prompt that selects a source and starts a Standard Apex scan, then returns handoff links immediately.

* **Read:** 7 min
* **Updated:** August 17, 2026
* **Audience:** Platform engineers and agent developers

## When to use this prompt

Use this environment prompt when an agent, CI worker, or orchestration service
must choose a source and start one Standard Apex scan without remaining attached
for hours. The agent returns the workspace and scan identifiers plus links as
soon as Apex accepts the scan. A person or separate worker can monitor it
afterward.

Do not combine it with CLI instructions. Apex CLI and MCP use device login;
`APEX_SERVICE_KEY` authenticates only the REST API.

Starting a scan requires `scans:create`. A later worker that polls status or
downloads findings also needs `scans:read` or `findings:read`, respectively.

<Note>
  `GET /api/apex/v1/credits` returns the service key organization's current
  standard, audit, and Lite balances plus effective scan-type availability. This
  is a point-in-time snapshot; scan creation remains authoritative if balances
  change before submission.
</Note>

This prompt intentionally starts only `standard` scans. It offers an exact
local archive or, when compatible, a provider-backed GitHub commit. It never
offers `audit` or `lite`.

## Copyable environment prompt

```text theme={null}
## Task
Help the caller choose a source, confirm, and start exactly one Standard Apex
security scan for this repository through the hosted REST API. As soon as Apex
accepts the scan, return the workspace ID, scan ID, accepted status, and direct
links. Do not wait for the scan to finish, poll it, or fetch findings in this
task. Never offer or start an Audit or Lite scan.

## Integration boundary
- Use the Apex service API documented at https://ai.cantina.xyz/docs/apex-api.
- Do not install or invoke Apex CLI or MCP.
- Do not run `apex login`; CLI device authentication does not accept service
  keys.

## Preconditions — check before doing anything else
1. Check only whether `APEX_SERVICE_KEY` is set and non-empty.
   - If missing or empty, stop immediately and report that
     `APEX_SERVICE_KEY` is not defined.
   - Never print, echo, log, serialize, or include its value in an error.
   - Do not inspect or print `CANTINA_API_KEY`; this workflow does not use it.
2. Confirm the key is intended to have `scans:create`. If the API returns 403,
   stop and report that the key lacks the required scope.
3. Read the current API documentation before making requests. If it conflicts
   with this prompt, follow the documentation and report the difference.
4. Call `GET /api/apex/v1/credits` with the service key.
   - If `scansEnabled` is false, stop and report that scans are disabled for
     the organization.
   - Retain `balances.standard` and `scanTypes.standard` in memory. Do not use
     CLI/MCP or ask the caller to supply balances.
   - Treat `scanTypes.standard.available` as a point-in-time credit check. The
     accompanying `ledger` and `creditsRequired` explain the Standard balance
     that will be charged.
   - Ignore Audit and Lite availability. This workflow never offers those scan
     types even when they have available credits.

## Choose before creating anything
1. Inspect the checkout without modifying it. Determine the repository
   directory name, full HEAD commit SHA, Git remote, and whether the checkout
   is clean and its HEAD commit is available from the GitHub remote.
2. Build the compatible choices below. Never show a source-incompatible choice.
   Apply the credit response before presenting the list.
   - `standard` + `local_archive`: available when
     `scanTypes.standard.available` is true, for the exact local checkout,
     including dirty, unpushed, non-Git, or non-GitHub source.
   - `standard` + `remote_repo`: available only for a clean, provider-backed
     GitHub commit that Apex can materialize and when
     `scanTypes.standard.available` is true.
   - If no compatible funded choice remains, report the Standard remaining
     balance and stop without creating anything.
3. Present one concise selection question. State that the scan type is fixed to
   Standard. For each choice show the source mode, effective ledger, credits
   required, and that ledger's remaining balance. Explain that a local archive
   scans the exact checkout, while a remote scan uses the named commit. Ask:
   `Which Standard scan source should I use?`
   - Do not create an archive, upload, workspace, or scan before the caller
     chooses.
   - If only one compatible choice remains, ask the caller to confirm it.
   - If the caller already selected a compatible source mode in the same
     request, summarize the Standard scan choice and treat it as confirmed.

## Start the confirmed scan

### Local archive choice
1. This source supports only `scanType: standard`. Create a temporary `tar.gz`
   archive outside the source tree without modifying tracked files.
2. Calculate the archive SHA-256, compressed byte count, and uncompressed byte
   count required by `POST /api/apex/v1/source-uploads`.
3. Create a source-upload session using the repository directory name as the
   workspace name. Retain the workspace ID, upload ID, signed PUT URL, and
   required upload headers in memory. Treat the signed URL as a credential.
4. PUT the archive to the signed URL using every returned header. Then call
   `POST /api/apex/v1/source-uploads/{uploadId}/complete` and retain its archive
   ID and verified SHA-256.
5. Build the scan request with the workspace ID, `scanType: standard`,
   `generateThreatModel: true`, and one `local_archive` scan source containing
   the archive ID and verified SHA-256. A new local workspace has no model to
   reuse, so do not omit `generateThreatModel: true`.

### Provider-backed choice
1. Use the canonical GitHub repository URL and full HEAD commit SHA. Do not use
   a moving branch or tag.
2. Build the scan request with `scanType: standard`, `repoUrl`, `commit`, and
   `generateThreatModel: true`.
3. If workspace resolution returns 409 with multiple matching workspaces, show
   those choices and ask which workspace to use. After selection, include its
   `workspaceId` and use a new idempotency key because the first request had a
   definitive 4xx response.

### Submit and hand off
1. Generate one stable idempotency key for this intended scan. Call
   `POST /api/apex/v1/scans` with the confirmed request.
2. After a successful HTTP 202 response, retain the workspace ID from source
   setup, workspace resolution, or the accepted response, plus the returned
   scan ID, status, `statusUrl`, and `findingsUrl`.
3. Resolve relative API URLs against `https://ai.cantina.xyz` and construct:
   - Workspace link:
     `https://ai.cantina.xyz/workspace/<workspaceId>`
   - Scan link:
     `https://ai.cantina.xyz/workspace/<workspaceId>?scanId=<scanId>`
4. Delete only the temporary local archive, if one was created. Do not modify
   repository files.
5. Return the handoff output immediately. Do not call the status or findings
   endpoints, wait for a terminal state, or create `apex-findings.json`.

## Credit and error UX
- On 402, report that the Standard scan credit is unavailable. Do not submit
  another scan. Refresh `GET /api/apex/v1/credits`; if Standard is available,
  re-present the compatible source choices and require confirmation. Otherwise
  report the remaining Standard balance and stop.
- On 403, report the missing `scans:create` scope.
- On a workspace-resolution 409, ask the caller to choose from the returned
  workspaces; do not guess.
- On an active-scan or other 409, report the conflict and stop rather than
  forcing or duplicating work.
- On an unrecoverable error, report the HTTP method, endpoint path, status, and
  redacted response body.

## Retry and safety rules
- Send `Authorization: Bearer <service key>` without logging the header.
- Credit-balance GET requests are safe to retry with bounded backoff.
- Reuse the same idempotency key and identical request body only after a
  transport error, timeout, or 5xx from scan creation.
- After correcting a definitive 4xx, use a new idempotency key.
- Never change source mode or workspace without caller confirmation. The scan
  type must remain `standard`.
- Never create a second scan merely because a request timed out or the client
  restarted.
- Do not improvise CLI commands or alternative authentication flows.

## Output
Return immediately after HTTP 202 in this shape:

Apex scan started
- Scan type: standard
- Source mode: <local_archive|remote_repo>
- Workspace ID: <workspace-id>
- Scan ID: <scan-id>
- Accepted status: <status returned by Apex>
- Workspace: https://ai.cantina.xyz/workspace/<workspace-id>
- Scan: https://ai.cantina.xyz/workspace/<workspace-id>?scanId=<scan-id>
- Status API: <absolute-status-url>
- Findings API: <absolute-findings-url> (available after completion)

Do not include elapsed time or finding counts because this task does not wait
for completion.
```

## Why this returns immediately

* The scan type is fixed to Standard, and the caller chooses and confirms the
  source before any upload or scan is created.
* Source compatibility and the authenticated Standard balance snapshot filter
  the choices before the caller confirms one.
* It returns stable workspace and scan identifiers plus clickable handoff links
  as soon as Apex accepts the scan.
* Monitoring and findings retrieval are separate, resumable tasks, so the
  initiating agent does not remain attached for a multi-hour scan.

See the [Apex service API guide](/apex/api) for request examples, archive limits,
scan-type constraints, status values, and retry behavior.
