Using scripts in Seal
Scripts can be run as standalone administrative tasks or embedded within an entity from a ‘Script’ field. When run from within another entity, a script can access the context of that entity, allowing it to read data and perform validation based on its content.Triggers
What is a trigger?
- A trigger is something that lives on a script, and automatically runs that script at a particular event.
- These triggering events can be
- Event based: This means they have been caused by edits or changes to particular entities
- Time based: e.g. every 5 minutes
How to set up a trigger
Navigate to the script that you want to be triggered. In the sidebar, you will see a ‘Triggers’ tab where you can view, remove, and create triggers.
- what event will trigger it
- what script it applies to
- all runs of the trigger, their status, timings and logs


Different trigger events
Entity dependent:
These events all relate to changes to certain entities, you can pick which entities classify when you make the event.
- Choose whether you want the trigger to apply to changes to Templates, Instances, or both
- Choose specific entities that you want to trigger on.
| Entity dependent event | Description | Notes |
|---|---|---|
onMoveOutOfEditable | This will trigger the script to run whenever a chosen entity becomes non-editable | The only way for entities to become ‘non-editable’ are to be sent for review or published |
onPublish | This will trigger the script to run whenever a chosen entity is published (transitions to PUBLISHED status) | This trigger fires for all entities transitioning to PUBLISHED, whether from EDITABLE, IN_REVIEW, or IN_VALIDATION status |
onCreate | This will trigger the script to run when a chosen entity is created | This trigger will only work when INSTANCE has been chosen, and a specific template selected. |
onArchive | This will trigger the script to run when a chosen entity is archived | - |
onRecover | This will trigger the script to run when a chosen entity is recovered | - |
onMakeEditable | This will trigger the script to run whenever a chosen entity moves from non-editable to editable | This can happen when new drafts are made, when review requests are disapproved or cancelled, or if validation checks fail. |
onCreate - every time an entity is created that matches the conditions, the script can tag that particular entity
Entity independent:
Entity independent triggers allow scripts to run autonomously, without being directly tied to a parent entity. These scripts can still interact with and perform actions on various entities, but they operate independently from any specific entity.| Name | Description | Notes |
|---|---|---|
onSchedule | This will execute the script at predetermined intervals, such as every 5 minutes or at midnight daily. | Scheduled times are evaluated in the UTC timezone, ensuring consistent execution regardless of local time variations. |
The Seal module for Python scripts
The Seal module is a Python package for interacting programmatically with the Seal platform. It provides a secure and audited method for administrators to perform advanced configuration and automation. It is automatically available in every Script’s Python environment - you don’t need to import it manually. The Seal module consists of a collection of methods on theseal object:
Getting entities
Passing an
entity_id returns the latest version or draft of the entity.
The entity id can be copied from the entity’s URL in Seal - it’s the final section of the url, after the entity title.
To get a specific version of an entity, include the version as a second argument. You can also pass an entity ref object instead.
Since it returns the whole json blob for the entity, you can get the entity’s fields via entity["fields"] , or a specific field via entity["fields"]["fieldName"] .
exact=False.
Query Config Structure
Available Filters
| Filter | Value Type | Example |
|---|---|---|
type | string[] | ["Sample", "Procedure"] |
kind | enum[] | ["INSTANCE", "TEMPLATE", "TYPE"] |
status | enum[] | ["EDITABLE", "IN_VALIDATION", "IN_REVIEW", "FINISHED"] |
template | uuid[] | ["template-uuid"] |
tag | uuid[] | ["tag-uuid"] |
archived | enum[] | ["TRUE"] or ["FALSE"] |
createdBy | string[] | ["user-role-id"] |
lastUpdatedBy | string[] | ["user-role-id"] |
assignees | uuid[] | ["role-id"] |
submittedFrom | uuid[] | ["entity-uuid"] |
field | string[] | ["Field Name"] - entities containing this field |
fieldValue | object[] | [{"name": "Field Name", "operator": "=", "value": "X"}] |
statusTag | string[] | ["Published", "Draft"] |
text | string[] | ["search term"] - title search |
changeSet | string[] | ["change-set-index"] |
hasTrigger | enum[] | ["TRUE"] or ["FALSE"] |
system | string[] | ["system-name"] |
contentType | enum[] | ["Page", "Script", "File", "Chart"] |
Filter Operators
in: Match any value in listnot_in: Exclude values in list
Field Value Operators
ForfieldValue filters, the following operators are available: =, >, <, >=, <=
Combining Filters (AND/OR)
Filters withinand are combined with AND logic. Use or for OR logic within an AND group:
Sorting Results
CREATED_AT, LAST_UPDATED_AT, CREATED_BY, LAST_UPDATED_BY
Available root columns: TITLE, TYPE, TEMPLATED_FROM, SUBMITTED_FROM, CREATED_FROM
Making an entity editable
Reverting entity drafts
entity_ids: List of entity IDs to revert (maximum 500)
Validating entities
Scripts can be used to run checks before an entity is published. A script can be added as a check on a type or template for its templates or instances.| Method | Checks that |
|---|---|
| validation.assertEqual(a, b) | a == b |
| validation.assertNotEqual(a, b) | a != b |
| validation.assertTrue(x) | bool(x) is True |
| validation.assertFalse(x) | bool(x) is False |
| validation.assertIs(a, b) | a is b |
| validation.assertIsNot(a, b) | a is not b |
| validation.assertIsNone(x) | x is None |
| validation.assertIsNotNone(x) | x is not None |
| validation.assertIn(a, b) | a in b |
| validation.assertNotIn(a, b) | a not in b |
| validation.assertIsInstance(a, b) | isinstance(a, b) |
| validation.assertNotIsInstance(a, b) | not isinstance(a, b) |
Archiving an entity
archive parameter should be a boolean: True to archive, False to recover. Returns the updated entity data.
Converting an Instance to a Template
Converting an Entity to a Different Type
new_type_id or new_kind must be provided.
entity_id: The ID of the entity to convertnew_type_id: The ID of the new Type to convert the entity to (optional)new_kind: The new kind to convert to, either'TEMPLATE'or'INSTANCE'(optional)
Updating the status tag on an entity
Getting the upcoming version info of an entity
Adding an entity to a change set
change_set_index can be found in the URL when on a change set page.
Returns information about the change set the provided entity now belongs to. This information includes id, index, name, status and description.
Adding multiple entities to a change set
entity_ids parameter should be a list of entity IDs, and the change_set_index can be found in the URL when on a change set page.
Returns information about the change set that the provided entities now belong to. This information includes id, index, name, status, description and entityRefs.
Creating change sets
Requesting review for a change set
change_set_id_or_index: The ID or index of the change set (found in the URL)review_config: (Optional) Custom review configuration dictionary withreviewPhasesarray. Custom phases are merged with (not replacing) the review requirements from entities. If the same role appears in both, the higherrequiredNumApprovalsis used.allow_direct_publish: (Optional) IfTrue, publishes the change set directly when no review phases exist. Defaults toFalse.
reviewPhases can have the following properties:
requestedRoleId(required): The role ID that should review this phaserequiredNumApprovals(required): Number of approvals needed from this roletitle(optional): Display title for this review phasenotifiedRoleIds(optional): Array of specific user role IDs to notify. If not provided, all users in the requested role group will be notified.
- Custom
review_configphases are always added to existing entity review requirements (never override them) - If any review phases exist (from entity requirements or custom config): Creates a review request
- If no review phases exist and
allow_direct_publish=True: Publishes the change set directly - If no review phases exist and
allow_direct_publish=False: Raises an error
Configuring reviewers without starting review
change_set_id_or_index: The ID or index of the change set (found in the URL)review_phases: Array of review phase configurations (same structure as inreview_config.reviewPhasesabove)
Getting the review config for a change set
change_set_id_or_index: The ID or index of the change set (found in the URL)
reviewPhases: Array of review phases, each with:requestedRoleId: The role ID that should review this phaserequiredNumApprovals: Number of approvals neededtitle(optional): Display title for this review phasenotifiedRoleIds(optional): Specific user role IDs to notify
Getting tags
Adding tags
Deleting tags
Sending notification emails
- emails: list of recipient email addresses (1–100). All recipients must be existing users in your organisation.
- subject: plain text subject. URLs are not allowed.
- message: plain text message body. URLs are not allowed.
- entity_id (optional): entity to link the call-to-action to. If omitted, the button opens your organisation home in Seal.
Updating system configuration
- system_slug: The slug of the system to update (found in the URL)
- homepage_entity_id (keyword-only, optional): The entity ID to set as the homepage,
Noneto clear it, or omit to leave unchanged
systemSlug: The slug of the systemhomepageEntityId: The current homepage entity ID (orNoneif not set)
Setting active versions
None to unpin and track the latest published version automatically. If the entity has review requirements, a review request will be created automatically.
Managing assignees
Getting assignees
assignees array, where each item contains id (the user role ID) and email (the user’s email address).
Setting assignees
assignees parameter should be a list of strings where each item is either an email address or a user id.
Appending assignees
set_assignees. The assignees parameter should be a list of strings where each item is either an email address or a user id.
Managing entity-specific permissions
Entity permissions control who can manage and operate on specific entities. There are two permission type lists: managers and operators. Each permission list can contain role IDs, or the special values"ALL_MANAGERS" or "ALL_OPERATORS".
Getting permissions
managers and operators arrays.
Setting permissions
managers, operators, or both. Each parameter should be a list of role IDs, "ALL_MANAGERS", or "ALL_OPERATORS".
Getting role information
email for users. Role groups automatically include all user members in a members array.
Getting all members of a user group:
"Org admin" and "All users", as well as custom user groups. Automatically includes all user members in a members array.
Getting the “All users” role group with members:
Getting workflow tasks
completedAt timestamp if the task has been completed, or null if the task is not completed.
completedAt timestamp if the task has been completed.
Getting workflows that reference an entity
Getting change sets
Adding fields
field_name(required): The name of the fieldfield_type(required): The field type (e.g."NUMBER","STRING","SELECT","BOOLEAN","DATE")field_value(optional): The initial value for the fieldallow_multiple(optional): Whether multiple values are allowedselect_options(optional): List of options for SELECT fieldsmulti_line(optional): Whether to use multi-line input for STRING fieldsformula_expression(optional): Formula expression for FORMULA fields
add_multiple_fields.
Updating fields
Only provided arguments will be updated. If you omitfield_value the value will not be changed, if you pass in None the value will be cleared.
search_config: For REFERENCE fields, controls which entities can be selected. Uses the same query config format asseal.search_entities()(see above).allow_entities_from: For REFERENCE fields, restricts selection to"CHANGE_SET"or"ANYWHERE".coupled: For REFERENCE fields, whenTrue, creates linked child entities.create_in_new_change_set: For coupled REFERENCE fields, creates children in separate change sets.display_mode: For REFERENCE fields, one of"pills","table", or"filePreview".
Deleting fields
Renaming fields
Adding fields to page content
Deleting fields from page content
Duplicating entities
entity_id and version arguments.
Set is_test=True to create a test entity duplicate.
Updating properties
overwrite_computed_title is set to True and the instance has a computed title, this will be overwritten.
Getting out of spec fields
Handling files
The value returned is the local file path as a string.
template_ref is optional. If not provided, the file will be created from the type’s default template if it exists.Returns the entire json blob of data of the new entity.
Submitting data
Creating entities from reference fields
type_or_template_ref is not provided, the entity is created based on the reference field’s search configuration.
Parameters:
field_name: Name of the reference fieldfield_values_df: (Optional) DataFrame with initial field values for created entities. If a column is called ‘title’ or ‘Title’, it will set the entities’ titlesnumber_of_empty_entities: (Optional) Number of blank entities to create in addition to any entities from the DataFrametype_or_template_ref: (Optional) Entity reference object pointing to either a type or template:- For template references:
{"id": "template_uuid", "version": "1"}(creates instances) - For type references:
{"ref": {"id": "type_uuid"}}(creates templates)
- For template references:
field_values_df with data, number_of_empty_entities, or both.
You can also create entities from a reference field in any entity:
Submission placeholder columns
Placeholder columns are additional fields that can be added to all rows in a submission table. These columns are automatically added to existing instances in the submission field.Creating templates
type_name: Name of the type to create a template fromtitle: (Required, keyword-only) Title for the new templateinitial_content_value: (Optional, keyword-only) Initial content value for the template (for content-based types)
Creating instances
template_id: ID of the template to create an instance fromversion: (Optional, keyword-only) Specific version of the templatefield_values: (Optional, keyword-only) Initial field values for the instance. The specified fields must exist on the template.
Configuring instance submission fields
field_name: Name of the instance submission fieldtype_or_template_ref: Entity reference object pointing to either a type or template- For template references:
{"id": "template_uuid", "version": "1"} - For type references:
{"ref": {"id": "type_uuid"}}
- For template references:
entity_id: (For the_in_entityversion) ID of the entity containing the field
Creating charts
entity_id as a string. See parameters below:\
chart: The Altair chart instancetitle:The name for the charttype_title: The name of the type to create a chart from. The content type must beChart.template_ref: (Optional) Entity reference object pointing to a template. i.e{"id": "template_uuid", "version": "1"}. If not provided, the chart instance will be created from the type’s default template if it exists.creating_via_entity_id: (Optional) The entity ID of a parent entity. When provided, the chart will be created in the parent entity’s open changeset instead of a new standalone changeset.
Running scripts
Script code. By default, the latest version of the entity is run.
To run a specific version of a script entity, include the version as a second argument. You can also pass an entity ref object instead.
Parameters:
script_id: ID of the script to runversion: (Optional, keyword-only) Specific version of the script
entity_id: ID of the entity with embedded scriptsversion: (Optional, keyword-only) Specific version of the entitycard_ids: (Optional, keyword-only) List of specific card ids to run on the page
card_ids argument to specify which scripts in particular should be run. These IDs can be found in the page content of the entity (see the Entity Schema for more details).
Getting live backlinks
Using Neil AI
Note the ai agent must be enabled for your organisation. Contact Seal support to find out more.user_prompt: The prompt to send to the AI agentfile_entity_ids: (Optional, keyword-only) List of file entity IDs to provide as context. Useful for passing a list of files to generate new entities from
change_set_index: The index of the change set to execute the agent in
Reviewing entities with AI
Note the AI agent must be enabled for your organisation. Contact Seal support to find out more.additional_instructions: (Optional) Additional instructions to guide the review. If not provided, the agent uses its default review expertise.
entity_id: The ID of the entity to reviewentity_version: (Optional) Version of the entity to review. If not provided, reviews the latest version.additional_instructions: (Optional) Additional instructions to guide the review. If not provided, the agent uses its default review expertise.
change_set_index: The index of the change set to reviewadditional_instructions: (Optional) Additional instructions to guide the review. If not provided, the agent uses its default review expertise.
Getting trigger info
about the trigger run:
trigger_id and triggered_by_entity_id.
Importing packages
Seal comes with many common Python packages pre-installed. If there are other python packages you regularly require, please contact Seal support. These packages are automatically imported in every Script, so don’t need to be manually imported: Available packages to import include:- altair
- annotated-types
- attrs
- blinker
- cachetools
- certifi
- cffi
- charset-normalizer
- click
- cloudevents
- contourpy
- cryptography
- cycler
- deprecation
- et-xmlfile
- flask
- fonttools
- functions-framework
- gcloud
- google-api-core
- google-auth
- google-cloud-appengine-logging
- google-cloud-audit-log
- google-cloud-core
- google-cloud-error-reporting
- google-cloud-logging
- google-cloud-storage
- google-crc32c
- google-resumable-media
- googleapis-common-protos
- grpc-google-iam-v1
- grpcio
- grpcio-status
- gunicorn
- httplib2
- idna
- itsdangerous
- jinja2
- joblib
- jsonschema
- jsonschema-specifications
- jwcrypto
- kiwisolver
- lxml
- markupsafe
- matplotlib
- numpy
- oauth2client
- openpyxl
- packaging
- pandas
- pillow
- proto-plus
- protobuf
- pyasn1
- pyasn1-modules
- pycorn
- pycparser
- pycryptodome
- pydantic
- pydantic-core
- pyparsing
- pyrebase4
- python-dateutil
- python-docx
- python-jwt
- pytz
- referencing
- requests
- requests-toolbelt
- rpds-py
- rsa
- scikit-learn
- scipy
- setuptools
- six
- tabulate
- threadpoolctl
- toolz
- typing-extensions
- urllib3
- vl-convert-python
- watchdog
- werkzeug
- xlrd
Examples
Creating and Linking Charts
This example script would be embedded in an entity containing a SUBMISSION field, with your chart data, and a REFERENCE field to embed the generated chart in.Creating labels
Create PDF labels from entity data with configurable layouts. This method requires the Label creation blueprint to be installed. To setup this up, see Creating labels blueprint.Field structure in JSON
Fields are stored as an object calledfields, keyed by the unique field names. Every field object has the following fields:
id- a unique UUID given to every field, so it can be referenced. When a Data Record is created from a Data Step, it will have the same fields with matchingids- the field’s
type - the field’s
dataType(usually the same as the type, but multiple field types may use the same underlying data type).typeis how it appears in the UI,dataTyperefers to the underlying data type value- the actual data. All field values are nullable - they are usually null in Data Steps (unless you want a default value for produced Records), and then populated in Data Records when a lab technician is doing data entry, for example.config- certain field have additional config, for example specifying a number display format, or whether the field can contain multiple values.
Field types
The columns in the dataframe are converted to fields in each Record. Seal infers the field types based on the data provided:| Data shape | Field type |
|---|---|
a number or None | NUMBER |
| a boolean | BOOLEAN |
| an ISO date string | DATE |
| an ISO datetime string (must be timezone aware) | DATETIME |
| a plain text string | STRING |
| an array of UUID strings | UPLOAD (i.e. an array of File ids) |
| an array of non-UUID strings | SELECT (a select field aka dropdown) |
| an array of id, version objects | REFERENCE (an entity reference field) |
Expand this section to find out more about specific field type configurations
Expand this section to find out more about specific field type configurations
Type: NUMBERDescription: Numeric value.Value: A valid JSON number or
Type: STRINGDescription: Text.Value: A string or
Type: BOOLEANDescription: True/false.Value: A JSON boolean or
Type: DATEDescription: A date in ISO 8601 format.Value: An ISO date string or
Type: DATETIMEDescription: A datetime in the UTC timezone in ISO 8601 format.Value: A timezone aware ISO datetime string with zero offset, or
Type: SELECTDescription: An array of enum-like strings. Displayed in the UI as a dropdown/select field with multiple options.Value: An array of strings.Config:
Type: REFERENCEDescription: An entity reference field for referencing other entities (of any kind), including File entities for referencing files.Value: An array of
null.Config:Type: STRINGDescription: Text.Value: A string or
null. The string must be at least length 1 - to represent an empty value, use null.Config: NoneType: BOOLEANDescription: True/false.Value: A JSON boolean or
null.Config: NoneType: DATEDescription: A date in ISO 8601 format.Value: An ISO date string or
nullConfig: NoneType: DATETIMEDescription: A datetime in the UTC timezone in ISO 8601 format.Value: A timezone aware ISO datetime string with zero offset, or
nullConfig: "2025-02-18T14:10:30.815Z"Type: SELECTDescription: An array of enum-like strings. Displayed in the UI as a dropdown/select field with multiple options.Value: An array of strings.Config:
Type: REFERENCEDescription: An entity reference field for referencing other entities (of any kind), including File entities for referencing files.Value: An array of
{id, version} objects.Config: