Skip to content
GitmoapAPIBeta
Integrateprovider-publishing
POST/providers

Submit the first version of a new provider for review.

submit_provider
  • 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 provider's id must sit in your publisher namespace, as {namespace}.{name}, and the manifest declares its capabilities, each with a container image pinned by its sha256 digest. The tier decides what happens next: a verified submission needs a verified publisher and is reviewed by the platform, while community and private submissions are checked automatically rather than reviewed, and a private provider names the top-level group, where you are a Maintainer or above, that alone may use it. Answers 202 with the submission; read it to follow its progress. Refused when the provider already exists or that version already has an open submission, and a publisher may have at most 20 submissions awaiting a decision. Open to any account that owns an active publisher.

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": "8e2eb565-6f53-447f-a275-fa1049f37925",
"description": "Renders each region as density contours of its operations.",
"image_digest": "image-digest-9a76",
"image_ref": "image-ref-0b68",
"name": "payments-api",
"stage_type": "source"
},
{
"capability_id": "d7f0c48d-d70e-4f8f-99c8-798916ffefd0",
"description": "Renders each region as density contours of its operations.",
"image_digest": "image-digest-f9d9",
"image_ref": "image-ref-b584",
"name": "payments-api",
"stage_type": "source"
}
],
"contract_version": 47,
"provider": {
"auth_schema": {},
"description": "Renders each region as density contours of its operations.",
"id": "id-09d7",
"name": "payments-api"
},
"version": "version-f5cb"
}

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": "7c4598d2-cbb3-46e2-a760-425ee0acceae",
"state": "submitted",
"submission_id": "a49fa8c3-7265-4081-896b-3c2d9c33c5ec",
"submitted_at": "2026-10-16T10:01:19Z",
"version": "version-97db"
}
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-01b8",
"message": "Draw the region map from operation density"
}
}
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-236f",
"message": "Label every synthesized example"
}
}
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-aca4",
"message": "Pin a page's payload to the build that rendered it"
}
}
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-a88b",
"message": "Label every synthesized example"
}
}
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-9fab",
"message": "Label every synthesized example"
}
}

CLI

gitmoap provider-publishing submit-provider

  • --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