# AppSource Ready > Get a SaaS offer and its Teams app onto Microsoft Marketplace. Paste your Teams app manifest and your SaaS offer's > plans, and get the locked-at-publish choices, the Teams link, the landing page and co-sell eligibility checked against > Microsoft Marketplace rules, then the publishing plan or the fixes for a validation report. > Built on the SkillSafe skill @samber/microsoft-appsource-playbook, from samber/developer-platform-skills (MIT), by > Samuel Berthe. > Not affiliated with or endorsed by Microsoft. > Scope: a B2B SaaS vendor taking a product onto Microsoft Marketplace and the Teams store - the transactable SaaS > offer, the choices locked at publish, Teams and Microsoft 365 app validation, Publisher Attestation, Teams-linked SaaS, > private offers, co-sell and Azure IP co-sell eligibility. Not listing copy or search rank, not Teams bot code, not > Windows Store apps, not services co-sell, not spending MACC as a buyer. https://appsource-ready.skillsafe.ai/ ## What is free - Parsing: the Teams manifest.json by JSON.parse, every error with its line and column: manifestVersion, id, version, developer (name, websiteUrl, privacyUrl, termsOfUseUrl, mpnId), name.short and name.full, description, bots, staticTabs, configurableTabs, composeExtensions, copilotAgents declarative agents, validDomains, webApplicationInfo, authorization.permissions.resourceSpecific and subscriptionOffer. - The plans, from a small line format: "offer: id | pricing: flat or per user | contract: standard or own terms", then "plan: id | name | public or private | seats min-max | price ... | dimension: id=value, id=value | pricing: ..." one per plan; blank lines and # comments skipped, every malformed line named with its number. - The locked-choice register: the pricing model, every plan ID, the seat limits of every per-user plan, every metered dimension, every plan's visibility and the contract, each row "locked once published", its owner and decision date "unassigned". - The checks, each with an id, the skill's rule and pass, fix, fail, note or n/a: teams_pricing, link_live and subscription_offer_id (the Teams link); pricing_mixed, metering_per_user and locked_pricing, locked_plan_id, locked_seats, locked_dimensions, locked_contract, locked_visibility (commitments locked at publish, against the plans as published); listing_eligibility and offer_type (who can list, and what counts); landing_hash, landing_https, webhook, entra_multitenant, activation_permissions, cert_notes, test_accounts_mfa and dev_offer (ship the SaaS offer); publisher_verification and attestation (Teams validation); manifest_fields, manifest_schema, app_name, developer_urls, valid_domains, sso_app and rsc_permissions (the manifest); macc_azure, ip_cosell, teams_cosell, seller_outreach and m365_certification (co-sell and MACC); renewal_attestation (private offers); timeline. - The path ladder: transact SaaS + private offers > + Teams app linked > + Azure IP co-sell eligible > Teams app alone > Contact me, re-ranked by the interview - no Microsoft 365 surface drops the Teams rungs, an add-in or a Copilot agent drops the Teams link, another cloud deletes IP co-sell and, with no Microsoft integration, the SaaS offer too; a target date promotes the Teams app and private offers; MACC buyers on Azure promote IP co-sell - each naming the answer that moved it, with the starved option, Microsoft 365 Certification, promoted only when regulated buyers' security reviews stall deals. - The co-sell target (not targeted, co-sell ready or Azure IP co-sell eligible) and its gap; the timeline backward from the target date or forward from today by the browser clock, one failed validation cycle included. - Exports: the register (.csv, its decision and owner columns filled from a plan reply when one exists), the checks (.csv), everything (.json), the fixed manifest (manifest.fixed.json, pretty-printed; subscriptionOffer added only when the offer is live and a plan names publisherId.offerId with a publisher ID the input already contains - never an invented id or URL) and the fixed plans (.txt: per user when the Teams link needs it and the offer is not published, the dimensions dropped; a locked field of a published offer is never changed - the change list says it needs a new offer or plan; seat limits and prices are never invented). - Saved offers keep a compact snapshot of the checks: reopening one, or pasting an offer of the same name, shows what changed since it was saved (checks fixed, checks newly failing, plans and dimensions removed or added, the fail count). "Mark as resubmitted" logs the date and the object that went back; the next fixes run then carries the previous round's fixes with the plan. - Every Microsoft figure the skill quotes carries a dagger: 3%†, the fee halves†, $100,000† in the trailing 12 months†, $1M+†, 48 h†, 24 hours†, 10 seconds†, hourly†, 72 hours†, 24 working hours†, three to six weeks†, 3-4 business days†, four to six weeks†, about a week†, October 2024†, schema 1.25†. † verify in Partner Center before quoting it, since Microsoft renames programs and moves criteria yearly. ## The metered lanes Two tasks on gpt-terra, metered per run, routed by `task`. Input string fields: `task` (plan or fixes), `product`, `manifest` (the manifest as read, or empty), `offer`, `setup`, `report` (fixes only: the validation report text), `carry` (fixes only: the plan's path, register, fixes and submission, plus the previous round's fixes once a resubmission is logged) and `facts`. - `plan` replies with `summary`, `path` (`rung` transact_private, teams_linked, ip_cosell, teams_only or contact_me, `why`), `locked` (`choice` pricing model, plan id, seat limits, dimensions, contract or plan visibility, `decision`, `owner`, `by`), `fixes` (`check`, `change`), `submission` (`item`, `object` teams_app, saas_offer or cosell, `done`), `cosell` (`status` not_targeted, cosell_ready or ip_cosell_eligible, `gap`), `timeline` (`step`, `wait`), `footnote` and `caveats`. - `fixes` replies with `summary`, `points` (`n`, `report`, `severity` must_fix, good_to_fix, blocker, query or unlabelled, `fix`, `check`), `resubmit` (`object`, `effect`, `when`), `reply` (each point on its own line), `footnote` and `caveats`. A reply stays on the page when the form changes after it ran, under an out-of-date banner, and its downloads and copies keep working; each plan fix and each report point copies on its own, and the fixes export a resubmission checklist (.md). The page holds every reply to its own facts: the plan keeps the page's top rung and co-sell target (a moved one is put back), gives every register row exactly one locked row and invents none, keeps owners "unassigned" and dates "before first publish" unless the input gives them, and carries every fail check as a fix; the fixes answer at least as many points as the report numbers or labels, keep each labelled item's severity, follow the re-validation rule (a manifest, screenshot or Partner Center change re-enters validation; a web-service-only change does not) and answer the reviewer one point per line, counting numbered points on their own lines or inline, never arguing and never asking to expedite; both carry the dagger on every Microsoft figure, the footnote, no URL, no backticks, no invented price and no implied Microsoft endorsement. ## Links - API tutorial: https://appsource-ready.skillsafe.ai/api.html - Source skill: https://skillsafe.ai/skill/@samber/microsoft-appsource-playbook - Source repository: https://github.com/samber/developer-platform-skills