Skip to content

Integrate AI agents with Forgeplane

An external AI agent can use Forgeplane to discover delivery resources, request a governed run, and observe its result. The safe integration boundary is the documented HTTP API. The agent should not scrape the web UI, invent request fields, handle raw infrastructure credentials, or make its own approval decisions.

This guide is framework-independent. It applies to coding agents, operations agents, LLM tool callers, and custom automation that can call HTTPS endpoints and parse JSON.

Forgeplane offers four ways to discover or reach product resources. Use the path that matches the caller:

Access path Entry point Best for Boundary
LLM documentation index llms.txt A fetch-based agent discovering the official API, authentication, permissions, and workflow documentation It is a curated public-documentation index, not a live coordinator endpoint list or an authorization contract.
Interactive API documentation /api/docs A human operator or browser-capable agent browsing declared methods, request fields, responses, and status codes on the running coordinator An agent may inspect it in read-only mode without a key. Only an authorized human should enter a personal key and use Try it out; the page keeps that key in the page only and clears it on reload.
Direct HTTP API /api/v1 AI agents, scripts, and application integrations using a standard HTTP client such as curl or a language HTTP library Send JSON and X-API-Key only to an allowlisted host, method, and route. This is the supported automation boundary.
Browser UI /catalog, /projects, /environments, and /workloads/runs Human review, resource selection, approval, and operational investigation Use a Forgeplane browser session. The browser UI is a human interface, not an agent API contract.

A browser-capable agent can open /api/docs in read-only mode to browse the interactive API documentation declared by the target coordinator. Do not give that browser agent a credential or let it use Try it out unless the operator explicitly authorizes the exact call. A fetch-only agent should start with Forgeplane llms.txt, follow the narrow documentation links needed for its task, and avoid scraping the JavaScript-rendered interactive page or the browser UI.

For live resource browsing, configure a narrow direct-HTTP allowlist and let the agent call reviewed GET /api/v1 routes. Use mutations only after the explicit authorization required by the default agent policy below.

Before authentication, GET /api/v1/system/identity and GET /api/v1/system/version identify the running coordinator and its API version. After authentication, use GET /api/v1/auth/whoami and current resource responses as runtime evidence. See the Coordinator API reference for the resource directory, access options, correlation headers, request limits, and error behavior.

Do not infer a route or field from an older client, another Forgeplane release, or an example on this page. Review the target coordinator’s interactive docs together with this website’s current behavior and permissions guidance before changing the agent’s allowlist. The actual server response remains authoritative. Fail closed when a response, field, status, or authorization result is outside the reviewed behavior.

Use this policy as the starting boundary for an agent integration:

ALLOW BY DEFAULT
- Inspect the authenticated identity and permission decisions.
- Read projects, environments, templates, versions, runs, and logs within the assigned scope.
- Request one run after its exact target, operation, template version, and inputs are confirmed.
- Observe the returned run ID until a known terminal result or the operator's deadline.
REQUIRE EXPLICIT OPERATOR AUTHORIZATION
- Create a run.
- Cancel or requeue a run.
- Change a project, environment, template, credential, policy, or feature gate.
DENY BY DEFAULT
- Approve or reject a run.
- Delete records.
- Use browser cookies or UI-only routes.
- Copy credentials or secret values into prompts, logs, artifacts, or model-visible context.
- Retry a mutation after an ambiguous result unless that operation documents safe retry behavior.

These are integration defaults, not a substitute for Forgeplane authorization. The coordinator still evaluates platform permissions, organization membership, team scope, resource ownership, lifecycle state, feature gates, quotas, and approval policy.

Use a user-owned requester service account for routine runs whose internal execution plan is already cached. The owner user supplies the user-level audit attribution required by the template-run endpoint and must have the necessary organization and team access. A requester can read delivery resources and execute a cached plan, but cannot approve, cancel, or materialize a missing internal execution plan. Do not reuse a human administrator’s credential.

Before requester automation uses a new plan identity, an authorized maintainer must create the first run for the exact project, template version, and operation. That first run materializes the internal execution plan. Its cache identity also includes the current compiler version and compiled graph, so a product or graph change can require materialization again. A requester can reuse the cached plan afterward. If automation itself must create the first run, it needs a user-owned maintainer account with broader assembly:write and approval authority; keep approval endpoints out of that agent’s tool set and disclose the broader authority.

