The Microsoft Store submission API: how to publish an MSIX update with code

The Microsoft Store submission API lets you publish an MSIX update from code instead of clicking through Partner Center. You sign in with a Microsoft Entra application, copy your last submission, change it, upload a ZIP with the new package, commit it and watch its status. Here's each request, the parts that trip people up, and how StoreFast runs the same flow for you.

If you want full control and don't mind writing and maintaining the code, call the API yourself with the requests below. If you'd rather not, StoreFast makes the same calls from a dashboard, a REST API, an MCP server or a GitHub Action.

  • You need a Microsoft Entra application with the Manager role in Partner Center, and a token for https://manage.devcenter.microsoft.com that lasts 60 minutes.
  • An update is six calls: check the app, create a submission, update it, upload a ZIP to its fileUploadUrl, commit, then poll the status.
  • The app and its first submission have to exist in Partner Center already. The API can't create them.
  • Once a submission is made through the API, don't touch it in Partner Center, or the API can't commit it anymore.
  • MSI and EXE apps use a different API. This one is for MSIX packages.

What you need first

  • A Microsoft Entra tenant linked to Partner Center. Microsoft's prerequisites ask for a directory where you're a Global administrator. If you signed up with a personal Microsoft account, you can create one in Partner Center for free, and StoreFast's connection guide walks through it.
  • An Entra application with the Manager role. In Partner Center, add the application under Account settings, User management and give it Manager. Then copy its Tenant ID and Client ID and choose Add new key. Microsoft shows the key once.
  • An app with one submission already made by hand. You reserve the name in Partner Center and make the first submission there, including the age ratings questionnaire. From then on the API can create submissions for it.
  • Your app's Store ID, like 9NBLGGH4R315. The API calls it applicationId.

Get an access token

Every call carries an Azure AD access token in the Authorization header. You get it with the client credentials flow, and the resource has to be https://manage.devcenter.microsoft.com.

POST https://login.microsoftonline.com/<tenant_id>/oauth2/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
&client_id=<client_id>
&client_secret=<key>
&resource=https://manage.devcenter.microsoft.com

The response has an access_token. It's good for 60 minutes. After that you send the same request again for a new one, so a long upload should fetch a fresh token before it commits.

Publish an update, request by request

