Publishing Teams Apps: The Manifest and App Catalog Workflow
Your bot works in sideload but won't install for the team. The gap is the app manifest and the catalog approval flow — here's the path from dev to org-wide.
- #microsoft-teams
- #app-manifest
- #publishing
- #devops
- #governance
- #ci-cd
The most demoralizing moment in Teams development isn’t writing the bot — it’s the moment your perfectly working app, the one you’ve been debugging via sideload for two weeks, refuses to install for anyone but you. Sideloading hides the entire distribution story, and that story is the app manifest plus the catalog approval flow. Get it wrong and your app is a personal toy; get it right and it’s installable org-wide with a click.
I’ve shipped enough internal DevOps apps to know exactly where the snags are. Here’s the path from “works on my machine” to “available in the company app catalog.”
The manifest is the contract
manifest.json is the single source of truth for what your app is and what it’s allowed to do. Teams reads it at install time to decide what surfaces to show and what permissions to request. The fields that matter most for distribution:
{
"manifestVersion": "1.17",
"id": "00000000-0000-0000-0000-000000000000",
"version": "1.4.0",
"developer": {
"name": "Platform Team",
"websiteUrl": "https://ops.example.com",
"privacyUrl": "https://ops.example.com/privacy",
"termsOfUseUrl": "https://ops.example.com/terms"
},
"name": { "short": "DeployBot", "full": "DevOps DeployBot" },
"description": {
"short": "Deploy and status via ChatOps",
"full": "Guarded deploys, rollbacks, and live status inside Teams."
},
"icons": { "color": "color.png", "outline": "outline.png" },
"accentColor": "#1F6FEB",
"bots": [{ "botId": "BOT-APP-ID", "scopes": ["team", "groupChat"] }],
"validDomains": ["ops.example.com"],
"webApplicationInfo": {
"id": "AAD-APP-ID",
"resource": "api://ops.example.com/AAD-APP-ID"
}
}
The fields that bite people:
validDomains— if your tab or dialog loads a URL whose domain isn’t listed here, it renders blank with no error. Every domain your app navigates to must be here.id— the Teams app ID, distinct from your bot ID and your Azure AD app ID. Three different GUIDs; mixing them up is the classic confusion.developerURLs — privacy and terms URLs are required for catalog submission. Missing them passes sideload and fails publish.- Icons — you need a 192×192 color icon and a transparent 32×32 outline icon. Wrong dimensions fail validation silently in some clients.
Validate before you ever try to publish
Run validation locally so you find schema errors at your desk, not in an admin’s rejection email:
teamsapp validate --manifest-path ./appPackage/manifest.json
# or use the App Validation tool in Developer Portal
The Developer Portal (dev.teams.microsoft.com) has a more thorough checker that flags the soft requirements — accessibility, metadata completeness — that the schema validator misses but the store reviewers don’t.
Three distribution paths
There isn’t one “publish” — there are three, and you pick by audience:
- Sideload (upload a custom app) — you, or anyone with permission, manually uploads the app package zip. Dev and small-team use. Requires custom app upload to be enabled in your tenant.
- Org app catalog — submit the package to your organization’s catalog. A Teams admin reviews and approves it, after which everyone in the org can install it from the “Built for your org” section. This is the path for internal DevOps tools.
- Microsoft Teams Store — public submission with Microsoft’s full certification review. Only relevant if you’re shipping to other companies.
For an internal deploy bot, you want path 2.
The org catalog flow
The package you submit is a zip of exactly three files: manifest.json, color.png, outline.png. Nothing else. Then:
teamsapp publish --env prod
# pushes the package to the org catalog, pending admin approval
Or upload the zip in the Teams admin center under Teams apps → Manage apps → Upload new app. An admin reviews it, approves it, and can pin it or pre-install it for specific groups. The admin also controls app permission policies — even an approved app won’t appear for users whose policy blocks it, which is a common “approved but invisible” head-scratcher.
Versioning and updates
Updating a published app is just a new package with a bumped version (semver), re-submitted. Two rules that save pain:
- Bump
versionon every change or Teams won’t recognize the update and users keep the old app. - Never change
idfor an update. A newidis a brand-new app, not an update — your users would have both installed. Theidis the app’s identity for its entire life.
If your update adds new permissions or RSC scopes, it triggers admin re-consent. Plan for that: a permission change is not a silent update, and users may need to re-accept.
Wire it into CI
Because the package is deterministic and teamsapp publish is scriptable, app distribution belongs in your release pipeline alongside the service deploy. A merge to main builds the service, builds the app package with the prod manifest, and submits to the catalog. The only manual step left is the admin approval — which is exactly the human gate you want for something that installs org-wide.
The manifest is small but unforgiving: every URL declared, three GUIDs kept straight, required developer fields present, version bumped. Get those right and the distribution story that sideloading hides becomes a one-command publish.
For more on shipping DevOps apps in Teams, see the Microsoft Teams guides, and the prompt library has prompts for generating and validating manifests.
Manifest schema versions, required fields, and admin center flows change over time. Validate against the current schema and Developer Portal before submitting to your catalog.
Download the Free 500-Prompt DevOps AI Toolkit
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.