In the current release, a team-owned service account cannot derive the user-level created_by required for template-run creation. Use a team-owned account only for operations that do not require that attribution. Do not work around this limit by sending an arbitrary user UUID.

Store the API key in the agent runtime’s secret store and inject it only into the HTTP client process. Do not put an API key in a prompt, command argument recorded by the agent, generated report, repository file, or conversation transcript. Do not give the model a tool that can print its environment.

Send the key through the documented header:

X-API-Key: <service-account-api-key>

A valid key does not widen its owner’s team or resource scope. Review Permissions and roles before assigning a broader role.

The normal read-and-run integration uses these layered checks. Platform permission and team action must both pass where shown. Resource, lifecycle, and feature-gate checks still apply.

Agent action API operation Required authorization
Inspect identity GET /api/v1/auth/whoami Authenticated principal
Test authorization POST /api/v1/auth/can-i Authenticated principal
List projects GET /api/v1/projects?team_id={team_id} project:read with team.metadata.read
List environments GET /api/v1/environments?team_id={team_id} environment:read with team.metadata.read
Read templates and versions GET /api/v1/registry/templates registry:read
Admit a template run for the environment POST /api/v1/registry/templates/{id}/run run:create with team.secret.read
Execute an already cached internal plan Same run request assembly:run with team.metadata.read
Materialize a missing internal plan First run for that plan identity assembly:write with team.metadata.write
Read a run and its persisted logs GET /api/v1/runs/{id} and /logs run:read with team.secret.read
Cancel an eligible run POST /api/v1/runs/{id}/cancel run:cancel with team.secret.read
Requeue an eligible run POST /api/v1/runs/{id}/requeue run:create with team.secret.read

The requester role has run:create and assembly:run, but not assembly:write. A missing internal plan therefore returns 403 for a requester until a maintainer has materialized that exact plan identity.

Do not treat can-i as a reservation or an authorization bypass. It is a preflight decision. The actual operation can still fail because state, scope, policy, quota, or another resource changed.

First, verify which principal the HTTP client uses:

Terminal window
curl --fail-with-body --silent --show-error \
"$FORGEPLANE_URL/api/v1/auth/whoami" \
-H "Accept: application/json" \
-H "X-API-Key: $FORGEPLANE_API_KEY"

The review envelope accepts only resource_attributes. Each review evaluates the authenticated User or service account; it cannot select another subject.

Check the Team-scoped run-creation capability:

{
"resource_attributes": {
"group": "forgeplane.io",
"version": "v1",
"resource": "runs",
"verb": "create",
"team_id": "22222222-2222-2222-2222-222222222222"
}
}

This collection review does not prove that an internal execution plan exists or that the caller can materialize it. Keep the maintainer-first workflow above; the actual run operation enforces those additional requirements.

Send the JSON object to POST /api/v1/auth/can-i. An allowed review returns HTTP 200:

{
"status": {
"allowed": true,
"denied": false,
"reason": {
"code": "allowed",
"message": "authorization granted"
}
}
}

Proceed only when status.allowed is true. A denial has status.denied: true. Both booleans false means an indeterminate evaluation_error; stop rather than treating it as permission to proceed. See the review contract for the safe result codes and validation rules.

After resolving IDs, use named projects/get, environments/get, or runs/get reviews with name and the matching team_id. A separately authorized cancellation can review runs/cancel. A runs/create review does not replace a requeue operation’s lifecycle checks. Do not expose cancel or requeue to the default requester tool set.

Stop if the identity is unexpected or status.allowed is false. Fix the narrow missing role, membership, or scope instead of granting general administrative access.

Resolve the target from authenticated API responses. Do not assume that display names are unique, and do not copy stale IDs from an old trace.

  1. Call GET /api/v1/projects?team_id={team_id} and select the intended project UUID.
  2. Call GET /api/v1/environments?team_id={team_id} and verify that the returned environment belongs to that project.
  3. Call GET /api/v1/registry/templates and select the intended template UUID.
  4. Call GET /api/v1/registry/templates/{id}/versions or GET /api/v1/registry/templates/{id}/versions/{version}.
  5. Read the base source_url, tool_type, and default worker pool from the template entry, then read the selected version’s git_ref, schema, and variables.
  6. Build the effective execution projection before authorization.