Every endpoint is under https://manage.devcenter.microsoft.com/v1.0/my/applications. These examples are cut down from the ones in Microsoft's Manage app submissions reference.

  1. 1

    Check that nothing is in progress

    Read the app first. If pendingApplicationSubmission has an ID, a submission is already open, either from Partner Center or another tool, and creating a new one fails. If lastPublishedApplicationSubmission is missing, the first version hasn't been published yet.

    GET https://manage.devcenter.microsoft.com/v1.0/my/applications/9NBLGGH4R315
    Authorization: Bearer <token>
    
    {
      "id": "9NBLGGH4R315",
      "packageIdentityName": "Contoso.MyApp",
      "lastPublishedApplicationSubmission": { "id": "1152921504621086517", ... },
      "pendingApplicationSubmission": { "id": "1152921504621243487", ... }
    }
  2. 2

    Create a submission

    The new submission is a copy of your last published one, with status PendingCommit. The response has its ID, all of its data, and a fileUploadUrl, a shared access signature (SAS) URL for Azure Blob Storage where your files go.

    POST https://manage.devcenter.microsoft.com/v1.0/my/applications/9NBLGGH4R315/submissions
    Authorization: Bearer <token>
    
    {
      "id": "1152921504621243540",
      "status": "PendingCommit",
      "fileUploadUrl": "https://productingestionbin1.blob.core.windows.net/ingestion/...?sv=...&sr=b&sig=...&sp=rwl",
      "listings": { "en-us": { "baseListing": { "releaseNotes": "", ... } } },
      "applicationPackages": [
        { "fileName": "MyApp_1.3.0.0_x64.msix", "fileStatus": "Uploaded", "version": "1.3.0.0", ... }
      ],
      ...
    }
  3. 3

    Update the submission

    Edit the JSON you got back and PUT the whole thing. Add the new package with fileStatus PendingUpload, and mark a package you're replacing as PendingDelete. For each package, Microsoft requires fileName, fileStatus, minimumDirectXVersion and minimumSystemRam. The last two are ignored for current Windows apps, but they still have to be there. The release notes for each language go in releaseNotes on that listing.

    PUT https://manage.devcenter.microsoft.com/v1.0/my/applications/9NBLGGH4R315/submissions/1152921504621243540
    Authorization: Bearer <token>
    Content-Type: application/json
    
    {
      ...every field you got back from the POST, without fileUploadUrl...
      "listings": {
        "en-us": { "baseListing": { "releaseNotes": "Starts faster and fixes a crash on close.", ... } }
      },
      "applicationPackages": [
        { "fileName": "MyApp_1.3.0.0_x64.msix", "fileStatus": "PendingDelete", "minimumDirectXVersion": "None", "minimumSystemRam": "None" },
        { "fileName": "MyApp_1.4.0.0_x64.msix", "fileStatus": "PendingUpload", "minimumDirectXVersion": "None", "minimumSystemRam": "None" }
      ]
    }

    The fileName has to match the file's name and relative path inside the ZIP you upload next. Leave the fields you don't change as they came, so nothing gets reset.

  4. 4

    Upload the ZIP

    Put the new package, and any new screenshots, in one ZIP and send it to the fileUploadUrl. MSIX files are already compressed, so storing them with zip -0 is fine. The upload goes straight to Azure Storage, so it needs no token, only the SAS URL.

    zip -0 upload.zip MyApp_1.4.0.0_x64.msix
    
    curl -X PUT -T upload.zip \
      -H "x-ms-blob-type: BlockBlob" \
      -H "x-ms-version: 2023-11-03" \
      "$FILE_UPLOAD_URL"

    A single Put Blob takes up to 5,000 MiB with Azure Storage version 2019-12-12 or later, which is why the example sets x-ms-version. Bigger files, or uploads you want to resume, go up in pieces with Put Block and Put Block List. Treat the SAS URL like a password and keep it out of logs.

  5. 5

    Commit

    Committing tells Partner Center you're done and sends the submission on for processing.

    POST https://manage.devcenter.microsoft.com/v1.0/my/applications/9NBLGGH4R315/submissions/1152921504621243540/commit
    Authorization: Bearer <token>
    
    { "status": "CommitStarted" }
  6. 6

    Poll the status

    Microsoft says the status goes from CommitStarted to PreProcessing when the commit worked, or to CommitFailed with the reasons in statusDetails. After that it moves through certification and publishing, and you can keep polling or watch it in Partner Center.

    GET https://manage.devcenter.microsoft.com/v1.0/my/applications/9NBLGGH4R315/submissions/1152921504621243540/status
    Authorization: Bearer <token>
    
    {
      "status": "PreProcessing",
      "statusDetails": { "errors": [], "warnings": [], "certificationReports": [] }
    }
StatusWhat it means
PendingCommitCreated but not committed. You can still change it or delete it.
CommitStartedPartner Center is checking what you sent.
CommitFailedSomething in the submission or the ZIP was wrong. statusDetails says what.
PreProcessing, CertificationThe package is being processed, then certified.
Release, Publishing, PendingPublicationCertification passed and the update is on its way to the Store.
PublishedThe update is live.
PreProcessingFailed, CertificationFailed, ReleaseFailed, PublishFailedIt stopped at that step. Fix it and submit again.

Things that go wrong

  • One submission in progress at a time. The app has a single pendingApplicationSubmission, and creating a submission returns 409 when the app's current state doesn't allow it. Finish or delete the open one first.
  • Editing an API submission in Partner Center. Microsoft warns that once you change it there, the API can't change or commit it anymore, and it can get stuck in an error state. Then you delete it and start over.
  • Features the API doesn't support. Apps that use mandatory updates or Store-managed consumable add-ons get a 409, and you have to use Partner Center for them. Apps on Pricing Version 2 come back with an unknown pricing tier, though you can still update everything else.
  • File names that don't match the ZIP. Every PendingUpload file in the submission has to be in the ZIP under the same name and relative path.
  • An expired token mid-flow. A big upload can outlast the 60 minutes. Get a new token before you commit.
  • Shallow JSON in PowerShell. ConvertTo-Json stops at two levels by default and mangles the submission. Microsoft suggests -Depth 20.
  • Retrying a commit. If a commit timed out but went through, trying again can return 409. Check the status before you assume it failed.

