> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stora.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Partner approval checklist

> Check your partner application is ready before you submit it for approval.

export const ChecklistItem = ({id, number, title, links = [], children}) => {
  const storageKey = `stora-partner-approval-checklist-${id}`;
  const [checked, setChecked] = useState(false);
  useEffect(() => {
    setChecked(localStorage.getItem(storageKey) === "true");
  }, [storageKey]);
  const toggle = () => {
    const nextChecked = !checked;
    setChecked(nextChecked);
    localStorage.setItem(storageKey, String(nextChecked));
  };
  return <div className="not-prose my-3 rounded-lg border border-zinc-950/10 p-3 text-sm leading-6 dark:border-white/10">
			<div className="grid grid-cols-[auto_auto_1fr] gap-x-3">
				<button type="button" onClick={toggle} aria-pressed={checked} aria-label={`${checked ? "Uncheck" : "Check"} item ${number}: ${title}`} className={checked ? "mt-1 flex h-4 w-4 shrink-0 items-center justify-center rounded border border-primary bg-primary text-[10px] font-bold leading-none text-white" : "mt-1 h-4 w-4 shrink-0 rounded border border-zinc-400 dark:border-zinc-500"}>
					{checked ? "✓" : ""}
				</button>
				<span className="mt-px shrink-0 font-semibold text-zinc-950/60 dark:text-white/60">
					{number}.
				</span>
				<div className={checked ? "text-zinc-950/60 line-through dark:text-white/60" : "text-zinc-950 dark:text-white"}>
					<strong>{title}:</strong> {children}
				</div>
			</div>

			{links.length > 0 && <details className="mt-3 border-t border-zinc-950/10 pt-3 pl-14 dark:border-white/10">
					<summary className="cursor-pointer text-sm font-medium text-primary dark:text-white">
						Resources
					</summary>
					<ul className="mt-2 list-disc space-y-1 pl-5 text-sm text-zinc-950/80 dark:text-white/80">
						{links.map(link => <li key={link.href}>
								<a className="font-medium text-primary underline dark:text-white" href={link.href}>
									{link.label}
								</a>
							</li>)}
					</ul>
				</details>}
		</div>;
};

Use this checklist before you submit a partner application approval request in the Developer Portal. It covers the integration behavior Stora expects to see during review.

Each item links to the guide or API reference page with more detail. Expand **Resources** under an item to see the relevant references. Your checked items are saved in this browser.

<Note>
  This page does not replace the approval request form in the Developer Portal. Use it to check your integration before you submit.
</Note>

## Before you submit

### Required for all partner integrations

<ChecklistItem id="authentication" number="1" title="Authentication" links={[{ label: "Read authentication requirements", href: "/2025-09/guides/partner-integrations#authentication" }, { label: "OAuth Authorization Code flow", href: "/2025-09/guides/authentication#option-c-oauth-2-0-%E2%80%94-authorization-code" }]}>
  Your integration uses the OAuth 2.0 Authorization Code flow for partner integrations.
</ChecklistItem>

<ChecklistItem id="token-refresh" number="2" title="Token refresh" links={[{ label: "Read token refresh guidance", href: "/2025-09/guides/authentication#refreshing-tokens" }]}>
  Your integration handles access-token expiry and refresh-token rotation.
</ChecklistItem>

<ChecklistItem id="scopes" number="3" title="Scopes" links={[{ label: "Read scope principles", href: "/2025-09/guides/partner-integrations#scope-principles" }]}>
  Your requested scopes are the minimum permissions your integration needs.
</ChecklistItem>

<ChecklistItem id="connected-operator" number="4" title="Connected operator" links={[{ label: "Read connected operator requirements", href: "/2025-09/guides/partner-integrations#identify-the-connected-operator" }, { label: "Retrieve token info", href: "https://docs.stora.co/2025-09/api-reference/oauth-2/retrieve-info-for-the-access-token" }]}>
  Your integration displays the connected <code>operator.name</code> returned by <code>GET /oauth2/token/info</code>.
</ChecklistItem>

<ChecklistItem id="scope-checking" number="5" title="Scope checking" links={[{ label: "Read scope principles", href: "/2025-09/guides/partner-integrations#scope-principles" }]}>
  Your integration checks granted scopes and prompts operators to reconnect when a new feature needs missing scopes.
</ChecklistItem>

<ChecklistItem id="disconnect" number="6" title="Disconnect" links={[{ label: "Read disconnect requirements", href: "/2025-09/guides/partner-integrations#disconnect-and-reconnect" }, { label: "Revoke an access token", href: "https://docs.stora.co/2025-09/api-reference/oauth-2/revoke-an-access-token" }]}>
  Operators can disconnect from inside your integration.
