Skip to content
GitmoapAPIBeta
Integrateprovider-publishing
POST/providers/{provider_id}/versions

Submit a new version of an existing provider you own, for review.

submit_provider_version
  • provider_publishing:write
    A token needs the provider_publishing:write scope: Submit and manage provider versionsGranted by write_api.Every operation this scope unlocks
  • Audited · mutation

    x-gitmoap-audit: {"kind":"audited","arg":"mutation"}

  • Quota · provider submissions per publisher

    x-gitmoap-quota: {"kind":"enforced","arg":"provider_submissions_per_publisher"}

The manifest's provider id must match the path, and the tier must be the provider's own: a version cannot change tier, and a private provider stays with the group it was first published for. Answers 202 with the submission; read it to follow its progress. Refused when that version is already published or already has an open submission, and a publisher may have at most 20 submissions awaiting a decision. Only the publisher that owns the provider may submit, and a verified version needs the publisher to be verified.

Parameters

Path
  • provider_idProviderId (string)Provider id

Request body

application/json
  • capabilitiesarray of SubmissionCapabilityInput
    • The SubmissionCapabilityInput schema
    • capability_idCapabilityId (string)
    • descriptionstring
    • image_digeststring
    • image_refstring
    • namestring
    • stage_typeStageTypesourcebuildtestpublishdeploynotifycustomThe pipeline stage a capability belongs to. Maps verbatim to the stage_type field of a capability in gitmoap-provider.yaml.
    • bindablearray of PortName (string)optionalConfig keys that can take their value from an earlier step. Each becomes an optional value input port of the same name when the version is published.
    • cache_enabledbooleanoptional
    • config_schemaobjectoptional
    • default_timeout_secondsinteger · int32optional0–∞
    • input_groupsarray of PortGroupoptionalRules over which of the capability's optional inputs may be connected together.
      • The PortGroup schema
      • kindPortGroupKindexactly_one_ofat_most_one_ofat_least_one_ofHow many of a group's ports may be connected.
      • portsarray of PortName (string)The member input ports, in the order the author should read them.
      • descriptionstring or nulloptionalWhy these ports constrain each other, in the provider's own words. Rendered beside the group, and repeated in the validation error when the group is unsatisfied — which is the point: the sentence explaining the rule reaches the person who broke it.
    • inputsarray of PortDescriptoroptional
      • The PortDescriptor schema
      • namePortName (string)
      • port_typePortTypegit_refartifactcontainer_imagetest_reportdeployment_refcredentialsevidencevaluecustomSemantic type of the data this port carries. Drives edge type-compatibility in the pipeline builder and validation/routing in the engine.
      • requiredboolean
      • cardinalityPortCardinalityonemanyoptionalHow many sources this input accepts. one by default; many takes several at once.
      • descriptionstring or nulloptionalWhat this port is for, in the provider's own words. Absent on a few older providers.
      • schema_idPortSchemaId (string) or nulloptionalFor a custom port, the id of the schema it carries (e.g. aws.ecs.task-definition/v1). Two custom ports connect only when their schema ids agree, or when either leaves this unset.
    • outputsarray of PortDescriptoroptional
      • The PortDescriptor schema
      • namePortName (string)
      • port_typePortTypegit_refartifactcontainer_imagetest_reportdeployment_refcredentialsevidencevaluecustomSemantic type of the data this port carries. Drives edge type-compatibility in the pipeline builder and validation/routing in the engine.
      • requiredboolean
      • cardinalityPortCardinalityonemanyoptionalHow many sources this input accepts. one by default; many takes several at once.
      • descriptionstring or nulloptionalWhat this port is for, in the provider's own words. Absent on a few older providers.
      • schema_idPortSchemaId (string) or nulloptionalFor a custom port, the id of the schema it carries (e.g. aws.ecs.task-definition/v1). Two custom ports connect only when their schema ids agree, or when either leaves this unset.
    • requires_dockerbooleanoptional
  • contract_versioninteger · int320–∞
  • providerSubmissionProviderInput
  • versionProviderVersion (string)
  • changelogMarkdownDoc (string) or nulloptionalOptional release notes for this version, in Markdown, up to 64 KB. They cannot be changed once the version is published.
  • owning_group_idGroupId (string · uuid) or nulloptionalRequired when target_tier is private: the organization (a top-level group) the provider is private to. You must be at least a Maintainer there.
  • registry_pull_secretRegistryPullSecretInput or nulloptionalOptional registry pull credential (Private only); rejected for other tiers.
  • target_tierProviderTierplatformverifiedcommunityprivateoptionalverified (default) / community / private. platform is rejected.
Request body exampleSynthesized example
{
"capabilities": [
{
"capability_id": "2a732626-0338-4454-8ab2-44b61a141a7e",
"description": "Renders each region as density contours of its operations.",
"image_digest": "image-digest-7ea8",
"image_ref": "image-ref-d13e",
"name": "payments-api",
"stage_type": "source"
},
{
"capability_id": "9231d1ae-f829-4ee6-8178-3c82874a7810",
"description": "Renders each region as density contours of its operations.",
"image_digest": "image-digest-8b32",
"image_ref": "image-ref-6239",
"name": "payments-api",
"stage_type": "source"
}
],
"contract_version": 82,
"provider": {
"auth_schema": {},
"description": "Renders each region as density contours of its operations.",
"id": "id-195f",
"name": "payments-api"
},
"version": "version-e7af"
}

