App Manifest Reference

The stripe-app.json manifest file is the central configuration for your Stripe App. It declares your app’s identity, permissions, UI views, security policies, and post-install behavior.

Full Manifest Example

{
"id": "com.tajo.brevo-integration",
"version": "1.2.0",
"name": "Tajo for Brevo",
"icon": "./assets/icon.png",
"distribution_type": "public",
"sandbox_install_compatible": true,
"stripe_api_access_type": "oauth",
"allowed_redirect_uris": [
"https://tajo.io/stripe/callback",
"https://tajo.io/stripe/oauth/complete"
],
"permissions": [
{
"permission": "customer_read",
"purpose": "Read customer profiles to sync with Brevo contacts"
},
{
"permission": "customer_write",
"purpose": "Update customer metadata with Brevo sync status"
},
{
"permission": "charge_read",
"purpose": "Access payment history for Brevo event tracking"
},
{
"permission": "product_read",
"purpose": "Sync product catalog to Brevo for personalized campaigns"
},
{
"permission": "event_read",
"purpose": "Subscribe to real-time events for Brevo automation triggers"
},
{
"permission": "invoice_read",
"purpose": "Track invoice lifecycle events in Brevo"
}
],
"ui_extension": {
"views": [
{
"viewport": "stripe.dashboard.customer.detail",
"component": "CustomerDetailView"
},
{
"viewport": "stripe.dashboard.customer.list",
"component": "CustomerListView"
},
{
"viewport": "stripe.dashboard.home.overview",
"component": "OverviewView"
},
{
"viewport": "stripe.dashboard.drawer.default",
"component": "DrawerView"
},
{
"viewport": "stripe.dashboard.settings",
"component": "SettingsView"
},
{
"viewport": "stripe.dashboard.onboarding",
"component": "OnboardingView"
}
],
"content_security_policy": {
"connect-src": [
"https://api.tajo.io",
"https://api.brevo.com"
],
"image-src": [
"https://cdn.tajo.io",
"https://assets.brevo.com"
],
"purpose": "Connect to Tajo API for data sync and Brevo API for contact management"
}
},
"post_install_action": {
"type": "onboarding"
},
"constants": {
"API_BASE_URL": "https://api.tajo.io/v1",
"SYNC_INTERVAL_SECONDS": "300"
}
}

Schema Reference

Top-Level Fields

FieldTypeRequiredDescription
idstringYesUnique app identifier in reverse domain notation (slug format)
versionstringYesSemantic version string (e.g., "1.2.0")
namestringYesDisplay name shown in the marketplace (max 35 characters)
iconstringYesRelative path to the app icon file (300x300 PNG or SVG)
distribution_typestringYes"public" for marketplace or "private" for internal use
sandbox_install_compatiblebooleanNoWhether the app can be installed in sandbox/test mode
stripe_api_access_typestringNoAPI access method: "oauth" or "api_key"
allowed_redirect_urisstring[]NoAllowed OAuth redirect URIs for install flow
permissionsPermissionRequest[]YesArray of permission requests
ui_extensionUIExtensionManifestNoUI extension configuration
post_install_actionPostInstallActionNoAction to take after app installation
constantsobjectNoKey-value pairs accessible in the app at runtime

id

The app identifier is a slug-format string, typically in reverse domain notation:

"id": "com.tajo.brevo-integration"
  • Must be globally unique across all Stripe Apps
  • Use lowercase letters, numbers, hyphens, and dots only
  • Cannot be changed after the app is created
  • Determines the app’s URL on the marketplace

version

Follows semantic versioning:

"version": "1.2.0"
  • MAJOR: Breaking changes or significant feature additions
  • MINOR: New features, backward compatible
  • PATCH: Bug fixes and minor improvements
  • Must be incremented for each upload

distribution_type

Controls who can install your app:

ValueDescription
"public"Available on the Stripe App Marketplace to all users
"private"Only installable by your own Stripe account

stripe_api_access_type

Determines how your app authenticates with the Stripe API:

ValueDescription
"oauth"Uses OAuth 2.0 flow for authentication (recommended for public apps)
"api_key"Uses restricted API keys (suitable for private apps)

PermissionRequest

Each permission request declares a specific Stripe API permission your app needs:

{
"permission": "customer_read",
"purpose": "Read customer profiles to sync with Brevo contacts"
}
FieldTypeRequiredDescription
permissionstringYesThe permission identifier (see Permissions Reference)
purposestringYesHuman-readable explanation of why this permission is needed