</ChecklistItem>

<ChecklistItem id="external-revocation" number="7" title="External revocation" links={[{ label: "Read refresh failure guidance", href: "/2025-09/guides/partner-integrations#disconnect-and-reconnect" }]}>
  Your integration detects when an operator revokes the connection in Stora BackOffice, clears invalid local tokens, and prompts the operator to reconnect.
</ChecklistItem>

<ChecklistItem id="reconnect" number="8" title="Reconnect" links={[{ label: "Read reconnect requirements", href: "/2025-09/guides/partner-integrations#disconnect-and-reconnect" }]}>
  Operators can reconnect or switch Stora accounts without uninstalling.
</ChecklistItem>

<ChecklistItem id="uninstall-deprovisioning" number="9" title="Uninstall or deprovisioning" links={[{ label: "Read uninstall requirements", href: "/2025-09/guides/partner-integrations#disconnect-and-reconnect" }, { label: "Revoke an access token", href: "https://docs.stora.co/2025-09/api-reference/oauth-2/revoke-an-access-token" }]}>
  Your integration revokes tokens and discards local state when it is uninstalled or deprovisioned.
</ChecklistItem>

<ChecklistItem id="external-events" number="10" title="External Events" links={[{ label: "Read External Events requirements", href: "/2025-09/guides/partner-integrations#external-events" }, { label: "Create a Timeline Event", href: "https://docs.stora.co/2025-09/api-reference/timeline-events/create-an-event" }, { label: "List Timeline Sources", href: "https://docs.stora.co/2025-09/api-reference/timeline-sources/list-all-sources" }]}>
  Your integration creates Timeline Events for actions it takes in Stora on behalf of an operator. Ask Stora to create a global Timeline Source for your integration during onboarding, then request only <code>public.timeline\_event:write</code> if you only need to write events.
</ChecklistItem>

<ChecklistItem id="rate-limits" number="11" title="Rate limits" links={[{ label: "Read rate limiting guidance", href: "/2025-09/guides/requests#rate-limiting" }]}>
  Your integration handles <code>429</code> responses with backoff.
</ChecklistItem>

<ChecklistItem id="idempotency" number="12" title="Idempotency" links={[{ label: "Read idempotent request guidance", href: "/2025-09/guides/requests#idempotent-requests" }]}>
  Your integration sends <code>Idempotency-Key</code> headers on <code>POST</code> requests.
</ChecklistItem>

<ChecklistItem id="errors" number="13" title="Errors" links={[{ label: "Read error handling guidance", href: "/2025-09/guides/errors" }]}>
  Your integration handles documented errors gracefully and does not retry indefinitely on <code>4xx</code> responses.
</ChecklistItem>

<ChecklistItem id="metadata" number="14" title="Metadata" links={[{ label: "Read metadata guidance", href: "/2025-09/guides/metadata" }]}>
  Your integration uses Stora <code>metadata</code> fields for external references where supported and appropriate.
</ChecklistItem>

<ChecklistItem id="webhooks" number="15" title="Webhooks" links={[{ label: "Read webhook guidance", href: "/2025-09/guides/webhooks" }]}>
  Your integration uses webhooks instead of polling where Stora event notifications fit the use case.
</ChecklistItem>

<ChecklistItem id="webhook-cleanup" number="16" title="Webhook cleanup" links={[{ label: "Read webhook guidance", href: "/2025-09/guides/webhooks" }, { label: "Delete a webhook endpoint", href: "https://docs.stora.co/2025-09/api-reference/webhook-endpoints/delete-a-webhook-endpoint" }]}>
  Your integration removes webhook endpoints it created when an operator disconnects, uninstalls, or is deprovisioned.
</ChecklistItem>

### Required for distributed plugins

<ChecklistItem id="distributed-plugins" number="17" title="Distributed plugins" links={[{ label: "Read distributed plugin guidance", href: "/2025-09/guides/distributing-public-plugins" }]}>
  Public plugins or other distributed code follow the broker pattern, or use the authorization proxy alternative only with the documented trade-offs.
</ChecklistItem>

<ChecklistItem id="naming" number="18" title="Naming" links={[{ label: "Read naming rules", href: "/2025-09/guides/third-party-plugin-naming" }]}>
  Your integration uses a distinct product name and does not imply Stora ownership, endorsement, or official status.
</ChecklistItem>