Responses

202application/json
  • provider_idProviderId (string)
  • stateSubmissionStatesubmittedin_reviewchanges_requestedapprovedmirroringsigningpublishedrejectedmirror_failedwithdrawnverifyingverification_failedWhere a provider submission stands, from review through to publication or refusal.
  • submission_idProviderSubmissionId (string · uuid)
  • submitted_atstring
  • versionProviderVersion (string)
202 exampleSynthesized example
{
"provider_id": "abdc6043-3b1c-42b2-94ee-1b697fe70aef",
"state": "submitted",
"submission_id": "0906c5ab-2ddf-46da-b519-9a994f717a38",
"submitted_at": "2026-10-16T11:24:25Z",
"version": "version-31fb"
}
400application/json
Error codes
  • BAD_REQUESTThe request is malformed: a parameter or a body field is not a well-formed value of its type
  • errorErrorBody
    • The ErrorBody schema
    • codestringThe coarse category, tied to the status: NOT_FOUND, CONFLICT, INSUFFICIENT_SCOPE. Every error has one; the API reference's error catalogue lists them all.
    • messagestringWhat went wrong, for a person. Written to be read, not parsed: match on reason or code.
    • fieldstring or nulloptionalOn a 400 that refused one field's value, the field, as its JSON path: email, items[0].name. Put the message under that input. Absent on every other error.
    • reasonstring or nulloptionalThe specific code, when the error has one: LAST_ORGANIZATION_OWNER, BRANCH_PROTECTED. The message starts with it too. Match on this when it is present, and on code otherwise.
    • required_scopestring or nulloptionalThe scope the access token was missing, on INSUFFICIENT_SCOPE.
    • violationsanyoptionalPresent on the structured-validation errors (PROVIDER_VALIDATION_FAILED per-node, PIPELINE_VALIDATION_FAILED DAG): a JSON array of the offending elements, so a caller can fix every one in a single round-trip. Absent (omitted) on every other error.
400 exampleSynthesized example
{
"error": {
"code": "code-eb49",
"message": "Stream pipeline status into the run header"
}
}
401Unauthenticated — no credential, or an invalid oneapplication/json
Error codes
  • UNAUTHORIZEDNo credential was sent, or the one sent is invalid, expired or revoked
  • errorErrorBody
    • The ErrorBody schema
    • codestringThe coarse category, tied to the status: NOT_FOUND, CONFLICT, INSUFFICIENT_SCOPE. Every error has one; the API reference's error catalogue lists them all.
    • messagestringWhat went wrong, for a person. Written to be read, not parsed: match on reason or code.
    • fieldstring or nulloptionalOn a 400 that refused one field's value, the field, as its JSON path: email, items[0].name. Put the message under that input. Absent on every other error.
    • reasonstring or nulloptionalThe specific code, when the error has one: LAST_ORGANIZATION_OWNER, BRANCH_PROTECTED. The message starts with it too. Match on this when it is present, and on code otherwise.
    • required_scopestring or nulloptionalThe scope the access token was missing, on INSUFFICIENT_SCOPE.
    • violationsanyoptionalPresent on the structured-validation errors (PROVIDER_VALIDATION_FAILED per-node, PIPELINE_VALIDATION_FAILED DAG): a JSON array of the offending elements, so a caller can fix every one in a single round-trip. Absent (omitted) on every other error.
401 exampleSynthesized example
{
"error": {
"code": "code-baf5",
"message": "Inline scalar newtypes but keep their brand"
}
}
403application/json
Error codes
  • FORBIDDENYou are signed in but may not do this here; reason names the permission or the rule that refused it
  • INSUFFICIENT_SCOPEThe access token lacks the scope this operation needs; required_scope names it
  • PERMISSION_REQUIREDYou need a permission you do not hold here; the message names it
  • errorErrorBody
    • The ErrorBody schema
    • codestringThe coarse category, tied to the status: NOT_FOUND, CONFLICT, INSUFFICIENT_SCOPE. Every error has one; the API reference's error catalogue lists them all.
    • messagestringWhat went wrong, for a person. Written to be read, not parsed: match on reason or code.
    • fieldstring or nulloptionalOn a 400 that refused one field's value, the field, as its JSON path: email, items[0].name. Put the message under that input. Absent on every other error.
    • reasonstring or nulloptionalThe specific code, when the error has one: LAST_ORGANIZATION_OWNER, BRANCH_PROTECTED. The message starts with it too. Match on this when it is present, and on code otherwise.
    • required_scopestring or nulloptionalThe scope the access token was missing, on INSUFFICIENT_SCOPE.
    • violationsanyoptionalPresent on the structured-validation errors (PROVIDER_VALIDATION_FAILED per-node, PIPELINE_VALIDATION_FAILED DAG): a JSON array of the offending elements, so a caller can fix every one in a single round-trip. Absent (omitted) on every other error.