Purpose guidelines:

  • Write clear, specific explanations that merchants can understand
  • Explain what the permission is used for, not just what it grants
  • Keep descriptions concise (one sentence)
  • Avoid technical jargon

UIExtensionManifest

Configures the UI components of your app:

{
"ui_extension": {
"views": [...],
"content_security_policy": {...}
}
}
FieldTypeRequiredDescription
viewsViewManifest[]YesArray of view declarations
content_security_policyCSPRequestNoContent Security Policy for external resources

ViewManifest

Each view maps a React component to a Stripe Dashboard viewport:

{
"viewport": "stripe.dashboard.customer.detail",
"component": "CustomerDetailView"
}
FieldTypeRequiredDescription
viewportstringYesThe Dashboard location where this view renders (see Viewports Reference)
componentstringYesName of the React component to render (must match the exported component name)

A single app can declare multiple views for different viewports:

"views": [
{
"viewport": "stripe.dashboard.customer.detail",
"component": "CustomerDetailView"
},
{
"viewport": "stripe.dashboard.payment.detail",
"component": "PaymentDetailView"
},
{
"viewport": "stripe.dashboard.home.overview",
"component": "OverviewView"
}
]

CSPRequest

The Content Security Policy controls which external domains your app can connect to:

{
"content_security_policy": {
"connect-src": [
"https://api.tajo.io",
"https://api.brevo.com"
],
"image-src": [
"https://cdn.tajo.io"
],
"purpose": "Connect to Tajo API for data sync and load images from CDN"
}
}
FieldTypeRequiredDescription
connect-srcstring[]NoDomains the app can make network requests to
image-srcstring[]NoDomains the app can load images from
purposestringYesExplanation of why these external connections are needed

Caution

Only include domains that your app actually needs to connect to. Excessive CSP entries may trigger additional review scrutiny.

PostInstallAction

Configures what happens immediately after a user installs your app:

{
"post_install_action": {
"type": "onboarding"
}
}
FieldTypeRequiredDescription
typestringYesThe action type (see below)
urlstringConditionalURL for external type actions

Action Types

TypeBehavior
"onboarding"Opens the app’s onboarding view in the Dashboard
"settings"Opens the app’s settings view in the Dashboard
"external"Redirects the user to an external URL (requires url field)

Examples:

// Open onboarding flow
{
"post_install_action": {
"type": "onboarding"
}
}
// Open settings page
{
"post_install_action": {
"type": "settings"
}
}
// Redirect to external setup
{
"post_install_action": {
"type": "external",
"url": "https://app.tajo.io/stripe/setup"
}
}

See the Post-Install Actions guide for detailed implementation patterns.

Constants

Define static key-value pairs accessible at runtime in your app:

{
"constants": {
"API_BASE_URL": "https://api.tajo.io/v1",
"SYNC_INTERVAL_SECONDS": "300",
"MAX_BATCH_SIZE": "100"
}
}
  • All values must be strings
  • Constants are embedded in the app at build time
  • Use constants for configuration that varies between environments
  • Never store secrets or API keys as constants — use the Secret Store API instead

Access constants in your app code:

import { constants } from '@stripe/ui-extension-sdk/constants';
const apiUrl = constants.API_BASE_URL;

Extended Manifest for Development

During local development, additional fields are available:

{
"id": "com.tajo.brevo-integration",
"version": "0.1.0",
"name": "Tajo for Brevo (Dev)",
"icon": "./assets/icon-dev.png",
"distribution_type": "private",
"sandbox_install_compatible": true,
"dev": {
"hot_reload": true,
"port": 4242
}
}

The dev section is stripped during production builds and app uploads. Use it for local development convenience settings only.

Validation

Validate your manifest before uploading:

Terminal window
# Validate manifest syntax and schema
stripe apps validate
# Check for common issues
stripe apps check

Common validation errors:

ErrorCauseFix
Invalid permissionUnknown permission identifierCheck the Permissions Reference
Invalid viewportUnknown viewport identifierCheck the Viewports Reference
Missing purposePermission without purpose fieldAdd a purpose string to each permission
Invalid versionNon-semver version stringUse format MAJOR.MINOR.PATCH
Icon not foundIcon path doesn’t resolveVerify the icon file exists at the specified path
AI Assistant

Hi! Ask me anything about the docs.

Start Free with Brevo