<ChecklistItem id="disclaimer" number="19" title="Disclaimer" links={[{ label: "Read disclaimer guidance", href: "/2025-09/guides/third-party-plugin-naming#required-disclaimer" }]}>
  Public plugin or integration materials include a clear third-party disclaimer where operators may otherwise assume Stora operates the integration.
</ChecklistItem>

## After approval

<ChecklistItem id="scope-changes" number="20" title="Scope changes" links={[{ label: "Read scope principles", href: "/2025-09/guides/partner-integrations#scope-principles" }]}>
  Submit scope changes for review before requesting additional production permissions.
</ChecklistItem>

<ChecklistItem id="re-authorization" number="21" title="Re-authorization" links={[{ label: "Read scope checking guidance", href: "/2025-09/guides/partner-integrations#identify-the-connected-operator" }]}>
  Prompt operators to re-authorize when new features require new scopes.
</ChecklistItem>

<ChecklistItem id="connection-lifecycle" number="22" title="Connection lifecycle" links={[{ label: "Read disconnect and reconnect guidance", href: "/2025-09/guides/partner-integrations#disconnect-and-reconnect" }]}>
  Keep disconnect, reconnect, token revocation, and webhook cleanup working after launch.
</ChecklistItem>

## When this applies, check this

These checks apply only to integrations that use the relevant API area.

<ChecklistItem id="order-creation" number="23" title="Order creation" links={[{ label: "Read booking flow guidance", href: "/2025-09/guides/booking-flow" }, { label: "Live prices guidance", href: "/2025-09/guides/booking-flow#list-available-unit-types" }, { label: "Finalize order guidance", href: "/2025-09/guides/booking-flow#step-4-finalize-the-order" }, { label: "Email notifications guidance", href: "/2025-09/guides/booking-flow#email-notifications" }, { label: "List Unit Types", href: "https://docs.stora.co/2025-09/api-reference/unit-types/list-all-unit-types" }, { label: "Create an order", href: "https://docs.stora.co/2025-09/api-reference/orders/create-an-order" }, { label: "Validate an order", href: "https://docs.stora.co/2025-09/api-reference/orders/validate-an-order" }, { label: "Finalize an order", href: "https://docs.stora.co/2025-09/api-reference/orders/finalize-an-order" }]}>
  If your integration creates orders, use Unit Type <code>live\_prices</code>, check Unit Type promotions where relevant, create orders with the correct line-item prices, validate and finalize orders through the Orders API, and use <code>payment\_url</code> or <code>email\_notifications.payment\_details</code> for customer payment recovery flows where the customer cannot easily retry payment.
</ChecklistItem>

<ChecklistItem id="contact-created" number="24" title="Contact created" links={[{ label: "Read External Events requirements", href: "/2025-09/guides/partner-integrations#external-events" }, { label: "Create a Contact", href: "https://docs.stora.co/2025-09/api-reference/contacts/create-a-contact" }, { label: "Create an Event", href: "https://docs.stora.co/2025-09/api-reference/timeline-events/create-an-event" }, { label: "Create a Task", href: "https://docs.stora.co/2025-09/api-reference/tasks/create-a-task" }]}>
  If your integration creates contacts, add a <code>Lead Received</code> Timeline Event and optionally create a task, such as <code>Contact the lead</code>, so the operator can follow up.
</ChecklistItem>

<ChecklistItem id="inbound-calls" number="25" title="Inbound calls" links={[{ label: "Read External Events requirements", href: "/2025-09/guides/partner-integrations#external-events" }, { label: "Create an Event", href: "https://docs.stora.co/2025-09/api-reference/timeline-events/create-an-event" }]}>
  If your integration handles inbound phone calls, add an <code>Inbound call</code> Timeline Event so the operator can see where the enquiry came from.
</ChecklistItem>

## Always required for review

<ChecklistItem id="test-account" number="26" title="Test account" links={[{ label: "Read Developer Portal guidance", href: "/2025-09/guides/developer-portal#create-partner-app" }]}>
  Provide a working test account. A demo path or setup instructions can support review, but they do not replace the test account.
</ChecklistItem>

## Optional ways to speed up review

These items are not separate approval requirements, but they can make review faster.

<ChecklistItem id="token-data-notes" number="27" title="Token and data notes" links={[{ label: "Read partner requirements", href: "/2025-09/guides/partner-integrations#technical-requirements" }]}>
  Prepare concise notes about how you store and protect tokens and operator data.
</ChecklistItem>

<ChecklistItem id="unusual-architecture" number="28" title="Unusual architecture" links={[{ label: "Contact us", href: "https://stora.co/contact" }]}>
  Contact Stora before submitting if your integration uses an unusual architecture or does not fit the documented patterns.
</ChecklistItem>
