checkly deploy command deploys all your checks and associated resources like alert channels to your Checkly account. This command synchronizes your local monitoring-as-code configuration with your Checkly account.
Prerequisites
Prerequisites
Before using
checkly deploy, ensure you have:- An initialized Checkly CLI project
- At least one check or resource defined in your project
- Valid Checkly account authentication (run
npx checkly loginif needed) - A
checkly.config.tsorcheckly.config.jsconfiguration file
Usage
The basic command deploys all resources to your Checkly account, synchronizing your local monitoring-as-code configuration with the Checkly monitoring infrastructure.Terminal
How a deploy previews its changes
A deploy works from a plan. Before it writes anything,checkly deploy asks Checkly what the deploy would change and shows you the plan. It prints the full preview (the overview of every resource it would create, update or delete, with the unchanged ones counted, and a diff of every updated resource) and then asks whether to apply the changes or cancel. While the plan is being checked nothing is uploaded, so cancelling at the prompt leaves your account untouched. In agent or CI environments the plan is returned as a confirmation_required envelope instead (see Deleting vs. detaching removed resources).
--no-plan deploys without a plan: every resource your project declares is written, whether or not it changed, and the ones you removed from your code are deleted; see --[no-]plan. The rest of this section describes a deploy with a plan.--dry-run envelope mark it as changed in Checkly, while the construct diff simply shows your account’s current value on the deployed side. In a terminal you can instead have the CLI update your code with that edit.
--preview and --output print the plan as an overview of every resource the deploy touches, followed by a diff per updated resource. Each row in the overview carries a marker, the construct type, the logical ID and either the source file or a note saying what happens to the resource:
+create,~update,-delete. A deleted resource is notedpermanently deleted, run history lost.-withkept in your Checkly account, now managed from the Checkly web appfor a resource removed from code that--preserve-resourcesdetaches instead of deleting.-on a relation withrelation on Check <id> not managed by this project, deleted by --prune-relations(orCheckGroup), naming the check or group it hangs off, and!on a check or group that has such relations when--prune-relationsis not passed.·withskipped (testOnly)for checks markedtestOnly: true, which are never deployed.- A closing
N unchangedrow counting the resources the deploy leaves alone.
--no-plan the overview has the same markers, but no source file column, no unchanged row and no diffs: every resource that exists is listed as an update, and the totals line always reads 0 unchanged.
Under the overview, every updated resource gets a header line with its type, logical ID and source file, followed by a diff of the construct as it is in your account against the construct in your code. A legend under the header says what the two sides are: - lines are what is live in Checkly, replaced or removed by this deploy; + lines are what is in your code, added or changed by this deploy. Everything else is context, and ⋯ marks skipped lines. A - line with no + line after it is a value your code no longer sets, which the deploy removes. Once the deploy is done, the legend reads was live in Checkly and now live in Checkly instead. Both sides are rendered the way checkly import writes a construct, which leaves out a property whose value is its default. The properties your code spells out are the exception: they are shown on both sides whatever their values, so a move to or from a default reads as a change of that one line. Other constructs are referred to by the names your code gives them. Both need the CLI to find the construct’s new …('id', { … }) call in your code; options passed in a variable or spread into the call keep the import rendering. Facts a diff cannot show are printed as ~ notes:
- The property’s path, such as
/script:, followed by a diff of two texts rather than of the construct, for a change that lives outside it: a browser or multi-step check’s script, an API check’s setup or teardown script. - A property Checkly stores encrypted, such as a locked environment variable, is shown inline with its value masked as
'********'. The side that changed reads'******** (changed)', or'******** (changed in Checkly)'on the deployed side. When the change cannot be shown inline, for example a secret that was renamed, the notesecret changed: <property>names the property holding it instead. changed: <what>, such aschanged: code bundleorchanged: dependency cache, playwright version, naming every cause in one note, for a change the plan reports by its cause rather than as a property: what the resource bundles or depends on, a setup or teardown snippet, its snapshots, its private locations.payload format changed (CLI upgrade)when the only differences come from a newer CLI describing the same construct differently, such as a private location list or retry strategy being sent in a new form. The deploy rewrites the stored form and nothing about the resource changes.- A plain list of the changed properties when the CLI cannot render the resource as a construct.
--output prints the same overview and diffs for what was done, with the totals in the past tense.
Every plan comes with a plan token that pins the account state it was computed against, so a deploy cannot silently apply to an account that changed in the meantime. See --plan-token.
With a plan, resources that did not change are not written at all. Deploying the same code twice finds nothing to apply the second time.
When a plan has nothing to create, update, delete or detach and no relation to prune, there is nothing to review, so the deploy asks for no confirmation, in a terminal and in agent or CI environments alike. It prints No changes. with the number of resources that match your code in place of the overview, and completes:
Terminal
--no-schedule-on-deploy, and clears the mark the Checkly web app puts on a resource that was edited outside your code once your code agrees with that edit. Rows that announce no write are still listed above the sentence: a ! row for a check or group with relations the project does not manage, and a · row for a testOnly check. --preview prints the same sentence without a plan token, since there is no plan to pin, and --dry-run prints its envelope as usual.
The first plan of a project
The first plannedcheckly deploy of an existing project has no earlier planned deploy to compare with. The same goes for the first deploy after one that did not plan, whether a deploy with --no-plan or one by an earlier major version of the CLI that did not pass --plan: it wrote every resource and recorded nothing to compare against. Such a deploy updates every resource it already deployed once to set a baseline: the plan compares your code with what is live in Checkly, lists each of those resources as an update whether or not anything differs, and counts them in a note under the overview.
Terminal
--no-plan, that is a resource added to the project with checkly import, which has no earlier plan to compare with either, and a baseline that a Checkly update made unusable.
Such a plan is applied like any other: it has resources to write, so the deploy asks for confirmation, and in agent or CI environments the confirmation_required envelope lists them as updates, summing up the rest of a long plan as usual.
A deploy with --no-plan in between starts this over for the resources it wrote, so a project gets the most out of plans when no deploy passes it.
The machine-readable plan marks each of these entries with "basis": "live", so a script reading the --dry-run or confirmation_required envelope can tell them apart.
Updating your code with changes made in Checkly
When the plan shows a resource that was edited in the Checkly web app or through the API, and the edit is on a property the CLI can write into your code, the prompt gets a third choice next to applying and cancelling:Terminal
git diff and run checkly deploy again. Only what can be written without guessing is written, so a reason found once the file is read (listed below) can still leave nothing to write:
- On every check:
name,description,activated,muted,shouldFail,tags,locations,frequencyandalertEscalationPolicy;retryStrategyon every check except agentic and Playwright checks, which do not take one. AlsodegradedResponseTimeandmaxResponseTimeon API checks and URL, TCP, DNS, gRPC, SSL and traceroute monitors; the packet-loss thresholds on ICMP monitors;periodandgraceon heartbeat monitors, each written together with its unit;environmentVariablesandruntimeIdon API, browser, multistep and Playwright checks (a check that relied on the project-wide runtime gets the value pinned, like any other defaulted property);sslCheckDomainandaiAutoRepairEnabledon browser checks andaiAutoRepairEnabledon multistep checks;prompton agentic checks (a multi-line prompt written as a template literal stays one); therequestof an API check (url,method,headers,queryParameters,body,bodyType,basicAuth,followRedirects,skipSSL,ipFamily), URL monitor (url,followRedirects,skipSSL,ipFamily), TCP monitor (hostname,port,data,ipFamily), DNS monitor (query,recordType,protocol, andnameServerandport, written together), ICMP monitor (hostname,pingCount,ipFamily), gRPC monitor (url,port,skipSSL,timeout,ipFamilyand thegrpcConfigkeys, exceptmetadata, whose values Checkly never returns), SSL monitor (hostname,port,ipFamilyand thesslConfigkeys) or traceroute monitor (every key); and therequest.assertionsof an API check and of every URL, TCP, DNS, gRPC, SSL, ICMP and traceroute monitor. Agentic checks take noshouldFail. - On a check group:
name,activated,muted,tags,locations,concurrency,environmentVariables,runtimeId,retryStrategy,alertEscalationPolicy, andapiCheckDefaults(url,headers,queryParameters,basicAuth,assertions). - On every alert channel:
sendRecovery,sendFailure,sendDegraded,sslExpiryandsslExpiryThreshold, plus the channel’s own properties:addresson an email channel;channelon a Slack channel;slackChannelson a Slack app channel;name,webhookType,templateandmethodon a webhook channel;name,regionandpriorityon an Opsgenie channel;accountandserviceNameon a PagerDuty channel;phoneNumberandnameon an SMS or phone call channel;nameandpayloadon an MS Teams or incident.io channel;nameon a Telegram channel. A credential (a webhook or Slack URL, an API key, a service key, a webhook secret, the values ofheadersandqueryParameters) is never written, since Checkly does not return it; a channel’s type, and the webhook type and method the MS Teams, Telegram and incident.io constructs fix, cannot change in the code; Telegram’schatId,messageThreadId,payloadandapiKeyare packed into the message template and URL, which the CLI does not unpack. - On a private location:
name,slugNameandicon(proxyUrlis never written). - On a dashboard: every property except
customCSS, which is a stylesheet rather than a value;tagsis written whole. - On a maintenance window:
name,timezone,pauseAllChecks,silenceAllAlerts,tags,silenceAlertsTags,startsAtandendsAt(written asnew Date('…')from the timestamp Checkly reports, over an existingnew Date(…)or a string), andrepeatInterval,repeatUnitandrepeatEndsAt, which are written together or not at all. - On a status page:
name,url,customDomain,logo,redirectTo,faviconanddefaultTheme, and on aStatusPageV3alsologoDark,description,privacyPolicyLink,termsOfServiceLink,supportLink,footerText,googleAnalyticsTag,allowIndexingand each colour ofthemeColors(a colour underlightordarkis added only when your code already has that object). Thecardsof aStatusPagehold services and are not written. - On a status page service:
name. On aStatusPageV3Component:type,name,description,hidden,displayOrder,showHistoricalDataandexpandedByDefault(its page and parent are references). On aStatusPageV3AutomationRule:name,enabled,firstUpdate,lastUpdate,notifySubscribers,tagsandcoolDownMinutes(its page and components are references). - The construct has to be declared as
new ApiCheck('logical-id', { … })in a JavaScript or TypeScript file, with the class imported by name fromcheckly/constructsor destructured from a top-levelrequireof it (a namespace import or a re-export from your own module is not recognised) and its options written out as an object literal. An existing value is replaced only when it is itself a literal (a string, number or boolean, or an array or object of those) or, for the properties below, an expression on the same helper whose arguments are literals; a property the code does not set is added after the last one of the object that holds it (requestitself has to exist forrequest.bodyto be added), in the file’s own quoting and indentation. Nothing else in the file is touched. The file searched is the one the CLI was loading when the construct was created, so a construct declared in a module that several files import (a common layout for alert channels and status pages) is looked for in the first file that imported it, where the lookup fails and the construct is listed as not updated. frequency,retryStrategy,alertEscalationPolicyandassertionsare written the waycheckly importspells them:Frequency.EVERY_30S(a whole-minute schedule stays a number where your code uses one),RetryStrategyBuilder.fixedStrategy({ maxRetries: 3 }),AlertEscalationBuilder.runBasedEscalation(3, …),AssertionBuilder.statusCode().equals(200)and the corresponding builder of each monitor type. A helper the file does not import yet is added to itsimport { … } from 'checkly/constructs'(or to itsconst { … } = require('checkly/constructs')), which the output reports as well. A check group of theCheckGroupV2class moved to the global alert policy getsalertEscalationPolicy: 'global'.
replaced a local edit; a list such as tags or assertions that your code changed too is left alone instead, since the CLI cannot merge the two. Every change that cannot be written is listed under Not updated · edit these by hand, per resource, with its reason; the usual ones are a reference to another resource (alert channels, private locations, a group, a status page’s services, components or parent), an incident trigger (Checkly does not report its settings), a secret or a locked variable that Checkly does not return, a script or code bundle, doubleCheck (replaced by retryStrategy; not listed when the retry strategy itself was written) and runParallel, the offset of a whole-minute schedule (Checkly assigns it), a property your code also changed, a helper call holding a variable, a check or a CheckGroup on the global alert policy or a group without a policy of its own (remove alertEscalationPolicy by hand; nothing is ever removed from your code), a retry strategy, alert policy or assertion this CLI version cannot spell, a helper name your file already uses for something else, a file with no checkly/constructs import to add a helper to, options built from a variable or a spread, or a construct the CLI cannot locate in the file (its id is computed, two constructs share it, or it is declared in a module several files import). TypeScript and JSX files need typescript installed in the project, as TypeScript check files already do.
The CLI then prints what it wrote in the layout of the plan: a header per resource with its construct, logical ID and file, and under it a diff of the construct’s source as it was against as it is now, followed by ~ notes for each helper it imported and each local edit it replaced.
Terminal
checkly import uses, so the diff can show more lines than the one value that changed when your formatting differs from it.
There is no flag for the choice, and the confirmation_required envelope does not change.
When Checkly cannot provide a plan, the CLI warns that it could not get one, for example
Could not check what this deploy would change or Checkly has deploy plans switched off at the moment, and deploys without one, which is what a deploy with --no-plan does on purpose. Without a plan, a deploy that deletes removed resources finds them with a dry run and lists them in the confirmation; with --preserve-resources nothing is listed. Either way the code bundle is uploaded only after you confirm. --plan-token and --prune-relations need a plan and are refused without one.Command Options
boolean
A deploy waits for a deployment of the same project that is still in progress. When that wait runs out, the CLI reports
A deployment for this project is still in progress. Pass this flag to cancel the running deployment and deploy now instead of waiting.Usage:Terminal
string
Specify a configuration file to use instead of the
checkly.config.ts or checkly.config.js in the current directory.Usage:Terminal
boolean
Print what the deploy would do as a JSON envelope and exit without deploying. The envelope carries every resource in the plan, unchanged ones included and, for each updated one, the changed properties with their values before and after, together with the plan token. A value longer than 256 characters (a script, a request body) is replaced by an
$omitted marker carrying its length. A sensitive value is a { "$masked": "same" | "changed" } marker, changed on the element whose secret moved. A change is flagged secret: true when a secret moved or when a sensitive list element has no counterpart on the other side (added, removed or renamed), in which case no marker reads changed and the list itself shows the difference. The deployed state itself is not included. Useful for scripts and agents that want to inspect a deploy before running it with --plan-token. With --no-plan, the envelope lists only the deploy’s options and the resources it would delete.Usage:Terminal
boolean
Skip the interactive confirmation dialog and proceed with the operation.Use Examples
--force to set up automated CI/CD pipelines testing preview environments and deploying monitoring changes automatically. A forced deploy still computes the plan; if the account changes while the code bundle is uploading, it plans again and deploys the current plan rather than failing the pipeline. A run pinned with --plan-token is refused instead, even with --force.Usage:Terminal
Terminal
boolean
Show the changes after deploying, in the same layout as Examples:
--preview. The output includes the diff of every updated resource and counts the unchanged ones; with --no-plan, every resource that already existed is listed as updated instead.Usage:Terminal
Terminal
boolean
default:"true"
Plan the deploy before running it, and deploy that plan. The plan compares every resource in your code, property by property, with what the project last deployed and with its current state in your account. The deploy then writes only the resources that differ, leaves the others alone, and refuses to run if your account changed after the plan you confirmed or pinned with
--plan-token was made; a forced deploy plans again instead. See How a deploy previews its changes.Pass --no-plan to deploy without a plan: every resource the project declares is written, and an edit made to one of them in the Checkly web app or through the API is overwritten without being reported. That is how a deploy ran in earlier major versions of the CLI unless it passed --plan. The next planned deploy then sets a baseline again for the resources it wrote.If Checkly cannot provide a plan, the CLI says so and deploys without one, unless the run also passed --plan-token or --prune-relations, in which case nothing is deployed.Usage:Terminal
string
Deploy exactly the plan an earlier
checkly deploy --preview or --dry-run showed. The token is a fingerprint of your account’s state at that time; if anything changed since, the deploy refuses and nothing is deployed, instead of overwriting an edit nobody reviewed. Run checkly deploy --preview again to see the current plan and get a fresh token. Not available with --no-plan.Usage:Terminal
boolean
Show a preview of the changes that would be made by the deploy command, without deploying. Every updated resource is printed with a diff of its construct as it is in your account against as it is in your code, and the plan token is printed at the end. With ExamplesThe lines printed under an updated resource are described in How a deploy previews its changes.
--no-plan, every resource that already exists is listed as an update, without a diff.Usage:Terminal
Terminal
boolean
When a resource is removed from your code, In the deploy output, a detached resource keeps its
checkly deploy deletes it from your account by default, which also permanently deletes its run history. Pass --preserve-resources to detach those resources instead: the project stops managing them, but the resources and their run history remain in your Checkly account as regular account-level resources. Detached resources can be re-attached later by adding them back to your code.This mirrors checkly destroy --preserve-resources, but applies per-deploy to only the resources removed in that deploy rather than the whole project.Usage:Terminal
- marker but is noted kept in your Checkly account, now managed from the Checkly web app instead of being reported as deleted; see Deleting vs. detaching removed resources.boolean
Alert channel subscriptions and private location assignments can be added to a check or group from the Checkly web app, outside your code. A deploy leaves those alone and reports them as relations the project does not manage. Pass
--prune-relations to delete them, so the check or group ends up with exactly the alert channels and private locations your code declares. Not available with --no-plan: the plan is what finds those relations and lists them before anything is deleted.Without the flag, a check or group whose only reported change is such a relation gets a ! row noted has alert channels or private locations this project does not manage (pass --prune-relations to delete them). With it, every relation to be deleted gets its own - row noted relation on Check <id> not managed by this project, deleted by --prune-relations (or CheckGroup), and is named in the confirmation, so you can see what goes before it does.Usage:Terminal
boolean
default:"true"
Checks are scheduled to run as soon as they are deployed. Pass Checks that run more often than the minimum frequency are not scheduled, and a deploy with more checks than the scheduling threshold schedules none of them, even with
--no-schedule-on-deploy to deploy them without scheduling, which is useful when you want to deploy changes but delay monitoring execution until later.Usage:Terminal
--schedule-on-deploy. See --schedule-on-deploy-min-frequency and --schedule-on-deploy-threshold.number | auto
default:"auto"
The most checks a deploy may schedule to run right after it is deployed, not counting the ones When Checkly does not schedule the checks of a deploy that asked for it, the CLI prints a warning saying so.
--schedule-on-deploy-min-frequency leaves out. A deploy with more checks than this schedules none of them, as if it were run with --no-schedule-on-deploy; the checks run at their next scheduled time instead. Heartbeat monitors are not counted, since they are never scheduled.With auto, Checkly applies its default threshold of 500 checks. You can set any whole number up to 2000; a higher value fails the deploy.Usage:Terminal
number | auto
default:"auto"
After the deploy, schedule only the checks that run every N minutes or less often. More frequent checks are left out and run at their next scheduled time; they gain little from an extra run right after a deploy.The frequency is the one Checkly resolves for each check, including its defaults: an SSL or traceroute monitor without an explicit frequency runs every minute, so the default minimum leaves it out. Sub-minute checks count as running more often than every minute. Heartbeat monitors are never scheduled.With
auto, Checkly applies its default minimum of 10 minutes. You can set any whole number up to 1440; a higher value fails the deploy. 0 schedules every check.When the minimum leaves checks out, the deploy says how many.Usage:Terminal
boolean
default:"true"
Return an error if checks import dependencies that are not supported by the selected runtime.Usage:Runtime-dependent checks run in a specific runtime with a pre-defined set of dependencies. If you’re using private locations and want to provide your own dependencies, disable the built-in dependency validation.
Terminal
boolean
Show the name and the ID of every created and updated resource in the deploy output. Implies
--output, so the changes are printed after the deploy, with their diffs unless run with --no-plan.Usage:Terminal
Deleting vs. detaching removed resources
When you remove a resource from your code and deploy, the CLI reconciles your account with your local configuration. By default, resources that no longer exist in code are deleted from your account, which also permanently deletes their run history. A non-forcedcheckly deploy shows you the whole plan, with the same overview and diffs as --preview but without the Deploy exactly this plan line since this run already pins the token, and asks you to apply it (with --no-plan, it lists the resources it is about to delete and asks you to confirm):
Terminal
--force (for CI/CD), and when a plan has nothing to apply. In agent or CI environments the CLI instead returns a confirmation_required JSON envelope and exits with code 2 rather than prompting. The envelope carries the plan and its token, and names the command that deploys that exact plan; with --no-plan it lists the deploy’s options and the resources it would delete. Its changes list deletions and detachments in full and created and updated resources up to 20, with the rest counted; the --dry-run envelope is capped the same way, while the preview.diff both carry is not.
To keep removed resources and their run history, deploy with --preserve-resources. Instead of deleting them, the CLI detaches them — they remain in your Checkly account as regular account-level resources, managed from the UI, and can be re-attached later by adding them back to your code:
Terminal
Detach-on-deploy requires a recent Checkly backend. Against older backends,
--preserve-resources still keeps your resources, but the deploy output may report them as permanently deleted rather than as kept in your account.Git Integration
When you deploy a project, you can attach Git-specific information so changes to any resources are displayed in the Checkly web UI with the correct commit, branch, and author information. The Checkly CLI evaluates Git information from your local or CI environment on a best effort basis. Override any automatically detected values by setting the corresponding environment variables.Related Commands
checkly login- Log in to your Checkly accountcheckly test- Test your setup before deployment