Appearance
Server Webhooks
User Permissions API
To efficiently manage access to email template and its different parts in the editor, Stripo has implemented a webhook designed to externally retrieve permissions for a specific user to interact with the email template. To process requests from Stripo, you will need to implement an API according to this specification.
OpenAPI Specification
Reference
yaml
openapi: 3.0.3
info:
title: User Permissions API
description: |
This API specification describes the webhook endpoint that your server must implement
to provide user permissions for the Stripo Email Editor.
The Stripo Plugin enforces role-based access control by calling your endpoint to retrieve
permissions for each user session. This allows you to define granular access controls for
different parts of the editor (code editor, appearance settings, content editing, modules,
version history, and comments management).
**How It Works**:
1. Configure the User Permissions API endpoint in your Stripo Plugin settings
2. When a user opens the editor, Stripo calls your endpoint with user metadata
3. Your server responds with a JSON object specifying which actions are allowed
4. The editor enforces these permissions by enabling or disabling features
**Authentication**: HTTP Basic Authentication is required. Configure credentials in the
plugin settings: Plugin → Server Settings → User Permissions API.
**Performance**: This endpoint is called during editor initialization, so response time
should be optimized (recommended: < 500ms).
version: 1.0.0
contact:
name: Stripo Support
url: https://stripo.email
servers:
- url: https://{YOUR_USER_PERMISSIONS_CHECKER_URL}
description: Your user permissions webhook endpoint
variables:
YOUR_USER_PERMISSIONS_CHECKER_URL:
default: ''
paths:
/:
get:
tags:
- Methods
summary: Get user permissions for email template
operationId: getUserPermissionsForEmail
description: |
Retrieves the set of permissions granted to a specific user for a particular email template.
The Stripo editor calls this endpoint during initialization with user metadata in the
`ES-PLUGIN-UI-DATA` header. Your server should:
1. Parse the metadata to identify the user and email template
2. Check the user's role and permissions in your system
3. Return a JSON object specifying which editor features are accessible
**Use Cases**:
- Restrict content editing for reviewers (read-only access)
- Allow text-only editing for copywriters
- Grant full access to administrators
- Control comment creation and moderation capabilities
- Manage module library access
**Performance Considerations**: This endpoint is called on every editor initialization,
so responses should be fast (< 500ms recommended) and may be cached by your application.
security:
- basicAuth: []
parameters:
- in: header
name: ES-PLUGIN-UI-DATA
required: true
schema:
type: string
description: |
User and email template metadata that was passed during editor initialization.
This header contains the `metadata` object you provided in the `window.Stripo.init()`
call. Typically includes email ID, and any custom context data.
The value is URL-encoded JSON. Your server should decode and parse this to identify
the user and determine their permissions.
example: '{"emailId":"456","projectId":"789"}'
- in: header
name: Cookies
required: true
schema:
type: string
description: |
Browser cookies from the user's session. Can be used for additional authentication
or session validation if needed.
example: 'sessionId=abc123;'
responses:
'200':
description: |
User permissions retrieved successfully.
content:
application/json:
schema:
$ref: '#/components/schemas/UserPermissions'
examples:
fullAccess:
summary: Full access (administrator)
description: All permissions granted for admin users
value:
codeEditor:
read: true
write: true
appearance:
read: true
write: true
content:
read: true
write: true
textOnly: false
modules:
read: true
write: true
versionHistory:
read: true
write: true
manageOwnComments:
read: true
write: true
manageAllComments:
read: true
write: true
readOnly:
summary: Read-only access (reviewer)
description: User can view everything but cannot make changes
value:
codeEditor:
read: true
write: false
appearance:
read: true
write: false
content:
read: true
write: false
textOnly: false
modules:
read: true
write: false
versionHistory:
read: true
write: false
manageOwnComments:
read: true
write: false
manageAllComments:
read: false
write: false
textOnlyEditor:
summary: Text-only editing (copywriter)
description: User can only edit text content, not layout or design
value:
codeEditor:
read: false
write: false
appearance:
read: true
write: false
content:
read: true
write: false
textOnly: true
modules:
read: true
write: false
versionHistory:
read: true
write: false
manageOwnComments:
read: true
write: true
manageAllComments:
read: false
write: false
contentEditor:
summary: Content editor with comment moderation
description: Can edit content and manage all comments, but not code or appearance
value:
codeEditor:
read: false
write: false
appearance:
read: true
write: false
content:
read: true
write: true
textOnly: false
modules:
read: true
write: true
versionHistory:
read: true
write: false
manageOwnComments:
read: true
write: true
manageAllComments:
read: true
write: true
components:
securitySchemes:
basicAuth:
type: http
scheme: basic
description: |
HTTP Basic Authentication using username and password configured in the
Stripo Plugin settings under: Plugin → Server Settings → User Permissions API.
The editor will send these credentials with every request to your endpoint.
schemas:
UserPermissions:
type: object
description: |
Complete set of user permissions for the email editor. Each permission group controls
access to specific editor features and capabilities.
**Permission Groups**:
- `codeEditor`: HTML code editor access
- `appearance`: Design and styling controls (fonts, colors, themes)
- `content`: Template content editing (blocks, text, images, layout)
- `modules`: Custom module library access (create, edit, delete saved modules)
- `versionHistory`: Version control features (view history, restore versions)
- `manageOwnComments`: Comment creation and participation
- `manageAllComments`: Comment moderation and management
**Permission Logic**:
- `read: false` hides the feature from the UI entirely
- `read: true, write: false` shows the feature but in read-only mode
- `read: true, write: true` grants full access to the feature
properties:
codeEditor:
allOf:
- $ref: '#/components/schemas/UserPermissionValue'
- description: |
Controls access to the HTML code editor.
**read: true** - User can open and view the HTML source code of the email template.
Useful for developers who need to inspect the markup.
**write: true** - User can edit and save changes to the HTML code. Requires
technical knowledge. Should be restricted to developers and administrators.
**Use Case**: Grant read-only access to designers who need to inspect HTML but
shouldn't modify it directly.
appearance:
allOf:
- $ref: '#/components/schemas/UserPermissionValue'
- description: |
Controls access to appearance settings (fonts, colors, styles, theme customization).
**read: true** - User can view current appearance settings and design system values.
**write: true** - User can modify appearance settings, affecting the overall look
and feel of the email template (global colors, fonts, spacing).
**Use Case**: Restrict appearance changes to brand managers and designers while
allowing editors to view the current settings.
content:
allOf:
- $ref: '#/components/schemas/UserContentPermissionValue'
- description: |
Controls access to template content editing capabilities.
**read: true** - User can view the email template content.
**write: true** - User can add/remove blocks, modify layout, change images, and
fully edit the template structure.
**textOnly: true** - Special mode that allows only text editing without structural
changes. Ideal for copywriters and translators. When enabled, `write` should be `false`.
**Use Cases**:
- Copywriters: read: true, write: false, textOnly: true
- Reviewers: read: true, write: false, textOnly: false
- Content editors: read: true, write: true, textOnly: false
modules:
allOf:
- $ref: '#/components/schemas/UserPermissionValue'
- description: |
Controls access to the custom module library (saved template blocks).
**read: true** - User can browse the module library and insert saved modules
into email templates.
**write: true** - User can create new modules, update existing ones, and delete
modules from the library.
**Use Case**: All users can typically insert modules (read: true), but only
designers and administrators should create/modify modules (write: true).
versionHistory:
allOf:
- $ref: '#/components/schemas/UserPermissionValue'
- description: |
Controls access to email template version history and restoration features.
**read: true** - User can view the version history, see who made changes and when,
and preview previous versions.
**write: true** - User can restore previous versions of the email template,
effectively reverting changes.
**Use Case**: Allow all editors to view history (read: true) but restrict
version restoration to administrators (write: true) to prevent accidental data loss.
manageOwnComments:
allOf:
- $ref: '#/components/schemas/UserPermissionValue'
- description: |
Controls the user's ability to participate in commenting and collaboration.
**read: true** - User can open the Comments tab and view all existing comments
on the email template. This allows them to see feedback and discussions.
**write: true** - User can create new comments, reply to existing comment threads,
and participate in discussions. They can edit and delete their own comments.
**Use Case**:
- Collaborators: read: true, write: true (can participate in discussions)
- Reviewers: read: true, write: false (can see feedback but not comment)
- External viewers: read: false, write: false (no access to comments)
**Note**: Users with write access can only manage their own comments. To allow
editing/deleting other users' comments, use `manageAllComments`.
manageAllComments:
allOf:
- $ref: '#/components/schemas/UserPermissionValue'
- description: |
Controls comment moderation capabilities across all users.
**read: true** - Currently not utilized by the system. Reserved for future use.
**write: true** - User can edit and delete comments created by any user, providing
full moderation capabilities. This is in addition to the permissions granted by
`manageOwnComments`.
**Use Case**:
- Administrators/Moderators: write: true (can moderate all comments)
- Regular users: write: false (can only manage their own comments via manageOwnComments)
**Important**: This permission grants elevated privileges and should only be given
to trusted administrators or moderators who need to manage inappropriate content
or maintain discussion quality.
UserPermissionValue:
type: object
description: |
Standard permission value structure with read and write access flags.
Used for most permission groups in the editor.
properties:
read:
type: boolean
description: |
Controls visibility and read access to the feature.
**true**: User can view and access the feature (possibly in read-only mode)
**false**: Feature is hidden from the user interface entirely
example: true
write:
type: boolean
description: |
Controls modification permissions for the feature.
**true**: User can make changes and save modifications
**false**: Feature is read-only (requires read: true)
Note: write: true is meaningless if read: false
example: false
UserContentPermissionValue:
type: object
description: |
Extended permission value structure for content editing with an additional
text-only editing mode. This allows fine-grained control over content editing capabilities.
properties:
read:
type: boolean
description: |
Controls visibility and read access to the template content.
**true**: User can view the email template content
**false**: User cannot access the template content at all
example: true
write:
type: boolean
description: |
Controls full content modification permissions.
**true**: User can add/remove blocks, change layout, edit text, modify images,
and make any structural changes to the template
**false**: User cannot make structural changes (but may still edit text if textOnly: true)
example: false
textOnly:
type: boolean
description: |
Enables text-only editing mode for copywriters and translators.
**true**: User can edit text content within existing blocks but cannot modify
layout, add/remove blocks, or change design elements. Perfect for copywriters
and translators who should focus only on content.
**false**: Standard editing mode (controlled by write permission)
**Important**: When textOnly: true, the write permission should be false.
The textOnly flag provides a special editing mode separate from full write access.
example: false
tags:
- name: Methods
description: User permissions API endpointsEmail Resources Permissions API
The Email Resources Permissions API ensures that only authorized users have the rights to edit email resources such as modules and images in your application. This feature helps prevent unauthorized access and ensures that the Stripo Plugin performs server-side operations only with your permission. To enable this feature, you need to implement the following backend endpoint on your server.
OpenAPI Specification
Reference
yaml
openapi: 3.0.3
info:
title: Email Resources Permissions API
description: The Email Resources Permissions API ensures that only authorized users have the rights to edit email resources such as modules and images in your application. This feature helps prevent unauthorized access and ensures that the Stripo Plugin performs server-side operations only with your permission. To enable this feature, you need to implement the following backend endpoint on your server.
version: 1.0.0
servers:
- url: https://{YOUR_RESOURCE_PERMISSIONS_CHECKER_URL}
variables:
YOUR_RESOURCE_PERMISSIONS_CHECKER_URL:
default: ''
paths:
/:
post:
tags:
- Methods
summary: Check and grant permissions
description: Verifies and assigns necessary permissions to a user for accessing specific features or content within the Stripo platform. The editor sends a request to the customer's endpoint with the information from the metadata and expects to receive a set of granted permissions in response. This method ensures that users have the appropriate access levels required to work inside the editor, enhancing security and effective role-based management.
security:
- basicAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ResourcePermissionsRequest'
responses:
'200':
description: Resources permissions
content:
application/json:
schema:
$ref: '#/components/schemas/ResourcePermissionsResponse'
components:
securitySchemes:
basicAuth:
type: http
scheme: basic
schemas:
ResourcePermissionsRequest:
type: object
properties:
pluginId:
type: string
description: ID of the plugin requesting permissions
example: YOUR_PLUGIN_ID
uiData:
type: object
description: The value of 'metadata' field from editor initialization parameters
additionalProperties:
type: string
requestPermissions:
type: array
description: Array of permissions that plugin requests
items:
$ref: '#/components/schemas/ResourcePermission'
required:
- pluginId
- uiData
- requestPermissions
ResourcePermission:
type: object
properties:
type:
type: string
description: Operation subject. Supported values - BLOCKS, DOCS
example: BLOCKS
action:
type: string
description: Operation type. Supported values - READ, MODIFY
example: READ
key:
type: string
description: >-
Key identifier that was configured in plugin settings with filled
values
example: pluginId_YOUR_PLUGIN_ID_emailId_123_id_456
keyTemplate:
type: string
description: Key identifier that was configured in plugin settings
example: emailId_${emailId}_id_${someAnotherIdentifier}
ResourcePermissionsResponse:
type: object
properties:
grantPermissions:
type: array
items:
$ref: '#/components/schemas/ResourcePermission'Email Change Notification API
The Email Change Notification API allows you to receive information about the time and author of each autosave for security and atomic integrity purposes during simultaneous editing. This webhook needs to be specified in the plugin settings to function correctly.
To ensure that the webhook functions correctly, you need to specify an endpoint in the plugin settings that meets the following specifications.
OpenAPI Specification
Reference
yaml
openapi: 3.0.1
info:
title: Email Changes Notifications API
description: |
The Email Change Notification API allows you to receive information about the time and author of each autosave for security and atomic integrity purposes during simultaneous editing. This webhook needs to be specified in the plugin settings to function correctly.
To ensure that the webhook functions correctly, you need to specify an endpoint in the plugin settings that meets the following specifications.
version: 1.0.0
servers:
- url: https://{YOUR_EMAIL_CHANGE_NOTIFICATION_URL}
variables:
YOUR_EMAIL_CHANGE_NOTIFICATION_URL:
default: ''
paths:
/:
post:
tags:
- Methods
summary: Notification on email changes
description: Provides details about the time and author of each autosave, ensuring security and atomic integrity during simultaneous editing.
operationId: handleEmailChanged
security:
- basicAuth: []
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/SaveRequest'
required: true
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: object
nullable: true
components:
securitySchemes:
basicAuth:
type: http
scheme: basic
schemas:
SaveRequest:
type: object
required:
- emailId
- userId
- updatedTime
properties:
emailId:
type: string
userId:
type: string
dateTime:
type: integer
format: int64Comments Notifications
This API delivers real-time notifications about all comment-related activities in your email templates — such as new comments, replies, mentions, and resolutions.
It allows your backend to stay synchronized with collaboration events happening inside the editor.
You can enable and configure this integration in your Plugin Settings → Commenting → Notifications API section.
For an overview of how the feature works, see the Commenting documentation.
OpenAPI Specification
Reference
yaml
openapi: 3.0.3
info:
title: Comments Notification API
description: |
This API specification describes the webhook endpoint that plugin servers must implement
to receive notification events from the Stripo Email Editor.
The editor will POST notification events to the configured plugin URL when specific
actions occur (e.g., comments created, replied, resolved, or viewed).
**Authentication**: HTTP Basic Authentication is required. The editor will send
credentials configured in the plugin settings.
**Important**: All event type and subtype values use UPPERCASE with underscores.
version: 1.0.0
contact:
name: Stripo Support
url: https://stripo.email
servers:
- url: https://{YOUR_PLUGIN_NOTIFICATION_URL}
description: Plugin notification webhook endpoint (configure in plugin settings)
variables:
YOUR_PLUGIN_NOTIFICATION_URL:
default: ''
security:
- basicAuth: []
paths:
/notifications:
post:
summary: Receive plugin notification events
description: |
Endpoint to receive notification events from the Stripo Email Editor.
Your plugin server must implement this endpoint and respond with either:
- 200 OK (with optional response body)
- 204 No Content (no response body)
Any other status code will be treated as an error.
operationId: receiveNotificationEvent
security:
- basicAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PluginNotificationEventRequest'
examples:
commentCreated:
summary: Comment Created Event
value:
createdOn: 1699564800000
type: "EDITOR_COMMENTS"
subtype: "COMMENT_CREATED"
pluginId: "my-plugin-123"
details:
emailId: "email-456"
commentId: "comment-789"
commentAuthorId: "user-001"
commentText: "This looks great!"
taggedUserIds: ["user-002", "user-003"]
commentReplied:
summary: Comment Replied Event
value:
createdOn: 1699564900000
type: "EDITOR_COMMENTS"
subtype: "COMMENT_REPLIED"
pluginId: "my-plugin-123"
details:
emailId: "email-456"
commentId: "comment-790"
threadCommentId: "comment-789"
replyAuthorId: "user-002"
commentText: "Thanks for the feedback!"
initialCommentText: "This looks great!"
repliesCount: 1
taggedUserIds: ["user-001"]
threadUserIds: ["user-001", "user-002"]
initialCommentAuthorId: "user-001"
initialCommentCreationDate: 1699564800000
commentResolved:
summary: Comment Resolved Event
value:
createdOn: 1699565000000
type: "EDITOR_COMMENTS"
subtype: "COMMENT_RESOLVED"
pluginId: "my-plugin-123"
details:
emailId: "email-456"
commentId: "comment-789"
resolveUserId: "user-001"
threadCommentId: "comment-789"
commentText: "This looks great!"
threadUserIds: ["user-001", "user-002"]
commentAuthorId: "user-001"
commentViewed:
summary: Comment Viewed Event
value:
createdOn: 1699565100000
type: "EDITOR_COMMENTS"
subtype: "COMMENT_VIEWED"
pluginId: "my-plugin-123"
details:
emailId: "email-456"
commentId: "comment-789"
threadCommentId: "comment-789"
viewerId: "user-003"
responses:
'200':
description: Event received and processed successfully
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: "Event processed successfully"
example:
message: "Event processed successfully"
'204':
description: Event received and processed successfully (no content)
'400':
description: Bad request - invalid event format or missing required fields
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
error: "Invalid request format"
message: "Missing required field: pluginId"
'401':
description: Unauthorized - invalid or missing credentials
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
error: "Unauthorized"
message: "Invalid credentials"
'500':
description: Internal server error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
error: "Internal Server Error"
message: "Failed to process event"
components:
securitySchemes:
basicAuth:
type: http
scheme: basic
description: |
HTTP Basic Authentication using username and password configured
in the plugin notification settings.
schemas:
PluginNotificationEventRequest:
type: object
required:
- createdOn
- type
- subtype
- pluginId
- details
properties:
createdOn:
type: integer
format: int64
description: Unix timestamp in milliseconds when the event was created
example: 1699564800000
type:
type: string
description: High-level event category (always "EDITOR_COMMENTS" for comment events)
example: "EDITOR_COMMENTS"
enum:
- EDITOR_COMMENTS
subtype:
type: string
description: Specific event type within the category
example: "COMMENT_CREATED"
enum:
- COMMENT_CREATED
- COMMENT_REPLIED
- COMMENT_RESOLVED
- COMMENT_VIEWED
pluginId:
type: string
description: Unique identifier of the plugin this event is for
example: "my-plugin-123"
details:
oneOf:
- $ref: '#/components/schemas/PluginCommentCreatedEventDetails'
- $ref: '#/components/schemas/PluginCommentRepliedEventDetails'
- $ref: '#/components/schemas/PluginCommentResolvedEventDetails'
- $ref: '#/components/schemas/PluginCommentViewedEventDetails'
description: Event-specific details. The structure depends on the type and subtype.
discriminator:
propertyName: subtype
mapping:
COMMENT_CREATED: '#/components/schemas/PluginCommentCreatedEventDetails'
COMMENT_REPLIED: '#/components/schemas/PluginCommentRepliedEventDetails'
COMMENT_RESOLVED: '#/components/schemas/PluginCommentResolvedEventDetails'
COMMENT_VIEWED: '#/components/schemas/PluginCommentViewedEventDetails'
PluginCommentCreatedEventDetails:
type: object
description: Details for a comment creation event
additionalProperties: false
required:
- emailId
- commentId
- commentAuthorId
- commentText
properties:
emailId:
type: string
description: Unique identifier of the email template
example: "534449i"
commentId:
type: string
description: Unique identifier of the created comment
example: "516ee02e-4325-42c6-9c54-48e60a1beba5"
commentAuthorId:
type: string
description: User ID of the comment author (string format)
example: "19"
commentText:
type: string
description: Text content of the comment
example: "This looks great!"
taggedUserIds:
type: array
description: List of user IDs tagged in the comment (optional, string array)
items:
type: string
example: ["user-002", "user-003"]
PluginCommentRepliedEventDetails:
type: object
description: Details for a comment reply event
additionalProperties: false
required:
- emailId
- commentId
- threadCommentId
- replyAuthorId
- commentText
- initialCommentText
- repliesCount
- initialCommentAuthorId
- initialCommentCreationDate
properties:
emailId:
type: string
description: Unique identifier of the email template
example: "534449i"
commentId:
type: string
description: Unique identifier of the reply comment
example: "516ee02e-4325-42c6-9c54-48e60a1beba5"
threadCommentId:
type: string
description: Unique identifier of the parent comment thread
example: "76836e77-2f3c-4b3e-9479-6e8330692325"
replyAuthorId:
type: string
description: User ID of the reply author (string format)
example: "19"
commentText:
type: string
description: Text content of the reply
example: "sss"
initialCommentText:
type: string
description: Text content of the initial comment in the thread
example: "ffff"
repliesCount:
type: integer
format: int32
description: Total number of replies in the thread
example: 0
taggedUserIds:
type: array
description: List of user IDs tagged in the reply (optional, string array)
items:
type: string
example: ["user-001"]
threadUserIds:
type: array
description: List of all user IDs participating in the thread (optional, string array)
items:
type: string
example: ["user-001", "user-002"]
initialCommentAuthorId:
type: string
description: User ID of the author who created the initial comment (string format)
example: "19"
initialCommentCreationDate:
type: integer
format: int64
description: Unix timestamp in milliseconds when the initial comment was created
example: 1761137862000
PluginCommentResolvedEventDetails:
type: object
description: Details for a comment resolution event
additionalProperties: false
required:
- emailId
- commentId
- resolveUserId
- threadCommentId
- commentText
- commentAuthorId
properties:
emailId:
type: string
description: Unique identifier of the email template
example: "534449i"
commentId:
type: string
description: Unique identifier of the resolved comment
example: "516ee02e-4325-42c6-9c54-48e60a1beba5"
resolveUserId:
type: string
description: User ID of the person who resolved the comment (string format)
example: "19"
threadCommentId:
type: string
description: Unique identifier of the comment thread
example: "76836e77-2f3c-4b3e-9479-6e8330692325"
commentText:
type: string
description: Text content of the resolved comment
example: "This looks great!"
threadUserIds:
type: array
description: List of all user IDs participating in the thread (optional, string array)
items:
type: string
example: ["user-001", "user-002"]
commentAuthorId:
type: string
description: User ID of the original comment author (string format)
example: "19"
PluginCommentViewedEventDetails:
type: object
description: Details for a comment view event
additionalProperties: false
required:
- emailId
- commentId
- threadCommentId
- viewerId
properties:
emailId:
type: string
description: Unique identifier of the email template
example: "534449i"
commentId:
type: string
description: Unique identifier of the viewed comment
example: "516ee02e-4325-42c6-9c54-48e60a1beba5"
threadCommentId:
type: string
description: Unique identifier of the comment thread
example: "76836e77-2f3c-4b3e-9479-6e8330692325"
viewerId:
type: string
description: User ID of the person who viewed the comment (string format)
example: "19"
ErrorResponse:
type: object
description: Standard error response format
properties:
error:
type: string
description: Error type or category
example: "Bad Request"
message:
type: string
description: Detailed error message
example: "Invalid request format"