Skip to main content
Skill publish-an-openai-app · version 1.0.0 · for sellers.

When to use

  • A seller admin asks what is ready for a ChatGPT app built on their storefront.
  • The person needs the CNAME for their public listing domain, or has a domain-ownership token from OpenAI to publish.
  • The person wants a checklist for the OpenAI submission form.
Registering and submitting the app happens in OpenAI’s own developer portal, under the seller’s own OpenAI account. That is the person’s step. Semicola can serve the listing domain and the token, and check both; it cannot see, test or submit an OpenAI draft.

Before you start

  • You are connected to the Seller account the person means to publish, and get_status shows an admin role. The listing-domain and token tools refuse anyone else.
  • The storefront is listed on the marketplace. Public distribution also needs the Distribution package; the Listing page says whether the account has it. See Listing.

Steps

  1. Call get_status. If the active account is not the intended Seller account, or the person is not an admin, stop and say which account or role is needed.
  2. Call open_page with page: "listing". Its result is the authority for the state you report: publicDistribution (hostname, status, the dnsRecord to add, checkedAt, error, public) and chatgpt (the projection OpenAI will see and the challenge with its token, url and status).
  3. If the listing is not on the marketplace yet, call publish_discovery with visibility: "marketplace" after the person confirms.
  4. Public listing domain. If publicDistribution.hostname is empty, ask the person for a hostname on their own domain and call save_discovery_hostname with it. Replacing a saved hostname needs confirmReplace: true. Give the person the exact CNAME from the result; never guess DNS values.
  5. After the person has added the record at their DNS provider, call activate_discovery_hostname. Only status: "active" means Semicola verified the routing. Anything else is not ready: report the returned error and stop until the person fixes DNS.
  6. Call publish_discovery with visibility: "public" so the listing is served on that domain.
  7. When OpenAI gives the person a domain-ownership token, ask them to paste it, confirm the exact value back, and call update_discovery_openai_challenge with token. Replacing or removing a saved token (token: null) needs the person’s explicit confirmation.
  8. Call probe_discovery_openai_challenge and report the challenge.status: ok means the address returns the exact token, mismatch or unreachable means it does not. This does not mean OpenAI has verified the domain; OpenAI checks on its own timeline.
  9. Walk the person through the parts of the OpenAI form that only they can complete: publisher identity and a monitored contact, app name and descriptions (compare with chatgpt.projection), website, support, privacy and terms URLs, logos and screenshots, starter prompts, supported locales and countries, the production MCP URL, reviewer access, tool justifications and test cases, policy answers, release notes and the review video. Ask the person to confirm each in the portal; never mark one complete yourself.
  10. Finish with a short checklist in three groups: ready in Semicola (from the Listing result), missing in Semicola, and manual in OpenAI. Name the next action and who owns it.

Guardrails

  • Never publish, submit or approve an OpenAI app for the person, and never say an app is submitted, reviewed or live in ChatGPT.
  • Never invent DNS records, portal values, locales or completion state.
  • Never ask for, repeat or store reviewer credentials or OAuth tokens. The domain-ownership token is the only secret-looking value this skill handles, and only because the person pastes it to publish.
  • Semicola does not generate an OpenAI submission package, app icons or a reviewer login yet. Say so when the person asks for them, and do not stand in for them with made-up files.
  • Do not use other seller writes (for example save_seller) to work around a Listing state you cannot change.
  • Stop at needs_input and pending_confirmation, as in every skill.

Done when

  • publicDistribution.status is active and the listing is public, or the person knows the one DNS step blocking it.
  • If the person has a token, challenge.status is ok.
  • The person has the three-group checklist and knows the submission itself is theirs to make in OpenAI’s portal.