# Workflows and apps

> The authoring surface behind geni resource, geni workflow, and geni app: scaffold, push files, validate, wire config, publish, test, and read executions.

Source: https://docs.generalinput.com/api/workflows



A workflow is a code workflow, an agent workflow, or an app. All three share one id space (`wf_…`) and one lifecycle. The routes here are what the CLI calls; a personal key can drive the same loop from CI or a script.

<Access scope="workflows:manage" />

## The loop [#the-loop]

1. [Create](/api/workflows/create) a workflow. The response is its detail; pull its scaffold with a [bundle URL](/api/workflows/bundle-url).
2. Edit the files locally.
3. Ask for a [bundle upload URL](/api/workflows/bundle-upload-url), `PUT` a gzipped tar of the directory to it, and keep the returned `bundleKey`.
4. [Validate](/api/workflows/validate) the staged bundle. Fix what it reports.
5. [Update config](/api/workflows/update-config) to wire credentials, consts, and schedules.
6. [Publish](/api/workflows/publish) the staged bundle as the live version.
7. [Test](/api/workflows/test) it and poll the [execution](/api/workflows/get-execution).

File bytes never cross this JSON API. Push and pull move a `code.tar.gz` through presigned storage URLs, so binary assets survive intact.

## What a bundle holds [#what-a-bundle-holds]

The files depend on the type. The contract for each is the authoring skill the CLI loads with [`geni skills load`](/cli/skills/load); the short version is on [code workflows](/cli/resource/code), [agent workflows](/cli/resource/agent), and [apps](/cli/resource/apps).

## Access [#access]

Every route resolves the workflow through the member the key acts as. A workflow the member cannot see answers `404`; one they can see but not edit answers `404` on writes too, so existence never leaks across a permission boundary. Sharing follows the dashboard: owner, collaborator, workspace grant, and the workflow admin role floor.

## Endpoints [#endpoints]

| Endpoint                                                                        | Does                                    |
| ------------------------------------------------------------------------------- | --------------------------------------- |
| [`GET /v1/workflows`](/api/workflows/list)                                      | List, or rank by a query                |
| [`POST /v1/workflows`](/api/workflows/create)                                   | Create and scaffold                     |
| [`GET /v1/workflows/:id`](/api/workflows/get)                                   | Detail                                  |
| [`PATCH /v1/workflows/:id/type`](/api/workflows/set-type)                       | Switch code and agent                   |
| [`GET /v1/workflows/:id/bundle-url`](/api/workflows/bundle-url)                 | Presigned download of the live bundle   |
| [`POST /v1/workflows/:id/bundle-upload-url`](/api/workflows/bundle-upload-url)  | Presigned upload for a staged bundle    |
| [`POST /v1/workflows/:id/validate`](/api/workflows/validate)                    | Validate a staged bundle                |
| [`POST /v1/workflows/:id/publish`](/api/workflows/publish)                      | Publish a staged bundle                 |
| [`GET /v1/workflows/:id/config`](/api/workflows/get-config)                     | Credential, const, and trigger bindings |
| [`PATCH /v1/workflows/:id/config`](/api/workflows/update-config)                | Wire bindings                           |
| [`POST /v1/workflows/:id/test`](/api/workflows/test)                            | Schedule a test execution               |
| [`GET /v1/workflows/:id/trigger-sample`](/api/workflows/trigger-sample)         | Live sample from the poll trigger       |
| [`POST /v1/workflows/:id/input-upload-url`](/api/workflows/input-upload-url)    | Stage a file-type test input            |
| [`GET /v1/workflows/:id/executions`](/api/workflows/list-executions)            | Recent executions                       |
| [`GET /v1/workflows/:id/executions/:executionId`](/api/workflows/get-execution) | One execution                           |
| [`GET …/executions/:executionId/logs`](/api/workflows/execution-logs)           | Its logs                                |
| [`GET …/executions/:executionId/trace`](/api/workflows/execution-trace)         | Its full trace                          |
| [`GET /v1/workflows/:id/app/build-status`](/api/workflows/app-build-status)     | App build state                         |
| [`POST /v1/workflows/:id/app/run-handler`](/api/workflows/app-run-handler)      | Run a handler                           |
| [`POST /v1/workflows/:id/app/run-agent`](/api/workflows/app-run-agent)          | Start an app agent                      |
| [`GET /v1/workflows/:id/app/invocations`](/api/workflows/app-invocations)       | Recent handler invocations              |
| [`GET /v1/workflows/:id/app/errors`](/api/workflows/app-errors)                 | Browser-side errors                     |
| [`POST /v1/workflows/:id/app/clear-cache`](/api/workflows/app-clear-cache)      | Clear the handler cache                 |
