neosourceDocs
Search docs

Upsert a workflow definition

POST/api/workflows

upsertWorkflow

Authentication is not described for this operation in the spec — that does not mean it is public. Check tokens and scopes.

curl

curl -X POST 'https://neosource.dev/api/workflows' \
  -H 'Content-Type: application/json' \
  -d '{"repo_id":"string","path":"string","source_operation":"string","definition":{}}'

fetch

fetch("https://neosource.dev/api/workflows", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({"repo_id":"string","path":"string","source_operation":"string","definition":{}}),
});

Request bodyrequired

application/json

UpsertWorkflowRequest

object

definitionrequired

object

Parsed `WorkflowDef`. JSON shape mirrors `neosource_core::model::WorkflowDef`.

pathrequired

string

Path within the repo (`.neosource/workflows/<name>.yml`).

repo_idrequired

string

Repo the workflow belongs to (UUID hex).

source_operationrequired

string

Hex-encoded 32-byte content-addressed operation id that the definition was extracted at.

Responses

200Workflow

application/json

WorkflowResponse

object

created_atrequired

integerint64

idrequired

string

namerequired

string

The `name:` declared in the workflow YAML, for display. A file that failed to parse is named after itself (e.g. `broken.yml`), so this is always something showable. This is the **only** projection of the parsed definition on the wire. The full `WorkflowDef` used to be returned here and reached ~100 KB per request on a real repo while every client read just the name; the runner gets definitions through the job-claim path, not this listing.

pathrequired

string

repo_idrequired

string

source_operationrequired

string

updated_atrequired

integerint64

warningsrequired

array

Parse diagnostics recorded when the file was indexed: unknown GHA keys / unsupported triggers ignored with `severity: "warning"`, or a whole-file parse failure as `severity: "error"` (such a workflow is stored inert — no triggers, no jobs — and never runs). Empty when the file parsed clean.

items

WorkflowWarning

object

A non-fatal diagnostic collected while parsing workflow YAML. GHA's own forward-compat posture: a valid-but-unmodeled key (`permissions:`, `concurrency:`, `defaults:`, …) must not fail the whole file — it is ignored and reported. Persisted alongside the indexed workflow (`workflows.warnings`) so the API/UI can surface "this workflow has warnings / failed to parse" instead of the file silently ceasing to exist.

locationrequired

string

Where in the document: `workflow`, `on.push`, `job 'build'`, `job 'build' step 2 ('Deploy')`, …

messagerequired

string

severityrequired
WorkflowWarningSeverity

403Forbidden — one of: forbidden, needs_scope

application/json

one of
  • ErrorForbidden
  • NeedsScopeError

    object

    `403` body returned when listing private repos but the linked identity lacks the required provider scope. The SPA turns this into an incremental-authorization prompt (Tier 2) that calls the `/elevate` OAuth endpoint with this `scope`.

    errorrequired

    string

    Always `needs_scope` — this body exists to carry the extra fields that kind needs.

    "needs_scope"

    scoperequired

    string

    The provider scope to request via elevation (e.g. `"repo"`).

Standard errors

Bodies documented once for the whole API — see standard errors.

  • 400Bad Request — one of: invalid_input
  • 404Not Found — one of: not_found
  • 409Conflict — one of: already_exists, conflict
  • 429Rate limited — retry after the `Retry-After` header
  • 500Internal server error
  • 503Service temporarily unavailable / at capacity — retry after the `Retry-After` header
  • 504Gateway timeout — the request exceeded the server's handling budget

Schemas

Referenced above. Listed here rather than expanded inline, so the same definition is not repeated at every level.

WorkflowWarningSeverity

string

Severity of a [`WorkflowWarning`].

"warning""error"