LanceSign Up

Blog

Fixing 'a required agreement is missing or has expired'

· 5 min read · Lance

Your build upload fails, or a sales report request that ran fine yesterday starts returning 403, and the response says "A required agreement is missing or has expired." The fix is quick, but only one person on your team can apply it. The Account Holder signs in to App Store Connect, clicks Business at the top of the page (this section was named Agreements, Tax, and Banking before Apple renamed it), opens the Agreements tab, and accepts anything marked pending or expired. If that tab shows nothing to accept, the pending item is a revision of the Apple Developer Program License Agreement instead, and it appears as a banner on the Apple Developer account page rather than as a row in the list. Accept it, wait a few minutes, and retry.

The full API response looks like this:

{
  "errors": [{
    "status": "403",
    "code": "FORBIDDEN.REQUIRED_AGREEMENTS_MISSING_OR_EXPIRED",
    "title": "A required agreement is missing or has expired.",
    "detail": "This request requires an in-effect agreement that has not been signed or has expired.",
    "links": { "see": "/business" }
  }]
}

Transporter and Xcode surface the same account state as "You do not have required contracts to perform an operation", code FORBIDDEN_ERROR.CONTRACT_NOT_VALID.

The Agreements table in App Store Connect's Business section, showing the Free Apps and Paid Apps agreements both Active with their effective dates

What healthy looks like: both agreements Active under Business, then Agreements. A missing or expired row here is what turns API calls into 403s.

What the error blocks

More than you would expect. Developers hit this 403 on plain reads, not just on submissions: sales report requests, certificate lists, and bundle ID lookups all return it once enforcement kicks in. Build uploads fail with the contract variant above. And if the agreement in question is the Paid Apps Agreement, the block extends to money, since an in-effect Paid Apps Agreement is one of Apple's requirements for paying out your proceeds at all.

The enforcement schedule is what makes the error feel random. When Apple publishes a new agreement version, App Store Connect warns immediately, but developers tracking this on the forums report the API keeps working until a deadline passes, then blocks. So CI stays green for weeks after the warning appears, and one morning every job fails at once. There is no supported endpoint that reports pending-agreement status either. The old /v1/agreements endpoint is gone from current API versions, which leaves the 403 itself as the only signal the API gives you.

Why only the Account Holder can fix it

Agreements are contracts between Apple and your legal entity, and the Account Holder is the one role bound to that entity. Apple's role documentation puts renewing the annual membership, accepting legal agreements, and approving banking changes on that single person. Admins and Finance users can open the Business section, see the same warning, and even fill in tax and banking forms. They cannot click Agree. Signing the Paid Apps Agreement lists exactly one required role, Account Holder.

This is why the error strands whole teams. Twelve people with Admin access can all see the problem and none of them can fix it. Find out who your Account Holder is before you need them; their name is in the Membership details section of the developer account.

One trap worth naming, because it fills forum threads: developers get the 403, open the Agreements tab, and find nothing pending there. That usually means the pending item is a Program License Agreement update, which lives behind the banner on the developer site homepage, not in the agreements list.

The membership renewal variant

Same symptom, different cause. When the annual membership lapses, Apple shuts off most of the account: apps come off sale in every storefront, and the App Store Connect API, TestFlight, Certificates, and Xcode Cloud all stop working. Renewal is, again, the Account Holder's job. After a late renewal, free apps return within about 24 hours. Paid apps stay down until the Account Holder signs in to App Store Connect and accepts the Paid Applications Agreement again, because a lapsed membership voids it.

The Paid Applications Agreement variant

The standard membership covers free apps. Selling paid apps or in-app purchases requires the Paid Applications Agreement (the row in App Store Connect is labeled "Paid Apps"), and its setup has an order people get backwards. The Account Holder signs first, through "View and Agree to Terms" on the Paid Apps row. The required tax forms only appear after signing, and the US tax form applies to every developer regardless of country. Apple processes banking information only once all required tax forms are in. With everything submitted, the agreement typically flips to Active within a day.

Until it is Active, paid apps and in-app purchases stay blocked, and that includes the sandbox. Apps have failed App Review because the reviewer's test purchase failed while the Paid Apps Agreement sat inactive. A new version of this agreement also blocks creating new apps and in-app purchases until the Account Holder re-accepts. So "Pending Agreement" usually means nothing is broken. The right person has not clicked yet, or a tax form is sitting half-finished.

Catching it before the 403

Since the API only reveals agreement trouble by failing, most teams learn about it from a dead pipeline. An agent doing your App Store Connect work can check instead. Connected to the Lance MCP server, an agent calls get_account_health and gets back each team's agreements standing as a plain ok or missing_or_expired, plus alert lines already written to be forwarded to the account owner. Instead of dying mid-upload on a bare 403, the agent tells its human which agreement needs signing and that the Account Holder has to do it under Business, Agreements in App Store Connect. Lance's operator runs the same check from the other side: ask it why a submission is stuck and agreement state is among the first things it rules out.

Setup is one command:

npx add-mcp https://api.lance.app/mcp

Agreement state is one of the few blockers in an iOS pipeline that no tool can click through, because the click legally has to come from the Account Holder. The useful automation is not signing for them. It is noticing early and telling the right person where the button is.

Your agent builds the app. Lance ships it.

Connect your App Store Connect account and delegate the listing, screenshots, TestFlight, and review from your coding agent.

Start shipping free500 credits included. No credit card required.
Or add it to your coding agent right now — OAuth, no API keys:npx add-mcp https://api.lance.app/mcp

More from the blog