Publishing an app
The path from developer access to a published app — sandbox, submission, the automated checks, and what sends a review to a human.
This is the developer’s route from nothing to an app Foundry customers can install. If you’re deciding whether to build one, start with building a partner app — it covers what an app is and how installs work.
The path
1. Get developer access ← we grant it; not self-serve
2. Get OAuth credentials ← client_id + client_secret, shown once
3. Build against your sandbox ← seeded, throwaway, yours
4. Submit a version
5. Automated checks run
any fail → rejected, with reasons you can act on
all pass → auto-approved, or queued for a human
6. Published — customers can install it
1. Getting developer access
Developer access is granted, not requested. Talk to us about what you’re building; if it’s a fit, we link your organization to a developer identity.
Two things happen when we do:
- Your org gains the ability to create and submit apps.
- We provision you a sandbox organization, seeded with a full demo catalog — products, variants, orders, purchase orders, work orders.
Being an approved Foundry partner is not the same as being an app developer. A partner works inside a client’s org; a developer ships software into it. Those are different trust relationships, so they’re granted separately — holding one doesn’t imply the other.
2. Getting OAuth credentials
Your app receives its access token through an authorization-code flow — the merchant approves a consent screen and your server gets the token directly. Nobody copies a key out of the Foundry admin.
So before you can connect anything, you need a client_id and client_secret. Ask us once your app row exists; we issue them. The secret is shown once and is not recoverable — lose it and we rotate, which invalidates the old one immediately.
You also register your redirect URIs. These live on the app version, not the app, so changing them is a version bump that goes through review exactly like changing a scope. Matching is byte-exact — no wildcards, no trailing-slash tolerance — so register the precise string you redirect to.
Read connecting an app with OAuth before you write any of this. It covers the required state parameter, the error codes, and what the token actually is.
3. Building against your sandbox
Your sandbox is a real Foundry organization with real API behavior. The same endpoints, the same keys, the same webhook deliveries. What you build against is what ships.
It’s also disposable. The demo data can be re-seeded, and nothing in it is backed up — deliberately, since it’s regenerable. Don’t keep anything there you’d miss.
Connect your own app to your sandbox, through the real OAuth flow. This isn’t optional busywork — two of the submission checks depend on it, and it’s the only way to exercise the consent screen, the token exchange, and your scoped token before a customer does.
You can do this before your app has ever been approved — that’s the point, since the checks that gate approval depend on it. Until a version is approved, the flow only works into your own sandbox: any other organization attempting to consent is refused. So test with your sandbox, not with a customer’s workspace.
Then, if your app subscribes to webhook events, register your webhook endpoint using that token. An OAuth connection doesn’t provision one for you, and the webhook-ping check below has nothing to ping until you do.
4. Submitting a version
An app is a container; a version is what gets reviewed. Everything a reviewer looks at — name, description, requested scopes, webhook events, config schema — lives on the version.
That split is what makes changes safe. When you later add a permission, that creates a new version rather than editing the live one, so existing installations are unaffected until their org agrees. More on that below.
Submit a version once it’s in DRAFT. Submission is a single call; everything after is automatic until a human is needed.
5. The automated checks
Five checks run on every submission. All are deterministic — you can predict and fix every one.
| Check | What it verifies |
|---|---|
| Metadata | Name and description present; description is a real description, not a placeholder |
| Config schema | Parses as a JSON object the install form can render |
| Scopes | Every requested scope and webhook event exists and is grantable to an app |
| Webhook ping | We send a signed test delivery to your sandbox endpoint and require a 2xx |
| Sandbox exercise | Your app has actually made an authenticated API call in your sandbox |
The webhook ping is the one worth preparing for. We sign it exactly as a production delivery: HMAC-SHA256 over <timestamp>.<rawBody>, sent as x-foundry-signature: t=…,v1=…, using your endpoint’s real secret. If your verification is wrong, this fails — which is the point. See webhook events for the verification recipe.
You get one retry, so a cold serverless endpoint won’t cost you a rejection. Your endpoint must be HTTPS on a public address; we don’t ping private or internal hosts.
Sandbox exercise needs exactly one successful authenticated request on the token your sandbox connection issued. One is enough — we’re proving the credential path works end to end, not measuring effort.
If any check fails, the version is rejected with per-check reasons. Fix and resubmit; there’s no penalty and no queue.
6. Auto-approval, or a human
Pass all five and the submission is auto-approved and published immediately — unless one of three things is true, in which case it queues for a person:
- It’s your first app. We look at every developer’s first submission once.
- It requests scopes that change data. Anything beyond read-only.
- It requests more than your last approved version. Adding a scope always gets looked at.
Nothing else queues. A read-only bug-fix release from an established developer ships without anyone touching it.
Worth being direct about what review is: we test behavior, not source. Foundry never receives your code — your app is a service you run, holding a scoped token. The same is true at Shopify and BigCommerce. Review is a quality filter, not a security boundary. What actually protects customers is the scoped token and per-org consent.
Changing an app after it’s published
Editing a published app creates a new version. Once approved:
- New installs get the new version.
- Existing installs keep the version they consented to, including its scopes. Their API key is never silently widened.
- Those orgs see an update prompt and move over when they re-authorize.
This has a real consequence for your code: some fraction of your installs will always be on an older version. If you add a scope, expect a 403 from it on installs that haven’t re-authorized yet. Handle it — don’t assume a permission you were granted is a permission you have everywhere.
You can see the split, so you know when it’s safe to depend on something new.
Practical notes
- Request the narrowest scopes that work. Read-only submissions skip human review entirely, and customers see exactly what you asked for on the consent screen.
- Narrowing scopes is never a risk trigger. Dropping a permission you no longer need costs you nothing.
- Keep your webhook endpoint responsive. Respond
2xxwithin 10 seconds; we retry with backoff, and an endpoint failing five consecutive deliveries is auto-disabled. - Your app key is a slug and permanent once published. Choose it deliberately.
Related
- Connecting an app with OAuth — the authorization-code flow, in full
- Building a partner app — what an app is, and how installs work
- Partner API — the endpoints your app calls
- Webhook events — signature verification, retries, replay
- Authentication & API keys — the scope model