{
  "openapi": "3.1.0",
  "info": {
    "title": "Reploya read API",
    "version": "1",
    "description": "Read only access to your organization's managed apps, approvals and releases. Two ways in, both sent as Authorization: Bearer <value>: an API key (create one under External access, API access), or an Entra access token of an application in your organization's own Microsoft tenant that you added on the same page. Every operation names the scope it needs in x-reploya-scope; today every operation needs api.read. At most 60 requests per minute per key or application."
  },
  "servers": [
    {
      "url": "https://app.reploya.com/api/v1"
    }
  ],
  "security": [
    {
      "bearer": []
    },
    {
      "entra": [
        "api://c1bf89f0-a80e-4ba8-936a-c4fc364c7da0/.default"
      ]
    }
  ],
  "paths": {
    "/organization": {
      "get": {
        "operationId": "getOrganization",
        "summary": "The organization and the credential behind this request (use it to test a credential).",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Organization"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credential: an unknown, revoked or expired key, or a token that is not a valid Entra application token of an added application; or the organization is scheduled for deletion (organization_pending_deletion).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The organization's subscription is not active (subscription_inactive), its plan does not include the API (plan_required), or the credential lacks the scope (insufficient_scope).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over 60 requests per minute; see Retry-After.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Entra tokens cannot be checked right now (auth_unavailable); see Retry-After. API keys are not affected.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-reploya-scope": "api.read"
      }
    },
    "/apps": {
      "get": {
        "operationId": "listApps",
        "summary": "Managed apps with live version and ring stage.",
        "parameters": [
          {
            "name": "platform",
            "in": "query",
            "required": false,
            "description": "Only this platform.",
            "schema": {
              "type": "string",
              "enum": [
                "windows",
                "macos"
              ]
            }
          },
          {
            "name": "patchStatus",
            "in": "query",
            "required": false,
            "description": "Only this status.",
            "schema": {
              "type": "string",
              "enum": [
                "up_to_date",
                "update_available",
                "updating",
                "failed",
                "not_assigned",
                "not_deployed",
                "removed",
                "draft"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "nextCursor of the previous page.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AppPage"
                }
              }
            }
          },
          "400": {
            "description": "Invalid parameter.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credential: an unknown, revoked or expired key, or a token that is not a valid Entra application token of an added application; or the organization is scheduled for deletion (organization_pending_deletion).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The organization's subscription is not active (subscription_inactive), its plan does not include the API (plan_required), or the credential lacks the scope (insufficient_scope).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over 60 requests per minute; see Retry-After.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Entra tokens cannot be checked right now (auth_unavailable); see Retry-After. API keys are not affected.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-reploya-scope": "api.read"
      }
    },
    "/apps/{id}": {
      "get": {
        "operationId": "getApp",
        "summary": "One app with its current release, rings and recent versions.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Managed app id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AppDetail"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credential: an unknown, revoked or expired key, or a token that is not a valid Entra application token of an added application; or the organization is scheduled for deletion (organization_pending_deletion).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The organization's subscription is not active (subscription_inactive), its plan does not include the API (plan_required), or the credential lacks the scope (insufficient_scope).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such app in your organization.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over 60 requests per minute; see Retry-After.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Entra tokens cannot be checked right now (auth_unavailable); see Retry-After. API keys are not affected.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-reploya-scope": "api.read"
      }
    },
    "/approvals": {
      "get": {
        "operationId": "listPendingApprovals",
        "summary": "Versions waiting for approval, newest first.",
        "parameters": [
          {
            "name": "appId",
            "in": "query",
            "required": false,
            "description": "Only this app.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "nextCursor of the previous page.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApprovalPage"
                }
              }
            }
          },
          "400": {
            "description": "Invalid parameter.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credential: an unknown, revoked or expired key, or a token that is not a valid Entra application token of an added application; or the organization is scheduled for deletion (organization_pending_deletion).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The organization's subscription is not active (subscription_inactive), its plan does not include the API (plan_required), or the credential lacks the scope (insufficient_scope).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over 60 requests per minute; see Retry-After.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Entra tokens cannot be checked right now (auth_unavailable); see Retry-After. API keys are not affected.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-reploya-scope": "api.read"
      }
    },
    "/releases": {
      "get": {
        "operationId": "listReleases",
        "summary": "Releases, newest first.",
        "parameters": [
          {
            "name": "appId",
            "in": "query",
            "required": false,
            "description": "Only this app.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Only this status.",
            "schema": {
              "type": "string",
              "enum": [
                "waiting",
                "canceling",
                "completed",
                "replaced",
                "queued",
                "building",
                "assigning",
                "reconciling",
                "active",
                "retiring",
                "retired",
                "failed",
                "canceled",
                "superseded"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "nextCursor of the previous page.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReleasePage"
                }
              }
            }
          },
          "400": {
            "description": "Invalid parameter.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credential: an unknown, revoked or expired key, or a token that is not a valid Entra application token of an added application; or the organization is scheduled for deletion (organization_pending_deletion).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The organization's subscription is not active (subscription_inactive), its plan does not include the API (plan_required), or the credential lacks the scope (insufficient_scope).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Over 60 requests per minute; see Retry-After.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Entra tokens cannot be checked right now (auth_unavailable); see Retry-After. API keys are not affected.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-reploya-scope": "api.read"
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearer": {
        "type": "http",
        "scheme": "bearer",
        "description": "An API key starting with rpk_. Keys created before scopes existed hold api.read."
      },
      "entra": {
        "type": "oauth2",
        "description": "Client credentials with Microsoft Entra. Replace organizations in the token URL with your tenant ID. The token carries the app roles granted to your application (today api.read), and the application must be added on the API access page.",
        "flows": {
          "clientCredentials": {
            "tokenUrl": "https://login.microsoftonline.com/organizations/oauth2/v2.0/token",
            "scopes": {
              "api://c1bf89f0-a80e-4ba8-936a-c4fc364c7da0/.default": "Every Reploya app role granted to your application (today api.read)."
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "invalid_request",
                  "unauthorized",
                  "organization_pending_deletion",
                  "subscription_inactive",
                  "plan_required",
                  "insufficient_scope",
                  "not_found",
                  "method_not_allowed",
                  "wrong_host",
                  "rate_limited",
                  "internal",
                  "auth_unavailable"
                ]
              },
              "message": {
                "type": "string"
              }
            },
            "additionalProperties": true
          }
        },
        "additionalProperties": true
      },
      "AppRef": {
        "type": "object",
        "required": [
          "id",
          "name",
          "platform"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "platform": {
            "type": "string",
            "enum": [
              "windows",
              "macos"
            ]
          }
        },
        "additionalProperties": true
      },
      "RingStage": {
        "oneOf": [
          {
            "type": "object",
            "required": [
              "kind",
              "reached",
              "total",
              "next",
              "dueAt"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "waiting"
                ]
              },
              "reached": {
                "type": "integer"
              },
              "total": {
                "type": "integer"
              },
              "next": {
                "type": "string"
              },
              "dueAt": {
                "type": "string",
                "format": "date-time"
              }
            },
            "additionalProperties": true
          },
          {
            "type": "object",
            "required": [
              "kind",
              "ring",
              "total"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "assigning"
                ]
              },
              "ring": {
                "type": "integer"
              },
              "total": {
                "type": "integer"
              }
            },
            "additionalProperties": true
          },
          {
            "type": "object",
            "required": [
              "kind",
              "reached",
              "total"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "paused"
                ]
              },
              "reached": {
                "type": "integer"
              },
              "total": {
                "type": "integer"
              }
            },
            "additionalProperties": true
          },
          {
            "type": "object",
            "required": [
              "kind",
              "total"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "assigned"
                ]
              },
              "total": {
                "type": "integer"
              }
            },
            "additionalProperties": true
          }
        ]
      },
      "Ring": {
        "type": "object",
        "required": [
          "position",
          "name",
          "status"
        ],
        "properties": {
          "position": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "waiting",
              "assigning",
              "assigned",
              "failed",
              "canceled"
            ]
          },
          "dueAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": true
      },
      "App": {
        "type": "object",
        "required": [
          "id",
          "name",
          "platform",
          "status",
          "patchStatus",
          "url"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "vendor": {
            "type": "string"
          },
          "platform": {
            "type": "string",
            "enum": [
              "windows",
              "macos"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "paused",
              "removed",
              "draft"
            ]
          },
          "patchStatus": {
            "type": "string",
            "enum": [
              "up_to_date",
              "update_available",
              "updating",
              "failed",
              "not_assigned",
              "not_deployed",
              "removed",
              "draft"
            ]
          },
          "latestVersion": {
            "type": "string"
          },
          "deployedVersion": {
            "type": "string"
          },
          "targets": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Group names of a single target release, or ring names in rollout order."
          },
          "pendingVersion": {
            "type": "string",
            "description": "The version the release holding the slot is taking out."
          },
          "ringStage": {
            "$ref": "#/components/schemas/RingStage"
          },
          "url": {
            "type": "string",
            "format": "uri"
          }
        },
        "additionalProperties": true
      },
      "AppDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/App"
          },
          {
            "type": "object",
            "required": [
              "versions"
            ],
            "properties": {
              "currentRelease": {
                "type": "object",
                "required": [
                  "id",
                  "status",
                  "version",
                  "deliveryModel"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "waiting",
                      "canceling",
                      "completed",
                      "replaced",
                      "queued",
                      "building",
                      "assigning",
                      "reconciling",
                      "active",
                      "retiring",
                      "retired",
                      "failed",
                      "canceled",
                      "superseded"
                    ]
                  },
                  "version": {
                    "type": "string"
                  },
                  "deliveryModel": {
                    "type": "string",
                    "enum": [
                      "single",
                      "rings"
                    ]
                  },
                  "haltedAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "rings": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/Ring"
                    }
                  }
                },
                "additionalProperties": true
              },
              "versions": {
                "type": "array",
                "maxItems": 10,
                "items": {
                  "type": "object",
                  "required": [
                    "version",
                    "detectedAt"
                  ],
                  "properties": {
                    "version": {
                      "type": "string"
                    },
                    "detectedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "releaseNotesUrl": {
                      "type": "string",
                      "format": "uri"
                    }
                  },
                  "additionalProperties": true
                }
              }
            },
            "additionalProperties": true
          }
        ]
      },
      "Approval": {
        "type": "object",
        "required": [
          "id",
          "createdAt",
          "app",
          "version",
          "detectedAt",
          "tenant",
          "url"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "app": {
            "$ref": "#/components/schemas/AppRef"
          },
          "version": {
            "type": "string"
          },
          "detectedAt": {
            "type": "string",
            "format": "date-time"
          },
          "tenant": {
            "type": "object",
            "required": [
              "id",
              "name"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              }
            },
            "additionalProperties": true
          },
          "blocked": {
            "type": "string",
            "enum": [
              "rings-required",
              "not-pending",
              "not-approved",
              "app-removed",
              "unpublished",
              "connection-not-ready",
              "missing-metadata",
              "missing-location",
              "missing-location-by-name",
              "missing-installer",
              "no-target",
              "company-portal-group-conflict"
            ],
            "description": "Why it cannot be approved right now."
          },
          "url": {
            "type": "string",
            "format": "uri"
          }
        },
        "additionalProperties": true
      },
      "Release": {
        "type": "object",
        "required": [
          "id",
          "status",
          "deliveryModel",
          "app",
          "version",
          "tenant",
          "createdAt",
          "updatedAt",
          "url"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "waiting",
              "canceling",
              "completed",
              "replaced",
              "queued",
              "building",
              "assigning",
              "reconciling",
              "active",
              "retiring",
              "retired",
              "failed",
              "canceled",
              "superseded"
            ]
          },
          "deliveryModel": {
            "type": "string",
            "enum": [
              "single",
              "rings"
            ]
          },
          "app": {
            "$ref": "#/components/schemas/AppRef"
          },
          "version": {
            "type": "string"
          },
          "tenant": {
            "type": "object",
            "required": [
              "name"
            ],
            "properties": {
              "name": {
                "type": "string"
              }
            },
            "additionalProperties": true
          },
          "target": {
            "type": "string",
            "description": "Group of a single target release."
          },
          "assignedAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "error": {
            "type": "string",
            "description": "Plain English failure text, present when status is failed."
          },
          "url": {
            "type": "string",
            "format": "uri"
          }
        },
        "additionalProperties": true
      },
      "Organization": {
        "type": "object",
        "required": [
          "organization",
          "caller"
        ],
        "properties": {
          "organization": {
            "type": "object",
            "required": [
              "id",
              "name"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              }
            },
            "additionalProperties": true
          },
          "key": {
            "type": "object",
            "required": [
              "name",
              "prefix"
            ],
            "properties": {
              "name": {
                "type": "string"
              },
              "prefix": {
                "type": "string"
              },
              "expiresAt": {
                "type": "string",
                "format": "date-time"
              }
            },
            "additionalProperties": true,
            "description": "The same key fields as caller, for API keys only (kept from the first version)."
          },
          "caller": {
            "oneOf": [
              {
                "type": "object",
                "required": [
                  "type",
                  "name",
                  "prefix",
                  "scopes"
                ],
                "properties": {
                  "type": {
                    "const": "key"
                  },
                  "name": {
                    "type": "string"
                  },
                  "prefix": {
                    "type": "string"
                  },
                  "expiresAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "scopes": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "api.read"
                      ]
                    }
                  }
                },
                "additionalProperties": true
              },
              {
                "type": "object",
                "required": [
                  "type",
                  "name",
                  "applicationId",
                  "scopes"
                ],
                "properties": {
                  "type": {
                    "const": "application"
                  },
                  "name": {
                    "type": "string"
                  },
                  "applicationId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "scopes": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "api.read"
                      ]
                    }
                  }
                },
                "additionalProperties": true
              }
            ]
          }
        },
        "additionalProperties": true
      },
      "AppPage": {
        "type": "object",
        "required": [
          "items"
        ],
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/App"
            }
          },
          "nextCursor": {
            "type": "string",
            "description": "Pass as cursor for the next page; absent on the last page."
          }
        },
        "additionalProperties": true
      },
      "ApprovalPage": {
        "type": "object",
        "required": [
          "items"
        ],
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Approval"
            }
          },
          "nextCursor": {
            "type": "string",
            "description": "Pass as cursor for the next page; absent on the last page."
          }
        },
        "additionalProperties": true
      },
      "ReleasePage": {
        "type": "object",
        "required": [
          "items"
        ],
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Release"
            }
          },
          "nextCursor": {
            "type": "string",
            "description": "Pass as cursor for the next page; absent on the last page."
          }
        },
        "additionalProperties": true
      }
    }
  }
}