# Billing, credits, and usage
Source: https://docs.script.it/account/billing
Understand Personal and organization credits, Pro packages, on-demand usage, member caps, and recurring integration costs.
Script.it uses credits for AI model calls, script execution, and selected built-in integrations. Usage is charged to your active account: Personal or an organization.
## How credits work
Credits are consumed each time you interact with the AI agent, run a script, or use a credit-priced integration. Three things drive credit usage:
* **AI model calls** — every message to the agent, every script build, and every automated run that involves the AI uses credits proportional to the amount of text processed.
* **Execution time** — running script blocks consumes credits based on how long the execution takes.
* **Gateway integrations** — calls made through the **LLM Gateway**, **Social Media Gateway**, and **Web Search Gateway** consume credits when used.
Personal accounts start with free included credits. A newly created organization must choose a credit plan before it can run billable actions.
## Pro packages
Pro packages are recurring plan sizes. Each package includes a monthly credit allowance, premium models, and the option to buy additional on-demand credits.
See the [Script.it pricing page](https://script.it/pricing/) for current package sizes and monthly or yearly pricing.
Premium models require Pro. Credit-priced integrations use the active account's available credits.
## Upgrade or change a package
Owners and billing admins can manage an organization's billing. Personal billing is available only to the account owner.
Switch to the Personal or organization account you want to pay for.
Open **Settings → Billing**.
Select a monthly credit package, then choose monthly or yearly billing.
Continue to Stripe and confirm the subscription.
Moving to a larger package on the same billing interval applies immediately and may be prorated. Downgrades, and any change of billing interval, take effect at renewal. You can manage payment methods, invoices, and cancellation through the Stripe customer portal.
Script.it does not store your payment card details. Stripe handles checkout and payment methods.
## Additional on-demand credits
Personal owners, organization owners, and billing admins can allow usage beyond the plan at **\$0.12 per credit**. Set a monthly USD limit under **Settings → Billing → Additional on-demand credits**.
The limit is additional to the recurring package. When the active account uses its included credits and reaches its on-demand limit, Script.it pauses new billable actions until credits become available or the next credit window begins.
## Recurring integration credits
LinkedIn, WhatsApp, Telegram, and Instagram connections currently cost **50 credits per connected account each month**. The connection dialog shows the recurring cost before you connect.
Disconnecting does not refund the current month's charge. If a renewal cannot be paid, Script.it warns you before unlinking the connection.
## View usage
Open **Settings → Usage** to see the active account's credit status and daily activity.
* In Personal, you see your own usage and remaining credits.
* Organization owners and admins can expand **Organization usage** to review usage by member, script, and active trigger.
* Organization members and billing admins see only their own usage. If an administrator set a member cap, they also see that cap and its reset date.
Billing and usage are separate: **Billing** manages the plan and payments, while **Usage** explains where credits were spent.
## Member usage caps
Organization owners and admins can set an optional monthly cap for a member from **Settings → Organization**. The cap limits how many credits that member can spend from the organization's shared pool.
Clearing the cap returns the member to shared-pool-only access. A cap does not reserve credits for the member and does not change credits already used.
## What happens when credits run out
When the active account has no usable credits:
* New agent messages and billable script runs are blocked.
* Triggers cannot run until the account can spend again.
* A credit-priced integration cannot be connected if the account cannot cover its recurring charge.
The notice links eligible owners to Billing. Organization members without billing permission see guidance to contact an owner or billing admin. You can switch back to Personal if that account still has credits.
See [Organizations and active accounts](/account/organizations) to understand what changes when you switch accounts.
# Organizations and active accounts
Source: https://docs.script.it/account/organizations
Use organizations to manage a company directory, shared workspace access, billing, and usage controls.
An organization is a company directory and account context in Script.it. It brings together members, organization-shared workspaces, billing, and usage controls.
You always have a **Personal** account, and you can create or join more than one organization. You use one active account at a time.
## Personal and organization accounts
| Account | Best for | Included access |
| - | - | - |
| Personal | Your own work | Your private workspace, workspaces shared with you from outside your organizations, and your personal credits |
| Organization | Company work | The organization's workspaces (shared org-wide or with you directly), workspace integrations, and the organization's credits and limits |
Switching accounts changes which workspaces and integrations are available and which account pays for new usage. It does not move or delete scripts, sessions, or connections.
Every shared workspace appears in exactly one of your accounts, decided by membership in the organization that owns it:
```mermaid theme={"theme":{"light":"github-light","dark":"github-dark"}}
flowchart TD
W["A workspace is shared with you"] --> M{"Are you a member of the
organization that owns it?"}
M -- "Yes" --> ORG["It appears in that organization's account.
Switch there to work in it —
your work uses the organization's credits."]
M -- "No" --> EXT["It appears in your Personal account,
grouped under Shared with you.
Your work there uses your own
credits and connections."]
```
The account switcher lists only organizations you are a member of. Being invited to a single workspace never adds an organization to your switcher — see [Working in a workspace shared from outside](#working-in-a-workspace-shared-from-outside) below.
Creating an organization does not automatically share a workspace with it. Create workspaces privately, then explicitly add people or an organization from the workspace's access settings.
## Working in a workspace shared from outside
When someone shares a workspace with you and you are **not** a member of the organization that owns it, the workspace shows up in your **Personal** account under **Shared with you**, labeled with the owner's name.
* You collaborate on the same scripts and files as everyone else in the workspace.
* Everything you run there uses **your own credits**. Your own connections stay yours: an integration you have connected resolves to your account, not the owner's.
* Connections other people have shared **into that workspace** are available to you as well, whoever owns the workspace. Using one calls the sharer's upstream account, not yours.
* If you later join the owning organization, the workspace moves out of **Shared with you** and becomes available through that organization's account instead. Any triggers you created on it start running under the organization from then on — the invitation screen shows this before you accept.
## Switch your active account
Use the account switcher in the sidebar or the Settings header:
1. Open the account switcher.
2. Choose **Personal** or an organization.
3. Wait for Script.it to synchronize your workspace access.
Script.it opens a new session after the switch and updates your workspace access.
## Create and manage an organization
Open **Settings → Organization** to create an organization or manage one you belong to. From an organization's menu, permitted roles can rename it, set an image, invite members, or delete it.
New organizations do not receive Personal free credits. To run billable actions, an organization must choose a credit plan. You can switch back to Personal at any time.
An owner can delete an organization only after its paid subscription has ended. Deleting it removes organization membership and inherited workspace access; it does not delete a workspace that still has another Editor.
## Roles and permissions
| Role | Organization settings | Members and auto-join | Organization usage | Billing |
| - | - | - | - | - |
| Owner | Manage | Manage | View and set member caps | Manage |
| Admin | Manage | Manage | View and set member caps | No access |
| Billing admin | View | View | Own usage only | Manage |
| Member | View | View | Own usage only | No access |
Owners can invite members, admins, and billing admins. Admins can invite members and other admins, but not billing admins. An admin cannot change or remove an owner or another admin, and an organization must always retain an owner.
## Invite members
Owners and admins can invite people from **Settings → Organization**:
1. Open the organization's **···** menu and select **Invite members**, or use the invite form for the active organization.
2. Enter an email address and choose an allowed role.
3. Send the invitation.
The recipient can accept or decline the invitation in Script.it. Accepting adds them to the directory but does not switch their active account.
## Configure auto-join domains
Auto-join domains let people with a verified work email join an organization automatically after they sign in.
1. Open **Settings → Organization** and select the organization.
2. Under **Auto-join domains**, enter the company's domain.
3. Add the displayed DNS TXT record at your domain provider.
4. Return to Script.it and verify the domain.
After verification, matching users join as members and can access workspaces shared with the organization. An organization can verify multiple domains, but a domain can belong to only one active organization.
## Share a workspace with an organization
Workspace Editors can manage access, but only an organization owner or admin can add or remove that entire organization.
1. Open **Settings → Sharing → Workspaces**.
2. Select **Members** for the workspace.
3. Search for a person or organization.
4. Choose **Can edit** or **Can view**, then send the invitation or add the organization.
All current and future organization members inherit the organization's workspace role. Direct grants to individual people remain separate, and the strongest applicable role wins.
Connections are shared with workspaces, not directly with organizations. A connection shared into a workspace reaches everyone that workspace grants access to — the organization's members and any collaborator invited from outside it. Because adding or removing an entire organization requires an organization owner or admin, that exposure is agreed when the invitation is made rather than each time a connection resolves.
See [Workspaces](/account/workspace) and [Billing](/account/billing) for details.
# Security and privacy
Source: https://docs.script.it/account/security
Script.it encrypts data in transit and at rest, runs scripts in isolated environments, and operates on Google Cloud with automatic failover and backups.
Script.it is built with security as a default, not an afterthought. Your data is encrypted wherever it travels or rests, scripts execute inside isolated environments that can't reach your other sessions, and the infrastructure is designed to stay available even when individual components fail. This page describes the specific protections in place.
## Data encryption
### In transit
All communication between your browser and Script.it is encrypted using HTTPS with TLS 1.2 or higher. This applies to every request — API calls, file uploads, webhook payloads, and everything in between.
### At rest
Data stored in Script.it is encrypted at rest. This includes scripts, session files, and any credentials you've connected through integrations.
## Credential security
When you connect an integration — Slack, Gmail, Google Sheets, or any other service — Script.it stores the access credentials in encrypted form. Your credentials are never exposed in plain text, and they're never included in script source files or chat history.
To revoke access for an integration at any time:
1. Go to **Settings → Integrations**.
2. Find the integration you want to disconnect.
3. Click **Disconnect**.
Disconnecting removes the stored credentials immediately. Any script that relied on the integration will fail until you reconnect it.
## Isolated run environments
Every session runs in its own isolated environment. This means:
* Concurrent sessions don't interfere with each other.
* Runtime files are scoped to the session that produced them.
* Script source and run output are stored separately.
This isolation protects both your data and the Script.it platform from unintended interactions between workloads.
## Workspace backups
Your Script.it data — scripts, session history, trigger configurations, and connected integrations — is automatically backed up. You don't need to configure anything for backups to work.
## Infrastructure
Script.it runs on Google Cloud. The infrastructure includes redundancy at multiple levels and automatic failover, so a failure in one component doesn't bring down your automations. Scheduled triggers and webhook triggers are designed to continue operating even during maintenance windows.
If you have specific compliance requirements or questions about data handling, contact [support@script.it](mailto:support@script.it).
# Workspaces
Source: https://docs.script.it/account/workspace
Workspaces are where teams collaborate on scripts and share integrations in Script.it.
Workspaces are where you collaborate in Script.it. Each workspace holds its own scripts and gives people and organizations a shared place to use integrations that have been shared with the workspace.
When you sign up, Script.it creates a private workspace in your Personal account automatically. You can create additional workspaces for teams, clients, departments, or any other collaboration boundary.
## Signing up
To create an account, go to [app.script.it/login](https://app.script.it/login). You can sign in with Google or with an email address and password. No credit card is required to get started — your account comes with free included credits right away.
New accounts are on the free plan by default. You can upgrade to a paid plan at any time from **Settings → Billing**. See [Billing, credits, and plans](/account/billing) for details.
## What workspaces contain
Each workspace contains:
* **Scripts** - reusable workflows with blocks, source files, assets, and trigger configuration.
* **Members** - the people and organizations that can view, run, or edit scripts in the workspace.
* **Shared integrations** - connected accounts or custom integration types that members can use.
* **Triggers** - rules that run scripts automatically on a schedule or in response to events.
Scripts are shared across sessions. If a member edits a script in one session, the updated script is visible everywhere that workspace is available.
Session files are separate. Files produced during a run belong to the session that produced them, not to the workspace's script source. See [Session files](/sessions/files) for details.
## Roles
Workspaces have two roles:
| Role | What they can do |
| - | - |
| Editor | Edit scripts, invite or remove members, change member roles, and manage workspace settings. |
| Reader | View and run scripts, and use integrations shared with the workspace. Readers cannot edit scripts or manage members. |
Workspace role does not automatically grant the right to manage an integration. Sharing, editing, rotating credentials, and deleting integration resources are controlled by per-integration permissions. A workspace Editor can still remove a shared integration from that workspace's catalog for cleanup.
## Sharing with people and organizations
New workspaces are private to their creator. Creating a workspace while an organization is active does not share it automatically.
From the workspace's **Members** dialog, an Editor can invite a person directly. An organization owner or admin who is also a workspace Editor can grant the entire organization **Editor** or **Reader** access. All current and future organization members inherit that role.
Direct and organization access coexist. If you have both, Script.it applies the stronger role.
A shared workspace appears in exactly one of each person's accounts. Members of the owning organization reach it through that organization's account. A person invited from **outside** the organization sees it in their own **Personal** account under **Shared with you** — they collaborate on the same scripts, and their runs use their own credits, their own connections, and any connection shared into the workspace itself. See [Working in a workspace shared from outside](/account/organizations#working-in-a-workspace-shared-from-outside).
Script.it keeps at least one Editor for every workspace. Removing an organization's access never leaves the workspace without someone who can manage it.
See [Organizations and active accounts](/account/organizations) for account switching, roles, and organization invitations.
## Shared integrations
Workspaces can receive two kinds of shared integrations:
* **Shared connections** - a collaborator shares their connected account with the workspace. The people it authorizes call that integration using the sharer's upstream account.
* **Shared custom integration types** - a collaborator shares the definition for an integration, such as the base URL, auth mode, OAuth client, or OpenAPI spec. Each authorized person connects their own credentials through that type.
Sharing a connection authorizes the account, not just a specific script or location — the people it reaches can use it from any of their sessions and scripts, and the same connection can be shared with multiple workspaces.
A share reaches **everyone the workspace grants access to**, however that access arrived:
```mermaid theme={"theme":{"light":"github-light","dark":"github-dark"}}
flowchart TD
S["A connection is shared
with a workspace"] --> W["Everyone with access to
that workspace can use it"]
W --> D["People invited directly —
including collaborators from
outside the owning organization"]
W --> O["Members of an organization
the workspace is shared with"]
D --> U["Calls run against the
sharer's upstream account"]
O --> U
```
Who owns the workspace does not narrow this. Instead, the decision is made when access is granted: only an organization owner or admin can add or remove an entire organization, and the sharing screen shows that connections shared into the workspace come along.
When you share an OAuth or API-key connection, the people the workspace authorizes can make requests under your authorization at the upstream provider. Those requests may appear as you in the provider's logs or audit trail.
## Accessing settings
To manage workspaces, open **Settings → Sharing → Workspaces**. From there you can:
* Create a workspace
* Rename or delete a workspace
* Invite people or add an organization
* Change a member's role
* Remove members
* Review what integrations are shared with a workspace
To manage account-level settings, open **Settings**. From there you can:
* View and edit your profile information
* Check your credit balance and usage history
* Upgrade your plan or manage billing
* Review connected integrations and revoke access if needed
The pages in this section cover billing and security in detail.
# Core concepts
Source: https://docs.script.it/core-concepts
Understand the key building blocks of Script.it: workspaces, scripts, blocks, sessions, triggers, integrations, the AI agent, and credits.
Before you start building on Script.it, it helps to understand the key ideas behind how the platform works. This page explains each core concept in plain terms — no technical background required.
## Workspaces
A workspace is a shared place for collaboration. It holds scripts, members, triggers, and shared integrations.
Workspaces have two roles:
* **Editors** can edit scripts and invite or remove members.
* **Readers** can view and run scripts and use shared integrations, but cannot change workspace content.
Workspaces also control which scripts are visible to which people. You can keep personal scripts in your private workspace and create team workspaces when you want others to use or maintain the same automations.
## Scripts
A script is an automation workflow. It defines a sequence of steps to carry out, what each step does, and in what order. Scripts are stored in a workspace and can be run manually, on a schedule, or triggered by an external event.
Each script has its own page where you can review its blocks, source files, reusable files, and recent changes. The AI agent manages the underlying setup for you, but you can still inspect what it creates.
Scripts are reusable. You can run the same script multiple times, share it with teammates, or use it as the starting point for a new workflow.
## Blocks
Blocks are the individual steps inside a script. Each block does one thing, and a script runs its blocks in order.
There are two types of block:
* **Executable blocks** — these run code, usually Python or shell, to perform an action, such as fetching data from an API, transforming a file, or sending a message.
* **Markdown blocks** — these contain documentation or notes. They don't run code, but they help you and your team understand what a script does.
When you describe a workflow to the agent, it figures out what blocks are needed and writes the code or notes for each one. You can ask the agent to add, remove, or change individual blocks at any time.
## Assets
Assets are files stored with a script. They persist across sessions and travel with the script when it is exported or shared through a workspace.
Use assets for templates, seed data, configuration, reference files, and small state files that a script should remember between runs. Files produced during a run are different: they belong to that session's `data_files/` folder and do not automatically become script assets.
See [Assets](/scripts/assets) for examples, including how to use assets as persistent script memory.
## Sessions
A session is a single conversation with the AI agent. Every time you open a new chat, you're starting a new session.
Each session runs in its own isolated working directory, so files created during one session don't interfere with another. However, changes to scripts — like creating or editing a workflow — are saved to the script's workspace and visible across all sessions that can access it.
Think of a session as the working context for a particular task. You can use it to build a new script, debug an existing one, or run a one-off automation. When a trigger fires a script automatically, that run gets a session too — sometimes a new one, and sometimes an ongoing session that groups related events together.
## Triggers
A trigger is a rule that runs a script automatically in response to something happening. Instead of clicking **Run** manually, triggers let your automations take care of themselves.
A trigger can watch for:
* **A schedule** — a set time or a recurring cadence, from a preset, plain-English timing, or a cron expression.
* **An app event** — something happening in a connected tool, such as a new email arriving, a form being submitted, or a row being added to a spreadsheet. Over 80 events across 40+ apps.
* **A webhook** — a request sent to a unique URL that Script.it provides, from a service that supports webhooks or from a form on your own website.
* **Anything else** — if none of those fit, the agent can build a custom trigger for you.
A trigger is saved as part of its script, so it travels with the script when you share, export, or import it. Because triggers run using a person's own connected accounts, a shared script's triggers appear switched off for your teammates until each of them enables their own copy.
See [Triggers](/triggers/overview) for setup instructions.
## Integrations
An integration is a connection to a third-party service. Script.it supports 600+ integrations including Slack, Gmail, Google Sheets, Notion, HubSpot, Airtable, and many more.
Once you connect an integration, your scripts can read from and write to that service. For example, a script could pull data from a Google Sheet, process it, and post a summary to a Slack channel — all without you copying or pasting anything.
You can keep a connection private or share it with a workspace. A shared connection lets every member call the service using the sharer's account. A shared custom integration type lets members connect their own credentials through the same API definition.
You can connect integrations from **Settings → Integrations**, or the agent will prompt you to connect one when a script needs it.
See [Integrations](/integrations/overview) for the full list of supported tools and connection instructions.
## The agent
The agent is the AI at the heart of Script.it. It builds, edits, and runs scripts in response to your chat messages.
When you describe what you want to automate, the agent writes the blocks, sets up the workflow, and can run the script right in your session so you can see what happens. You can keep chatting to iterate — ask it to add a step, fix a bug, explain what a block does, or try a different approach.
The agent is designed to be transparent: every action it takes shows up in your chat, and the scripts it creates are yours to inspect and modify.
## Credits
Credits are the usage-based currency that tracks the cost of running Script.it. AI usage (chat, building scripts, running automations) and execution time both consume credits.
Your account starts with free included credits. When you need more, you can upgrade to a paid plan or purchase credits on demand. You can check your credit balance and usage history in the **Account** section of your workspace.
No credit card is required to sign up. Free credits are available for all new accounts.
See [Billing & credits](/account/billing) for details on plans and pricing.
# Technical reference
Source: https://docs.script.it/developers/overview
Technical details for developers who want to inspect Script.it scripts, understand SKILL.md files, work with trigger payloads, or integrate custom systems.
This section is for developers and technical operators. You do not need these details to build automations in Script.it, but they are useful if you want to inspect generated scripts, review changes, debug a run, or connect Script.it to internal systems.
## Script file structure
Each script is stored as a small project with a `SKILL.md` definition, source files, and optional assets.
```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
workspaces//my-script/
├── SKILL.md # Script definition in Agent Skills format
├── scripts/ # Source files used by executable blocks
│ ├── fetch-data.py
│ └── process.sh
└── assets/ # Persistent files bundled with the script
```
The AI agent manages these files for you. You can still inspect them, export them, or version-control them if your workflow requires it.
## Script definition
`SKILL.md` is the canonical Script.it script definition. It follows the Agent Skills format: YAML frontmatter at the top, followed by a Markdown body. Each fenced `yaml` block in the body declares one executable block or one Markdown block.
````markdown theme={"theme":{"light":"github-light","dark":"github-dark"}}
---
name: weekly-summary
description: Fetch report data and post a summary to Slack
disable-model-invocation: true
metadata:
id: scr_xxxxxxxxxx
---
## About this script
Fetches the latest report data, creates a concise summary, and posts it to Slack.
```yaml
id: fetch-report
name: Fetch report data
description: Fetches source data and writes `report.json`.
source_file: ${{ src }}/fetch-report.py
output_directory: fetch/
```
```yaml
id: post-to-slack
name: Post summary to Slack
description: Posts the generated summary to Slack.
source_file: ${{ src }}/post-to-slack.py
output_directory: slack/
inputs:
report_path: ${{ block.fetch-report.output_directory }}/report.json
```
````
Blocks run in document order. Prose between block fences is preserved as documentation in the script view.
### Frontmatter fields
Common frontmatter fields:
| Field | Purpose |
| - | - |
| `name` | Required slug. It matches the script directory name. |
| `display-name` | Optional user-facing title with spaces and punctuation. |
| `description` | Required description used for discovery and display. |
| `arguments` | Optional ordered list of script input names. |
| `argument-hint` | Optional metadata for script inputs, including type, default, description, and UI hints. |
| `disable-model-invocation` | Prevents the agent from auto-invoking the script unless referenced explicitly. |
| `always-include` | Includes the full `SKILL.md` in the agent's context on every prompt turn. |
| `metadata.id` | Stable script ID assigned by Script.it. Do not edit it manually. |
Legacy scripts may still contain `flow.script.yaml`, but new and migrated scripts use `SKILL.md`.
### Path expressions
Use `${{ ... }}` expressions in block fields and inputs:
| Expression | Resolves to |
| - | - |
| `${{ src }}` | The script's `scripts/` source directory. |
| `${{ script.assets }}` | The script's persistent `assets/` directory. |
| `${{ session.data_files }}` | The current session's runtime data directory. |
| `${{ builtins }}` | Built-in Script.it blocks. |
| `${{ inputs.name }}` | A script-level input value. |
| `${{ block.fetch.outputs.file }}` | A value returned by an earlier block. |
| `${{ block.fetch.output_directory }}` | The output directory for an earlier block. |
Use script assets for persistent files. Use session data files and block output directories for run-specific output.
## Runtime files
Script files and session files are separate:
* Script files live with the script and are shared across sessions.
* Script assets live in `assets/` and persist across sessions.
* Session files live in the session's `data_files/` directory and contain outputs from a specific run.
* Runtime artifacts, logs, and block outputs belong to the session that produced them.
Each session runs in an isolated sandbox environment. That keeps concurrent sessions from reading or overwriting each other's runtime files.
## Agent context fields
Script.it uses `SKILL.md` frontmatter to control **Agent context**:
| App mode | Frontmatter update | Effect |
| - | - | - |
| Not Included | `disable-model-invocation: true` and `always-include: null` | Script not included in context, but searchable by the agent. |
| Description Included | `disable-model-invocation: false` and `always-include: null` | Agent will read the script if description is relevant. |
| Script Included | `always-include: true` and `disable-model-invocation: null` | The full script content is included in the agent context. |
See [Agent context](/scripts/agent-context) for user-facing guidance.
## Trigger payloads
When a trigger starts a script, Script.it creates a new session and passes event data into that session.
* Webhook triggers receive an HTTP POST body.
* Integration event triggers receive event data from the connected tool.
* Schedule triggers receive schedule metadata such as the scheduled time.
For scripts that need to read trigger data directly, the payload is available as a session file, commonly `data_files/trigger_event.json`.
## Schedules and cron
Schedule triggers can use presets or a custom five-field cron expression:
```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
minute hour day-of-month month day-of-week
```
Examples:
| Cron expression | Meaning |
| - | - |
| `0 9 * * *` | Every day at 9:00 AM |
| `0 9 * * 1` | Every Monday at 9:00 AM |
| `*/30 * * * *` | Every 30 minutes |
Cron expressions use the timezone configured on the trigger.
## Integrations and credentials
Integrations use OAuth, API keys, or custom headers depending on the connected service. Script.it stores integration credentials in encrypted form and does not write them into script source files or chat history.
Custom integrations use a two-layer model:
* The integration type defines the API shape: base URL, auth mode, OAuth URLs, docs URL, logo, and schema.
* The connection stores one user's credentials for that type.
Connections and custom integration types can be shared with workspaces. Connection sharing delegates use of the owner's upstream account. Custom type sharing exposes the API definition so each member can connect their own credentials.
## Versioning
Script changes are tracked as version snapshots. If the agent changes a script and you want to go back, ask it to revert the last change or restore a previous version.
# Connect integrations
Source: https://docs.script.it/integrations/connecting
Connect built-in and custom integrations, share them with workspaces, and understand how Script.it handles credentials.
Connecting an integration takes a few clicks. You authorize a tool from your account settings, then scripts can use it without storing credentials in the script itself. Script.it supports OAuth for tools like Gmail and Slack, API key authorization for tools like Airtable, and custom REST API definitions for tools outside the built-in catalog.
## Connecting an integration
In Script.it, click **Settings** in the sidebar, then select **Integrations**. This page shows your connected tools, shared integrations, and a search field for the full catalog.
Type the name of the tool in the search field. The catalog includes 600+ apps — scroll the results or refine your search until you find the one you need.
Click **Connect** next to the tool. Script.it opens the authorization flow for that integration.
* **OAuth tools** (Gmail, Slack, Google Sheets, Notion, and most others) — you'll be redirected to the tool's own sign-in page to grant access. Sign in and approve the requested permissions.
* **API key tools** (Airtable, and others that use token-based access) — a dialog prompts you to paste your API key or personal access token.
Follow the prompts until the authorization is complete. For OAuth tools, you'll be redirected back to Script.it automatically once you approve access. For API key tools, click **Save** after entering your credentials.
The tool now appears in your connected integrations list with a **Connected** badge. It is immediately available to your scripts.
Some premium connections, including LinkedIn, WhatsApp, Telegram, and Instagram, cost **50 credits per connected account each month**. Script.it shows this recurring cost before authorization. Your active account must have enough usable credits to connect; if it does not, the connection screen shows an upgrade or billing action instead.
Disconnecting a credit-priced integration stops future renewals but does not refund the current month's charge. If a renewal cannot be paid, Script.it warns you before unlinking the connection.
The AI agent can also prompt you to connect a missing integration during a session. If you describe an automation that requires a tool you haven't connected yet, the agent will pause and ask you to authorize it before continuing. You can complete the connection without leaving the chat.
## Sharing a connection with a workspace
When you share a connection, workspace members can call the upstream API using your connected account. This is useful for team-owned tools such as a shared Slack bot, a reporting mailbox, or a company CRM account.
Go to **Settings → Integrations** and find the connected account you want to share.
Use the sharing control on the integration row. It shows which workspaces already have access.
Select the workspace that should be able to use the connection. The share is scoped to that workspace. You can share the same connection with more than one workspace.
Confirm that members of the target workspace should be able to use the connection under your upstream account.
A shared connection delegates use of your upstream account. Every Editor and Reader in the workspace can call it, and provider logs may show requests as you.
## Sharing a custom integration type
Custom integration types are different from connections. A type is the API recipe: base URL, auth mode, OAuth client details, schema, and display metadata. It does not share member credentials.
When you share a custom integration type with a workspace, members see it in their integration catalog and can connect their own accounts through it. Scripts can reference the same integration type, while each run uses the runner's own credentials.
This works well for internal APIs, customer-specific APIs, or partner APIs where every teammate should connect their own account.
## Disconnecting an integration
To remove a tool's access to your account:
1. Go to **Settings → Integrations**.
2. Find the connected tool.
3. Click the **···** menu next to it and select **Disconnect**.
Disconnecting an integration immediately revokes Script.it's access to that connected account. Any scripts that use that connection will fail if they try to call it after disconnection. To restore access, connect the integration again.
If the connection was shared with one or more workspaces, disconnecting it removes the underlying account for everyone. If you only want to stop one workspace from using it, remove the workspace share instead.
## Authorization types
Different tools use different authorization methods. Script.it handles both transparently, but it's helpful to know which to expect:
| Method | How it works | Examples |
| - | - | - |
| OAuth | You sign in to the tool directly and grant permission. Tokens are managed automatically. | Gmail, Slack, Google Sheets, Notion, HubSpot, Linear, Jira |
| API key | You paste a key or token from the tool's developer settings. | Airtable, and other tools with personal access tokens |
For OAuth integrations, Script.it stores only the access token — your credentials are never visible to Script.it. For API key integrations, your key is encrypted at rest.
## Custom APIs
If the API you need is not in the built-in catalog, create a [custom integration](/integrations/custom-integrations). Custom integrations support API keys, bearer tokens, basic auth, custom headers, and OAuth2 flows.
# Custom integrations
Source: https://docs.script.it/integrations/custom-integrations
Create custom REST API integrations for tools and internal services that are not available in Script.it's built-in catalog.
Custom integrations let your scripts connect to REST APIs that are not available in Script.it's built-in catalog. They are useful for internal services, partner APIs, customer-specific systems, and niche SaaS tools.
## What a custom integration is
A custom integration has two layers:
* **Integration type** - the reusable API definition, including the display name, base URL, auth mode, OAuth URLs, docs URL, logo, and optional schema.
* **Connection** - a user's credentials for that type, such as an API key, bearer token, username and password, or OAuth grant.
The integration type does not contain a teammate's personal credentials. Each member can connect their own account through the type, or the owner can share a connected account with a workspace when that is the right trust model.
## When to use one
Create a custom integration when you need to connect to:
* An internal company API not available in the public catalog
* A service that exposes a REST endpoint but doesn't have a native Script.it integration
* A custom backend you've built yourself
* A partner or customer API with a nonstandard auth header
* An OAuth API where your team owns the OAuth app registration
If the tool is already in Script.it's built-in catalog, use the built-in integration instead.
## Supported auth modes
| Auth mode | How it works | What the user enters |
| - | - | - |
| API key | Sends a secret in a configured header such as `X-API-Key`. | API key |
| Bearer token | Sends `Authorization: Bearer `. | Access token |
| Basic auth | Sends a basic auth header. | Username and password |
| Custom headers | Sends one or more static or templated headers. | The secret fields referenced by the headers |
| OAuth2 authorization code | Opens a browser authorization flow. | OAuth client ID and client secret, then user consent |
| OAuth2 client credentials | Uses server-to-server OAuth. | OAuth client ID and client secret |
Script.it handles credential storage and request authentication. Scripts call the integration by name; they do not store or print secrets.
## Creating a custom integration
In Script.it, click **Settings** in the sidebar, then select **Integrations**.
Choose the custom integration option. Give the integration a short name that identifies the API, such as "Acme internal API" or "Partner reporting API".
Add the base URL, docs URL, logo URL if available, and the auth mode the API requires. For OAuth APIs, the connection flow will show the redirect URL you need to add to your OAuth app.
Saving creates the reusable integration definition. It does not connect credentials yet.
Click **Connect** for the new custom integration and enter the credential values. For OAuth APIs, enter the OAuth client credentials and complete the authorization flow.
## Sharing custom integrations
You can share a custom integration type with a workspace. Members of that workspace can then see the integration in their catalog and connect their own credentials through it.
You can also share a connected account, but that has different security semantics: members call the API using the connection owner's credentials.
Sharing a custom integration type shares the API recipe, not personal credentials. Sharing a connection shares the connected account. Use connection sharing only when every workspace member should be able to act through that account.
Managing a custom integration type is controlled by per-integration editor rights. A workspace Editor who only receives the type through a share can use it, but cannot automatically edit, rename, or delete it.
## How the agent uses custom integrations
Once connected, the AI agent can call a custom integration from any script that can access it. When you describe an automation that involves your internal API, the agent can use the custom integration by name, send requests, pass payloads, and use responses in later blocks.
For example, if you tell the agent "post the results of this script to our compliance API," it can:
1. Identify the custom integration for the compliance API.
2. Format the script output as a JSON payload.
3. Send a POST request through the authenticated integration.
4. Use the API response in the next step.
## Managing a custom integration
To update or remove a custom integration:
1. Go to **Settings → Integrations**.
2. Find the custom integration by name.
3. Use the action menu to edit the definition, manage sharing, connect or disconnect accounts, or delete the type if no active connections depend on it.
Changing a custom integration type can affect every script and workspace that uses that type. Review shared workspaces before editing auth settings, base URLs, or schemas.
# Integrations
Source: https://docs.script.it/integrations/overview
Connect built-in tools, custom REST APIs, and shared workspace integrations so scripts can read and write data wherever your team works.
Integrations give your scripts access to the tools you already use. Script.it connects to 600+ apps — including Slack, Gmail, Notion, HubSpot, Airtable, Google Sheets, Linear, Jira, and Shopify. You can also create custom integrations for REST APIs that are not in the built-in catalog.
## What integrations are
An integration is either:
* **A connection** - an authorized account for an external tool, such as your Slack workspace, Gmail account, or internal API key.
* **An integration type** - the reusable definition for an API, such as the auth mode, base URL, OAuth settings, and API schema.
For built-in tools, Script.it provides the integration type. You connect your account. For custom integrations, you or a teammate can define the type, then each member can connect credentials through it.
When a script uses an integration, Script.it injects authentication securely. Scripts do not store API keys, OAuth tokens, or secrets in source files.
## How the AI agent uses integrations
When you describe an automation in chat, the agent automatically figures out which integrations it needs. If you say "send a Slack message whenever a new row is added to my Airtable base," the agent identifies that it needs Slack and Airtable, uses the actions those integrations provide, and builds the script accordingly.
The agent can also detect mid-session when a required integration isn't connected yet. Rather than failing silently, it will prompt you to authorize the missing tool so the automation can proceed.
## Sharing integrations with workspaces
You can keep integrations private or share them with a workspace.
There are two kinds of sharing:
| Share type | What is shared | How runs authenticate |
| - | - | - |
| Shared connection | Your connected account and credentials | Workspace members call the upstream API as you. |
| Shared custom integration type | The API definition only, with no member credentials | Each member connects and runs with their own account. |
Sharing a connection authorizes the account, not just the workspace location. Once shared, every member of that workspace can use the connection from their sessions and scripts. The same connection can be shared with multiple workspaces.
Share connections only with people you trust. When members use a shared OAuth or API-key connection, upstream requests may appear as the connection owner in the provider's logs or audit trail.
Managing an integration is separate from workspace role. The creator can manage it, and custom integration editors can be granted management access. A workspace Editor who only received an integration through a share can use it, but does not automatically get permission to edit, rotate, or delete it.
## The 600+ available tools
Script.it's integration catalog covers tools across every major category:
* **Communication** — Slack, Gmail, Microsoft Teams, Discord
* **Productivity** — Notion, Google Docs, Confluence, Coda
* **Spreadsheets & databases** — Google Sheets, Airtable, Smartsheet
* **CRM & sales** — [HubSpot](/integrations/hubspot), Salesforce, Pipedrive
* **Project management** — Linear, Jira, Asana, Trello, ClickUp
* **E-commerce** — Shopify, WooCommerce
* **Developer tools** — GitHub, GitLab, Bitbucket, PagerDuty
* **Finance** — Stripe, QuickBooks, Xero
If a tool you need isn't in the catalog, create a [custom integration](/integrations/custom-integrations) for its REST API.
## How to get started
To use an integration in your scripts, first connect it from **Settings → Integrations**. Search for the tool, click **Connect**, and complete the authorization flow.
For team workflows, open the integration's sharing controls and choose which workspaces should be able to use it. See [Connect integrations](/integrations/connecting) for details.
# Introduction
Source: https://docs.script.it/introduction
Script.it turns plain-English descriptions into working automation workflows — no coding required. Connect 600+ tools and run scripts on any schedule.
Script.it is an AI-powered automation platform that lets you describe what you want to automate in plain English and have a working workflow built and running in minutes. You don't need to write code, wire up logic blocks, or manage infrastructure — you just tell the AI agent what you need.
You can build privately or collaborate in shared workspaces. Workspaces hold scripts, members, triggers, and shared integrations, so a team can run the same automations and reuse the same connected tools.
## How it works
Every automation on Script.it follows the same pattern:
1. **Describe** — you type what you want to automate in the chat interface.
2. **The agent builds** — Script.it's AI agent creates a script with the right blocks and supporting code.
3. **Runs safely** — each run uses its own isolated environment, so your automation runs without affecting anything else.
4. **Connects your tools** — scripts can read from and write to 600+ integrations including Slack, Gmail, Notion, HubSpot, and more.
No credit card is required to get started. Sign up at [app.script.it/login](https://app.script.it/login) and start automating with included free credits.
## Why Script.it
Most automation tools make you choose between rigid visual builders that break when your needs change, or fully autonomous AI agents that are hard to inspect or control. Script.it sits between these extremes: the AI does the heavy lifting, but every workflow is a readable script you can review, edit, and reuse.
## Key concepts
Here's a quick overview of the building blocks you'll encounter:
* **Workspaces** — collaboration spaces that hold scripts, members, triggers, and shared integrations.
* **Scripts** — Workflow definitions, each containing one or more blocks.
* **Blocks** — the individual steps in a script. Each block runs part of the automation or contains documentation.
* **Assets** — persistent files stored with a script, such as templates, reference data, or small state files.
* **Sessions** — chat conversations with the AI agent, each with its own isolated run files.
* **Triggers** — rules that run a script automatically: on a schedule, when something happens in a connected app, or when a webhook URL is called.
* **Integrations** — connected third-party services that your scripts can interact with.
* **Credits** — the usage-based currency that tracks AI and execution costs.
See [Core concepts](/core-concepts) for a full explanation of each.
## Explore the docs
Sign up and run your first automation in under five minutes.
Learn how scripts and blocks are structured.
Connect Slack, Gmail, Notion, and 600+ other tools.
Run scripts on a schedule, via webhook, or from integration events.
# Quickstart
Source: https://docs.script.it/quickstart
Go from zero to a running automation in minutes — sign up, describe your workflow, and watch the AI agent build and run it for you.
This guide walks you through creating and running your first automation on Script.it. You'll sign up, describe a workflow, and have the AI agent build and run it — no coding required. The whole process takes about five minutes.
Go to [app.script.it/login](https://app.script.it/login) and create a free account. No credit card is required. Once you sign in, you'll land in your private workspace where you can start building right away.
Your free account comes with included credits so you can build and run scripts straight away.
You can begin in one of two ways:
* **Browse templates** at [script.it/templates](https://script.it/templates) — ready-made workflows for common tasks like reporting, research, data processing, and content creation. Use the public page to compare templates, then choose one from the app template picker.
* **Start from scratch** — open a new session and describe what you want to automate.
If this is your first time, starting from a template is a great way to see how scripts are structured before customising them.
In the chat panel, type a description of what you want your automation to do. Be as specific as you like — the agent handles the rest.
For example:
> "Every morning, fetch the top 5 headlines from Hacker News and send them to my Slack channel."
The agent will ask any clarifying questions it needs, then generate a script with the appropriate blocks. You'll see the script appear in your workspace as it's being built.
You can iterate freely — just keep chatting to refine the script. Ask the agent to add steps, change behaviour, or explain what a block does.
Once the agent finishes building, take a moment to review the script. You can see each block listed in order, with a description of what it does.
When you're ready, click **Run** to execute the script. The agent runs it in a secure isolated environment and streams the output back to your chat session so you can see what happened.
If anything doesn't look right, describe the issue in chat and the agent will fix it.
If your script reads from or writes to an external service — Slack, Gmail, Notion, Google Sheets, and so on — you'll need to connect that integration first.
The agent will prompt you if a connection is missing. You can also connect integrations ahead of time from **Settings → Integrations**. If you are working with teammates, you can share a connection or custom integration type with a workspace. See [Connecting integrations](/integrations/connecting) for details.
Running the script manually is useful for testing, but the real power comes from automation. Triggers let your script run itself:
* **A schedule** — run on a recurring cadence using plain-English timing like "every day at 9 AM" or a cron expression.
* **An app event** — run when something happens in a connected tool, like a new email or a new row in a spreadsheet.
* **A webhook** — run when an external service, or a form on your own website, sends a request to a unique URL Script.it provides.
To set up a trigger, describe it in chat: "Run this every weekday morning at 8 AM." The agent will create the trigger for you.
See [Triggers](/triggers/overview) for everything a trigger can watch for.
## What's next
Now that your first script is running, here are some things to explore:
Understand workspaces, scripts, sessions, triggers, and credits.
Find ready-made workflows to customise for your use case.
See all 600+ supported tools and how to connect them.
Schedule your script or fire it from an external event.
# Agent context
Source: https://docs.script.it/scripts/agent-context
Choose how much of a script the agent can use as context.
Agent context controls how much of a script the Script.it agent can use when it responds in chat.
You can change this from the script header. The control is labeled **Agent context**.
| Mode | What it does |
| - | - |
| Not Included | Script not included in context, but searchable by the agent. |
| Description Included | Agent will read the script if description is relevant. |
| Script Included | The full script content is included in the agent context. |
## When to use each mode
Use **Description Included** for most runnable scripts. Keep the script description accurate, because the agent uses it to decide when the script is relevant.
Use **Not Included** when the script should not be added to the agent's context. This is useful for scripts that are sensitive, noisy, experimental, or only useful in narrow situations.
Use **Script Included** for persistent instructions, preferences, or memory that should guide the agent across sessions. For example, a private memory script can tell the agent how you like reports formatted, what tone to use, or which recurring assumptions to follow.
## Agent context and assets
Agent context and assets solve different problems:
* **Agent context** affects what the agent reads before it responds.
* **Assets** are files stored with a script, such as templates, reference data, or small state files.
You can use them together. For example, a **Script Included** memory script can explain which preferences matter, while a small asset file stores values that are updated over time.
# Assets
Source: https://docs.script.it/scripts/assets
Use assets for persistent files, templates, reference data, and small memory files that survive across sessions.
Assets are files stored with a script in its `assets/` folder. They persist across sessions, stay with the script when it is shared in a workspace, and are included when the script is exported.
Assets are different from session files. Session files are runtime outputs in the session's `data_files/` folder. They belong to one run or conversation. Assets belong to the script.
## Assets vs. session files
| File type | Where it lives | Lifetime | Best for |
| - | - | - | - |
| Assets | `assets/` | Persist across sessions | Templates, configuration, reference data, and small script state |
| Session files | `data_files/` | Scoped to one session | Downloads, generated reports, intermediate files, and run output |
Use assets when a file should stay with the script. Use session files when a file is just the result of one run.
## Use cases
Use assets for files that should be part of the script rather than one session's output.
Common examples:
* **Templates** - store `assets/email-template.md`, `assets/report-template.docx`, or `assets/slides-template.pptx` so every run starts from the same source.
* **Reference data** - store small lookup tables, taxonomy files, prompt examples, approval rules, or sample input files.
* **Configuration** - store non-secret settings such as default channels, account mappings, or report sections.
* **Persistent script memory** - store a small file that the script reads and updates on every run.
Persistent memory is useful when a script needs to remember something between sessions. For example:
* A lead enrichment script can append processed lead IDs to `assets/processed-leads.json` so future runs skip duplicates.
* A weekly reporting script can write the last successful reporting window to `assets/state.json`.
* A monitoring script can keep `assets/seen-events.json` so it only notifies about new items.
* A personalization script can keep tone, formatting, or routing preferences in `assets/preferences.md`.
Keep persistent asset files small. For large or fast-growing data, store the data in an external system such as Google Sheets, Airtable, a database, or object storage, and keep only references or cursors in assets.
Do not store secrets in assets. Use integrations for API keys, OAuth tokens, and credentials.
# Blocks
Source: https://docs.script.it/scripts/blocks
Blocks are the steps inside a Script.it script. Learn how executable and Markdown blocks work, what they produce, and how to manage them in chat.
Every script in Script.it is made up of blocks — the individual units of work that run in sequence when you execute a workflow. Each block does one thing, and together they form a complete automation.
## Executable blocks
An executable block runs code when the block is executed. This is how your automation actually does things: fetches data from an API, processes a file, sends a message, transforms records, and so on.
### What executable blocks do
When the agent runs an executable block, Script.it runs the source file for that block and shows the result in the session. The agent normally handles the implementation for you, but the source file remains inspectable if you want to review it.
Each executable block has a clear label in the script view. Use those labels when you ask the agent to change a specific step.
### Supported languages
Executable blocks support Python and shell scripts. The agent chooses the right approach for the job, so you usually don't need to decide which language to use.
### Output and artifacts
When an executable block runs, any files it writes become artifacts that you can inspect or download. Standard output and errors are streamed back to the chat panel so you can see what happened in real time.
When you open a block run, the output area has three tabs:
* **Timeline** — shows the block's progress while it is running. Use it to see which step is active, whether the block is still working, and where a failure happened if the run stops.
* **Files** — shows the artifacts created by that block run. These are the generated reports, datasets, downloaded files, logs, or other files the block wrote during execution.
* **Output** — shows the first layer of inspection for the run, including the output file names the block produced. Start here to understand what the block returned, then open files from **Files** when you need to inspect the full artifact.
Runtime artifacts — files produced during a run — are stored in the session, not the script. This means the same script can be run in many sessions without the outputs conflicting with each other. If a file should persist with the script, store it as a [script asset](/scripts/assets).
## Markdown blocks
A Markdown block contains plain text formatted with Markdown. It doesn't run any code — it's purely for documentation and notes.
Use Markdown blocks to describe what a script does, explain the purpose of a group of steps, or leave instructions for teammates. They appear inline in the script view, making it easier to understand a workflow at a glance.
## Managing blocks via chat
You never need to edit script files by hand. The AI agent creates and maintains all blocks for you based on your chat instructions.
You can ask the agent to add, edit, or remove blocks at any time by describing the change in plain English — for example: "Add a step that sends the output to Slack" or "Remove the data validation step."
Here's how the agent handles common block operations:
Describe the new step you want: "Add a block that reads a CSV file and filters rows where the status is 'active'." The agent writes the source file, creates the block, and places it in the right position in the sequence.
Describe the change: "Update the fetch block to also include the author field in the response." The agent edits the block and its source file directly — you don't need to open an editor.
Ask the agent to remove it: "Remove the email notification step." The agent removes the block and updates the script.
## Reviewing a script
The script view shows blocks in the order they run. For a weekly report script, you might see:
* **About this script** — a Markdown block that explains the goal and what the script needs.
* **Fetch report data** — an executable block that collects the latest data.
* **Create summary** — an executable block that turns the data into a readable summary.
* **Post summary to Slack** — an executable block that sends the result to the right channel.
You can click a block to review its purpose, see recent results, or ask the agent to change it.
# Scripts
Source: https://docs.script.it/scripts/overview
Scripts are reusable workflows built by the AI agent. Each script contains blocks, source files, reusable files, and context settings for your automation.
A script is the core unit of automation in Script.it. It defines a sequence of steps — called blocks — that the platform runs in order. You describe what you want to automate in plain English, and the AI agent builds the script for you: it creates the blocks, writes the source files, and connects the pieces.
## What a script is
Every script has a name, description, ordered blocks, source files, and any reusable files it needs. You can open a script in your workspace to review what it does, run it, or ask the agent to change it.
Scripts are **reusable** — you can run the same script many times, in many sessions, without the results of one run affecting another. They are also **version-tracked**: any change the agent makes to a script is captured as a version snapshot, so you can revert to a previous state at any time.
## How the agent builds scripts
When you describe an automation in the session, the agent figures out what blocks are needed and creates the script automatically. It writes the code for executable blocks, adds documentation where useful, connects any required tools, and prepares the script so you can run it.
You don't need to manage the underlying files directly. But because the script is inspectable, you can read the source files, copy them, share them, or restore an earlier version when needed.
You can ask the agent to modify a script at any time — add a step, change the logic of a block, or restructure the whole workflow. Just describe what you want in the chat.
## What scripts can contain
A script can contain any number of blocks. Blocks come in two types:
* **Executable blocks** — run Python or shell code to perform an action, such as fetching data, calling an API, transforming a file, or sending a notification.
* **Markdown blocks** — contain plain text for documentation and notes, helping you and your team understand what the script does.
Blocks run in the order shown in the script view. The agent handles the wiring — you just describe the workflow you need.
Scripts can also contain **assets**: persistent files such as templates, reference data, configuration, and small memory files that survive across sessions. See [Assets](/scripts/assets) for details.
A script can also carry its own **triggers** — the rules that run it automatically. They appear in the script alongside its blocks, and they're saved with it, so they travel with the script when you share, export, or import it. See [Triggers](/triggers/overview).
## Agent context
Scripts also have context settings that control how much of the script the agent can use in chat. See [Agent context](/scripts/agent-context) for details.
You do not need to edit these settings for normal use, but they are useful when a script should behave like persistent context rather than an automation the agent should run.
## Where to go next
The pages in this section cover how blocks are structured, how reusable files work, and how to start from ready-made templates.
# Templates
Source: https://docs.script.it/scripts/templates
Browse pre-built Script.it templates for reporting, research, content creation, and more.
Templates are complete, ready-to-use scripts built by the Script.it team. Each template covers a common automation task and is configured with the right blocks, source code, and integrations out of the box. Browse the public templates page, choose a workflow, and use it as a starting point for your own automation.
## Available templates
Turns a topic idea into a researched, SEO-optimized post — keyword research, outline, draft, SEO polish — with optional publishing to WordPress.
Aggregates CSV or JSON data, generates an AI-powered trend summary, and delivers the finished report to a Slack channel.
Discovers competitors, gathers pricing, features, and review data, then builds a formatted battle card in Notion.
Transforms a product brief into a structured PRD with user stories and acceptance criteria, exported directly to Notion.
Converts notes or a brief into a polished slide deck — generates an outline, writes the slides, and publishes to Google Slides.
Analyzes marketing campaign CSV or JSON data, extracts key metrics, generates AI-powered insights, and posts the summary to Slack.
## Starting from a template
Go to [script.it/templates](https://script.it/templates) to see all available templates with descriptions and previews. You can also browse templates from within the app by clicking **New script** and selecting **Start from template**.
After you select a template in the app, Script.it copies the template instructions into your workspace. You get an editable script that the agent can adapt for your workflow.
Most templates use one or more integrations (Slack, Notion, Google Slides, and so on). If you haven't connected a required integration yet, the agent will prompt you to do so before running the first relevant block. You can also connect integrations ahead of time from **Settings → Integrations**.
See [Connecting integrations](/integrations/connecting) for step-by-step instructions.
Once the integrations are connected, you can run the script as-is by clicking **Run**, or ask the agent to tailor it first:
> "Change the report to pull from my Google Sheet instead of a CSV file."
> "Add a step that also sends a summary email to the team after the Slack message."
The agent will edit the blocks and source code to match your request.
Templates are a great way to learn how scripts are structured. After opening one, browse the blocks and source files to see exactly how each step works — then customize from there.
# Agent chat
Source: https://docs.script.it/sessions/chat
Build, run, modify, and debug scripts by chatting with the Script.it AI agent — from your first message to a working, iterated automation.
The chat panel is how you interact with the Script.it AI agent. You describe what you want in plain English — build a script, run it, fix a bug, add a step — and the agent does the work. Responses stream back in real time, so you can follow along as the agent thinks and acts.
## Starting a new session
When you open a new session, the chat starts empty and offers a few suggestions to help you begin. You can click one of the starter prompts or type your own message directly into the composer at the bottom of the panel.
Click **New session** in the sidebar. The agent chat opens with starter suggestions including "Guide me to automation," "Teach me about Script.it," and a template picker.
Type what you want to build in the composer and press **Enter** (or click the send button). Be specific about the goal — what data should flow in, what should happen to it, and where the result should go.
The agent responds as it works, streaming its progress live. You'll see a **Working...** indicator while it's active, which collapses into a **Details** section once it finishes. Any script changes appear in the changes bar above the composer.
## Building a script
To have the agent build a new script, describe the automation you want. The more context you give, the more accurate the result will be.
**Example prompts:**
```
Build me a script that fetches the latest 10 issues from our GitHub repo and posts a summary to Slack.
```
```
Create a script that downloads a CSV from a URL, filters rows where the "status" column is "active", and saves the result as a new file.
```
```
Build a weekly digest script that pulls unread emails from Gmail, summarizes each one with AI, and emails me the summary every Monday morning.
```
The agent will create the blocks, write the source files, and set up the script — you don't need to touch any files manually.
Start with one clear goal per script. Once the agent builds the initial version, you can add steps, change logic, or connect new integrations one at a time.
## Running a script from chat
You can trigger a script to run without leaving the chat by referencing it with `@`:
```
Run @weekly-digest
```
The agent parses the script name and starts execution. Block results stream back into the chat as they complete, so you can see exactly what ran and what each step produced.
You can also run a script directly from the script view — look for the run button next to each block or at the top of the script panel. Clicking it brings up a run widget in the composer where you can confirm or adjust inputs before running.
## Asking the agent to modify a script
Once a script exists, you can refine it through conversation. Reference the script by name or just describe the change you want — the agent knows which script you've been working on.
**Example prompts:**
```
Update the Fetch Issues block to also include the issue author and assignee.
```
```
Add a step after "Process Data" that uploads the output file to Google Drive.
```
```
The email block is failing with a 401 authentication error. Can you fix it?
```
Script changes are tracked as version snapshots. If the agent makes a change you don't want, you can ask it to revert: "Undo that last change" or "Go back to the version before you added the upload step."
## Understanding agent output
The agent's responses have a consistent structure:
* **Working...** — shown while the agent is processing. Expands to show reasoning and tool calls in progress.
* **Details** — after the agent finishes, the working section collapses to "Details." You can click it to expand and inspect exactly what the agent did.
* **Response text** — the agent's explanation of what it did or what you should do next.
* **Block results** — when a script runs, each block's output appears inline so you can review results without leaving the chat.
If the agent encounters an error during a run, it shows the error inline and often suggests or automatically applies a fix.
## Undoing changes
The agent supports reverting to previous states. If a change didn't work out, you can ask the agent to undo it at any point in the conversation:
```
Revert that last change.
```
```
Go back to the version before you added the Slack step.
```
The agent uses snapshots taken before each edit, so it can restore an earlier state of any script accurately.
## Tips for effective prompts
Getting good results from the agent comes down to being specific and iterating in small steps.
* **Be specific about inputs and outputs.** Instead of "process the data," say "read `report.csv`, filter rows where the `revenue` column is greater than 1000, and save the result to `filtered.csv`."
* **One change at a time.** Ask for one modification per message. The agent handles multi-step tasks well, but focused requests produce more predictable results.
* **Name the script.** When you have multiple scripts, reference the one you mean: "In the @daily-report script, update the fetch block to…"
* **Describe the goal, not the implementation.** Tell the agent what you want to accomplish, not how to write the code. Let it choose the right approach.
* **Iterate.** If the first version isn't quite right, describe what's missing or wrong. The agent will refine the script based on your feedback.
# Session files
Source: https://docs.script.it/sessions/files
Every session has its own files panel showing outputs, downloads, and data your scripts produced. Learn how to view, use, and export session files.
When your scripts run, they often produce files — downloaded data, generated reports, transformed datasets, or any other output written to disk. These files are stored in your session's working directory and are available to browse, preview, and download from the session files panel.
## The session files panel
The files panel sits alongside the chat in your session view. It shows everything inside your session's `data_files/` folder — the directory where scripts write their runtime outputs.
To open a file, click its name in the panel. A preview pane opens below the file list, where you can read the file's contents inline. You can resize the preview by dragging its bottom edge. To close the preview, click the **X** in the resize handle.
If you have many files, use the search icon in the panel header to filter by name.
## What gets stored as a session file
Any file your script creates during a run ends up in `data_files/`. Common examples include:
* CSV or JSON files produced by a data-fetching block
* Reports or summaries generated by an AI step
* Images, PDFs, or other documents downloaded from external services
* Intermediate files written by one block and consumed by the next
The agent can also reference session files directly in chat — if a file tag appears in a message, clicking it opens that file in the panel automatically.
## Session files vs. script files
Session files and script files are stored separately and serve different purposes.
**Script files** define the saved automation, and changes to them are visible across sessions. **Session files** in `data_files/` are runtime outputs produced when the script runs. They belong to the session that created them and are not shared with other sessions.
This separation keeps scripts clean and reusable. You can run the same script dozens of times, in different sessions, without the outputs from one run interfering with another.
## Downloading files
To download a file from your session, right-click it in the files panel and choose **Download**, or open the file preview and use the download option there.
You can also ask the agent to help you find or organize session files through chat — for example, "What files were created during the last run?" or "Show me the output from the fetch block."
## Exporting a session
You can export an entire session as a zip archive for backup or sharing. The export includes:
* Your chat history
* All files in `data_files/`
* Block execution artifacts
Saved scripts are managed separately from session exports, since they're shared across sessions.
To export a session, use the export option in the session menu. Script source files can be exported independently from the script's own export option.
# Sessions
Source: https://docs.script.it/sessions/overview
A session is a chat conversation with the Script.it AI agent. Build scripts, run them, review output, and iterate through natural language.
A session is a conversation you have with the Script.it AI agent. Every time you open a new chat, you're starting a new session — and within it you can build scripts from scratch, run them, review their output, and refine them through follow-up messages. The agent understands context across the whole conversation, so you can iterate naturally without repeating yourself.
## Sessions and scripts
Sessions and scripts are closely related but serve different purposes. A **script** is the reusable automation workflow. A **session** is the working context in which you build and run those scripts.
When the agent edits a script inside a session, that change is immediately visible anywhere the script's workspace is available. But the files your scripts produce during a run — downloaded files, generated outputs, and results — belong to the session, not the script. This keeps your scripts clean and reusable while giving each session its own isolated working directory.
## What you can do in a session
Sessions are where most of the work happens in Script.it:
* **Build scripts** — describe an automation in plain English and let the agent generate the workflow for you.
* **Run scripts** — trigger a script from chat and watch the execution results appear in real time.
* **Review output** — inspect block results, read files produced during the run, and see what your automation actually did.
* **Iterate** — ask the agent to modify a block, debug a failure, add a new step, or restructure the workflow entirely, all in the same conversation.
* **Manage files** — view and download files your scripts created during the session.
## Session working directories
Each session has its own isolated working directory. When a script runs, any files it creates — fetched data, generated reports, temporary outputs — are stored in that session. Those files won't appear in other sessions, which means concurrent sessions never interfere with each other.
The script itself is the one exception: because scripts are shared, any change the agent makes to a script in one session is immediately reflected everywhere. The agent tracks these changes and can revert them if you ask.
## Picking up where you left off
Session history persists. You can leave a session and return later — your chat history will be there, and the agent will have full context from your previous conversation. When you reconnect, the session restores its state so you can continue right where you left off.
The pages in this section cover the two main parts of a session in detail: the agent chat and the session files panel.
# App events
Source: https://docs.script.it/triggers/app-events
Run a script when something happens in an app you've connected — a new Slack message, a GitHub pull request, a Notion item, a Calendly booking, a new spreadsheet row.
An app event trigger runs your script when something happens in one of your connected apps. Instead of checking a tool yourself or starting a script by hand, you pick the event you care about — a new Slack message, a Calendly booking, an issue opened in Linear — and Script.it runs the script the moment it happens.
## Before you start
Connect the app first. Only apps you've connected show up in the trigger list.
You can connect from **Settings → Integrations**, or just ask the agent — it'll prompt you when a connection is missing. See [Connecting integrations](/integrations/connecting).
A trigger uses the account you connected. If that connection is removed or expires, the trigger stops firing until you reconnect. Script.it flags affected triggers so you can spot them.
## Creating an app event trigger
Open the script you want to run, click the **Triggers** tab, then click **Add Trigger**.
Search the list for the app or the thing you want to watch for — type "pull request", "new row", or "Slack". The list shows events for the apps you've connected.
If you've connected more than one account for that app, choose which one the trigger should watch.
Most events have a setting or two to narrow them down — which Slack channel, which Notion database, which spreadsheet, which Gmail search to match.
Narrow the trigger as much as you can. A Gmail trigger scoped to one sender is more useful, and cheaper to run, than one that fires on every incoming message.
Pick the script to run, and fill in any inputs it needs.
Click **Create Trigger**. It starts watching straight away.
Or skip all of that and describe it in chat: *"Run this whenever a new row is added to the Q3 leads sheet."*
## Available events
**This list isn't a limit.** If your app isn't here, or the event you want isn't in the list, you can still trigger on it. Connect the service as a [custom integration](/integrations/custom-integrations) — any REST API works — and ask the agent to build a [custom trigger](/triggers/custom) that watches it. The result behaves exactly like a built-in event: it lives in your script, has its own settings and run history, and travels with the script when you share it.
The events below are ready to use out of the box — over 80 across these apps:
| App | Events |
| - | - |
| Airtable | New record |
| Asana | New task, task updated, new comment |
| Box | New file |
| Calendly | New event |
| ClickUp | New task |
| Confluence | New page |
| Discord | New message |
| Dropbox | New file |
| Freshdesk | New ticket |
| GitHub | New pull request, PR merged, new push, new commit, new issue, new issue comment, new PR review comment, new release, new star, new fork |
| GitLab | New issue, new merge request |
| Gmail | New email, new email matching a search |
| Google Calendar | New event, event updated, event cancelled, event starting soon |
| Google Docs | Document updated |
| Google Drive | New file, new file in a folder, file updated |
| Google Forms | New response |
| Google Sheets | New row, new tab, spreadsheet updated |
| Google Tasks | New task, task completed |
| HubSpot | New contact, new company, new deal, new ticket |
| Intercom | New conversation |
| Jira | Issue event, new project |
| Linear | Issue event, comment created, project event |
| Mailchimp | New subscriber |
| monday.com | New item |
| Notion | New database item, database item updated |
| OneDrive | New file |
| Outlook | New email |
| Pipedrive | New deal, new person |
| Salesforce | New record |
| Shopify | New order, new product |
| Slack | New message, bot mentioned, reaction added, reaction removed, file shared, channel created |
| Stripe | New event, new customer |
| Microsoft Teams | New channel message |
| Todoist | New task |
| Trello | New card, card updated, card archived, new board |
| YouTube | New video |
| Zendesk | New ticket, ticket updated |
| Zoom | Meeting started, meeting ended, recording completed |
We add to this regularly, so the list in the app is always the current one — check there first, and build a custom trigger for whatever isn't in it yet.
## How quickly a trigger fires
It depends on the app:
* **Instantly** — apps that notify Script.it directly the moment something happens. Slack, GitHub pushes, Stripe, Linear, Jira, Trello, Asana, Zoom, and Shopify orders work this way.
* **On a regular check** — for everything else, Script.it checks the app periodically and runs your script when it finds something new. Expect a short delay rather than an instant reaction, and a slightly longer one for triggers that have been quiet for a while.
Either way you don't have to configure anything — each event already uses the fastest method its app supports.
## Email your agent
**Agent Email** is a trigger too: your agent gets its own email address, and mail sent to it can run a script. Useful for forwarding things in — a receipt to file, a report to summarize, a request to act on.
## What your script receives
When the trigger fires, the event's details are handed to the script — the message text, the issue title and body, the row that was added, whatever the app sent. Your script can read those values and act on them.
If the script produces files, they're available in that run's session, just like a run you started yourself.
## Managing app event triggers
Turn a trigger off and on from the script, and check its recent runs there too. See [Managing triggers](/triggers/managing) for run history, failures, and limits.
# Custom triggers
Source: https://docs.script.it/triggers/custom
A custom trigger is a block that runs before your script: it can use any app you've connected, and it starts nothing until something actually happens.
Sometimes the thing you want to watch for isn't in any event list. Maybe you want to fire only when a Notion page's status flips to **Done**, or when a number in a dashboard crosses a threshold, or when a service you use isn't in the catalog at all.
For those, the agent writes a custom trigger. The easiest way to understand one: it's a block that runs *before* your script.
## Like a block — but before the script
A block is a step of your script: code the agent writes for you, with access to your connected apps. A custom trigger is the same kind of code, written and saved the same way. The difference is its job. Instead of being a step *of* the workflow, it decides whether the workflow should run at all. That difference gives it three properties:
* **It can use any integration.** The trigger reaches services through the connections you've already made — the same ones your blocks use. Script.it supplies the sign-in on every call. No API keys pasted into code, nothing to rotate by hand. If the service isn't a built-in app, connect it as a [custom integration](/integrations/custom-integrations) first. Any REST API works, so a custom trigger can watch anything a block could talk to.
* **It doesn't start a script.** Blocks run inside a session. A trigger's check doesn't create one. It looks at the service, decides nothing happened, and disappears — no script run, no session in your history, next to no cost. Your script only starts when the trigger finds a real event. That's when a session is created, with the event's details handed to the script.
* **It runs outside your environment.** Most of the time the check isn't running in your environment at all. Script.it runs it on its own always-on infrastructure. There's nothing for you to host, schedule, or keep awake. The trigger keeps watching around the clock, whether or not you're using Script.it.
Put together, that's the whole idea: a block's power, without a session's price, until there's actually something to do.
## Why not just a schedule?
The obvious way to watch for something is a scheduled script: run every half hour, fetch the data, quit if nothing interesting happened. It works, but every check is a full run. That means a session in your history and credits spent even when nothing changed — which, for most watchers, is almost every check.
A custom trigger makes the same decision *before* any of that exists. Quiet checks leave no trace. Your session history only ever contains real events.
The same logic applies to incoming events. If a service sends you everything and your script ignores most of it, you still pay for a run per ignored event, forever. A custom trigger drops the uninteresting ones at the door — they never become a session at all.
## Asking for one
Describe what should start the script, as specifically as you can:
> Trigger this when a page in the Roadmap database moves to "Done".
> Check our status page every 10 minutes and run this if anything is degraded.
> Run this when a customer's plan changes to Enterprise in our billing system.
The agent writes the trigger, tests it against your real data, and switches it on. The test is a dry run: it shows what the trigger *would* have fired on, without creating anything. You both see what it picks up before it goes live. If it's catching too much or too little, say so — the agent adjusts it before turning it on.
## What the platform handles for you
The agent writes the watching logic — the part that's unique to your request. Everything around it comes with the platform. Anywhere else, this is the part you'd have to build yourself:
* **Memory.** Script.it tracks what the trigger has already seen. Each new item fires exactly once, in order. The first check takes stock of what's already there instead of flooding you with everything that ever existed.
* **Pacing.** A trigger watching a connected app can check as often as every minute. It eases off on its own when nothing has happened for a while. Schedules honor your time zone, including daylight saving.
* **Safety.** Custom triggers get the same protections as every trigger: plain-English error explanations, automatic pausing after repeated failures, and the daily failure email. See [Managing triggers](/triggers/managing).
## Two ways a custom trigger works
The agent picks whichever fits what you asked for:
* **Checking on a cadence** — the trigger looks at the service on an interval or a schedule and fires when it finds something new. Best for services that don't announce their changes.
* **Receiving events** — Script.it mints a URL for the trigger, signature-checked like a [webhook trigger](/triggers/webhook). The trigger decides which incoming notifications are worth acting on. Best when the service can call you but sends more than you care about.
Both behave identically once running — same switch, same run history, same everything.
## A first-class trigger
Once it exists, a custom trigger behaves like any other:
* It shows up **in the script**, with an on/off switch and run history.
* It can have its own **settings** — which channel, which database, what threshold. The agent declares them, and you edit them in the script like any built-in event's settings. Adjusting a setting never means touching code.
* It's **saved with the script**, like a block is. Share, export, or import the script and the trigger travels with it.
* In a **shared workspace** it follows the same rules as every trigger. Teammates can enable their own copy, which runs on *their* connected accounts and credits. Nobody inherits your automation just by opening the script.
Because it's saved as part of the script, you can also open it and read what it does. You don't have to, but it's there — nothing about your automation is hidden away. And you can always ask the agent to explain it in plain terms.
## Keeping it up to date
Custom triggers evolve by conversation. *"Also ignore drafts."* *"Check every five minutes instead."* *"Watch the EU status page too."* The agent edits the trigger and the change takes effect on its own. There's no publish or redeploy step. Teammates who've enabled the same trigger pick up the change the next time theirs runs.
If a custom trigger's code is deleted from the script, the trigger pauses instead of continuing to run an old copy. You'll see it flagged in the script.
If a built-in [app event](/triggers/app-events) already covers what you need, the agent will use that instead. Custom triggers are for everything the list doesn't reach.
# Managing triggers
Source: https://docs.script.it/triggers/managing
Check a trigger's run history, understand why one failed or paused, turn triggers on and off, and know the limits.
Once a trigger is running, everything you need is on the script itself: whether it's on, what it's done recently, and whether anything went wrong.
## Turning a trigger on and off
Each trigger has a switch on the script. Turn it off to stop it firing without losing its settings, its webhook URL, or its history. Turn it back on and it picks up from there.
This only affects **your** copy. If teammates have enabled the same trigger, theirs keep running.
## Run history
Open a trigger's recent runs to see what it's been doing. Each run shows what happened:
| Result | What it means |
| - | - |
| **Fired** | It found something and started your script |
| **Nothing new** | It checked and there was nothing to do — completely normal |
| **Running** | In progress right now |
| **Failed** | Something went wrong — see below |
A trigger that checks on a cadence will show a lot of "nothing new" runs between the real ones. That's healthy, not a problem.
If the most recent run failed, the trigger is marked in the script so you can spot it without opening anything.
## When a run fails
Expand a failed run and you'll get a plain-English explanation, with the technical detail tucked behind **Show error details** if you want it. The common ones:
* **The trigger hit an error** — usually the connected app returned something unexpected, or the account no longer has access.
* **It took too long and was stopped.**
* **It tried to do too much at once** — for example, it found thousands of items on its first run.
* **Its setup is missing** — the trigger was removed from the script but a copy is still switched on.
A single failure isn't unusual — services have blips. Repeated failures are worth looking at, and you can ask the agent to investigate: *"Why is my Notion trigger failing?"*
## Triggers that pause themselves
If a trigger fails **five times in a row**, Script.it pauses it and stops retrying. This protects you from a broken trigger burning credits in a loop.
Fix the cause — reconnect the app, ask the agent to correct the script — and switch it back on. The count resets.
A trigger can also pause if the app it depends on gets disconnected or its access expires. Reconnect the app and re-enable it.
## Failure emails
If any of your triggers fail or pause, Script.it emails you a short daily summary of what needs attention. It's at most one email a day, and it stops on its own if a trigger keeps failing for a long time — so a broken automation doesn't turn into a daily inbox habit.
## Deleting a trigger
Deleting a trigger is a shared change. It removes the trigger from the script, and removes it for **every workspace member** who had enabled it. Deleting the whole script does the same.
If you only want to stop your own, turn it off instead.
Webhook triggers are worth an extra beat: deleting one permanently invalidates its URL. Anything still sending to that URL will stop working, and creating a new trigger gives you a different URL.
## Limits
* **50 triggers per person.** Triggers that are switched off still count. If you hit the limit, delete ones you no longer need.
* **Schedules run at most every 30 minutes.** See [Schedule triggers](/triggers/schedule).
* **App events that work by checking** have a minimum gap between checks, and back off when there's been nothing new for a while. Events that arrive instantly aren't affected.
## Credits
Triggers use credits like any other run — the work happens in your environment, on your account. A trigger that checks and finds nothing costs very little; the cost is in the script runs it starts.
If teammates enable the same trigger, each of them pays for their own runs.
# Triggers
Source: https://docs.script.it/triggers/overview
Triggers let your scripts run on their own — on a schedule, when something happens in a connected app, or when a webhook URL receives a request.
Triggers let your scripts run automatically — no need to open the app and start them by hand. You attach a trigger to a script, tell it what to watch for, and Script.it runs the script every time that thing happens.
## What a trigger can watch for
There's one kind of trigger, with a menu of things it can watch for:
* **A schedule** — every weekday at 8 AM, every six hours, the first of the month. See [Schedule triggers](/triggers/schedule).
* **An app event** — a new Notion database item, a GitHub pull request, a Slack mention, a Calendly booking, a new row in a Google Sheet. Over 80 events across 40+ apps. See [App events](/triggers/app-events).
* **A webhook** — your own URL that any service can send a request to, or that a form on your own website can post to. See [Webhook triggers](/triggers/webhook).
* **Anything else** — if nothing in the menu fits, the agent can build a custom trigger for you. See [Custom triggers](/triggers/custom).
They all behave the same way once they exist: they watch for something, and when they see it, they run your script.
## Creating a trigger
The easiest way is to ask the agent in chat:
> Run this every weekday morning at 8 AM.
> Trigger this whenever someone opens a pull request on our repo.
The agent picks the right trigger, fills in the settings, and switches it on.
You can also create one yourself: open the script, click the **Triggers** tab, and click **Add Trigger**. A searchable list shows every event available for the apps you've connected.
Either way, the trigger starts working as soon as it's created.
## What a trigger does
A trigger runs a script. You choose which script, and optionally the input values it should run with — the same inputs you'd fill in when running it by hand.
When the trigger fires, the details of what happened are handed to your script, so it can act on them — the contents of the Slack message, the fields on the new Notion item, the body of the webhook request.
Runs show up in your session history alongside sessions you started yourself. Related events can be grouped into a single ongoing session instead of opening a new one every time, so a busy trigger doesn't flood your history.
## Triggers are part of the script
A trigger isn't a separate thing hanging off your script — it lives inside it, like a block does:
* It appears **in the script**, with its own settings, an on/off switch, and its recent run history.
* It's saved with the script's files.
* So it **travels with the script**. Export the script, import it into another workspace, or share it with a teammate, and its triggers come along.
There's no separate place to keep in sync: change the trigger and the script updates with it.
## Triggers in a shared workspace
Scripts are shared with your workspace, but triggers run **for a person**. So when a teammate opens a shared script, its triggers appear switched **off**, with an **Enable** button.
Turning one on creates their own copy. It runs with their connected accounts and their credits, and it has its own settings and run history.
This is deliberate. A Gmail trigger your teammate enables watches *their* inbox, never yours — and nobody is signed up for someone else's automation just by opening a shared script.
Any member of the workspace can enable a script's triggers. Doing so doesn't change the script or affect anyone else's copy.
Deleting a trigger is a shared change: it removes the trigger from the script and removes **every member's** copy of it. Turning a trigger off only affects your own. See [Managing triggers](/triggers/managing).
## Next steps
Run a script on a recurring cadence.
React to activity in Slack, GitHub, Notion, and more.
Give your script a URL any service — or a form on your website — can call.
Run history, failures, pausing, and limits.
# Schedule triggers
Source: https://docs.script.it/triggers/schedule
Schedule triggers fire your script automatically at a fixed cadence — choose a common interval or write a custom cron expression with timezone support.
A schedule trigger fires your script on a recurring basis without any manual action. You define when it should run — daily, weekly, monthly, or on a custom cadence — and Script.it creates a new session and runs the script each time the schedule fires. Schedule triggers are well-suited for reports, digests, data syncs, and any routine task that belongs on a fixed cadence.
## Setting up a schedule trigger
Open the script you want to schedule. Click the **Triggers** tab, then click **Add Trigger**.
Enter a name for the trigger — something descriptive like "Daily sales report". In the **Trigger Type** dropdown, select **Schedule**.
Use the **How often?** dropdown to pick a preset or write a custom cron expression:
* **Every 30 minutes** — runs twice an hour
* **Every hour** — runs at the start of each hour
* **Every few hours** — choose an interval of 2, 3, 4, 6, 8, or 12 hours
* **Every day at…** — runs once a day at the time you select
* **Every weekday at…** — runs Monday through Friday at the time you select
* **Every week on…** — runs once a week on the day and time you select
* **Every month on…** — runs once a month on the day (1–28) and time you select
* **Advanced (custom cron)** — enter a cron expression directly
The UI shows a plain-English summary of your schedule as you build it (for example, "At 9:00 AM, every day").
The minimum allowed interval is every 30 minutes. Schedules that would fire more frequently than that are not accepted.
Use the **Timezone** picker to choose the timezone your schedule should be interpreted in. By default, this is set to your browser's timezone. If you share a trigger with a team member in another timezone, make sure the timezone is set explicitly so the schedule fires when you expect.
Pick the script to run, and fill in any inputs it needs.
Click **Create Trigger**. The trigger activates immediately and will fire at its next scheduled time.
You can skip the form entirely and describe the schedule in chat: *"Run this every weekday morning at 8 AM."* The agent sets it up for you.
## Cron expression format
When you select **Advanced (custom cron)**, you write a standard five-field cron expression:
```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
minute hour day-of-month month day-of-week
```
Each field accepts a specific set of values:
| Field | Allowed values | Special characters |
| - | - | - |
| Minute | 0–59 | `*` `,` `/` |
| Hour | 0–23 | `*` `,` `/` |
| Day of month | 1–31 | `*` `,` `/` |
| Month | 1–12 | `*` `,` `/` |
| Day of week | 0–6 (0 = Sunday) | `*` `,` `/` `-` |
### Common examples
| Cron expression | When it runs |
| - | - |
| `0 9 * * *` | Every day at 9:00 AM |
| `0 9 * * 1` | Every Monday at 9:00 AM |
| `0 9 * * 1-5` | Every weekday (Mon–Fri) at 9:00 AM |
| `0 */6 * * *` | Every 6 hours |
| `0 9 1 * *` | The 1st of every month at 9:00 AM |
| `*/30 * * * *` | Every 30 minutes |
All cron expressions are evaluated in the timezone you selected. `0 9 * * 1` means Monday at 9:00 AM in your chosen timezone, not UTC — unless you explicitly choose UTC as the timezone.
## What happens when a schedule fires
When a scheduled trigger fires, Script.it runs your script. The run appears in your session history like any other, and if the script produces output files they're available there.
If a scheduled run fails — because the script has an error, say — the trigger stays active and tries again at the next scheduled time. If it fails five times in a row, Script.it pauses it and lets you know. See [Managing triggers](/triggers/managing).
## Turning a schedule off
Use the switch on the trigger in your script to stop it firing without losing its settings, and the same switch to start it again.
Deleting a trigger removes it for everyone in the workspace who had enabled it — see [Managing triggers](/triggers/managing) before you delete a schedule on a shared script.
# Webhook triggers
Source: https://docs.script.it/triggers/webhook
A webhook trigger gives your script its own URL. Anything that can send an HTTP request — your own code, a service like Stripe or GitHub, or a form on your website — can run it, with signature checking on by default.
A webhook trigger is a URL Script.it mints for your script. A `POST` to it runs the script, with the request body as the trigger's payload. How the caller proves itself depends on who it is:
Sign each request with the trigger's secret.
Stripe, Slack, GitHub and others: pick the provider, paste its secret.
No secret in the page — a reCAPTCHA check and your allowed domains instead.
The quickest way to get one is to ask the agent — "run my welcome-email script whenever my order service posts a shipment", or "add a signup form to acme.com that runs my welcome-email script" — and it creates the trigger and hands you the URL, the secret, or the form. The settings are the same whether the agent sets them or you do in the app; see [Settings reference](#settings-reference) and [Setting it up in the app](#setting-it-up-in-the-app).
## The contract
* **URL**: `https://api.script.it/api/webhooks/` (your installation's own API host when self-hosted). The token is minted when the trigger is created and never changes. Turning the trigger off keeps it; deleting the trigger invalidates it.
* **Request**: `POST`, with a JSON body or an `application/x-www-form-urlencoded` body (what a form sends). The body is what your script receives: JSON as sent; a form body as its fields, with a field that appears more than once as a list.
* **Response**: `200` with `{"inbox_id": "…"}` as soon as the request is accepted. The script runs right after, so a slow script never times the sender out. A refused request answers `4xx` with `{"detail": {"code": "WEBHOOK_INVALID", "reason": "", "message": "…"}}`; a `429` also carries `Retry-After`. Each section below lists its reasons.
## Signing your requests
Webhook triggers are **signed by default**: Script.it creates a signing secret with the trigger and checks every request against it, so knowing the URL isn't enough to run your script. A signed request carries two headers:
| Header | Value |
| - | - |
| `X-Scriptit-Timestamp` | Unix time in seconds, when the request was made |
| `X-Scriptit-Signature` | `sha256=` followed by the hex HMAC-SHA256 of `"."`, keyed with the signing secret |
The HMAC is computed over the exact body string you send, so sign the serialized body, not an object you serialize again afterwards. A request whose timestamp is more than 5 minutes old is refused, so a captured request can't be replayed later (`max_timestamp_age_seconds` changes the window).
```bash curl theme={"theme":{"light":"github-light","dark":"github-dark"}}
TIMESTAMP=$(date +%s)
BODY='{"order_id": "A-1042", "email": "ada@example.com"}'
SIGNATURE="sha256=$(printf '%s' "$TIMESTAMP.$BODY" | openssl dgst -sha256 -hmac "$SIGNING_SECRET" | cut -d' ' -f2)"
curl -X POST "$WEBHOOK_URL" \
-H "Content-Type: application/json" \
-H "X-Scriptit-Timestamp: $TIMESTAMP" \
-H "X-Scriptit-Signature: $SIGNATURE" \
-d "$BODY"
```
```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import hashlib, hmac, json, os, time, requests
body = json.dumps({"order_id": "A-1042", "email": "ada@example.com"})
timestamp = str(int(time.time()))
signature = "sha256=" + hmac.new(
os.environ["SIGNING_SECRET"].encode(), f"{timestamp}.{body}".encode(), hashlib.sha256
).hexdigest()
requests.post(os.environ["WEBHOOK_URL"], data=body, headers={
"Content-Type": "application/json",
"X-Scriptit-Timestamp": timestamp,
"X-Scriptit-Signature": signature,
})
```
```javascript Node.js theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { createHmac } from "node:crypto";
const body = JSON.stringify({ order_id: "A-1042", email: "ada@example.com" });
const timestamp = String(Math.floor(Date.now() / 1000));
const signature = "sha256=" + createHmac("sha256", process.env.SIGNING_SECRET)
.update(`${timestamp}.${body}`)
.digest("hex");
await fetch(process.env.WEBHOOK_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Scriptit-Timestamp": timestamp,
"X-Scriptit-Signature": signature,
},
body,
});
```
Keep the secret in the sender's environment — never in a web page, a repository, or anything a visitor can read. To **rotate it**, clear the signing secret field in the trigger's settings (or ask the agent): Script.it issues a new one and the URL stays the same, so only the sender needs updating.
A refused signed request answers `400` with the reason `webhook_missing_signature_headers`, `webhook_invalid_signature`, `webhook_invalid_timestamp` or `webhook_timestamp_out_of_range`.
## Provider-signed webhooks
If the calls come from a service that signs its webhooks its own way, set **Provider** on the trigger to that service and paste in the secret it gives you. Script.it then checks each request the way that provider signs it, so you point the service straight at your URL with nothing in between.
Supported providers: Stripe, Slack, GitHub, Shopify, Zoom, HubSpot, Jira, Trello, Asana, Discord, Zendesk, Intercom, Linear, monday.com, SendGrid, Square, Paddle, Figma, Lemon Squeezy, WhatsApp (and the other Meta webhook products) and Telegram bots.
* **Verification handshakes** (Slack, GitHub, Zoom, Asana, Discord, monday.com, WhatsApp) are answered for you. WhatsApp verifies with a token you paste into Meta's dashboard; Script.it shows it after you create the trigger.
* **Square, Trello and HubSpot** sign over the URL as well as the body, so their trigger also needs its own public URL in the **Notification URL** setting.
* **monday.com** signs only the webhooks made through a monday app. A webhook made from monday's UI or API carries no signature, so it needs signature checking off — see [Turning signatures off](#turning-signatures-off).
If the service is one you've already connected to Script.it — Slack, GitHub, Stripe and many more — you usually don't need a webhook trigger at all. An [app event](/triggers/app-events) receives the same events with no URL to set up.
## Calling it from a web page
A form on your own website — a signup form, a contact form, a request form — can post straight to your webhook. A page can't keep a signing secret (anyone can read the page's source), so the form proves itself a different way:
1. The trigger has **Allowed domains** set to the site's domain — `example.com` covers `www.example.com` and every other subdomain; several are separated by commas, and a pasted page URL is reduced to its host (`https://www.example.com/signup` → `www.example.com`) — and **Allow browser requests** turned on. Signature checking stays on for everything else that calls the URL.
2. The page loads reCAPTCHA Enterprise with the site key Script.it gives you (shown with the form in the app, and returned to the agent as `browser_requests_site_key`), and each submission sends the form's fields `application/x-www-form-urlencoded` plus one extra field, `_captcha_token`, holding a token minted for the action `webhook_submit`.
3. Script.it checks the token, that it was minted on a page served from one of the allowed domains, and that it wasn't scored as a bot, then removes `_captcha_token` and runs your script with the remaining fields.
The simplest way to get a working form is to copy it: **Web page form** on the trigger in the app has the URL and site key filled in, and the agent hands you the same form when you ask it for one. It's plain HTML — rename the fields to what you want to collect, style it as you like, and it can appear more than once on a page. Its shape:
```html theme={"theme":{"light":"github-light","dark":"github-dark"}}
```
Visitors' browsers load Google's reCAPTCHA script, so Google sees that a visitor was on your page; the token is the only thing that reaches Script.it, and it's checked and discarded before your script runs.
To keep a public form from being abused, each visitor can submit up to 30 times a minute, and a webhook takes up to 120 submissions a minute and 5,000 a day. A refused submission answers with the reason: `webhook_captcha_required` (`400`, no token in the body), `webhook_captcha_rejected` (`403`, the token was invalid, expired or scored as a bot), `webhook_captcha_domain_not_allowed` (`403`, the page isn't on an allowed domain), `webhook_browser_rate_limited` or `webhook_browser_budget_exhausted` (`429`, with `Retry-After`).
A self-hosted installation decides what a page may do: it can bring its own reCAPTCHA key, allow a form without a captcha for pages that aren't public (an intranet) on triggers with signature checking off, or allow neither — then the page posts to your own server, which signs the request and forwards it. Where a setting isn't allowed, the trigger refuses it with a message that names what the installation does allow.
## Limiting who can call it
An **IP allowlist** on the trigger — individual addresses or CIDR ranges — refuses every request from anywhere else with `webhook_ip_not_allowed` (`403`), including a request whose address can't be determined. It applies on top of signatures and captchas, and it's the one protection left when signatures are off.
### Turning signatures off
You can turn **Require signature** off when the sender can't sign its requests — a webhook made from monday's UI, a tool with no signing option, or a form on a page that isn't public, on a self-hosted installation that allows it.
With signatures off, the URL is the only thing protecting the trigger — anyone who has it can run your script. Treat it like a password: don't share it publicly, commit it to a repository, or put it in client-side code, and add an IP allowlist whenever the sender's addresses are known. If it leaks, delete the trigger and create a new one to get a fresh URL.
Some self-hosted installations don't allow webhooks without a signature. There, the setting can't be turned off, and a webhook that already has it off answers `webhook_signature_required_by_deployment` (`403`) until it's turned back on.
## What your script receives
The request body is the trigger's payload: a JSON body as sent, a form body as its fields (a repeated field as a list). It reaches your script the way every trigger's payload does — as a session file, by default `data_files/trigger_event.json`. See [Trigger payloads](/developers/overview#trigger-payloads).
Runs appear in your session history like any other run, and in the trigger's run history on the script. See [Managing triggers](/triggers/managing).
## Settings reference
A webhook trigger's settings are flat keys. In the app they're the trigger's settings; the agent sets them with `scriptit trigger create webhook --inputs '{…}'` and changes them with `scriptit trigger update --inputs '{…}'`.
| Setting | Default | What it does |
| - | - | - |
| `require_signature` | `true` | Check each request's signature. `false` lets anyone with the URL run the script. |
| `signing_secret` | generated | The secret signatures are checked with. Clear it to rotate; for a provider, paste the provider's secret. |
| `webhook_provider` | `scriptit` | Whose signature scheme to check: `scriptit` for your own code, or a provider preset (`stripe`, `slack`, `github`, …). |
| `ip_allowlist` | none | Addresses or CIDR ranges allowed to call the URL, e.g. `["203.0.113.0/24"]`. |
| `max_timestamp_age_seconds` | `300` | How old a signed request may be (60–3600). |
| `allow_browser_requests` | `false` | Also accept web page form posts that carry a captcha token. Needs `require_signature`, the `scriptit` provider and allowed domains. |
| `browser_allowed_domains` | none | Domains whose pages may post, comma-separated; subdomains included. |
| `notification_url` | none | The trigger's public URL, for providers that sign over it (Square, Trello, HubSpot). |
| `verify_token` | generated | The token a provider's URL-verification handshake checks (WhatsApp). |
## Managing webhook triggers
* **Turn it off and on** from the script. The URL is kept, so turning it back on resumes with the same setup.
* **Delete it** to permanently invalidate the URL. Anything still calling it stops working, and a new trigger gets a different URL.
## Setting it up in the app
### Creating a webhook trigger
Open the script you want to run, click the **Triggers** tab, then click **Add Trigger**.
Give it a name that says where the calls will come from — "Stripe payment received", "Deploy finished" — and choose **Webhook**.
Click **Create Trigger**. Script.it shows you the **webhook URL** and the **signing secret**, with example code for sending a signed request. Copy them — you'll need them to set up the sending service.
Paste the URL into whatever should call it. Most services have a **Send test event** button — use it, and check that the run shows up on your trigger. For a provider's own signing, set **Provider** and **Signing secret** in the trigger's settings first.
### Adding a web page form
Open the trigger's settings and enter your site's domain under **Allowed domains**.
Check **Allow browser requests**.
Open **Web page form** on the trigger, copy the code, rename the fields to what you want to collect, and paste it into your page.
Fill the form in on your live page and check that the run shows up on the trigger.