403 exampleSynthesized example
{
"error": {
"code": "code-606d",
"message": "Pin a page's payload to the build that rendered it"
}
}
404application/json
Error codes
  • NOT_FOUNDThe resource does not exist — or exists and you cannot see it: a private resource you have no access to answers exactly as an absent one does
  • errorErrorBody
    • The ErrorBody schema
    • codestringThe coarse category, tied to the status: NOT_FOUND, CONFLICT, INSUFFICIENT_SCOPE. Every error has one; the API reference's error catalogue lists them all.
    • messagestringWhat went wrong, for a person. Written to be read, not parsed: match on reason or code.
    • fieldstring or nulloptionalOn a 400 that refused one field's value, the field, as its JSON path: email, items[0].name. Put the message under that input. Absent on every other error.
    • reasonstring or nulloptionalThe specific code, when the error has one: LAST_ORGANIZATION_OWNER, BRANCH_PROTECTED. The message starts with it too. Match on this when it is present, and on code otherwise.
    • required_scopestring or nulloptionalThe scope the access token was missing, on INSUFFICIENT_SCOPE.
    • violationsanyoptionalPresent on the structured-validation errors (PROVIDER_VALIDATION_FAILED per-node, PIPELINE_VALIDATION_FAILED DAG): a JSON array of the offending elements, so a caller can fix every one in a single round-trip. Absent (omitted) on every other error.
404 exampleSynthesized example
{
"error": {
"code": "code-4ceb",
"message": "Inline scalar newtypes but keep their brand"
}
}
409application/json
Error codes
  • CONFLICTThe request conflicts with the resource's current state; reason says how
  • LEGAL_ACCEPTANCE_REQUIREDAccept the current Terms of Service before changing anything; reading stays open
  • errorErrorBody
    • The ErrorBody schema
    • codestringThe coarse category, tied to the status: NOT_FOUND, CONFLICT, INSUFFICIENT_SCOPE. Every error has one; the API reference's error catalogue lists them all.
    • messagestringWhat went wrong, for a person. Written to be read, not parsed: match on reason or code.
    • fieldstring or nulloptionalOn a 400 that refused one field's value, the field, as its JSON path: email, items[0].name. Put the message under that input. Absent on every other error.
    • reasonstring or nulloptionalThe specific code, when the error has one: LAST_ORGANIZATION_OWNER, BRANCH_PROTECTED. The message starts with it too. Match on this when it is present, and on code otherwise.
    • required_scopestring or nulloptionalThe scope the access token was missing, on INSUFFICIENT_SCOPE.
    • violationsanyoptionalPresent on the structured-validation errors (PROVIDER_VALIDATION_FAILED per-node, PIPELINE_VALIDATION_FAILED DAG): a JSON array of the offending elements, so a caller can fix every one in a single round-trip. Absent (omitted) on every other error.
409 exampleSynthesized example
{
"error": {
"code": "code-0e0d",
"message": "Inline scalar newtypes but keep their brand"
}
}
429Open-submission limit reached for this publisherapplication/json
Error codes
  • TOO_MANY_REQUESTSRetryableA quota, a rate limit or a transfer budget is spent. When the response carries Retry-After, retry after that many seconds
  • errorErrorBody
    • The ErrorBody schema
    • codestringThe coarse category, tied to the status: NOT_FOUND, CONFLICT, INSUFFICIENT_SCOPE. Every error has one; the API reference's error catalogue lists them all.
    • messagestringWhat went wrong, for a person. Written to be read, not parsed: match on reason or code.
    • fieldstring or nulloptionalOn a 400 that refused one field's value, the field, as its JSON path: email, items[0].name. Put the message under that input. Absent on every other error.
    • reasonstring or nulloptionalThe specific code, when the error has one: LAST_ORGANIZATION_OWNER, BRANCH_PROTECTED. The message starts with it too. Match on this when it is present, and on code otherwise.
    • required_scopestring or nulloptionalThe scope the access token was missing, on INSUFFICIENT_SCOPE.
    • violationsanyoptionalPresent on the structured-validation errors (PROVIDER_VALIDATION_FAILED per-node, PIPELINE_VALIDATION_FAILED DAG): a JSON array of the offending elements, so a caller can fix every one in a single round-trip. Absent (omitted) on every other error.
429 exampleSynthesized example
{
"error": {
"code": "code-e6a3",
"message": "Stream pipeline status into the run header"
}
}

CLI

gitmoap provider-publishing submit-provider-version

  • --provider-ididProvider id
  • --capabilitiesjson
  • --changelogstringoptional
  • --contract-versionnumber
  • --owning-group-idstringoptional
  • --providerjson
  • --registry-pull-secretjsonoptional
  • --target-tierplatform | verified | community | privateoptional`verified` (default) / `community` / `private`. `platform` is rejected.
  • --versionstring

Used in these guides