TemplateVersion.variables can override the base source URL, Git ref, path, tool type, and input schema. Apply the runtime precedence exactly:

  • source_url, git_url, repo_url, or repository in variables override the template entry’s source_url; conflicting non-empty URL aliases are invalid;
  • the first non-empty git_ref, ref, or revision in variables overrides the version’s top-level git_ref; an empty effective ref defaults to main;
  • variables.path overrides the default empty path by presence;
  • the first non-empty tool_type or tool in variables overrides the template entry’s tool_type; and
  • variables.input_schema, then variables.schema, overrides the version’s top-level schema.

Validate the effective source URL, Git ref, path, tool type, and schema as one projection. Require the effective Git ref to be a reviewed immutable commit SHA; validating only the top-level git_ref is unsafe because an override can select different code. Validate non-secret inputs against the effective schema and show the whole resolved projection to the operator. If the agent cannot reproduce this precedence, fail closed whenever a reserved projection override is present and ask an operator to normalize the template version.

Use the returned UUIDs as identifiers. Use names only for confirmation messages shown to the operator.

The template-run request requires environment_id and operation. A typical Terraform or OpenTofu plan request is:

{
"environment_id": "11111111-1111-1111-1111-111111111111",
"operation": "plan",
"version": "1.2.3",
"inputs": {
"region": "eu-central-1"
}
}

Send the request to POST /api/v1/registry/templates/{id}/run:

Terminal window
curl --fail-with-body --silent --show-error \
-X POST \
"$FORGEPLANE_URL/api/v1/registry/templates/$TEMPLATE_ID/run" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "X-API-Key: $FORGEPLANE_API_KEY" \
--data-binary @run-request.json

Apply these rules before sending it:

  • Use an operation supported by the selected tool and release. Ansible uses execute; Terraform and OpenTofu use their documented run operations.
  • Before a requester submits, confirm that an authorized maintainer has already created the first run for this project, template version, operation, compiler version, and compiled graph. A new identity needs materialization again; do not retry a requester’s 403 as though it were transient.
  • Validate inputs against the effective schema after applying the documented version-variable precedence. See Input schema. Do not place secret values in ordinary inputs when Forgeplane’s secret mechanism should supply them.
  • Omit requested_worker_pool_name unless the operator intentionally requests a pool. If provided, it must match the template’s configured default pool; it cannot replace that default.
  • Let the authenticated user-owned service account establish audit identity through its owner user. Omit created_by; do not supply it as a way to impersonate another actor. Stop instead of submitting a run through a team-owned service account.
  • Show the resolved project, environment, template, version, effective source URL, Git ref, path, tool type, schema, operation, and non-secret inputs to the operator before mutation.

For Ansible-specific inventory, secret-slot, host-key, structured-output, and worker requirements, follow Ansible execution.

The coordinator returns the accepted run, including its id. A 202 Accepted response does not mean that the run succeeded. Persist the returned run ID and the coordinator’s X-Request-ID and X-Support-ID response headers before observing the run.

Use the run ID returned by the create request. Do not search by name and assume the newest result is the one the agent created.

Purpose Operation
Read current run state GET /api/v1/runs/{id}
Read persisted log entries GET /api/v1/runs/{id}/logs
UI-oriented log stream GET /api/v1/runs/{id}/logs/stream

For a generic machine integration, poll GET /api/v1/runs/{id} and read persisted JSON logs from GET /api/v1/runs/{id}/logs. In the current release, pending_approval is a valid nonterminal run status. Treat queued, pending_approval, running, and canceling as known nonterminal states. The known terminal states are succeeded, failed, canceled, and timed_out.

The SSE endpoint is UI-oriented. Its response has no documented machine event-payload or reconnect contract, and runtime component events can contain HTML. Do not use it as a generic machine-readable log protocol. A purpose-built client can consume it only when it is coupled to and tested against the exact runtime implementation.

Use bounded observation:

  1. stop when the run reaches a known terminal result;
  2. stop at the operator’s configured observation deadline;
  3. report the run ID, last known status, and correlation identifiers when observation ends; and
  4. fail closed on an unknown status instead of treating it as success.

A successful HTTP read is not evidence that infrastructure execution succeeded. The run’s terminal state and evidence are the result.

Cancellation and requeue are separate mutations

Section titled “Cancellation and requeue are separate mutations”

The advanced endpoints are POST /api/v1/runs/{id}/cancel and POST /api/v1/runs/{id}/requeue. Keep them out of the requester’s default tool set.

Cancellation is allowed when the run is queued, pending_approval, running, or canceling. A queued or pending run becomes canceled with 200. A running run becomes canceling with 202; keep polling the same run ID until it reaches a terminal status, because the worker stops the tool and reports the outcome first.