MSIX vs MSI and EXE

Everything above is the original Microsoft Store submission API, which takes MSIX packages. MSI and EXE apps use the Microsoft Store submission API for MSI or EXE apps, at https://api.store.microsoft.com. Its token comes from the v2.0 endpoint with the scope https://api.store.microsoft.com/.default, and it has its own requests.

How StoreFast does this for you

StoreFast calls the same submission API. You don't write the requests, and you don't keep a key.

  • Connecting without a key. You choose Sign in with Microsoft as an admin of the tenant linked to Partner Center. StoreFast adds an application named StoreFast Partner Center access to your tenant with a federated credential instead of a key. It trusts StoreFast's sign-in for your StoreFast account only, so there's no secret to copy, leak or renew. You give it the Manager(Windows) role in Partner Center. The permission to create the application is used once and not kept. If you'd rather make the application yourself, you can paste a Tenant ID, Client ID and key, and StoreFast encrypts the key before storing it. The connection guide has the steps.
  • Checks before anything is sent. StoreFast makes sure the new version is higher than the one in the Store, that there's no submission already in progress, and that the first version was published in Partner Center. On the dashboard it also checks the package name against your app.
  • The six calls. When you submit, StoreFast creates the submission, sets What's new in every listing language, replaces the old package with the new one, uploads the ZIP to the fileUploadUrl in 8 MB blocks, commits and follows the status until the update is live or fails. Packages can be up to 4000 MB.
  • Cleanup. If a step keeps failing before the commit, StoreFast deletes the draft it made, so the next try doesn't hit a 409.
  • Hold for release. With holdPublish, the submission waits after certification until you press Publish now in Partner Center.

You can run that from the dashboard, from your own code with the StoreFast REST API and one API key, from a coding agent through the MCP server, or from CI with the GitHub Action. If you're weighing Microsoft's own tools, the msstore CLI and StoreBroker are built on this API too.

Calling it yourself or through StoreFast

FeatureStoreFastYour own code
CredentialsFederated, no keyor your own key, encryptedA key you store and renew
Token handlingYesYou write it
Checks for a submission in progressYesYou write it
Large uploads in blocksYesup to 4000 MBYou write it
What's new translated into every languageYesNo
Deletes a failed draftYesYou write it
MSI and EXE appsNocomingYesa separate API
Gradual rollout and flightsNoYes
PriceFrom $12 a monthFree, plus your time

Who it's for

StoreFast is a good fit if

  • You publish MSIX updates and would rather not write and maintain the submission code.
  • You don't want a Partner Center key sitting in CI secrets.
  • Your listing has several languages and you want What's new in all of them.

Look elsewhere if

  • You need gradual rollout, package flights or add-ons from code. The API has methods for those.
  • You ship an MSI or EXE. Use the submission API for MSI or EXE apps, or the msstore CLI.
  • You want everything in your own scripts with no service in between.

Questions

Can the submission API create a new app or its first submission?
No. Microsoft's docs say you reserve the app's name in Partner Center and make one submission there, including the age ratings questionnaire. After that, the API can create every new submission for the app.
How long does the access token last?
60 minutes. When it expires, you make the same token request again.
Does the same API publish MSI and EXE apps?
No. Those use a separate Microsoft Store submission API for MSI or EXE apps at api.store.microsoft.com, with its own token scope. The API on this page is the one for MSIX packages.
Why does my request return 409?
Microsoft returns 409 when the app's current state doesn't allow the request, such as another submission already in progress, or when the app uses something the API doesn't support, like mandatory updates or Store-managed consumable add-ons.
Do I need a client secret?
Microsoft's docs use a key you create in Partner Center. StoreFast doesn't keep one: the app it creates in your tenant has a federated credential instead, so there's no key to copy or renew. You can still paste your own key if you'd rather.

Skip writing the submission code

Sign in with Microsoft once, then publish from the dashboard, your own scripts, a coding agent or GitHub Actions. Try it free for 7 days, no card needed.

Sources

Facts about Microsoft's tools were checked against these pages on October 5, 2026.