100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Microsoft 365

The Teams App Manifest

The manifest.json file is the declarative blueprint that tells Microsoft Teams who an app is, what it can do, and where it is allowed to run.

Building Teams AppsBeginner8 min readJul 10, 2026
Analogies

What Is the Teams App Manifest?

Every Microsoft Teams app is described by a single JSON file, manifest.json, which acts as the contract between the app and the Teams client. Before Teams ever renders a tab, starts a bot conversation, or shows a message extension, it reads this file to learn the app's identity, required capabilities, and permitted domains. Nothing runs in Teams that isn't first declared here.

🏏

Cricket analogy: Just as a cricket team submits its playing XI and fielding plan to the match referee before the toss, declaring exactly who bowls and where each fielder stands, the manifest declares every capability an app needs before Teams allows it to take the field.

Manifest Structure and Required Fields

The manifest's top-level fields anchor the app's identity: $schema and manifestVersion pin which version of the manifest schema Teams should validate against (currently 1.19 or 1.20), id is a GUID that uniquely identifies the app across tenants, and packageName follows reverse-DNS convention like com.contoso.helpdesk. The developer object records the publisher's name, website, and support/privacy URLs, while name, description, and version fields exist in both short and full variants for display in the Teams app catalog. Icons must be supplied as a 192x192 color PNG and a 32x32 transparent outline PNG, referenced by filename and bundled in the same zip package.

🏏

Cricket analogy: The id GUID is like a player's unique ICC registration number that never changes even if they switch franchises between IPL seasons, letting scorers and broadcasters track the same person across every tournament unambiguously.

Capabilities: Tabs, Bots, and Message Extensions

Capabilities are declared in dedicated arrays. staticTabs list personal-scope tabs pinned to the app's personal app bar entry, each with an entityId and contentUrl. configurableTabs are added to a channel or group chat and include a configurationUrl the user visits once to set up the tab instance. The bots array holds one entry per bot, referencing its botId (the Azure AD app ID from Bot Framework registration) and a scopes array such as personal, team, or groupchat. composeExtensions likewise reference a botId and list commands the user can invoke from the compose box, each with a type of query or action.

🏏

Cricket analogy: Declaring scopes like personal, team, and groupchat for a bot is like a franchise registering a player as eligible for T20, ODI, and Test formats separately, since eligibility in one format doesn't automatically carry to another.

json
{
  "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.19/MicrosoftTeams.schema.json",
  "manifestVersion": "1.19",
  "version": "1.0.0",
  "id": "9c4b1f2e-7a3d-4e5c-8f1a-2b3c4d5e6f7a",
  "packageName": "com.contoso.helpdesk",
  "developer": {
    "name": "Contoso",
    "websiteUrl": "https://contoso.com",
    "privacyUrl": "https://contoso.com/privacy",
    "termsOfUseUrl": "https://contoso.com/terms"
  },
  "name": { "short": "Helpdesk", "full": "Contoso Helpdesk Assistant" },
  "description": { "short": "Log and track IT tickets", "full": "Create, track, and resolve IT support tickets without leaving Teams." },
  "icons": { "color": "color.png", "outline": "outline.png" },
  "accentColor": "#464775",
  "staticTabs": [
    { "entityId": "myTickets", "name": "My Tickets", "contentUrl": "https://helpdesk.contoso.com/tab", "scopes": ["personal"] }
  ],
  "bots": [
    { "botId": "9c4b1f2e-7a3d-4e5c-8f1a-2b3c4d5e6f7a", "scopes": ["personal", "team"], "supportsFiles": false }
  ],
  "validDomains": ["helpdesk.contoso.com"]
}

You rarely hand-write a manifest from a blank file. Teams Toolkit (for VS Code) and the Teams Developer Portal both scaffold a valid starting manifest and offer a schema-aware editor that flags missing required fields before you ever try to sideload the app.

Permissions, validDomains, and Packaging

The validDomains array whitelists every external domain the app's tabs, bots, or connectors are allowed to load content from or redirect to; any domain not listed will be blocked by the Teams client, typically showing a blank iframe with no error surfaced to the user. The webApplicationInfo object enables single sign-on by pointing to the Azure AD app registration's client id and the API resource URI Teams should request a token for, letting getAuthToken() in the Teams JS SDK silently obtain access without a separate login prompt. Once all fields are complete, the manifest.json plus the two icon PNGs are zipped together into a single app package, which is what gets uploaded to the Developer Portal, sideloaded for testing, or published to the tenant app catalog.

🏏

Cricket analogy: validDomains acting as a whitelist is like a stadium's accredited-vehicle list for the players' entrance; any car not on that list, even a legitimate team bus, gets turned away silently at the gate.

The most common manifest failures aren't syntax errors but silent runtime ones: an icon that isn't exactly 192x192 or 32x32 pixels, a botId that doesn't match the Azure Bot Service's Microsoft App ID, or a tab's contentUrl domain missing from validDomains. These pass JSON validation but produce a blank tab or a bot that never responds, so always test with a real sideload, not just schema validation.

  • manifest.json is the single declarative source of truth Teams reads before loading any app capability.
  • Required top-level fields include manifestVersion, a unique id GUID, packageName, developer info, and two icon sizes (192x192 color, 32x32 outline).
  • staticTabs are personal-scope tabs with a fixed contentUrl; configurableTabs are added to channels/chats via a one-time configurationUrl.
  • bots and composeExtensions both reference a botId tied to an Azure Bot Service registration and declare their allowed scopes or commands.
  • validDomains must whitelist every external domain used by tabs or auth redirects, or content silently fails to load.
  • webApplicationInfo enables SSO by linking the manifest to an Azure AD app registration.
  • The final app package is a zip of manifest.json plus both icon files, used for sideloading or catalog publishing.

Practice what you learned

Was this page helpful?

Topics covered

#Microsoft365#MicrosoftTeamsDevelopmentStudyNotes#MicrosoftTechnologies#TheTeamsAppManifest#Teams#App#Manifest#Structure#StudyNotes#SkillVeris