Requeue is limited to eligible failed, canceled, or timed_out runs. It mutates the existing run back to queued; it does not create a new run. The same run ID remains authoritative, so continue polling that ID. Requeue clears prior execution result fields while preserving the original intent and execution snapshot. Capture evidence that must remain separately accessible before requeueing.

Require explicit operator authorization for either action. Do not automatically retry a mutation after a timeout, connection loss, or other ambiguous response. First read the authoritative run state and follow any idempotency behavior declared for that exact operation.

The default agent identity must not approve or reject a run. Treat approval as an external human decision boundary, not as another step the requesting model can satisfy.

Use separate principals for request and review. A requester submits the execution intent. An authorized reviewer inspects the exact run, evidence, reason, pending-run identity, and irreversible-impact acknowledgement through the governed approval workflow. The agent can report that review is required, but it must not decide that its own request is safe.

This guide deliberately provides no approval-mutation recipe. If you build a separate operator integration, use only the reviewed approval endpoint on the target coordinator, keep run:approve out of the requester identity, and follow Approval workflows.

Forgeplane errors generally use {"error":"message"}. Preserve the actual HTTP response and correlation headers, then apply these defaults:

Status Agent behavior
400 Correct the request against the runtime schema. Do not drop rejected fields silently.
401 Stop. The credential is missing, invalid, or expired.
403 Stop. Inspect permission, membership, scope, lifecycle, feature gate, and approval state.
404 Re-resolve the resource in the authenticated scope. Do not substitute a same-named object.
409 Read current state and present the conflict. Do not overwrite it.
422 Treat the operation-specific validation result as a failed precondition.
429 Respect Retry-After and the operation’s retry safety.
500 or 503 Record correlation identifiers and stop the mutation path unless the exact contract makes retry safe.

X-Client-Request-ID helps correlate client logs. It is not an idempotency key. Use Idempotency-Key only on operations that explicitly declare it.

Give an integrating agent this short instruction after an operator has reviewed /api/docs on the target coordinator and configured its direct HTTP allowlist:

Use only the reviewed Forgeplane /api/v1 methods and routes in your HTTP-tool allowlist. Do not scrape the interactive API docs or browser UI, and do not invent request fields. Use the permissions reference, self-subject resource_attributes reviews, and the actual operation for authorization.
Authenticate with the injected service-account API key, but never print, return, store, or place it in model-visible context.
Before a run request, call whoami; resolve all UUIDs from current API responses; review the required resource and verb with matching name and team_id where applicable, proceeding only when status.allowed is true; build and validate the effective template projection after reserved variable overrides; confirm its effective Git ref is an immutable commit; confirm a maintainer has materialized this exact execution-plan identity; validate non-secret inputs against the effective schema; and show the resolved intent for operator authorization.
Submit at most one mutation for that authorization. A 202 response is acceptance, not success. Persist the returned run ID and correlation headers, then poll that exact ID and read its persisted JSON logs. Do not treat the UI-oriented SSE stream as a generic machine protocol.
Do not approve, reject, cancel, requeue, delete, or modify configuration unless the operator explicitly authorizes that separate action.
Do not infer success from HTTP status, cancellation from process termination, or safety from the agent's own judgment. Fail closed on unknown fields, states, routes, or ambiguous mutation results.
  • Confirm the target coordinator with GET /api/v1/system/identity and GET /api/v1/system/version.
  • Have an operator review /api/docs, then allowlist only the required direct /api/v1 host, methods, routes, and fields.
  • Use a user-owned requester service account only for cached-plan runs; do not invent created_by for a team-owned account.
  • Have an authorized maintainer create the first run for each new project, template-version, operation, compiler, and graph identity.
  • Keep the API key outside prompts, logs, and repository files.
  • Limit the HTTP tool to the required host, methods, and routes.
  • Verify identity and all combined permission, team-action, and team-ID checks before mutation.
  • Resolve current UUIDs and validate the effective source URL, Git ref, path, tool type, and schema after reserved version-variable overrides.
  • Require operator authorization for the resolved run intent.
  • Persist the returned run ID and correlation headers.
  • Observe that exact run and report unknown states as errors.
  • Keep approval, cancellation, requeue, deletion, and configuration changes outside the default agent authority.

For the underlying product model, read Run operations, Service accounts, Permissions and roles, and the Coordinator API reference.