<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Checkly Blog: Monitoring Insights & Trends]]></title><description><![CDATA[Learn about the latest tips, tricks & how-to articles on advanced synthetic monitoring, Playwright & Monitoring as Code trends.]]></description><link>https://www.checklyhq.com/blog</link><image><url>https://www.checklyhq.com/favicon-32x32.png</url><title>Checkly Blog: Monitoring Insights &amp; Trends</title><link>https://www.checklyhq.com/blog</link></image><generator>RSS for Node</generator><lastBuildDate>Mon, 27 Jul 2026 15:44:11 GMT</lastBuildDate><atom:link href="https://www.checklyhq.com/blog/rss" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How Upstash Monitors Every Redis Replica with Checkly]]></title><description><![CDATA[How Upstash monitors uptime for every Redis replica: Checkly URL monitors in Terraform, checks from 18 global locations, and an end-to-end QStash check.]]></description><link>https://www.checklyhq.com/blog/how-upstash-monitors-every-redis-replica-with-checkly</link><guid isPermaLink="false">ak-6fhIAACcAHlWJ</guid><category><![CDATA[Monitoring as Code (MaC)]]></category><category><![CDATA[Terraform]]></category><category><![CDATA[Uptime Monitoring]]></category><dc:creator><![CDATA[Ilter Kavlak]]></dc:creator><pubDate>Fri, 10 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;p&gt;&lt;em&gt;This is a guest post by Ilter Kavlak, Site Reliability Engineer at Upstash. It&amp;#x27;s a companion to &lt;a target=&quot;_blank&quot; href=&quot;https://upstash.com/blog/how-upstash-monitors-uptime&quot; rel=&quot;noreferrer&quot;&gt;his post on the Upstash blog&lt;/a&gt;, which covers the internal side of the same monitoring stack.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;There&amp;#x27;s a support ticket every SRE dreads: &amp;quot;is something wrong with my database?&amp;quot; The outage is bad enough. Worse is the possibility that the customer knew first.&lt;/p&gt;&lt;p&gt;At Upstash, we treat that scenario as two failures rather than one: the incident itself, and the uptime monitoring gap that let a customer beat us to it. We write a postmortem for the gap, too.&lt;/p&gt;&lt;p&gt;This post is about the layer we built to make sure that never happens: a fleet of Checkly checks that watches our platform from the outside, the way a customer would. One check per replica, running every minute from 18 locations around the world, all of it defined in Terraform. I&amp;#x27;ll walk through what we check, how a failing check reaches a human, and how we monitor a product where &amp;quot;reachable&amp;quot; and &amp;quot;working&amp;quot; are very different claims.&lt;/p&gt;&lt;h2 id=&quot;why-every-replica-gets-its-own-uptime-check&quot;&gt;&lt;a href=&quot;#why-every-replica-gets-its-own-uptime-check&quot;&gt;Why every replica gets its own uptime check&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://upstash.com/redis&quot; rel=&quot;noreferrer&quot;&gt;Upstash Redis&lt;/a&gt; is multitenant and multizone. Every database is backed by at least two replicas, and with the &lt;a target=&quot;_blank&quot; href=&quot;https://upstash.com/docs/redis/overall/enterprise#multi-zone-high-availability&quot; rel=&quot;noreferrer&quot;&gt;Prod Pack&lt;/a&gt; those replicas live in different availability zones. When a replica dies, the survivors elect the most up-to-date among themselves and the database keeps serving; customers notice nothing.&lt;/p&gt;&lt;p&gt;That resilience is exactly what makes replica-level monitoring easy to skip. If your checks only watch the database endpoint, a dead replica is invisible: the endpoint stays green while you quietly run with less redundancy than you promised your customers. And the &lt;em&gt;next&lt;/em&gt; failure is no longer a non-event.&lt;/p&gt;&lt;p&gt;So our rule is blunt. A dead replica is an incident even when no customer can feel it. Every single replica gets its own uptime check, and losing any one of them wakes the oncall.&lt;/p&gt;&lt;h2 id=&quot;a-couple-hundred-url-monitors-all-in-terraform&quot;&gt;&lt;a href=&quot;#a-couple-hundred-url-monitors-all-in-terraform&quot;&gt;A couple hundred URL monitors, all in Terraform&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Because Upstash Redis &lt;a target=&quot;_blank&quot; href=&quot;https://upstash.com/docs/redis/features/restapi&quot; rel=&quot;noreferrer&quot;&gt;speaks HTTP alongside the Redis protocol&lt;/a&gt;, health checking stays simple. No Redis client, no connection pooling, no scripted scenario. Each replica exposes a /ping endpoint over HTTPS, and a 200 means that replica is serving its databases the same way it would serve a real client.&lt;/p&gt;&lt;p&gt;We use &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/detect/uptime-monitoring/url-monitors/overview/&quot; rel=&quot;noreferrer&quot;&gt;Checkly URL monitors&lt;/a&gt; for these, defined in &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/integrations/iac/terraform/overview/&quot; rel=&quot;noreferrer&quot;&gt;Terraform&lt;/a&gt;. Each replica is one module block:&lt;/p&gt;&lt;div class=&quot;code-block theme-light&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;module&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot;check-eu-central-1-r2&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  source &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot;../modules/checkly_url_monitor&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  name              &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot;eu-central-1-r2&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  base_url          &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot;https://&amp;lt;replica-endpoint&amp;gt;.upstash.io/ping&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  frequency_minutes &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  locations         &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;.default_locations&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  alert_channel_ids &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;local&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;.default_alert_channel_ids&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This is &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/concepts/monitoring-as-code/&quot; rel=&quot;noreferrer&quot;&gt;Monitoring as Code&lt;/a&gt;, and it&amp;#x27;s the feature that made us commit to Checkly. Our monitoring configuration lives in the same repository as the rest of our infrastructure, and a single apply deploys or updates the whole fleet. By now, the file reads like a census: one block per replica, a couple of hundred in total, spanning AWS and GCP regions from Tokyo to São Paulo. When a new replica joins a cluster, a new block gets written, reviewed, and applied like any other infrastructure change. No monitor is ever created by clicking around a dashboard; &lt;strong&gt;if it isn&amp;#x27;t in git, it doesn&amp;#x27;t exist in Checkly.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;That discipline would be optional at two checks. At two hundred, it&amp;#x27;s the only way to be sure nobody forgot one.&lt;/p&gt;&lt;p&gt;Redis isn&amp;#x27;t the only product in that file. &lt;a target=&quot;_blank&quot; href=&quot;https://upstash.com/vector&quot; rel=&quot;noreferrer&quot;&gt;Upstash Vector&lt;/a&gt; and &lt;a target=&quot;_blank&quot; href=&quot;https://upstash.com/docs/search/overall/getstarted&quot; rel=&quot;noreferrer&quot;&gt;Search&lt;/a&gt; replicas get the same per-replica treatment, except their checks go beyond a ping: each one upserts a record and runs a query against it, because an index that accepts connections but can&amp;#x27;t answer queries is not &amp;quot;up&amp;quot; in any sense a customer cares about. Keep that idea in mind for the QStash section below.&lt;/p&gt;&lt;h2 id=&quot;from-18-locations-every-minute&quot;&gt;&lt;a href=&quot;#from-18-locations-every-minute&quot;&gt;From 18 locations, every minute&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The hardest-working parameter in that module block is locations. Upstash serves clients globally, with &lt;a target=&quot;_blank&quot; href=&quot;https://upstash.com/docs/redis/features/globaldatabase&quot; rel=&quot;noreferrer&quot;&gt;replicas placed close to their readers&lt;/a&gt;, so a replica answering from one vantage point proves very little. Every monitor runs from all 18 of the &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/concepts/locations/&quot; rel=&quot;noreferrer&quot;&gt;Checkly locations&lt;/a&gt; we&amp;#x27;ve configured, covering North and South America, Europe, Africa, and Asia-Pacific. A routing problem that only affects clients in Singapore is a full outage for a client in Singapore, so our monitoring treats it as one.&lt;/p&gt;&lt;p&gt;Each monitor runs every minute, and a failed request is &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/communicate/alerts/retries/&quot; rel=&quot;noreferrer&quot;&gt;retried after a short backoff&lt;/a&gt; before anything alerts, since a single dropped packet somewhere on the public internet is no reason to wake a human. And we refuse to conflate &lt;em&gt;slow&lt;/em&gt; with &lt;em&gt;down&lt;/em&gt;: a response over five seconds marks the monitor degraded, and past ten it counts as failed. Two different signals, routed two different ways.&lt;/p&gt;&lt;h2 id=&quot;how-a-failing-check-reaches-a-human&quot;&gt;&lt;a href=&quot;#how-a-failing-check-reaches-a-human&quot;&gt;How a failing check reaches a human&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Every monitor is wired to the same set of alert channels, also defined in Terraform:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/integrations/incident-management/opsgenie/&quot; rel=&quot;noreferrer&quot;&gt;&lt;strong&gt;Opsgenie&lt;/strong&gt;&lt;/a&gt; pages the oncall on failure. This is the loud one.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Slack&lt;/strong&gt; receives both failures and recoveries, giving the rest of the team context without waking anyone.&lt;/li&gt;&lt;li&gt;Degraded-state notifications land in a &lt;strong&gt;Slack channel of their own&lt;/strong&gt;. Slowness deserves eyes but not a 3 a.m. page, and it shouldn&amp;#x27;t drown in a busy alerts channel either.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;When a replica check fails, the oncall is looking at it within a couple of minutes, whatever the hour. None of that is remarkable. The habit worth writing down is how incidents &lt;em&gt;end&lt;/em&gt;: we don&amp;#x27;t call anything resolved because internal dashboards look healthy. &lt;strong&gt;Resolved means the Checkly check is green again&lt;/strong&gt;, from all 18 locations. Internal metrics can tell you a process is running; only the external check can tell you a client on the other side of the planet is actually being served. The second claim is the one customers experience, so it&amp;#x27;s the one that closes the incident.&lt;/p&gt;&lt;h2 id=&quot;qstash-proving-messages-actually-get-delivered&quot;&gt;&lt;a href=&quot;#qstash-proving-messages-actually-get-delivered&quot;&gt;QStash: proving messages actually get delivered&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;For &lt;a target=&quot;_blank&quot; href=&quot;https://upstash.com/qstash&quot; rel=&quot;noreferrer&quot;&gt;QStash&lt;/a&gt;, our message queue and task scheduler, a health endpoint would prove almost nothing. QStash exists to &lt;em&gt;deliver messages&lt;/em&gt;; it could happily return a 200 for every publish, deliver none of them, and a ping check would stay green the whole time.&lt;/p&gt;&lt;p&gt;So instead of a ping, QStash gets a &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/detect/synthetic-monitoring/api-checks/overview/&quot; rel=&quot;noreferrer&quot;&gt;Checkly API check&lt;/a&gt; that uses the product the way a customer would. The check publishes a real message through the &lt;a target=&quot;_blank&quot; href=&quot;https://upstash.com/docs/qstash/api-reference/messages/publish-a-message&quot; rel=&quot;noreferrer&quot;&gt;QStash publish API&lt;/a&gt; and points it at an Opsgenie heartbeat endpoint, so every successful delivery resets the heartbeat&amp;#x27;s timer.&lt;/p&gt;&lt;p&gt;One message tests the whole pipeline, and the two ways it can fail are distinguishable:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;The publish fails.&lt;/strong&gt; QStash is unreachable or rejecting requests. The Checkly check turns red and pages the oncall.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The publish succeeds but nothing arrives.&lt;/strong&gt; QStash accepted the request and then failed to deliver it. The heartbeat falls silent, Opsgenie notices the silence, and the page goes out.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Either way a human is investigating within minutes, and the alert already names &lt;em&gt;which half of the flow&lt;/em&gt; broke before anyone opens a dashboard. That&amp;#x27;s a serious head start.&lt;/p&gt;&lt;p&gt;My favorite property of this check is that it&amp;#x27;s indistinguishable from a customer. Same publish API, same delivery path, same retries as real traffic. There is no separate test mode that could pass while production fails.&lt;/p&gt;&lt;h2 id=&quot;what-checkly-doesn-t-cover-on-purpose&quot;&gt;&lt;a href=&quot;#what-checkly-doesn-t-cover-on-purpose&quot;&gt;What Checkly doesn&amp;#x27;t cover, on purpose&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;External checks answer one question: would a customer be served right now, from where they are? Two other layers answer the questions they can&amp;#x27;t.&lt;/p&gt;&lt;p&gt;Internally, a federated Prometheus stack watches the clusters themselves and catches pod-level trouble. And in every region, a fleet of benchmark clients (deployed deliberately outside the clusters they measure) pushes a steady mix of reads and writes around the clock, recording every latency it observes. That fleet is our second, independent paging path, and its historical dashboards are where slow-moving problems like release regressions and noisy neighbors show up as trend lines long before they&amp;#x27;d trip any single alert. Both layers are managed the same way as the Checkly monitors: Terraform modules in the same repository, one workflow for everything. I&amp;#x27;ve written about that side of the stack in detail &lt;a target=&quot;_blank&quot; href=&quot;https://upstash.com/blog/how-upstash-monitors-uptime&quot; rel=&quot;noreferrer&quot;&gt;on the Upstash blog&lt;/a&gt;.&lt;/p&gt;&lt;section class=&quot;theme-light py-10 md:py-12&quot; data-slice-type=&quot;dynamic_data_table&quot; data-slice-variation=&quot;default&quot;&gt;&lt;div class=&quot;overflow-x-auto pb-2 [scrollbar-color:theme(colors.checkly.blue)_theme(colors.gray.100)] [scrollbar-width:thin] [&amp;amp;::-webkit-scrollbar-thumb]:rounded-full [&amp;amp;::-webkit-scrollbar-thumb]:bg-checkly-blue [&amp;amp;::-webkit-scrollbar-track]:rounded-full [&amp;amp;::-webkit-scrollbar-track]:bg-gray-100 [&amp;amp;::-webkit-scrollbar]:h-2&quot;&gt;&lt;table class=&quot;w-full text-left text-sm max-md:text-xs [&amp;amp;_td]:whitespace-nowrap [&amp;amp;_tr:first-child]:font-semibold [&amp;amp;_tr:first-child]:text-checkly-deep-blue&quot;&gt;&lt;tbody&gt;&lt;tr class=&quot;text-gray-500 even:bg-gray-100&quot;&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Layer&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Question it answers&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Who gets woken&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;text-gray-500 even:bg-gray-100&quot;&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Checkly per-replica checks (Redis, Vector, Search)&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Is each replica serving traffic, from every region, right now?&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Oncall&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;text-gray-500 even:bg-gray-100&quot;&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Internal cluster monitoring&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Is the software healthy on the inside?&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Oncall&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;text-gray-500 even:bg-gray-100&quot;&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Continuous latency benchmarks&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Is each replica as fast as it should be?&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Oncall on failure, internal alerts on drift&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;text-gray-500 even:bg-gray-100&quot;&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;QStash end-to-end check&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Does the product do its real job, end to end?&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Oncall, with the broken half already identified&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/section&gt;&lt;p&gt;Every layer exists to cover a blind spot in the others. &lt;strong&gt;But when internal and external monitoring disagree, the external answer wins the argument, because it&amp;#x27;s the only one describing what customers actually experience.&lt;/strong&gt;&lt;/p&gt;&lt;h2 id=&quot;the-philosophy-in-five-sentences&quot;&gt;&lt;a href=&quot;#the-philosophy-in-five-sentences&quot;&gt;The philosophy, in five sentences&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Watch every replica, because redundancy you can&amp;#x27;t verify isn&amp;#x27;t redundancy. Watch from wherever your users actually are. Treat ‘slow’ as its own signal rather than a milder form of down. Test the thing the product promises to do, not just whether it answers. And don&amp;#x27;t declare victory until the outside world agrees.&lt;/p&gt;&lt;p&gt;None of this prevents outages; hardware still fails, zones still have bad days, and the internet remains the internet. What it buys is time and clarity: minutes from failure to a human engaged, an alert that names what broke, and a client&amp;#x27;s-eye definition of &amp;quot;fixed.&amp;quot; The ticket asking &amp;quot;is something wrong?&amp;quot; should only ever get one reply: &amp;quot;yes, we know, and we&amp;#x27;re already on it.&amp;quot;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Upstash runs a couple hundred Checkly monitors, every one of them defined in code. If you want the same workflow, start with &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/concepts/monitoring-as-code/&quot; rel=&quot;noreferrer&quot;&gt;Monitoring as Code&lt;/a&gt;: define your monitors in TypeScript with the &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/cli/&quot; rel=&quot;noreferrer&quot;&gt;Checkly CLI&lt;/a&gt;, or use the &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/integrations/iac/terraform/overview/&quot; rel=&quot;noreferrer&quot;&gt;Terraform provider&lt;/a&gt; like Upstash does. &lt;a target=&quot;_blank&quot; href=&quot;https://app.checklyhq.com/signup/&quot; rel=&quot;noreferrer&quot;&gt;Start monitoring for free&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;]]&gt;</content:encoded></item><item><title><![CDATA[Autoscaling Checkly Private Location Agents in Kubernetes with KEDA]]></title><description><![CDATA[Monitor your Private Location health with Checkly, and autoscale agents with KEDA on live load. Stop guessing at agent capacity.]]></description><link>https://www.checklyhq.com/blog/autoscaling-checkly-agents-with-keda-in-kubernetes</link><guid isPermaLink="false">ZDkQ7BEAACIAiBc2</guid><category><![CDATA[Product]]></category><category><![CDATA[Prometheus]]></category><dc:creator><![CDATA[Edvinas Janusevicius]]></dc:creator><pubDate>Thu, 02 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;p&gt;Monitoring load is not always steady. A team might add a new batch of checks or run several ad hoc tests during a rollout. When that happens, your Private Location agents need to pick up more work at once.&lt;/p&gt;&lt;p&gt;If there aren’t enough agents available during a burst, checks start piling up in the queue, which can delay or disrupt check execution. But solving this by running a high number of agents around the clock has the opposite problem: most of that capacity sits idle until the next busy period.&lt;/p&gt;&lt;p&gt;Autoscaling solves both ends of that problem. You scale agents up when checks queue, scale back down when the burst clears, and stop guessing in between. This guide covers two things that landed together: the new Private Location metrics that show you whether your agents are running efficiently, and the KEDA setup that automatically scales your agent deployment.&lt;/p&gt;&lt;h2 id=&quot;how-do-you-know-if-a-private-location-has-enough-agents-&quot;&gt;&lt;a href=&quot;#how-do-you-know-if-a-private-location-has-enough-agents-&quot;&gt;How do you know if a Private Location has enough agents?&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;You can now monitor Private Location health with Checkly, so capacity stops being a guessing game. &lt;a target=&quot;_blank&quot; href=&quot;https://app.checklyhq.com/accounts/private-locations&quot; rel=&quot;noreferrer&quot;&gt;Open any Private Location in the UI&lt;/a&gt; and you&amp;#x27;ll find three metrics that tell you exactly how your agents are doing:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Queue duration&lt;/strong&gt;: how long check runs wait before an agent picks them up. This is the number to watch. If it creeps up, your agents may be falling behind on work.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Agent count&lt;/strong&gt;: how many agents are currently reporting for the location.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Scheduled check runs&lt;/strong&gt;: how many runs are queued for the location right now.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;These metrics are also available via our &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/integrations/observability/prometheus-v2/#private-location-metrics&quot; rel=&quot;noreferrer&quot;&gt;Prometheus v2 integration&lt;/a&gt;.&lt;/p&gt;&lt;p class=&quot;block-img&quot;&gt;&lt;img src=&quot;https://images.prismic.io/checklyhq/7TFhRN2oaq9W9iPF_DASHBOARD-2-.png?auto=format,compress&quot;/&gt;&lt;/p&gt;&lt;p&gt;Together, these signals help you understand whether your agents are healthy and whether your Private Location has enough capacity. For example, if two agents are reporting but queue duration keeps climbing and scheduled runs are stacking up, you may be under-provisioned. If ten agents are reporting and queue duration stays near zero all day, you may be running more capacity than you need. Those are the two states autoscaling exists to fix, and now you can see which one you&amp;#x27;re in.&lt;/p&gt;&lt;h2 id=&quot;scaling-on-the-right-signal&quot;&gt;&lt;a href=&quot;#scaling-on-the-right-signal&quot;&gt;Scaling on the right signal&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Checkly agents are stateless: they sit in your network, pull scheduled checks from a shared queue, run them, and send the results back. You can add or remove agents freely without losing or duplicating work. That&amp;#x27;s the property that makes scaling safe.&lt;/p&gt;&lt;p class=&quot;block-img&quot;&gt;&lt;img src=&quot;https://prismic-io.s3.amazonaws.com/checklyhq/Y2Y0ZWE2MGUtZmQwOC00NWRkLWEyNjAtODgzOTE2YmYxMjMx_untitled-2022-06-15-1142-1.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;To develop a practical approach to autoscaling, we studied a range of large Private Location setups across customers, including &lt;a target=&quot;_self&quot; href=&quot;https://www.checklyhq.com/case-study/dvag-migrates-to-checkly/&quot; rel=&quot;noreferrer&quot;&gt;DVAG&lt;/a&gt;, &lt;a target=&quot;_self&quot; href=&quot;https://www.checklyhq.com/case-study/modernizing-linkedins-monitoring-infrastructure/&quot; rel=&quot;noreferrer&quot;&gt;LinkedIn&lt;/a&gt;, Sherwin-Williams, and Auto Trader. Looking at how those fleets handle different checks and workloads helped us identify the signal that best reflects a location’s current demand.&lt;/p&gt;&lt;p&gt;For teams running agents on Kubernetes, that signal is &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;checkly_private_location_check_runs&lt;/code&gt;. This gauge reports the number of check runs routed through a Private Location, broken down by state.&lt;/p&gt;&lt;p&gt;Two states matter for capacity:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;queued&lt;/code&gt;: the check run is scheduled, but no agent has picked it up yet.&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;inflight&lt;/code&gt;: an agent is running it right now.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Add those two and you have the total live load on the location, which is the signal you want driving replica count. To use this metric, make sure &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/integrations/observability/prometheus-v2/&quot; rel=&quot;noreferrer&quot;&gt;Prometheus V2 metrics&lt;/a&gt; are enabled for your account.&lt;/p&gt;&lt;p&gt;ℹ️ If your existing KEDA config still uses &lt;/p&gt;&lt;p&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;checkly_private_location_oldest_scheduled_check_run&lt;/code&gt;, consider switching to &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;checkly_private_location_check_runs&lt;/code&gt; with the &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;queued&lt;/code&gt; and &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;inflight&lt;/code&gt; states. The older metric is useful for spotting backlog, but &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;queued&lt;/code&gt; plus &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;inflight&lt;/code&gt; gives KEDA a more direct signal for current load.&lt;/p&gt;&lt;h2 id=&quot;setting-up-keda&quot;&gt;&lt;a href=&quot;#setting-up-keda&quot;&gt;Setting up KEDA&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://keda.sh&quot; rel=&quot;noreferrer&quot;&gt;KEDA&lt;/a&gt; (Kubernetes Event-Driven Autoscaling) reads a Prometheus metric and scales a Kubernetes deployment up or down based on that value. You&amp;#x27;ll need KEDA installed in the cluster, your agents deployed via the &lt;a target=&quot;_blank&quot; href=&quot;https://github.com/checkly/helm-charts/tree/main/charts/agent&quot; rel=&quot;noreferrer&quot;&gt;Checkly agent Helm chart&lt;/a&gt;, and &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/integrations/observability/prometheus-v2/&quot; rel=&quot;noreferrer&quot;&gt;Prometheus V2&lt;/a&gt; enabled for your Checkly account.&lt;/p&gt;&lt;p&gt;Here&amp;#x27;s a &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;ScaledObject&lt;/code&gt; with sensible defaults. Adjust the bounds to your workload:&lt;/p&gt;&lt;div class=&quot;code-block theme-light&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;apiVersion&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;keda.sh/v1alpha1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;ScaledObject&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;metadata&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;checkly-agent-autoscaler&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;spec&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;scaleTargetRef&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;namespace&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;lt;namespace_for_agent_deployment&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;lt;agent_deployment_name&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;minReplicaCount&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;maxReplicaCount&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;10&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;advanced&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;horizontalPodAutoscalerConfig&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;behavior&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;scaleUp&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;          &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;policies&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;            - &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;Pods&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;              &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;              &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;periodSeconds&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;60&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;scaleDown&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;          &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;selectPolicy&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;Min&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;          &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;policies&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;            - &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;Pods&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;              &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;              &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;periodSeconds&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;60&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;triggers&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    - &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;prometheus&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;metadata&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;serverAddress&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;http://prometheus-k8s.monitoring.svc.cluster.local:9090&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;metricName&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;checkly_private_location_check_runs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;threshold&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;query&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;sum(checkly_private_location_check_runs{state=~&amp;quot;queued|inflight&amp;quot;, private_location_slug_name=&amp;quot;&amp;lt;slug&amp;gt;&amp;quot;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The query targets a single Private Location using &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;private_location_slug_name&lt;/code&gt;. If you run multiple Private Locations, create one &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;ScaledObject&lt;/code&gt; for each. Because the slug name is immutable, renaming the location in the UI won’t affect your scaling config.&lt;/p&gt;&lt;p&gt;If you deploy agents with the Helm chart, template the &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;ScaledObject&lt;/code&gt; alongside your chart values. This keeps the autoscaler tied to the agent deployment instead of managing it as a separate manifest.&lt;/p&gt;&lt;p&gt;For a Prometheus instance outside the cluster, add an &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;authenticationRef&lt;/code&gt; that points to a &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;TriggerAuthentication&lt;/code&gt; with the required credentials.&lt;/p&gt;&lt;h2 id=&quot;how-many-pods-will-you-get-&quot;&gt;&lt;a href=&quot;#how-many-pods-will-you-get-&quot;&gt;How many pods will you get?&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Set the &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;threshold&lt;/code&gt; to match your agent &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;JOB_CONCURRENCY&lt;/code&gt;. This defines how many checks one agent pod can process at the same time. With the default &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;JOB_CONCURRENCY&lt;/code&gt; of &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;1&lt;/code&gt;, use &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;threshold: &amp;quot;1&amp;quot;&lt;/code&gt;. That means KEDA will try to keep roughly one queued or in-flight check run per agent pod, within your min and max replica limits.&lt;/p&gt;&lt;p&gt;For example, with &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;minReplicaCount: 2&lt;/code&gt; and &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;maxReplicaCount: 10&lt;/code&gt;:&lt;/p&gt;&lt;section class=&quot;theme-light py-10 md:py-12&quot; data-slice-type=&quot;dynamic_data_table&quot; data-slice-variation=&quot;default&quot;&gt;&lt;div class=&quot;overflow-x-auto pb-2 [scrollbar-color:theme(colors.checkly.blue)_theme(colors.gray.100)] [scrollbar-width:thin] [&amp;amp;::-webkit-scrollbar-thumb]:rounded-full [&amp;amp;::-webkit-scrollbar-thumb]:bg-checkly-blue [&amp;amp;::-webkit-scrollbar-track]:rounded-full [&amp;amp;::-webkit-scrollbar-track]:bg-gray-100 [&amp;amp;::-webkit-scrollbar]:h-2&quot;&gt;&lt;table class=&quot;w-full text-left text-sm max-md:text-xs [&amp;amp;_td]:whitespace-nowrap [&amp;amp;_tr:first-child]:font-semibold [&amp;amp;_tr:first-child]:text-checkly-deep-blue&quot;&gt;&lt;tbody&gt;&lt;tr class=&quot;text-gray-500 even:bg-gray-100&quot;&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Queued + in-flight check runs&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Resulting pods&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;text-gray-500 even:bg-gray-100&quot;&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;0&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;2 (idle floor)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;text-gray-500 even:bg-gray-100&quot;&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;1&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;2&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;text-gray-500 even:bg-gray-100&quot;&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;3&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;3&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;text-gray-500 even:bg-gray-100&quot;&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;7&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;7&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;text-gray-500 even:bg-gray-100&quot;&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;20&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;10 (capped)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/section&gt;&lt;figure class=&quot;my-6&quot;&gt;&lt;video class=&quot;w-full rounded-lg border border-gray-300 border-solid border-opacity-20&quot; autoplay=&quot;&quot; loop=&quot;&quot; controls=&quot;&quot; muted=&quot;&quot; playsinline=&quot;&quot; preload=&quot;auto&quot;&gt;&lt;source src=&quot;https://checklyhq.cdn.prismic.io/checklyhq/a1yAa7wDzbHnJPGP_autoscaling-testing-blog-v6.mp4&quot;/&gt;Your browser does not support the video tag.&lt;/video&gt;&lt;figcaption class=&quot;mt-2 text-center text text-sm&quot;&gt;Autoscaling in action: a burst of checks spikes the queue, the agent count scales from 1 to 11 to clear the backlog, then settles back to a right-sized floor.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;A few rules of thumb for the bounds:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Keep &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;minReplicaCount&lt;/code&gt; at 2 or higher. One agent is a single point of failure, and if it dies your whole location goes dark until a replacement spins up.&lt;/li&gt;&lt;li&gt;Set &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;maxReplicaCount&lt;/code&gt; above your expected peak load, because check runs that pile up past the cap get dropped after the queue&amp;#x27;s six-minute TTL.&lt;/li&gt;&lt;li&gt;Leave &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;threshold&lt;/code&gt; at &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;&amp;quot;1&amp;quot;&lt;/code&gt; unless you&amp;#x27;ve raised &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;JOB_CONCURRENCY&lt;/code&gt;; packing more checks per pod can delay long-running checks.&lt;/li&gt;&lt;li&gt;If you want to scale to zero when a location is completely idle, set &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;minReplicaCount: 0&lt;/code&gt; and tune &lt;a target=&quot;_blank&quot; href=&quot;https://keda.sh/docs/latest/reference/scaledobject-spec/#cooldownperiod&quot; rel=&quot;noreferrer&quot;&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;cooldownPeriod&lt;/code&gt;&lt;/a&gt;, which controls how long KEDA waits after load drops before scaling all the way down.&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;don-t-kill-checks-mid-run&quot;&gt;&lt;a href=&quot;#don-t-kill-checks-mid-run&quot;&gt;Don&amp;#x27;t kill checks mid-run&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Scaling down means evicting pods, and an evicted pod might be running a check. Checkly handles this for you: an in-flight check on a terminating pod gets rerun on another agent after a 300-second timeout, so a scale-down never silently loses a result. To give a pod room to finish its current work before Kubernetes sends &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;SIGKILL&lt;/code&gt;, set &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;terminationGracePeriodSeconds&lt;/code&gt; above that window on the agent pod spec:&lt;/p&gt;&lt;div class=&quot;code-block theme-light&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;spec&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;template&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;spec&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;terminationGracePeriodSeconds&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;330&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Set it to match your longest check type. Most checks finish fast, but Playwright Check Suites can run up to an hour, so bump the grace period accordingly:&lt;/p&gt;&lt;section class=&quot;theme-light py-10 md:py-12&quot; data-slice-type=&quot;dynamic_data_table&quot; data-slice-variation=&quot;default&quot;&gt;&lt;div class=&quot;overflow-x-auto pb-2 [scrollbar-color:theme(colors.checkly.blue)_theme(colors.gray.100)] [scrollbar-width:thin] [&amp;amp;::-webkit-scrollbar-thumb]:rounded-full [&amp;amp;::-webkit-scrollbar-thumb]:bg-checkly-blue [&amp;amp;::-webkit-scrollbar-track]:rounded-full [&amp;amp;::-webkit-scrollbar-track]:bg-gray-100 [&amp;amp;::-webkit-scrollbar]:h-2&quot;&gt;&lt;table class=&quot;w-full text-left text-sm max-md:text-xs [&amp;amp;_td]:whitespace-nowrap [&amp;amp;_tr:first-child]:font-semibold [&amp;amp;_tr:first-child]:text-checkly-deep-blue&quot;&gt;&lt;tbody&gt;&lt;tr class=&quot;text-gray-500 even:bg-gray-100&quot;&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Check type&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Maximum runtime&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;text-gray-500 even:bg-gray-100&quot;&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;API, TCP, DNS, ICMP&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;30 seconds&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;text-gray-500 even:bg-gray-100&quot;&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Browser&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;4 minutes&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;text-gray-500 even:bg-gray-100&quot;&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Multistep&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;4 minutes&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;text-gray-500 even:bg-gray-100&quot;&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Playwright Check Suite&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;60 minutes&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/section&gt;&lt;p&gt;If you run Playwright Check Suites in this location, &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;terminationGracePeriodSeconds&lt;/code&gt; can go as high as 1800.&lt;/p&gt;&lt;h2 id=&quot;what-this-gets-you&quot;&gt;&lt;a href=&quot;#what-this-gets-you&quot;&gt;What this gets you&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Your checks stay reliable under load. When a deploy or a traffic spike floods the queue, agents scale up to clear it instead of letting runs wait. That means faster, more dependable detection from inside your own infrastructure.&lt;/p&gt;&lt;p&gt;You also avoid paying for idle capacity. Rather than keeping enough agents running all day to handle occasional peaks, you can maintain a smaller baseline and scale up only when needed. Across multiple Private Locations, that unused capacity can add up quickly.&lt;/p&gt;&lt;h2 id=&quot;get-started&quot;&gt;&lt;a href=&quot;#get-started&quot;&gt;Get started&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Private Locations are available on Checkly&amp;#x27;s Team and Enterprise plans. If you&amp;#x27;re already running agents on Kubernetes, follow the &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/platform/private-locations/autoscaling/&quot; rel=&quot;noreferrer&quot;&gt;Private Location Autoscaling guide&lt;/a&gt; for the complete setup, including how to verify that KEDA is receiving the metric. Enable &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/integrations/observability/prometheus-v2/&quot; rel=&quot;noreferrer&quot;&gt;Prometheus V2&lt;/a&gt;, apply in the &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;ScaledObject&lt;/code&gt;, and run a batch of checks to see how your agent deployment scales with demand.&lt;/p&gt;&lt;p&gt;Already using Private Locations? Open a location in the Checkly UI to view its queue duration, agent count, and scheduled check runs. These metrics help you quickly identify whether you have too little or too much capacity.&lt;/p&gt;&lt;p&gt;New to Checkly? &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/pricing/&quot; rel=&quot;noreferrer&quot;&gt;See pricing&lt;/a&gt; to find the plan that fits, or &lt;a target=&quot;_blank&quot; href=&quot;https://app.checklyhq.com/signup&quot; rel=&quot;noreferrer&quot;&gt;start for free&lt;/a&gt; to try the rest of the platform.&lt;/p&gt;]]&gt;</content:encoded></item><item><title><![CDATA[Rocky reads your stack, not just your check]]></title><description><![CDATA[Rocky AI root cause analysis now reads OpenTelemetry traces. When a Checkly check fails, Rocky walks the backend span chain to find the root cause.]]></description><link>https://www.checklyhq.com/blog/rocky-ai-opentelemetry-traces</link><guid isPermaLink="false">ah_0pxIAAC4Af59-</guid><category><![CDATA[AI]]></category><category><![CDATA[Announcements]]></category><category><![CDATA[OpenTelemetry]]></category><dc:creator><![CDATA[Stefan Judis]]></dc:creator><pubDate>Thu, 04 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;p&gt;You get an infrastructure alert. Something&amp;#x27;s off, so you task your agent to investigate, and it ends up grepping through the logs. You both wonder if there&amp;#x27;s customer impact.&lt;/p&gt;&lt;p&gt;There’s a simple rule: &lt;strong&gt;AI agents in the incident loop are only as good as the signal you feed them. And logs alone aren&amp;#x27;t a great signal.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Synthetic monitoring at least solves the impact question. When a check fails, something user-facing is broken. You know &lt;em&gt;what&lt;/em&gt; broke, not &lt;em&gt;why&lt;/em&gt;. OpenTelemetry traces have answered that &lt;em&gt;why&lt;/em&gt; for a while, and &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/traces-open-telemetry/&quot; rel=&quot;noreferrer&quot;&gt;Checkly supports them natively&lt;/a&gt;. But there was an unacceptable catch in the agentic world: a human still had to correlate the two by switching tabs, finding the right service, copying a trace ID, and walking the spans. By the time they had an answer, the next check had already run.&lt;/p&gt;&lt;blockquote class=&quot;bg-gray-100 p-4 border-l-2 my-4 border-blue-300 inline-block space-y-4&quot;&gt;&lt;p&gt;&amp;quot;We have a lot of traces collected, but people maybe don&amp;#x27;t know they exist… I think Checkly is a way to integrate traces into developers&amp;#x27; workflow.&amp;quot;&lt;/p&gt;&lt;p&gt;— Observability lead, leading public-safety tech company&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Rocky AI, &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/resolve/ai-root-cause-analysis/overview/&quot; rel=&quot;noreferrer&quot;&gt;Checkly&amp;#x27;s agent&lt;/a&gt;, now does that investigation walk for you. &lt;strong&gt;If a check fails, Rocky reads your OpenTelemetry traces and walks the spans behind the failure.&lt;/strong&gt; When you&amp;#x27;re on call, &amp;quot;Where do I even start looking?&amp;quot; becomes &amp;quot;Let me validate my agent&amp;#x27;s fix!&amp;quot;.&lt;/p&gt;&lt;figure class=&quot;my-6&quot;&gt;&lt;video class=&quot;w-full rounded-lg border border-gray-300 border-solid border-opacity-20&quot; autoplay=&quot;&quot; loop=&quot;&quot; controls=&quot;&quot; muted=&quot;&quot; playsinline=&quot;&quot; preload=&quot;auto&quot;&gt;&lt;source src=&quot;https://checklyhq.cdn.prismic.io/checklyhq/aiFGaQeQX7-eWuVk_RockyOtelRCABlog.mp4&quot;/&gt;Your browser does not support the video tag.&lt;/video&gt;&lt;figcaption class=&quot;mt-2 text-center text text-sm&quot;&gt;Rocky Analysis using OTEL traces&lt;/figcaption&gt;&lt;/figure&gt;&lt;h2 id=&quot;what-rocky-ai-reads-per-check-type&quot;&gt;&lt;a href=&quot;#what-rocky-ai-reads-per-check-type&quot;&gt;What Rocky AI reads, per check type&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Good signal in, good answer out. So Rocky&amp;#x27;s context comes in three layers:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The failure itself (whatever the check type produces: request, response, headers, traceroute, assertions, test source, etc.)&lt;/li&gt;&lt;li&gt;A set of on-demand tools Rocky reaches for when the picture is incomplete (the last passing run, PCAP data for API checks, Playwright trace files for browser failures)&lt;/li&gt;&lt;li&gt;Context provided by a human (the check description field, the tags, the &amp;quot;add context&amp;quot; box in the RCA UI)&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;OTEL traces are the newest tool in that on-demand layer.&lt;/p&gt;&lt;section class=&quot;theme-light py-10 md:py-12&quot; data-slice-type=&quot;dynamic_data_table&quot; data-slice-variation=&quot;default&quot;&gt;&lt;div class=&quot;overflow-x-auto pb-2 [scrollbar-color:theme(colors.checkly.blue)_theme(colors.gray.100)] [scrollbar-width:thin] [&amp;amp;::-webkit-scrollbar-thumb]:rounded-full [&amp;amp;::-webkit-scrollbar-thumb]:bg-checkly-blue [&amp;amp;::-webkit-scrollbar-track]:rounded-full [&amp;amp;::-webkit-scrollbar-track]:bg-gray-100 [&amp;amp;::-webkit-scrollbar]:h-2 [&amp;amp;_td]:text-center [&amp;amp;_th]:text-center&quot;&gt;&lt;table class=&quot;w-full text-left text-sm max-md:text-xs [&amp;amp;_td]:whitespace-nowrap [&amp;amp;_tr:first-child]:font-semibold [&amp;amp;_tr:first-child]:text-checkly-deep-blue&quot;&gt;&lt;tbody&gt;&lt;tr class=&quot;text-gray-500 even:bg-gray-100&quot;&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Source&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;API&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Playwright&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Browser&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;MultiStep&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;DNS&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;TCP&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;ICMP&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Notes&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;text-gray-500 even:bg-gray-100&quot;&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Check Result Payload&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;text-gray-500 even:bg-gray-100&quot;&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Check Description&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Description context&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;text-gray-500 even:bg-gray-100&quot;&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;User Context&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;UI text box&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;text-gray-500 even:bg-gray-100&quot;&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Tags&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Tag names&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;text-gray-500 even:bg-gray-100&quot;&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Last Passing Result&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;On-demand tool&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;text-gray-500 even:bg-gray-100&quot;&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;OTEL traces (new!)&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;On-demand tool&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;text-gray-500 even:bg-gray-100&quot;&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;PCAP&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;-&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;-&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;-&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;-&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;-&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;-&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;API-Checks only&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;text-gray-500 even:bg-gray-100&quot;&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;Playwright Trace&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;-&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;✅&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;-&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;-&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;-&lt;/p&gt;&lt;/td&gt;&lt;td class=&quot;px-5 py-4 first:font-semibold first:text-checkly-deep-blue&quot;&gt;&lt;p&gt;On-demand tool&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/section&gt;&lt;h2 id=&quot;what-rocky-ai-does-with-otel-traces&quot;&gt;&lt;a href=&quot;#what-rocky-ai-does-with-otel-traces&quot;&gt;What Rocky AI does with OTEL traces&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Once you set up traces, every check Checkly runs injects a W3C &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;traceparent&lt;/code&gt; header (tagged &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;tracestate: checkly=true&lt;/code&gt;) on its outgoing requests. Your backend&amp;#x27;s OpenTelemetry instrumentation continues that same trace, so your spans share the trace ID Checkly generated. When those traces are sent back to Checkly, it stitches them to the originating check run by trace ID. That&amp;#x27;s what puts your backend traces right alongside a failing check, giving Rocky the evidence to pinpoint the root cause.&lt;/p&gt;&lt;p&gt;A 500 error on an API or Playwright check might trace back to a downstream identity provider returning DNS errors, a Clickhouse server timing out, or a third-party payment API throwing 502s through your load balancer. The same check failure could have countless reasons, different stories in the spans, and multiple teams that own the fix.&lt;/p&gt;&lt;p class=&quot;block-img&quot;&gt;&lt;img src=&quot;https://images.prismic.io/checklyhq/ah_-aweQX7-eWpn3_otel.png?auto=format,compress&quot;/&gt;&lt;/p&gt;&lt;p&gt;Rocky classifies (&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;INFRASTRUCTURE_ERROR&lt;/code&gt;, &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;DOWNSTREAM_DEPENDENCY&lt;/code&gt;), names the offending service, and writes a root cause, user impact, and suggested fix. It all lands in whatever alert channel you already use, Slack, PagerDuty, a webhook.&lt;/p&gt;&lt;p&gt;There&amp;#x27;s no separate add-on. If &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/resolve/traces/import/open-telemetry/&quot; rel=&quot;noreferrer&quot;&gt;your traces are flowing into Checkly&lt;/a&gt;, Rocky reads them.&lt;/p&gt;&lt;p&gt;Remember the agent you tasked at the top of this post? The one grepping logs? It can read this analysis too.&lt;/p&gt;&lt;h2 id=&quot;the-same-root-cause-analysis-for-your-coding-agent&quot;&gt;&lt;a href=&quot;#the-same-root-cause-analysis-for-your-coding-agent&quot;&gt;The same root cause analysis, for your coding agent&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Rocky&amp;#x27;s analysis &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/blog/rocky-ai-cli-and-public-api/&quot; rel=&quot;noreferrer&quot;&gt;is also available via the Checkly CLI&lt;/a&gt;, and who loves using CLI tools? Your agent!&lt;/p&gt;&lt;p&gt;Make sure to install the &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/ai/skills/&quot; rel=&quot;noreferrer&quot;&gt;Checkly skills&lt;/a&gt;, point your coding agent at a failing check, and ask it to investigate. It picks up the right CLI commands on its own and reads the same classification, root cause, user impact, and suggested fix. Including, when it&amp;#x27;s available, the OTEL trace Rocky walked.&lt;/p&gt;&lt;figure class=&quot;my-6&quot;&gt;&lt;video class=&quot;w-full rounded-lg border border-gray-300 border-solid border-opacity-20&quot; autoplay=&quot;&quot; loop=&quot;&quot; controls=&quot;&quot; muted=&quot;&quot; playsinline=&quot;&quot; preload=&quot;auto&quot;&gt;&lt;source src=&quot;https://checklyhq.cdn.prismic.io/checklyhq/aiFM4AeQX7-eWuZ0_rocky-otel-chat.mp4&quot;/&gt;Your browser does not support the video tag.&lt;/video&gt;&lt;figcaption class=&quot;mt-2 text-center text text-sm&quot;&gt;Agent Conversation using Rocky&amp;#x27;s Root Cause Analysis&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;That&amp;#x27;s &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/blog/the-agentic-software-layer/&quot; rel=&quot;noreferrer&quot;&gt;the agentic layer&lt;/a&gt; in action. There&amp;#x27;s no magic. Just CLI commands and agents helping each other out with good signal. And what about you?&lt;/p&gt;&lt;p&gt;You don&amp;#x27;t need to post screenshots into Slack threads, or investigate by hand. You&amp;#x27;re only in charge of validating the fix! Welcome to the new world.&lt;/p&gt;&lt;h2 id=&quot;wire-up-otel-and-inspect-the-why&quot;&gt;&lt;a href=&quot;#wire-up-otel-and-inspect-the-why&quot;&gt;Wire up OTEL and inspect the &lt;em&gt;why&lt;/em&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;If you&amp;#x27;re already on Checkly with OTEL flowing in, Rocky is already walking those traces. Enjoy! Open a failing check and read the analysis.&lt;/p&gt;&lt;p&gt;If you&amp;#x27;re not yet sending traces to Checkly, the &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/resolve/traces/how-it-works/&quot; rel=&quot;noreferrer&quot;&gt;setup docs&lt;/a&gt; get you there.&lt;/p&gt;&lt;p&gt;Without traces, Rocky&amp;#x27;s intelligence stops at the border of your app. With them, your check failures come with the &lt;em&gt;why&lt;/em&gt; attached so you can stop hunting for it. And your agent will happily stop grepping logs. Win-win!&lt;/p&gt;]]&gt;</content:encoded></item><item><title><![CDATA[Two AI agents, one incident: Rocky AI comes to the terminal]]></title><description><![CDATA[Rocky AI analysis is now in your Checkly CLI and behind a public API. Pull root cause analysis straight from `checkly checks get` to get your agents context to fix failed checks faster]]></description><link>https://www.checklyhq.com/blog/rocky-ai-cli-and-public-api</link><guid isPermaLink="false">ae97rRoAAEQAoHhx</guid><category><![CDATA[AI]]></category><category><![CDATA[Announcements]]></category><category><![CDATA[Monitoring as Code (MaC)]]></category><dc:creator><![CDATA[Stefan Judis]]></dc:creator><pubDate>Wed, 29 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;p&gt;A Playwright Check fails at 2 am. The login flow is broken. Until today, that alert triggered a human to get up, open the Checkly dashboard, copy &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/resolve/ai-root-cause-analysis/overview/&quot; rel=&quot;noreferrer&quot;&gt;Rocky AI root cause analysis (RCA)&lt;/a&gt;, and then tell an agent to get to work.&lt;/p&gt;&lt;p&gt;There were two AI agents, one incident, and no way for them to talk to each other.&lt;/p&gt;&lt;p&gt;The extended &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;checkly checks&lt;/code&gt; and new &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;checkly rca&lt;/code&gt; CLI commands close that gap. Your coding agent can now pull Rocky AI&amp;#x27;s analysis into its ongoing work, read the diagnosis, and go fix the code. Everything happens in the same session.&lt;/p&gt;&lt;p&gt;There&amp;#x27;s no poor soul on call required to pass around information.&lt;/p&gt;&lt;h2 id=&quot;meet-the-two-agents&quot;&gt;&lt;a href=&quot;#meet-the-two-agents&quot;&gt;Meet the two agents&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;One sees production from the outside. The other sees the code from the inside.&lt;/p&gt;&lt;p&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/blog/introducing-rocky-ai/&quot; rel=&quot;noreferrer&quot;&gt;Rocky AI&lt;/a&gt; is the one watching your production site. It knows about failed checks, error messages, monitoring scripts, logs, metrics, network waterfalls, packet captures, and Playwright traces. Its entire and only job is to come back with a classification, a plain-English root cause, a user-impact assessment, evidence, and a suggested fix.&lt;/p&gt;&lt;p&gt;Your coding agent, on the other hand, is the one handling your application. If it uses &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/blog/the-agentic-software-layer/&quot; rel=&quot;noreferrer&quot;&gt;the agentic layer&lt;/a&gt;, it can query databases, tail logs, hit APIs, and poke at your entire infrastructure. It can see production from the inside, the way the code sees it.&lt;/p&gt;&lt;p&gt;What it couldn&amp;#x27;t reach, until now, was Rocky AI analysis itself. Rocky sits a layer above the raw signals. It&amp;#x27;s a specialist who&amp;#x27;s already analyzed everything your monitoring produces into one diagnosis. For your coding agent, that&amp;#x27;s gold. Your agent skips the evaluation and already knows the kind of bug plus the evidence to reason from. Without Rocky&amp;#x27;s analysis, your agent has to redo the triage from scratch, which only burns tokens and risks the wrong fix. Especially on production alerts, every minute counts.&lt;/p&gt;&lt;p&gt;Until now, those two agents have never met. Rocky AI analysis stayed inside the Checkly UI. Your coding agent had plenty of reach, except for your alert analysis. This changes now.&lt;/p&gt;&lt;h2 id=&quot;rocky-ai-analysis-in-your-terminal&quot;&gt;&lt;a href=&quot;#rocky-ai-analysis-in-your-terminal&quot;&gt;Rocky AI analysis, in your terminal&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;If you have &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/resolve/ai-root-cause-analysis/overview/#automatic-analysis&quot; rel=&quot;noreferrer&quot;&gt;automatic Rocky analysis&lt;/a&gt; enabled, the root cause analysis is already embedded in the check result. Your agent doesn&amp;#x27;t need a new command. &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;checkly checks&lt;/code&gt; already returns the results:&lt;/p&gt;&lt;div class=&quot;code-block code-block-inline syntax-bash&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-comment)&quot;&gt;# access the failing checks&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checks&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;--status&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;failing&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-comment)&quot;&gt;# access check results&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checks&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;check-i&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;d&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-comment)&quot;&gt;# access the root cause analysis for the current error group&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checks&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;check-i&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;d&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;--error-group&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;group-i&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;d&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The error group&amp;#x27;s output includes the root cause, user impact, cited evidence (HTTP traces, assertions, timings), and reference links. Everything Rocky already checked and analyzed is available for you and your agent.&lt;/p&gt;&lt;p class=&quot;block-img&quot;&gt;&lt;img src=&quot;https://images.prismic.io/checklyhq/afH2KsBOoF08xanx_AdobeExpress-RockyAITerminal-ErrorGroupRCA-1-.gif?auto=format,compress&quot;/&gt;&lt;/p&gt;&lt;h3 id=&quot;when-should-you-use-checkly-rca-directly-&quot;&gt;&lt;a href=&quot;#when-should-you-use-checkly-rca-directly-&quot;&gt;When should you use &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;checkly rca&lt;/code&gt; directly?&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;There are two cases where you reach for &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/cli/checkly-rca/&quot; rel=&quot;noreferrer&quot;&gt;the dedicated &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;rca&lt;/code&gt; command&lt;/a&gt;:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;You&amp;#x27;ve turned off automatic analysis&lt;/strong&gt; to control your invocation quota, and you want to trigger RCA only for specific failures.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;You want to analyze a past failure&lt;/strong&gt; that never got an automatic analysis. It could be a flaky check from last week, a historical outage, anything predating when you enabled Rocky.&lt;/li&gt;&lt;/ol&gt;&lt;div class=&quot;code-block code-block-inline syntax-bash&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-comment)&quot;&gt;# Run a fresh analysis on an error group&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;rca&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;run&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;--error-group&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;group-i&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;d&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;--watch&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-comment)&quot;&gt;# Fetch a previously-triggered analysis by its RCA ID&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;rca&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;rca-i&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;d&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;--output&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;json&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;rca&lt;/code&gt; command supports different output formats: &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;detail&lt;/code&gt;(default, human-friendly), &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;md&lt;/code&gt; (good for PR descriptions), and &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;json&lt;/code&gt; (the one agents love).&lt;/p&gt;&lt;p class=&quot;block-img&quot;&gt;&lt;img src=&quot;https://images.prismic.io/checklyhq/afH27MBOoF08xaoN_AdobeExpress-RockyAITerminal-RcaRunWatch-2-.gif?auto=format,compress&quot;/&gt;&lt;/p&gt;&lt;h3 id=&quot;not-in-the-terminal-the-same-data-is-in-the-public-api&quot;&gt;&lt;a href=&quot;#not-in-the-terminal-the-same-data-is-in-the-public-api&quot;&gt;&lt;strong&gt;Not in the terminal? The same data is in the public API&lt;/strong&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;There &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/api-reference/rocky-ai/retrieve-one-root-cause-analysis/&quot; rel=&quot;noreferrer&quot;&gt;are three new endpoints&lt;/a&gt; to analyze your failing checks and start new Rocky analyses:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;GET /v1/root-cause-analyses/{id}&lt;/code&gt; to retrieve an existing root cause analysis&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;POST /v1/root-cause-analyses/error-groups/{errorGroupId}&lt;/code&gt; to generate a new root cause analysis for a check error group&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;POST /v1/root-cause-analyses/test-session-error-groups/{testsessionErrorGroupId}&lt;/code&gt; to generate a new root cause analysis for a test session error group&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;from-alert-to-pr-a-fast-and-optimized-agent-loop&quot;&gt;&lt;a href=&quot;#from-alert-to-pr-a-fast-and-optimized-agent-loop&quot;&gt;From alert to PR — a fast and optimized agent loop&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Here&amp;#x27;s the workflow end-to-end with an agent driving.&lt;/p&gt;&lt;p&gt;An alert is triggered. Rocky has already analyzed what&amp;#x27;s going on. It pulled the evidence, classified the failure, and wrote up the root cause. You hand it over to your agent, telling it only that &amp;quot;something&amp;#x27;s off&amp;quot;.&lt;/p&gt;&lt;p&gt;From there, your agent already knows which commands to reach for. &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/ai/skills/&quot; rel=&quot;noreferrer&quot;&gt;The Checkly skill&lt;/a&gt; taught it the playbook. It finds the failing check, accesses the analysis, and gets to work — pointed at the right surface, whether the fix lands in the check config, the production code, or infrastructure. The investigation is already done. Less guessing, quicker resolution.&lt;/p&gt;&lt;p class=&quot;block-img&quot;&gt;&lt;img src=&quot;https://images.prismic.io/checklyhq/afH3ScBOoF08xaom_AdobeExpress-RockyAITerminal-InvestigateAlertSquare-5-.gif?auto=format,compress&quot;/&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;See the full loop in motion.&lt;/strong&gt; Stefan demos the end-to-end agentic workflow, from generating checks with coding agents to resolving incidents with Rocky AI, on the &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/webinars/our-agentic-workflow-e2e&quot; rel=&quot;noreferrer&quot;&gt;agentic workflow webinar&lt;/a&gt;.&lt;/p&gt;&lt;h2 id=&quot;get-started&quot;&gt;&lt;a href=&quot;#get-started&quot;&gt;Get started&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Install or upgrade to the latest Checkly CLI:&lt;/p&gt;&lt;div class=&quot;code-block code-block-inline syntax-bash&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npm &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;install&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly@latest&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Install &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/ai/skills/&quot; rel=&quot;noreferrer&quot;&gt;the Checkly skills&lt;/a&gt; so your agent knows which commands to use:&lt;/p&gt;&lt;div class=&quot;code-block code-block-inline syntax-bash&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;skills&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;install&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Tell your coding agent to investigate a failing check. With automatic analysis on, Rocky AI analysis comes inline:  &lt;/p&gt;&lt;p&gt;&lt;em&gt;&lt;blockquote class=&quot;bg-gray-100 p-4 border-l-2 my-4 border-blue-300 inline-block&quot;&gt;I&amp;#x27;ve received a Checkly alert. Can you investigate?&lt;/blockquote&gt;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;And that’s it!  &lt;/p&gt;&lt;p&gt;Previously, there were two AI agents, one incident, and a human connecting them.  &lt;/p&gt;&lt;p&gt;Now, &lt;strong&gt;there&amp;#x27;s a single prompt&lt;/strong&gt;. That&amp;#x27;s the agentic layer in action. Specialized agents work together to resolve production issues as quickly as possible. Isn&amp;#x27;t this beautiful?&lt;/p&gt;]]&gt;</content:encoded></item><item><title><![CDATA[How to Monitor a Shopify Store with Playwright and Checkly]]></title><description><![CDATA[Learn how to monitor Shopify storefronts with Playwright and Checkly, including bot protection, consent popups, and checkout monitoring.]]></description><link>https://www.checklyhq.com/blog/monitoring-shopify-store-playwright-checkly</link><guid isPermaLink="false">adzXCxoAAEkAB7dD</guid><category><![CDATA[Playwright]]></category><category><![CDATA[Synthetic Monitoring]]></category><category><![CDATA[Monitoring as Code (MaC)]]></category><dc:creator><![CDATA[Vince Graics]]></dc:creator><pubDate>Mon, 13 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;p&gt;&lt;em&gt;This is a guest post by Vince Graics, Staff QA Engineer at World of Books.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;If you&amp;#x27;re running a Shopify storefront and want reliable synthetic monitoring, you&amp;#x27;ll hit a wall. Shopify&amp;#x27;s bot detection doesn&amp;#x27;t care that your headless browser is friendly; it sees datacenter IPs and acts accordingly. Cart API calls get hit with &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;429&lt;/code&gt; rate limits, Cloudflare challenge pages pop up mid-check, and you&amp;#x27;re left wondering whether the bug is in your code or in the platform fighting you.&lt;/p&gt;&lt;p&gt;At &lt;a target=&quot;_blank&quot; href=&quot;https://www.worldofbooks.com/&quot; rel=&quot;noreferrer&quot;&gt;World of Books&lt;/a&gt;, a UK-based secondhand bookseller running on Shopify, we ran into all of this while setting up monitoring with Checkly. The good news: Shopify actually has a fix for the bot-protection problem. The bad news: almost nobody talks about it, and there are a couple of non-obvious traps along the way.&lt;/p&gt;&lt;p&gt;This guide covers how we solved three Shopify-specific problems: bot protection headers, consent pop-up interception, and checkout flow testing. The patterns here work for any Shopify store. Swap out the selectors, plug in your store&amp;#x27;s URLs, and you have a working setup to monitor your Shopify store with Playwright.&lt;/p&gt;&lt;h2 id=&quot;what-makes-shopify-stores-hard-to-monitor-&quot;&gt;&lt;a href=&quot;#what-makes-shopify-stores-hard-to-monitor-&quot;&gt;What makes Shopify stores hard to monitor?&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Shopify stores introduce platform-level obstacles that standard Playwright tests don&amp;#x27;t account for.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Bot protection.&lt;/strong&gt; Shopify evaluates incoming traffic based on IP reputation, headers, and behavioral patterns. Monitoring checks run from cloud infrastructure, and datacenter IPs get treated with suspicion. Sometimes you get a &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;429 Too Many Requests&lt;/code&gt; on a cart API call. Sometimes Cloudflare intercepts the request entirely and serves a challenge page. And sometimes everything &lt;em&gt;looks&lt;/em&gt; like it loaded, the page shell renders, the layout is there, but the interactive parts are quietly broken. A search page shows zero product cards. A mini-cart notification never appears.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Privacy and consent interception.&lt;/strong&gt; Shopify&amp;#x27;s privacy SDK fires on every page load, showing a cookie consent banner and blocking script execution until the user accepts. In a headless context, that banner just sits there, adding flakiness and wasted seconds to every run.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Checkout DOM isolation.&lt;/strong&gt; Shopify&amp;#x27;s checkout runs on &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;checkout.shopify.com&lt;/code&gt; with a completely different markup. The selectors you wrote for the storefront don&amp;#x27;t work on checkout, and the page structure can change between Shopify editions.&lt;/p&gt;&lt;p&gt;Each section below tackles one of these problems and builds on the solution.&lt;/p&gt;&lt;h2 id=&quot;how-do-you-bypass-shopify-bot-protection-&quot;&gt;&lt;a href=&quot;#how-do-you-bypass-shopify-bot-protection-&quot;&gt;How do you bypass Shopify bot protection?&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Shopify provides a mechanism for authorized crawlers to identify themselves: &lt;a target=&quot;_blank&quot; href=&quot;https://help.shopify.com/en/manual/promoting-marketing/seo/crawling-your-store&quot; rel=&quot;noreferrer&quot;&gt;HTTP signature headers&lt;/a&gt;. You register your crawler in the Shopify admin, and Shopify gives you three headers: &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;Signature&lt;/code&gt;, &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;Signature-Input&lt;/code&gt;, and &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;Signature-Agent&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;When your requests include these headers, Shopify&amp;#x27;s bot protection lets them through cleanly.&lt;/p&gt;&lt;h3 id=&quot;creating-your-crawler-signature-in-shopify&quot;&gt;&lt;a href=&quot;#creating-your-crawler-signature-in-shopify&quot;&gt;Creating your crawler signature in Shopify&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;From your Shopify admin:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Go to &lt;strong&gt;Online Store &amp;gt; Preferences&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;In the &lt;strong&gt;Crawler access&lt;/strong&gt; section, click &lt;strong&gt;Create signature&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;Enter a descriptive name (e.g., &amp;quot;Checkly Monitoring&amp;quot;)&lt;/li&gt;&lt;li&gt;Select the domain and an expiration period&lt;/li&gt;&lt;li&gt;Copy the &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;Signature-Input&lt;/code&gt; and &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;Signature&lt;/code&gt; values&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The third header, Signature-Agent, is static; its value is always &amp;quot;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;&amp;lt;https://shopify.com&amp;gt;&lt;/code&gt;&amp;quot; (with quotes).&lt;/p&gt;&lt;p&gt;One thing to watch for: signatures have an expiration date. Set a calendar reminder to rotate them before they expire, or your checks will start failing again with zero code changes. When they expire, every check returns a challenge page and it looks like your entire store is down.&lt;/p&gt;&lt;h3 id=&quot;storing-headers-as-checkly-secrets&quot;&gt;&lt;a href=&quot;#storing-headers-as-checkly-secrets&quot;&gt;Storing headers as Checkly secrets&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Add the three values as &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/platform/secrets/&quot; rel=&quot;noreferrer&quot;&gt;secrets in your Checkly account&lt;/a&gt;:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;SHOPIFY_SIGNATURE&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;SHOPIFY_SIGNATURE_INPUT&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;SHOPIFY_SIGNATURE_AGENT&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This keeps your credentials out of code and makes them available to all your &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/browser-checks/playwright-test/&quot; rel=&quot;noreferrer&quot;&gt;browser checks&lt;/a&gt; at runtime.&lt;/p&gt;&lt;h3 id=&quot;injecting-the-headers-in-playwright&quot;&gt;&lt;a href=&quot;#injecting-the-headers-in-playwright&quot;&gt;Injecting the headers in Playwright&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The simplest approach, and what you should try first:&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;await&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;page&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;.setExtraHTTPHeaders&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;#39;Signature&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;process&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;SHOPIFY_SIGNATURE&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;#39;Signature-Input&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;process&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;SHOPIFY_SIGNATURE_INPUT&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;#39;Signature-Agent&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;process&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;SHOPIFY_SIGNATURE_AGENT&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;setExtraHTTPHeaders&lt;/code&gt; adds these headers to every request the page makes. For many Shopify stores, this just works and you&amp;#x27;re done.&lt;/p&gt;&lt;h3 id=&quot;when-you-need-scoped-header-injection&quot;&gt;&lt;a href=&quot;#when-you-need-scoped-header-injection&quot;&gt;When you need scoped header injection&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;If your store uses third-party services that don&amp;#x27;t play nice with extra headers, &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;setExtraHTTPHeaders&lt;/code&gt; can cause problems. At World of Books, we hit this with a third-party search provider: the extra headers on cross-origin requests appeared to interfere with its responses, and product listings silently came back empty. No errors, no warnings; just an empty product grid and a check that fails for reasons that take an hour to debug.&lt;/p&gt;&lt;p&gt;The fix is Playwright&amp;#x27;s &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;page.route()&lt;/code&gt;, which scopes header injection to your own domain:&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;crawlerHeaders&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;Record&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;process&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;SHOPIFY_SIGNATURE&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;process&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;SHOPIFY_SIGNATURE_INPUT&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;process&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;SHOPIFY_SIGNATURE_AGENT&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;#39;Signature&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;process&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;SHOPIFY_SIGNATURE&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;#39;Signature-Input&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;process&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;SHOPIFY_SIGNATURE_INPUT&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;#39;Signature-Agent&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;process&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;SHOPIFY_SIGNATURE_AGENT&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; {};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;await&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;page&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;.route&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;#39;**/www.yourstore.com/**&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; route &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;route&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;.continue&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    headers&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;route&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;.request&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;.headers&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;crawlerHeaders }&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  })&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Third-party requests pass through untouched. A few things to note:&lt;/p&gt;&lt;p&gt;All three headers are required together. If any are missing, skip the injection entirely; partial headers won&amp;#x27;t work with Shopify&amp;#x27;s validation. And spread existing headers first: &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;route.continue()&lt;/code&gt; replaces headers entirely, so the spread preserves cookies, content types, and everything else the browser set. After your test, call &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;page.unrouteAll({ behavior: &amp;#x27;ignoreErrors&amp;#x27; })&lt;/code&gt; to avoid route handler leaks between checks.&lt;/p&gt;&lt;h3 id=&quot;scaling-this-with-playwright-fixtures&quot;&gt;&lt;a href=&quot;#scaling-this-with-playwright-fixtures&quot;&gt;Scaling this with Playwright fixtures&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Once you have more than a couple of checks, you don&amp;#x27;t want to repeat the header setup in every file. Playwright fixtures let you extend the base &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;page&lt;/code&gt; object once and use it everywhere:&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; { test &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; base } &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;#39;@playwright/test&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;base&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;.extend&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;page&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; ({ page }&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; use) &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;Object&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;.keys&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;(crawlerHeaders).&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;await&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;page&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;.route&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;#39;**/www.yourstore.com/**&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; route &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;route&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;.continue&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;          headers&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;route&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;.request&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;.headers&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;crawlerHeaders }&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;        })&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;      );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;await&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;(page);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;await&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;page&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;.unrouteAll&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;({ behavior&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;#39;ignoreErrors&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  }&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Every check that imports &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;test&lt;/code&gt; from this fixture gets crawler header injection automatically. No headers configured? The fixture is a no-op; your checks still work locally without Shopify credentials.&lt;/p&gt;&lt;h2 id=&quot;how-do-you-handle-shopify-consent-popups-&quot;&gt;&lt;a href=&quot;#how-do-you-handle-shopify-consent-popups-&quot;&gt;How do you handle Shopify consent popups?&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The consent banner problem is frustrating because it&amp;#x27;s invisible in manual testing (you click it once and forget it) but it breaks every automated check.&lt;/p&gt;&lt;p&gt;Playwright&amp;#x27;s &lt;a target=&quot;_blank&quot; href=&quot;https://playwright.dev/docs/api/class-page#page-add-locator-handler&quot; rel=&quot;noreferrer&quot;&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;page.addLocatorHandler()&lt;/code&gt;&lt;/a&gt; lets you register a handler that fires whenever a matching element appears. Think of it as a popup bouncer for your checks:&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;base&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;.extend&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;page&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; ({ page }&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; use) &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;await&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;page&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;.addLocatorHandler&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;page&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;.locator&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;#39;[aria-label=&amp;quot;Close popup&amp;quot;]&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;await&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;page&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;.locator&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;#39;[aria-label=&amp;quot;Close popup&amp;quot;]&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;.click&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;      }&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;await&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;(page);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  }&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This works well for stores with a single, consistent popup. If your store has multiple overlays (newsletter signups, region selectors), you can register additional handlers with different locators. The key is keeping the selectors stable; &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;aria-label&lt;/code&gt; attributes tend to survive theme updates better than CSS classes.&lt;/p&gt;&lt;h2 id=&quot;how-do-you-test-shopify-checkout-&quot;&gt;&lt;a href=&quot;#how-do-you-test-shopify-checkout-&quot;&gt;How do you test Shopify checkout?&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Checkout is where monitoring gets tricky, because you&amp;#x27;re crossing into &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;checkout.shopify.com&lt;/code&gt; with its own DOM, its own selectors, and real money involved.&lt;/p&gt;&lt;h3 id=&quot;setting-up-safe-checkout-testing-with-shopify-flow&quot;&gt;&lt;a href=&quot;#setting-up-safe-checkout-testing-with-shopify-flow&quot;&gt;Setting up safe checkout testing with Shopify Flow&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;You can&amp;#x27;t just skip checkout monitoring; it&amp;#x27;s the flow that matters most to your business. But running real transactions in production sounds terrifying. Here&amp;#x27;s the approach my team at World of Books came up with, using &lt;a target=&quot;_blank&quot; href=&quot;https://apps.shopify.com/flow&quot; rel=&quot;noreferrer&quot;&gt;Shopify Flow&lt;/a&gt;:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Get a company card&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Create a dedicated test user&lt;/strong&gt; on your production store&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Set up a Flow automation&lt;/strong&gt;: if this specific user purchases something, the workflow immediately refunds the order and cancels the trade&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Run your checkout checks&lt;/strong&gt; against this test user&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;You can now run regular checkout validations until you run out of the company card budget, and wait for the refunds. It&amp;#x27;s not elegant, but it works, and it tests the &lt;em&gt;real&lt;/em&gt; checkout flow, not a staging approximation.&lt;/p&gt;&lt;h2 id=&quot;deploying-to-checkly&quot;&gt;&lt;a href=&quot;#deploying-to-checkly&quot;&gt;Deploying to Checkly&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Once the checks pass locally, deploy with the &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/cli/&quot; rel=&quot;noreferrer&quot;&gt;Checkly CLI&lt;/a&gt;:&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;# Test against Checkly infrastructure first&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;checkly test &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;--&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;record&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;# Deploy&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;checkly deploy &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;f &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;o&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Set your environment variables in the Checkly dashboard under the check group. The required ones: &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;SHOPIFY_SIGNATURE&lt;/code&gt;, &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;SHOPIFY_SIGNATURE_INPUT&lt;/code&gt;, &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;SHOPIFY_SIGNATURE_AGENT&lt;/code&gt;. Add &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;LOGIN_EMAIL&lt;/code&gt;, &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;LOGIN_PASSWORD&lt;/code&gt;, and discount codes if you&amp;#x27;re monitoring authenticated or promotional flows.&lt;/p&gt;&lt;p&gt;Because everything lives in your repo as code, your Shopify monitoring ships through the same CI/CD pipeline as your application. That&amp;#x27;s the &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/product/monitoring-as-code/&quot; rel=&quot;noreferrer&quot;&gt;Monitoring as Code&lt;/a&gt; approach: your checks are versioned, reviewed in PRs, and deployed automatically. No clicking through a UI to update a threshold.&lt;/p&gt;&lt;h2 id=&quot;troubleshooting-common-failures&quot;&gt;&lt;a href=&quot;#troubleshooting-common-failures&quot;&gt;Troubleshooting common failures&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Challenge page instead of storefront.&lt;/strong&gt; Your crawler headers are missing or expired. Regenerate them in Shopify Admin and update the env vars in Checkly.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Login fails or loops.&lt;/strong&gt; Test account credentials are wrong, the account is locked, or MFA got enabled. Use a dedicated test account that the store admin has allowlisted.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Discount code shows &amp;quot;not valid.&amp;quot;&lt;/strong&gt; The code expired, hit its usage limit, or targets the wrong region. Verify it in Shopify Admin &amp;gt; Discounts. Use unlimited test codes.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Checks pass locally, fail on Checkly.&lt;/strong&gt; Almost always missing environment variables. Run &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;checkly env ls&lt;/code&gt; to verify. Second most common cause: viewport mismatch. Set &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;viewport: { width: 1920, height: 1080 }&lt;/code&gt; explicitly in your Playwright config.&lt;/p&gt;&lt;h2 id=&quot;wrapping-up&quot;&gt;&lt;a href=&quot;#wrapping-up&quot;&gt;Wrapping up&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;At World of Books, customer experience is the reason we monitor our Shopify storefront so closely. If search breaks, checkout stalls, or a pop-up blocks the flow, it&amp;#x27;s important that we know before our customers do. Shopify can be difficult to test with headless browsers, but once we added crawler-signature headers via Checkly secrets, used a Playwright fixture to centralize header injection and consent handling, and set up Shopify Flow to clean up checkout test orders, the setup became reliable. The checks now see the same storefront our customers see, without the &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;429&lt;/code&gt;s, Cloudflare challenges, or quiet failures that make Shopify monitoring so frustrating.&lt;/p&gt;&lt;p&gt;If your checks keep mysteriously failing, check your headers.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Get started:&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/cli/&quot; rel=&quot;noreferrer&quot;&gt;Checkly CLI documentation&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/browser-checks/playwright-test/&quot; rel=&quot;noreferrer&quot;&gt;Playwright browser check docs&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://help.shopify.com/en/manual/promoting-marketing/seo/crawling-your-store&quot; rel=&quot;noreferrer&quot;&gt;Shopify crawler header documentation&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://app.checklyhq.com/signup&quot; rel=&quot;noreferrer&quot;&gt;Sign up for Checkly free&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;]]&gt;</content:encoded></item><item><title><![CDATA[Checkly Playwright Reporter: A Cloud Dashboard for Your Playwright Tests]]></title><description><![CDATA[Send Playwright test runs to Checkly with traces, videos, screenshots, flaky test visibility, and session history, then take key tests into monitoring.]]></description><link>https://www.checklyhq.com/blog/checkly-playwright-reporter</link><guid isPermaLink="false">acOgGRoAAEYAuCWu</guid><category><![CDATA[Product]]></category><category><![CDATA[Playwright]]></category><category><![CDATA[Announcements]]></category><dc:creator><![CDATA[Pırıl Kavlak,María de Antón]]></dc:creator><pubDate>Wed, 01 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;p&gt;&lt;strong&gt;The Checkly Playwright Reporter&lt;/strong&gt; is an npm package that sends the results of npx playwright test to Checkly as a cloud test session, including traces, screenshots, videos, and full debugging context. Run your Playwright suite in CI or locally, and every result gets a persistent, shareable home in Checkly with AI-powered analysis, richer trace-derived views, and a direct path to production monitoring.&lt;/p&gt;&lt;p&gt;It does not replace Playwright. It makes the output of Playwright much easier to work with.&lt;/p&gt;&lt;p&gt;Today, the reporter is available at no additional cost on all Checkly plans.&lt;/p&gt;&lt;h2 id=&quot;why-we-built-this&quot;&gt;&lt;a href=&quot;#why-we-built-this&quot;&gt;Why we built this&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Checkly has supported Playwright for years. You could write Playwright tests, validate them with npx checkly test, and deploy them as production monitors with npx checkly deploy. That workflow is powerful for production monitoring.&lt;/p&gt;&lt;p&gt;But most teams run npx playwright test hundreds of times a week in GitHub Actions, GitLab CI, or locally, and those results never reach Checkly. The evidence ends up scattered across CI logs, local trace files, and one-off HTML reports. That&amp;#x27;s manageable for an individual, but it breaks down for a team.&lt;/p&gt;&lt;p&gt;The Checkly Playwright Reporter helps close that gap by giving teams a shared place to review Playwright runs in Checkly.&lt;/p&gt;&lt;p&gt;From there, teams can run Playwright Check Suites with npx checkly pw-test, and when a test is important enough, npx checkly deploy can take it into production monitoring.&lt;/p&gt;&lt;p&gt;But it is not only about having a place to persist your test results. Once those results are in Checkly, &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/product/ai-analysis/&quot; rel=&quot;noreferrer&quot;&gt;Rocky AI&lt;/a&gt; can help analyze failed runs directly in the UI.&lt;/p&gt;&lt;p&gt;When enabled, Rocky AI can include AI-assisted root cause analysis and visibility into recurring failures across runs.&lt;/p&gt;&lt;p class=&quot;block-img&quot;&gt;&lt;img src=&quot;https://images.prismic.io/checklyhq/ac1Nm5GXnQHGZLQZ_rockyAIanalysis.png?auto=format,compress&quot;/&gt;&lt;/p&gt;&lt;h2 id=&quot;what-you-get-beyond-a-hosted-report&quot;&gt;&lt;a href=&quot;#what-you-get-beyond-a-hosted-report&quot;&gt;What you get beyond a hosted report&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Today, there are several ways to get Playwright test results into the cloud, including Microsoft&amp;#x27;s own Playwright Workspaces. But most of them stop at hosting: they take the same local Playwright HTML report and put it behind a URL. That solves the sharing problem. It does not solve the understanding problem.&lt;/p&gt;&lt;p&gt;The Checkly Playwright Reporter goes further:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Filterable network view&lt;/strong&gt; — every request and response captured from the trace, organized so you can focus on the failures instead of scanning a raw list.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Filterable browser console&lt;/strong&gt; — browser console output pulled into a cleaner view, including an errors-only filter.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Automatic secret scrubbing&lt;/strong&gt; — secrets can be scrubbed before upload, including support for the CHECKLY_SECRET_ prefix and sensitive header redaction.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;System performance graphs&lt;/strong&gt; — CPU and memory usage tracked throughout the test run, so you can spot whether a flaky or failing test might be tied to resource pressure.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Terminal progress and summary table&lt;/strong&gt; — a clearer terminal view of what passed, failed, flaked, or got skipped across projects.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Automatic git detection&lt;/strong&gt; — branch, commit, and author metadata can be attached to sessions automatically in CI and local git environments.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;History across runs&lt;/strong&gt; — instead of treating every run as an isolated local report, you can review patterns over time and see when the same failures keep coming back.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Hosting a report gives you a link. A reporting system gives you answers.&lt;/p&gt;&lt;p class=&quot;block-img&quot;&gt;&lt;img src=&quot;https://images.prismic.io/checklyhq/ac1NypGXnQHGZLQc_viewsourcecode.png?auto=format,compress&quot;/&gt;&lt;/p&gt;&lt;h2 id=&quot;how-to-set-up-the-checkly-playwright-reporter&quot;&gt;&lt;a href=&quot;#how-to-set-up-the-checkly-playwright-reporter&quot;&gt;How to set up the Checkly Playwright Reporter&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;You need:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Node.js 18 or newer&lt;/li&gt;&lt;li&gt;Playwright 1.40 or newer&lt;/li&gt;&lt;li&gt;a Checkly account&lt;/li&gt;&lt;li&gt;your CHECKLY_API_KEY and CHECKLY_ACCOUNT_ID&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Install the package:&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npm install &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;--&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;save&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;dev @checkly&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;playwright&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;reporter&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Add it to your  playwright.config.ts:&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; { defineConfig } &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;#39;@playwright/test&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; { createChecklyReporter } &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;#39;@checkly/playwright-reporter&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;default&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;defineConfig&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  reporter&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    [&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;#39;list&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;createChecklyReporter&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  ]&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  use&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    screenshot&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;#39;only-on-failure&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    video&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;#39;retain-on-failure&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    trace&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;#39;on&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  }&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Set credentials:&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;CHECKLY_API_KEY&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;your_api_key&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;CHECKLY_ACCOUNT_ID&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;your_account_id&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Then run your suite as usual:&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx playwright test&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;When the run finishes, you get a Checkly test session URL in the terminal. That is the entire setup. No cloud infrastructure to provision, no storage accounts to link, no role assignments to configure.&lt;/p&gt;&lt;h2 id=&quot;try-the-checkly-playwright-reporter&quot;&gt;&lt;a href=&quot;#try-the-checkly-playwright-reporter&quot;&gt;&lt;strong&gt;Try the Checkly Playwright Reporter&lt;/strong&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;If your team already uses Playwright, this is the fastest way to stop losing useful test context after the run.&lt;/p&gt;&lt;p&gt;Start here:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/detect/testing/playwright-reporter/&quot; rel=&quot;noreferrer&quot;&gt;Docs&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/detect/testing/playwright-reporter-changelog/&quot; rel=&quot;noreferrer&quot;&gt;Reporter changelog&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://github.com/checkly/playwright-reporter-demo&quot; rel=&quot;noreferrer&quot;&gt;Demo repo&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://www.npmjs.com/package/@checkly/playwright-reporter&quot; rel=&quot;noreferrer&quot;&gt;npm package&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;section data-slice-type=&quot;blog_faq&quot; data-slice-variation=&quot;default&quot; class=&quot;py-10 mt-4&quot;&gt;&lt;h2 class=&quot;title mb-2 text-2xl md:text-3xl&quot;&gt;Frequently Asked Questions&lt;/h2&gt;&lt;div class=&quot;space-y-3&quot;&gt;&lt;div class=&quot;rounded-2xl border border-blue-300/20 transition-[border-color] duration-200 ease-out hover:border-blue-300/35&quot;&gt;&lt;button type=&quot;button&quot; aria-expanded=&quot;false&quot; class=&quot;flex justify-between items-center px-6 py-5 md:px-8 w-full text-left text-checkly-deep-blue cursor-pointer transition-transform duration-150 motion-safe:active:scale-[0.995]&quot;&gt;&lt;span class=&quot;select-none text-base&quot;&gt;Is the Checkly Playwright Reporter free?&lt;/span&gt;&lt;svg viewBox=&quot;0 0 14 8&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; class=&quot;w-3 shrink-0 transition-transform duration-[250ms] ease-out rotate-0&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M0.46967 0.46967C0.762563 0.176777 1.23744 0.176777 1.53033 0.46967L7 5.93934L12.4697 0.46967C12.7626 0.176777 13.2374 0.176777 13.5303 0.46967C13.8232 0.762563 13.8232 1.23744 13.5303 1.53033L7.53033 7.53033C7.23744 7.82322 6.76256 7.82322 6.46967 7.53033L0.46967 1.53033C0.176777 1.23744 0.176777 0.762563 0.46967 0.46967Z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;div style=&quot;max-height:0px;opacity:0;transition:max-height 250ms cubic-bezier(0.23, 1, 0.32, 1), opacity 150ms ease-out;overflow:hidden&quot;&gt;&lt;div class=&quot;px-6 pb-6 md:px-8 md:pb-8 rich-text&quot;&gt;&lt;p&gt;Yes. The reporter is free on all Checkly plans today, including the free tier. As we learn from usage and continue improving the product, pricing may evolve over time. Our goal is to keep it highly competitive relative to other reporting tools and make it easy for teams to get started.&lt;/p&gt;&lt;p&gt;If you are already using the reporter and want to share feedback, &lt;a target=&quot;_blank&quot; href=&quot;mailto:support@checklyhq.com&quot; rel=&quot;noreferrer&quot;&gt;get in touch&lt;/a&gt;! We&amp;#x27;d love to hear from early users helping shape the product.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;rounded-2xl border border-blue-300/20 transition-[border-color] duration-200 ease-out hover:border-blue-300/35&quot;&gt;&lt;button type=&quot;button&quot; aria-expanded=&quot;false&quot; class=&quot;flex justify-between items-center px-6 py-5 md:px-8 w-full text-left text-checkly-deep-blue cursor-pointer transition-transform duration-150 motion-safe:active:scale-[0.995]&quot;&gt;&lt;span class=&quot;select-none text-base&quot;&gt;Can I use the reporter in CI?&lt;/span&gt;&lt;svg viewBox=&quot;0 0 14 8&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; class=&quot;w-3 shrink-0 transition-transform duration-[250ms] ease-out rotate-0&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M0.46967 0.46967C0.762563 0.176777 1.23744 0.176777 1.53033 0.46967L7 5.93934L12.4697 0.46967C12.7626 0.176777 13.2374 0.176777 13.5303 0.46967C13.8232 0.762563 13.8232 1.23744 13.5303 1.53033L7.53033 7.53033C7.23744 7.82322 6.76256 7.82322 6.46967 7.53033L0.46967 1.53033C0.176777 1.23744 0.176777 0.762563 0.46967 0.46967Z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;div style=&quot;max-height:0px;opacity:0;transition:max-height 250ms cubic-bezier(0.23, 1, 0.32, 1), opacity 150ms ease-out;overflow:hidden&quot;&gt;&lt;div class=&quot;px-6 pb-6 md:px-8 md:pb-8 rich-text&quot;&gt;&lt;p&gt;Yes. The reporter works with local and CI runs, as long as the Checkly credentials are available.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;rounded-2xl border border-blue-300/20 transition-[border-color] duration-200 ease-out hover:border-blue-300/35&quot;&gt;&lt;button type=&quot;button&quot; aria-expanded=&quot;false&quot; class=&quot;flex justify-between items-center px-6 py-5 md:px-8 w-full text-left text-checkly-deep-blue cursor-pointer transition-transform duration-150 motion-safe:active:scale-[0.995]&quot;&gt;&lt;span class=&quot;select-none text-base&quot;&gt;Does the reporter automatically turn tests into monitors?&lt;/span&gt;&lt;svg viewBox=&quot;0 0 14 8&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; class=&quot;w-3 shrink-0 transition-transform duration-[250ms] ease-out rotate-0&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M0.46967 0.46967C0.762563 0.176777 1.23744 0.176777 1.53033 0.46967L7 5.93934L12.4697 0.46967C12.7626 0.176777 13.2374 0.176777 13.5303 0.46967C13.8232 0.762563 13.8232 1.23744 13.5303 1.53033L7.53033 7.53033C7.23744 7.82322 6.76256 7.82322 6.46967 7.53033L0.46967 1.53033C0.176777 1.23744 0.176777 0.762563 0.46967 0.46967Z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;div style=&quot;max-height:0px;opacity:0;transition:max-height 250ms cubic-bezier(0.23, 1, 0.32, 1), opacity 150ms ease-out;overflow:hidden&quot;&gt;&lt;div class=&quot;px-6 pb-6 md:px-8 md:pb-8 rich-text&quot;&gt;&lt;p&gt;No. The reporter uploads test runs as Checkly test sessions. Production monitoring is the next step in Checkly’s &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/quickstarts/playwright-check/&quot; rel=&quot;noreferrer&quot;&gt;Playwright monitoring workflow&lt;/a&gt;, where teams define Playwright Check Suites in a checkly.config.ts file and deploy them as monitors.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;]]&gt;</content:encoded></item><item><title><![CDATA[One CLI, Two Audiences: How We Built for Agents and Humans]]></title><description><![CDATA[50% of Checkly CLI users are already coding agents. Learn how built-in skills, structured output, and agent guardrails make one CLI work for humans and agents alike.]]></description><link>https://www.checklyhq.com/blog/agentic-cli</link><guid isPermaLink="false">acVVJRoAAE4Aur67</guid><category><![CDATA[AI]]></category><category><![CDATA[Product]]></category><dc:creator><![CDATA[Stefan Judis]]></dc:creator><pubDate>Thu, 26 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;p&gt;Half of the Checkly CLI users are already coding agents. This is not a prediction — it&amp;#x27;s what the data shows today.&lt;/p&gt;&lt;p&gt;Since February, more and more agents have been using the CLI to manage and configure their Checkly monitoring setups. Right now, we&amp;#x27;re at 50% human and 50% agentic CLI users. And we predict that by the end of 2026, it won&amp;#x27;t be humans using the CLI; the agents will have taken over.&lt;/p&gt;&lt;p class=&quot;block-img&quot;&gt;&lt;img src=&quot;https://images.prismic.io/checklyhq/acVVrpGXnQHGZAdk_agentic-cli-users.png?auto=format,compress&quot; alt=&quot;Graph showing that 50% CLI users are human and 50% agents.&quot;/&gt;&lt;/p&gt;&lt;p&gt;The terminal became the primary interface for AI agents doing real work in the Checkly ecosystem. Configuring monitoring, resolving incidents, and communicating outages; all this can be done automatically.&lt;/p&gt;&lt;p&gt;The CLI became &lt;a href=&quot;/blog/the-agentic-software-layer/&quot;&gt;the new agentic layer&lt;/a&gt;. So we asked: how do you build for two audiences at once?&lt;/p&gt;&lt;h2 id=&quot;the-full-agentic-loop-from-alert-to-resolution&quot;&gt;&lt;a href=&quot;#the-full-agentic-loop-from-alert-to-resolution&quot;&gt;The full agentic loop — from alert to resolution&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;To show what this looks like in practice, here&amp;#x27;s a real scenario: &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/detect/synthetic-monitoring/playwright-checks/overview/&quot; rel=&quot;noreferrer&quot;&gt;a Playwright check&lt;/a&gt; detects that the storefront&amp;#x27;s login flow is broken. The old way would be to manually open the Checkly dashboard, click through results, and switch between the IDE, alert information, and Git logs to figure out what&amp;#x27;s off. We now hand these tasks to the agent with a single prompt.&lt;/p&gt;&lt;blockquote class=&quot;bg-gray-100 p-4 border-l-2 my-4 border-blue-300 inline-block space-y-4&quot;&gt;&lt;p&gt;I just received a monitoring alert in Checkly about a broken login flow. Can you check what&amp;#x27;s up, investigate a fix, and communicate the issue?&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;It&amp;#x27;s a simple but powerful prompt. Here&amp;#x27;s what happens next:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;The agent discovers Checkly capabilities.&lt;/strong&gt; With the installed &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/ai/skills/&quot; rel=&quot;noreferrer&quot;&gt;Checkly Skill&lt;/a&gt;, it pulls in the context it needs to act. Available commands, your account information and plan, investigation playbooks, and best practices; all these things become accessible through &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;checkly skills.&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The agent investigates.&lt;/strong&gt; It calls &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;npx checkly checks&lt;/code&gt; to get the current state of all monitors, identify the failing check, and analyze the Playwright error. It reads the check results, correlates them with your codebase, and additional context sources. Eventually, it finds the root cause.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The agent communicates.&lt;/strong&gt; Before fixing anything, it tries to open an incident so customers know what&amp;#x27;s happening, but the CLI rejects the command and prompts for confirmation. Agents can&amp;#x27;t just declare a public incident without approval. Once confirmed, the incident goes live: &amp;quot;Login flow is broken, users cannot log in.&amp;quot;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The agent provides a fix and deploys.&lt;/strong&gt; It applies the fix, commits, and pushes. Your existing CI/CD pipeline takes it from there — the agent waits for the deployment to complete.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The agent verifies.&lt;/strong&gt; Once deployed, it triggers the Checkly checks to confirm the fix actually works.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;The agent resolves.&lt;/strong&gt; If all the ad hoc tests pass, the incident is resolved with a summary of what happened and what was done. The status page goes green.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;This might sound like future music, but you can see this flow in action below.&lt;/p&gt;&lt;div data-oembed=&quot;https://www.youtube.com/watch?v=wkP21FuZx4c&quot; data-oembed-type=&quot;video&quot; data-oembed-provider=&quot;YouTube&quot;&gt;&lt;iframe width=&quot;200&quot; height=&quot;113&quot; src=&quot;https://www.youtube.com/embed/wkP21FuZx4c?feature=oembed&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen title=&quot;Automate Your Monitoring and Incident Handling: How Agents Dominate the Checkly CLI&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;p&gt;Coding agents can handle the full incident life cycle today. Detect, understand, communicate, fix, verify, resolve; all this can happen in a single agent session. All actions are enabled through the CLI. There&amp;#x27;s no need for you to open a monitoring dashboard. There&amp;#x27;s no context switching. Sit back and let the agent be the incident manager.&lt;/p&gt;&lt;p&gt;But how does this work in detail? How did the agent know what to do?&lt;/p&gt;&lt;h2 id=&quot;checkly-skills-teach-your-agent-how-to-handle-your-monitoring&quot;&gt;&lt;a href=&quot;#checkly-skills-teach-your-agent-how-to-handle-your-monitoring&quot;&gt;Checkly Skills: teach your agent how to handle your monitoring&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Your agent didn&amp;#x27;t hallucinate, fetch docs, or browse the internet. It was tasked by &lt;a target=&quot;_blank&quot; href=&quot;https://checklyhq.com/docs/ai/skills/&quot; rel=&quot;noreferrer&quot;&gt;the Checkly skill&lt;/a&gt; to rely on the built-in documentation accessible via &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;npx checkly skills&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;You can install the Checkly skill with a single command:&lt;/p&gt;&lt;div class=&quot;code-block code-block-inline syntax-bash&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex pr-12&quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;skills&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;install&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;button type=&quot;button&quot; class=&quot;group bg-inherit absolute rounded flex items-center justify-center top-0 right-0  text-white bg-inherit h-14 w-14&quot; title=&quot;Copy code to clipboard&quot;&gt;&lt;svg viewBox=&quot;0 0 16 11&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; class=&quot;absolute h-5 w-5 transition duration-200 ease-out text-checkly-blue -translate-y-2 opacity-0 scale-90&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M15.1085 0.558056C15.3526 0.802133 15.3526 1.19786 15.1085 1.44194L5.94187 10.6086C5.82466 10.7259 5.66568 10.7917 5.49992 10.7917C5.33416 10.7917 5.17519 10.7259 5.05798 10.6086L0.891309 6.44194C0.647232 6.19786 0.647233 5.80213 0.891312 5.55806C1.13539 5.31398 1.53112 5.31398 1.7752 5.55806L5.49992 9.28281L14.2246 0.55806C14.4687 0.313981 14.8644 0.31398 15.1085 0.558056Z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;svg viewBox=&quot;0 0 18 19&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; class=&quot;absolute h-5 w-5 transition duration-200 ease-out translate-y-0 opacity-100 scale-100 text-white/30 group-hover:text-white/80&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M5.875 8.85929C5.875 7.59364 6.90101 6.56763 8.16667 6.56763H15.6667C16.9323 6.56763 17.9583 7.59365 17.9583 8.85929V16.3593C17.9583 17.6249 16.9323 18.651 15.6667 18.651H8.16667C6.901 18.651 5.875 17.6249 5.875 16.3593V8.85929ZM8.16667 7.81763C7.59137 7.81763 7.125 8.28399 7.125 8.85929V16.3593C7.125 16.9346 7.59138 17.401 8.16667 17.401H15.6667C16.2419 17.401 16.7083 16.9346 16.7083 16.3593V8.85929C16.7083 8.28398 16.2419 7.81763 15.6667 7.81763H8.16667Z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M2.33464 1.98438C2.05836 1.98438 1.79341 2.09412 1.59807 2.28946C1.59807 2.28946 1.59807 2.28946 1.59807 2.28946M1.59807 2.28946C1.40272 2.48482 1.29297 2.74978 1.29297 3.02604V10.5261C1.29297 10.8023 1.4027 11.0672 1.59809 11.2626C1.79343 11.458 2.05838 11.5678 2.33464 11.5678H3.16797C3.51315 11.5678 3.79297 11.8476 3.79297 12.1928C3.79297 12.5379 3.51315 12.8178 3.16797 12.8178H2.33464C1.72684 12.8178 1.14393 12.5763 0.714149 12.1465C0.284418 11.7167 0.0429688 11.1338 0.0429688 10.5261V3.02604C0.0429688 2.41826 0.284405 1.83537 0.71417 1.40559C1.14395 0.975814 1.72686 0.734375 2.33464 0.734375H9.8346C10.4424 0.734375 11.0253 0.9758 11.4551 1.40563C11.8849 1.8354 12.1263 2.41827 12.1263 3.02604V3.85938C12.1263 4.20455 11.8465 4.48438 11.5013 4.48438C11.1561 4.48438 10.8763 4.20455 10.8763 3.85938V3.02604C10.8763 2.74979 10.7666 2.48485 10.5712 2.28949C10.3759 2.09419 10.111 1.98438 9.8346 1.98438H2.33464&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;p&gt;This command drops a &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;SKILL.md&lt;/code&gt; file into your project that any coding agent (Claude Code, Cursor, Codex, Copilot) can pick up. Everybody is raging about skills right now, but most skills have a fundamental flaw. &lt;strong&gt;Most skills are static&lt;/strong&gt;. If you look at all the skills listed on &lt;a target=&quot;_blank&quot; href=&quot;https://skills.sh/&quot; rel=&quot;noreferrer&quot;&gt;skills.sh&lt;/a&gt;, you&amp;#x27;ll find that the majority of them are on-off documentation that you need to update manually.&lt;/p&gt;&lt;p&gt;The Checkly skill file is different because it&amp;#x27;s only a thin wrapper around the &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;checkly skills&lt;/code&gt; command.&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;Run `npx checkly skills communicate` for the full protocol details.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;### `npx checkly skills initialize`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;Learn how to initialize and set up a new Checkly CLI project from scratch.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;### `npx checkly skills configure`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;Learn how to create and manage monitoring checks using Checkly constructs and the CLI.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;#### `npx checkly skills configure api-checks`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;Api Check construct (`ApiCheck`), assertions, and authentication setup scripts&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Yes, you read that right, &lt;strong&gt;we&amp;#x27;ve put optimized agent documentation right into the CLI itself.&lt;/strong&gt; Required monitoring context ships within the tooling you use to manage your monitoring. Every CLI version update brings updated documentation, new workflows, and current best practices. There&amp;#x27;s no web search, no stale docs, no external files to maintain. Whenever you update the CLI, your agent gets smarter.&lt;/p&gt;&lt;p&gt;But we didn&amp;#x27;t stop there. Skills also use progressive disclosure across three levels:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Overview&lt;/strong&gt; — &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;npx checkly skills&lt;/code&gt; lists all available action categories: &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;initialize&lt;/code&gt;, &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;configure&lt;/code&gt;, &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;investigate&lt;/code&gt;, &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;communicate&lt;/code&gt; and &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;manage&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Action&lt;/strong&gt; — &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;npx checkly skills investigate&lt;/code&gt; returns the detailed guide for that category — which commands to run, what to look for, and how to triage.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Reference&lt;/strong&gt; — &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;npx checkly skills configure api-checks&lt;/code&gt; returns construct-level documentation for any resource.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The built-in Checkly skills save tokens and tell your agent exactly what to do. No guessing. No hallucinations.&lt;/p&gt;&lt;p class=&quot;block-img&quot;&gt;&lt;img src=&quot;https://images.prismic.io/checklyhq/acVZ7ZGXnQHGZAmt_agentic-learn1.gif?auto=format,compress&quot; alt=&quot;Agent session showing the discovery of the skills command.&quot;/&gt;&lt;/p&gt;&lt;p&gt;This single command transforms your agent into an up-to-date Checkly expert. But what can your agent handle for you now that it knows every corner of the Checkly ecosystem?&lt;/p&gt;&lt;h2 id=&quot;structured-output-the-agent-s-dashboard&quot;&gt;&lt;a href=&quot;#structured-output-the-agent-s-dashboard&quot;&gt;Structured output: the agent&amp;#x27;s dashboard&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;If you&amp;#x27;re facing issues and alerts, as a human, you head into Checkly, open the dashboard, click through the check results, and scan the graphs. And while you could task your agent to open the web app with a browser, this process couldn&amp;#x27;t be more inefficient. We released new CLI commands to enable the agent to access structured output, replacing the good old Checkly dashboard you know and love.&lt;/p&gt;&lt;p&gt;Read commands support multiple output formats optimized for agentic workflows:&lt;/p&gt;&lt;div class=&quot;code-block code-block-inline syntax-bash&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checks&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;--output&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;json&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checks&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;12345&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;--output&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;md&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checks&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;stats&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;--output&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;table&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;It&amp;#x27;s the same data you&amp;#x27;ll find in your Checkly web app, but rendered in text. Agents get parseable data they can reason about.&lt;/p&gt;&lt;p&gt;The new read commands cover the full monitoring setup:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;checks list&lt;/code&gt; : All checks with current status. Filter by name (&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;--search&lt;/code&gt;), tag (&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;--tag&lt;/code&gt;), or check type (&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;--type&lt;/code&gt;).&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;checks get &amp;lt;id&amp;gt;&lt;/code&gt; : Configuration, recent results, error groups, and analytics for a single check. Customize with &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;--stats-range&lt;/code&gt;, &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;--group-by&lt;/code&gt;, &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;--metrics&lt;/code&gt;, and &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;--filter-status&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;checks stats&lt;/code&gt; : Availability, response times, and key metrics across multiple checks at once.&lt;/li&gt;&lt;/ul&gt;&lt;div class=&quot;code-block code-block-inline syntax-bash&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-comment)&quot;&gt;# Stats for all production API checks over the last 7 days&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checks&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;stats&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;--range=last7Days&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;--tag=production&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;--type=API&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p class=&quot;block-img&quot;&gt;&lt;img src=&quot;https://images.prismic.io/checklyhq/acVbBpGXnQHGZAn0_checks-list.gif?auto=format,compress&quot; alt=&quot;Different output options of the checks list command.&quot;/&gt;&lt;/p&gt;&lt;p&gt;By exposing the monitoring data via the CLI, your agent now understands what an alert means and how to investigate. With access to your codebase, it can get to work and provide a fix.&lt;/p&gt;&lt;h2 id=&quot;incident-lifecycle-through-the-cli&quot;&gt;&lt;a href=&quot;#incident-lifecycle-through-the-cli&quot;&gt;Incident lifecycle through the CLI&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Once the agent (and you) decide that you&amp;#x27;re facing a real issue, it&amp;#x27;s time to communicate it. The CLI covers the full incident lifecycle on your status pages:&lt;/p&gt;&lt;div class=&quot;code-block code-block-inline syntax-bash&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;status-pages&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;          &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-comment)&quot;&gt;# discover your status pages&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;status-pages&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;d&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-comment)&quot;&gt;# inspect a specific page and its services&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;incidents&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;           &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-comment)&quot;&gt;# open a new incident&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;incidents&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;update&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;d&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-comment)&quot;&gt;# post a progress update&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;incidents&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;resolve&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;d&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;     &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-comment)&quot;&gt;# close the incident&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The same communication loop a human on-call would run: detect, communicate, resolve. But this time, you&amp;#x27;ll be faster, don&amp;#x27;t have to leave your terminal, and can supervise your agent to do the dirty work.&lt;/p&gt;&lt;p&gt;But isn&amp;#x27;t it dangerous to let your agent handle incidents? We thought so, too!&lt;/p&gt;&lt;h2 id=&quot;guardrails-safe-autonomy&quot;&gt;&lt;a href=&quot;#guardrails-safe-autonomy&quot;&gt;Guardrails: safe autonomy&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Providing agents read-only commands was an easy decision, but what if wrong reasoning could have real consequences? What if the agent accidentally opens an incident, updates your monitors without you reviewing, or destroys your entire Checkly project, thinking it&amp;#x27;s &amp;quot;absolutely right&amp;quot;?&lt;/p&gt;&lt;p&gt;These actions and commands are deep in the danger zone, and you definitely don&amp;#x27;t want to wake up your teammates because your agent misconfigured something while you were vibing the time of your life.&lt;/p&gt;&lt;p&gt;We thought about how to handle these situations and decided to implement agent guardrails. If your agent decides to declare a public incident or deploy your monitoring, they need to ask you for confirmation first.&lt;/p&gt;&lt;p&gt;Critical commands implement an agent confirmation protocol. The CLI detects agent usage by checking for environment variables that coding agents set automatically (like &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;CLAUDE_CODE&lt;/code&gt;, &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;CURSOR_SESSION&lt;/code&gt;, or &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;CODEX&lt;/code&gt;). If we detect that an agent is running a critical command, the CLI returns an exit code &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;2&lt;/code&gt; with a JSON envelope:&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;quot;status&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot;confirmation_required&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;quot;command&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot;incidents create&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;quot;changes&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot;Will create incident \\&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;Login flow broken\\&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot; on status page \\&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;Acme Store\\&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot;Severity: major&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  ]&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;quot;confirmCommand&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot;checkly incidents create --title=\\&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;Login flow broken\\&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot; ... --force&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This forces the agent to present the &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;changes&lt;/code&gt; to the user, wait for approval, and only then run the provided &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;confirmCommand&lt;/code&gt;.&lt;/p&gt;&lt;p class=&quot;block-img&quot;&gt;&lt;img src=&quot;https://images.prismic.io/checklyhq/acVcV5GXnQHGZApF_incident.gif?auto=format,compress&quot; alt=&quot;Guardrails in the Checkly incident command.&quot;/&gt;&lt;/p&gt;&lt;p&gt;And what if the agent gets it wrong? What if it misdiagnoses the root cause or opens an incident for a false positive? That&amp;#x27;s exactly why the confirmation protocol exists. &lt;strong&gt;The agent proposes, you approve.&lt;/strong&gt; A misdiagnosis becomes a learning moment, not an incident. The human stays in the loop for every action that has real-world consequences.&lt;/p&gt;&lt;h2 id=&quot;clis-are-the-new-agent-interface&quot;&gt;&lt;a href=&quot;#clis-are-the-new-agent-interface&quot;&gt;CLIs are the new agent interface&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;CLIs were built for humans first. But with a few design patterns, they become agent-ready. Here&amp;#x27;s what we learned building for both audiences:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Built-in documentation.&lt;/strong&gt; Don&amp;#x27;t make agents search the web or rely on external docs. Ship agent-optimized documentation inside the CLI itself. When the tooling updates, the docs update as well. Minimize stale knowledge and hallucinations.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Structured output.&lt;/strong&gt; Every read command should support machine-readable formats (&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;--output json&lt;/code&gt;, &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;--output md&lt;/code&gt;). Agents don’t care about colorful output, and humans shouldn&amp;#x27;t have to read raw JSON. Support both worlds.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Human/agent detection.&lt;/strong&gt; Some CLI flows need to behave differently depending on who&amp;#x27;s running them. Detect the caller through environment variables and adapt — interactive prompts for humans, structured JSON responses, and additional command information for agents.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Agent guardrails.&lt;/strong&gt; Critical commands need a confirmation protocol. Enforce human approval. Autonomy without oversight is just a liability.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;These patterns aren&amp;#x27;t Checkly-specific. They&amp;#x27;re how every CLI should think about agent users. One CLI, two audiences — and the design choices made for agents make things better for everyone.&lt;/p&gt;&lt;p&gt;Half of our CLI users are already agents. Keep them coming!&lt;/p&gt;&lt;h2 id=&quot;get-started&quot;&gt;&lt;a href=&quot;#get-started&quot;&gt;Get started&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Upgrade to the latest Checkly CLI:&lt;/p&gt;&lt;div class=&quot;code-block code-block-inline syntax-bash&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex pr-12&quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npm &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;install&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly@latest&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;button type=&quot;button&quot; class=&quot;group bg-inherit absolute rounded flex items-center justify-center top-0 right-0  text-white bg-inherit h-14 w-14&quot; title=&quot;Copy code to clipboard&quot;&gt;&lt;svg viewBox=&quot;0 0 16 11&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; class=&quot;absolute h-5 w-5 transition duration-200 ease-out text-checkly-blue -translate-y-2 opacity-0 scale-90&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M15.1085 0.558056C15.3526 0.802133 15.3526 1.19786 15.1085 1.44194L5.94187 10.6086C5.82466 10.7259 5.66568 10.7917 5.49992 10.7917C5.33416 10.7917 5.17519 10.7259 5.05798 10.6086L0.891309 6.44194C0.647232 6.19786 0.647233 5.80213 0.891312 5.55806C1.13539 5.31398 1.53112 5.31398 1.7752 5.55806L5.49992 9.28281L14.2246 0.55806C14.4687 0.313981 14.8644 0.31398 15.1085 0.558056Z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;svg viewBox=&quot;0 0 18 19&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; class=&quot;absolute h-5 w-5 transition duration-200 ease-out translate-y-0 opacity-100 scale-100 text-white/30 group-hover:text-white/80&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M5.875 8.85929C5.875 7.59364 6.90101 6.56763 8.16667 6.56763H15.6667C16.9323 6.56763 17.9583 7.59365 17.9583 8.85929V16.3593C17.9583 17.6249 16.9323 18.651 15.6667 18.651H8.16667C6.901 18.651 5.875 17.6249 5.875 16.3593V8.85929ZM8.16667 7.81763C7.59137 7.81763 7.125 8.28399 7.125 8.85929V16.3593C7.125 16.9346 7.59138 17.401 8.16667 17.401H15.6667C16.2419 17.401 16.7083 16.9346 16.7083 16.3593V8.85929C16.7083 8.28398 16.2419 7.81763 15.6667 7.81763H8.16667Z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M2.33464 1.98438C2.05836 1.98438 1.79341 2.09412 1.59807 2.28946C1.59807 2.28946 1.59807 2.28946 1.59807 2.28946M1.59807 2.28946C1.40272 2.48482 1.29297 2.74978 1.29297 3.02604V10.5261C1.29297 10.8023 1.4027 11.0672 1.59809 11.2626C1.79343 11.458 2.05838 11.5678 2.33464 11.5678H3.16797C3.51315 11.5678 3.79297 11.8476 3.79297 12.1928C3.79297 12.5379 3.51315 12.8178 3.16797 12.8178H2.33464C1.72684 12.8178 1.14393 12.5763 0.714149 12.1465C0.284418 11.7167 0.0429688 11.1338 0.0429688 10.5261V3.02604C0.0429688 2.41826 0.284405 1.83537 0.71417 1.40559C1.14395 0.975814 1.72686 0.734375 2.33464 0.734375H9.8346C10.4424 0.734375 11.0253 0.9758 11.4551 1.40563C11.8849 1.8354 12.1263 2.41827 12.1263 3.02604V3.85938C12.1263 4.20455 11.8465 4.48438 11.5013 4.48438C11.1561 4.48438 10.8763 4.20455 10.8763 3.85938V3.02604C10.8763 2.74979 10.7666 2.48485 10.5712 2.28949C10.3759 2.09419 10.111 1.98438 9.8346 1.98438H2.33464&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;p&gt;Install the Checkly skill:&lt;/p&gt;&lt;div class=&quot;code-block code-block-inline syntax-bash&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex pr-12&quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;skills&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;install&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;button type=&quot;button&quot; class=&quot;group bg-inherit absolute rounded flex items-center justify-center top-0 right-0  text-white bg-inherit h-14 w-14&quot; title=&quot;Copy code to clipboard&quot;&gt;&lt;svg viewBox=&quot;0 0 16 11&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; class=&quot;absolute h-5 w-5 transition duration-200 ease-out text-checkly-blue -translate-y-2 opacity-0 scale-90&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M15.1085 0.558056C15.3526 0.802133 15.3526 1.19786 15.1085 1.44194L5.94187 10.6086C5.82466 10.7259 5.66568 10.7917 5.49992 10.7917C5.33416 10.7917 5.17519 10.7259 5.05798 10.6086L0.891309 6.44194C0.647232 6.19786 0.647233 5.80213 0.891312 5.55806C1.13539 5.31398 1.53112 5.31398 1.7752 5.55806L5.49992 9.28281L14.2246 0.55806C14.4687 0.313981 14.8644 0.31398 15.1085 0.558056Z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;svg viewBox=&quot;0 0 18 19&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; class=&quot;absolute h-5 w-5 transition duration-200 ease-out translate-y-0 opacity-100 scale-100 text-white/30 group-hover:text-white/80&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M5.875 8.85929C5.875 7.59364 6.90101 6.56763 8.16667 6.56763H15.6667C16.9323 6.56763 17.9583 7.59365 17.9583 8.85929V16.3593C17.9583 17.6249 16.9323 18.651 15.6667 18.651H8.16667C6.901 18.651 5.875 17.6249 5.875 16.3593V8.85929ZM8.16667 7.81763C7.59137 7.81763 7.125 8.28399 7.125 8.85929V16.3593C7.125 16.9346 7.59138 17.401 8.16667 17.401H15.6667C16.2419 17.401 16.7083 16.9346 16.7083 16.3593V8.85929C16.7083 8.28398 16.2419 7.81763 15.6667 7.81763H8.16667Z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M2.33464 1.98438C2.05836 1.98438 1.79341 2.09412 1.59807 2.28946C1.59807 2.28946 1.59807 2.28946 1.59807 2.28946M1.59807 2.28946C1.40272 2.48482 1.29297 2.74978 1.29297 3.02604V10.5261C1.29297 10.8023 1.4027 11.0672 1.59809 11.2626C1.79343 11.458 2.05838 11.5678 2.33464 11.5678H3.16797C3.51315 11.5678 3.79297 11.8476 3.79297 12.1928C3.79297 12.5379 3.51315 12.8178 3.16797 12.8178H2.33464C1.72684 12.8178 1.14393 12.5763 0.714149 12.1465C0.284418 11.7167 0.0429688 11.1338 0.0429688 10.5261V3.02604C0.0429688 2.41826 0.284405 1.83537 0.71417 1.40559C1.14395 0.975814 1.72686 0.734375 2.33464 0.734375H9.8346C10.4424 0.734375 11.0253 0.9758 11.4551 1.40563C11.8849 1.8354 12.1263 2.41827 12.1263 3.02604V3.85938C12.1263 4.20455 11.8465 4.48438 11.5013 4.48438C11.1561 4.48438 10.8763 4.20455 10.8763 3.85938V3.02604C10.8763 2.74979 10.7666 2.48485 10.5712 2.28949C10.3759 2.09419 10.111 1.98438 9.8346 1.98438H2.33464&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;p&gt;Or, if you don’t have Checkly set up yet. Tell your agent the following:&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex pr-12&quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;Run &amp;#39;npx checkly skills initialize&amp;#39; and follow the instructions.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;button type=&quot;button&quot; class=&quot;group bg-inherit absolute rounded flex items-center justify-center top-0 right-0  text-white bg-inherit h-16 w-16&quot; title=&quot;Copy code to clipboard&quot;&gt;&lt;svg viewBox=&quot;0 0 16 11&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; class=&quot;absolute h-5 w-5 transition duration-200 ease-out text-checkly-blue -translate-y-2 opacity-0 scale-90&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M15.1085 0.558056C15.3526 0.802133 15.3526 1.19786 15.1085 1.44194L5.94187 10.6086C5.82466 10.7259 5.66568 10.7917 5.49992 10.7917C5.33416 10.7917 5.17519 10.7259 5.05798 10.6086L0.891309 6.44194C0.647232 6.19786 0.647233 5.80213 0.891312 5.55806C1.13539 5.31398 1.53112 5.31398 1.7752 5.55806L5.49992 9.28281L14.2246 0.55806C14.4687 0.313981 14.8644 0.31398 15.1085 0.558056Z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;svg viewBox=&quot;0 0 18 19&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; class=&quot;absolute h-5 w-5 transition duration-200 ease-out translate-y-0 opacity-100 scale-100 text-white/30 group-hover:text-white/80&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M5.875 8.85929C5.875 7.59364 6.90101 6.56763 8.16667 6.56763H15.6667C16.9323 6.56763 17.9583 7.59365 17.9583 8.85929V16.3593C17.9583 17.6249 16.9323 18.651 15.6667 18.651H8.16667C6.901 18.651 5.875 17.6249 5.875 16.3593V8.85929ZM8.16667 7.81763C7.59137 7.81763 7.125 8.28399 7.125 8.85929V16.3593C7.125 16.9346 7.59138 17.401 8.16667 17.401H15.6667C16.2419 17.401 16.7083 16.9346 16.7083 16.3593V8.85929C16.7083 8.28398 16.2419 7.81763 15.6667 7.81763H8.16667Z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M2.33464 1.98438C2.05836 1.98438 1.79341 2.09412 1.59807 2.28946C1.59807 2.28946 1.59807 2.28946 1.59807 2.28946M1.59807 2.28946C1.40272 2.48482 1.29297 2.74978 1.29297 3.02604V10.5261C1.29297 10.8023 1.4027 11.0672 1.59809 11.2626C1.79343 11.458 2.05838 11.5678 2.33464 11.5678H3.16797C3.51315 11.5678 3.79297 11.8476 3.79297 12.1928C3.79297 12.5379 3.51315 12.8178 3.16797 12.8178H2.33464C1.72684 12.8178 1.14393 12.5763 0.714149 12.1465C0.284418 11.7167 0.0429688 11.1338 0.0429688 10.5261V3.02604C0.0429688 2.41826 0.284405 1.83537 0.71417 1.40559C1.14395 0.975814 1.72686 0.734375 2.33464 0.734375H9.8346C10.4424 0.734375 11.0253 0.9758 11.4551 1.40563C11.8849 1.8354 12.1263 2.41827 12.1263 3.02604V3.85938C12.1263 4.20455 11.8465 4.48438 11.5013 4.48438C11.1561 4.48438 10.8763 4.20455 10.8763 3.85938V3.02604C10.8763 2.74979 10.7666 2.48485 10.5712 2.28949C10.3759 2.09419 10.111 1.98438 9.8346 1.98438H2.33464&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;p&gt;It will figure out the rest.&lt;/p&gt;]]&gt;</content:encoded></item><item><title><![CDATA[Checkly and the Agentic Software Layer]]></title><description><![CDATA[CLIs are the new agent interface. Discover how Checkly turned its CLI into an agentic layer with built-in skills, structured output, and confirmation protocols for safe autonomous monitoring.]]></description><link>https://www.checklyhq.com/blog/the-agentic-software-layer</link><guid isPermaLink="false">acVVMhoAAEsAur7R</guid><category><![CDATA[AI]]></category><dc:creator><![CDATA[Hannes Lenke]]></dc:creator><pubDate>Thu, 26 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;p&gt;November 24th, the &lt;a target=&quot;_blank&quot; href=&quot;https://www.anthropic.com/news/claude-opus-4-5&quot; rel=&quot;noreferrer&quot;&gt;Opus 4.5 release&lt;/a&gt; turned around the entire tech industry. This was the moment when agents became capable. Capable enough to write solid staff-level code. Capable enough to reason about alerts, investigate root causes much faster than most engineers, and set up the reliability layer faster.&lt;/p&gt;&lt;p&gt;For me, this feels like an iPhone moment on steroids; the adoption of AI is accelerating much faster than any adoption curve I’ve seen over the past few decades. This rapid growth is fueled by early adopters who experienced their eureka moments early on, followed by many startup CEOs who have been actively developing prompting software during the holidays, making significant progress 10x quicker than ever before.&lt;/p&gt;&lt;p&gt;Now, AI is a topic in every customer conversation. While it took years to adopt DevOps, AI is on track to outpace that by a wide margin; in fact, it is already surpassing it.&lt;/p&gt;&lt;p&gt;The rise of AI agents introduced a new user of developer tools, one that doesn&amp;#x27;t click buttons, doesn&amp;#x27;t read dashboards, and doesn&amp;#x27;t care about your beautifully designed settings page. Agents live in the terminal. They reason over text. Over the last few years, we introduced &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/learn/monitoring/monitoring-as-code/&quot; rel=&quot;noreferrer&quot;&gt;Monitoring as Code (MaC)&lt;/a&gt;, a workflow that enables developers to own reliability; in text. Accidentally, MaC is exactly what agents need.&lt;/p&gt;&lt;p&gt;You can see where we are going here. The work we did to make Checkly great for developers turns out to be the groundwork for making Checkly great for agents.&lt;/p&gt;&lt;p&gt;But &amp;quot;accidentally ready&amp;quot; isn’t a strategy - it was an opportunity.&lt;/p&gt;&lt;h2 id=&quot;three-layers-of-software-interfaces&quot;&gt;&lt;a href=&quot;#three-layers-of-software-interfaces&quot;&gt;Three Layers of Software Interfaces&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Every software platform serves its users through interfaces. Historically, there have been two, sometimes three:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;UIs&lt;/strong&gt; are built for humans. They&amp;#x27;re visual, interactive, optimized for comprehension and exploration. Dashboards, forms, drag-and-drop builders. These are how people interact with software.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;APIs&lt;/strong&gt; are built for machines. They&amp;#x27;re structured, predictable, and designed for integration between systems. CI/CD pipelines, webhooks, Terraform providers. This is how humans have automated software.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;CLIs&lt;/strong&gt; are built to enable engineers to scale and automate their interactions with APIs. Especially, but not only for developer tools.&lt;/p&gt;&lt;p&gt;Turns out &lt;strong&gt;CLIs are great interfaces and became the agentic layer,&lt;/strong&gt; and this is new. AI agents don&amp;#x27;t need pixel-perfect UIs or REST endpoints designed for static integrations. They need CLIs that output structured data in Markdown or JSON. They need progressive self-discovery, a way to explore capabilities without reading documentation. They need confirmation protocols for dangerous actions.&lt;/p&gt;&lt;p&gt;Most monitoring platforms were built for layer one. Some invested in layers two and three. Checkly is the first to double down on a new and redefined third layer. An application layer optimized for agents and for the modern software factory.&lt;/p&gt;&lt;h2 id=&quot;why-code-&amp;amp;-cli-first-platforms-win&quot;&gt;&lt;a href=&quot;#why-code-&amp;amp;-cli-first-platforms-win&quot;&gt;Why Code &amp;amp; CLI-First Platforms Win&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Here&amp;#x27;s the thing about Monitoring as Code: it was already agent-friendly before agents existed.&lt;/p&gt;&lt;p&gt;When your monitoring lives in &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;.ts&lt;/code&gt; files alongside your application code, an AI agent can read it, reason about it, generate new tests and checks, and deploy them the same way it works with any other code in your repository. There&amp;#x27;s no proprietary DSL to learn, no UI to scrape, no brittle browser automation required.&lt;/p&gt;&lt;p&gt;An agent working with the Checkly CLI can open your &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;__checks__&lt;/code&gt; directory, understand what&amp;#x27;s being monitored, identify gaps, write new checks using standard Playwright syntax, run &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;npx checkly test&lt;/code&gt; to validate against our global infrastructure, and &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;npx checkly deploy&lt;/code&gt; to ship the entire monitoring setup. Every step happens in the terminal, in code, using tools the agent already knows.&lt;/p&gt;&lt;p&gt;Legacy monitoring platforms trapped behind proprietary UIs and frameworks can&amp;#x27;t offer this. They&amp;#x27;ll bolt on a chatbot and call it AI. That&amp;#x27;s &lt;strong&gt;not&lt;/strong&gt; the agentic layer: that&amp;#x27;s an AI-colored coat of paint.&lt;/p&gt;&lt;h2 id=&quot;making-the-implicit-explicit&quot;&gt;&lt;a href=&quot;#making-the-implicit-explicit&quot;&gt;Making the Implicit Explicit&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Being code &amp;amp; CLI-first gave Checkly the agentic head start. But a head start doesn’t finish the race. We&amp;#x27;ve shipped a new set of capabilities designed for the speed of this new world and purpose-built for agents.&lt;/p&gt;&lt;h3 id=&quot;teaching-your-agent-testing-and-monitoring&quot;&gt;&lt;a href=&quot;#teaching-your-agent-testing-and-monitoring&quot;&gt;Teaching your Agent Testing and Monitoring&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Your agent understands how to configure Checkly today, because it can read the &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;checkly.config&lt;/code&gt; and &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;check.ts&lt;/code&gt; files. It also includes Checkly code in its training data, and if nothing else works, it can still fetch the docs to troubleshoot. But we thought, what if we could make it even easier?&lt;/p&gt;&lt;p&gt;Agent Skills are an open standard supported by Claude Code, Cursor, OpenAI Codex, and GitHub Copilot. Skills are providing agents with specialized knowledge on demand. &lt;strong&gt;Most skills out there are static files, though.&lt;/strong&gt; We thought we could do better than providing some Markdown files!&lt;/p&gt;&lt;p&gt;Install the Checkly skill and see the magic happen:&lt;/p&gt;&lt;div class=&quot;code-block code-block-inline syntax-bash&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex pr-12&quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;skills&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;install&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;button type=&quot;button&quot; class=&quot;group bg-inherit absolute rounded flex items-center justify-center top-0 right-0  text-white bg-inherit h-14 w-14&quot; title=&quot;Copy code to clipboard&quot;&gt;&lt;svg viewBox=&quot;0 0 16 11&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; class=&quot;absolute h-5 w-5 transition duration-200 ease-out text-checkly-blue -translate-y-2 opacity-0 scale-90&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M15.1085 0.558056C15.3526 0.802133 15.3526 1.19786 15.1085 1.44194L5.94187 10.6086C5.82466 10.7259 5.66568 10.7917 5.49992 10.7917C5.33416 10.7917 5.17519 10.7259 5.05798 10.6086L0.891309 6.44194C0.647232 6.19786 0.647233 5.80213 0.891312 5.55806C1.13539 5.31398 1.53112 5.31398 1.7752 5.55806L5.49992 9.28281L14.2246 0.55806C14.4687 0.313981 14.8644 0.31398 15.1085 0.558056Z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;svg viewBox=&quot;0 0 18 19&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; class=&quot;absolute h-5 w-5 transition duration-200 ease-out translate-y-0 opacity-100 scale-100 text-white/30 group-hover:text-white/80&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M5.875 8.85929C5.875 7.59364 6.90101 6.56763 8.16667 6.56763H15.6667C16.9323 6.56763 17.9583 7.59365 17.9583 8.85929V16.3593C17.9583 17.6249 16.9323 18.651 15.6667 18.651H8.16667C6.901 18.651 5.875 17.6249 5.875 16.3593V8.85929ZM8.16667 7.81763C7.59137 7.81763 7.125 8.28399 7.125 8.85929V16.3593C7.125 16.9346 7.59138 17.401 8.16667 17.401H15.6667C16.2419 17.401 16.7083 16.9346 16.7083 16.3593V8.85929C16.7083 8.28398 16.2419 7.81763 15.6667 7.81763H8.16667Z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M2.33464 1.98438C2.05836 1.98438 1.79341 2.09412 1.59807 2.28946C1.59807 2.28946 1.59807 2.28946 1.59807 2.28946M1.59807 2.28946C1.40272 2.48482 1.29297 2.74978 1.29297 3.02604V10.5261C1.29297 10.8023 1.4027 11.0672 1.59809 11.2626C1.79343 11.458 2.05838 11.5678 2.33464 11.5678H3.16797C3.51315 11.5678 3.79297 11.8476 3.79297 12.1928C3.79297 12.5379 3.51315 12.8178 3.16797 12.8178H2.33464C1.72684 12.8178 1.14393 12.5763 0.714149 12.1465C0.284418 11.7167 0.0429688 11.1338 0.0429688 10.5261V3.02604C0.0429688 2.41826 0.284405 1.83537 0.71417 1.40559C1.14395 0.975814 1.72686 0.734375 2.33464 0.734375H9.8346C10.4424 0.734375 11.0253 0.9758 11.4551 1.40563C11.8849 1.8354 12.1263 2.41827 12.1263 3.02604V3.85938C12.1263 4.20455 11.8465 4.48438 11.5013 4.48438C11.1561 4.48438 10.8763 4.20455 10.8763 3.85938V3.02604C10.8763 2.74979 10.7666 2.48485 10.5712 2.28949C10.3759 2.09419 10.111 1.98438 9.8346 1.98438H2.33464&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;p&gt;The Checkly &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;SKILL.md&lt;/code&gt; file is your agents entry point to learn how to set up, configure and handle Checkly testing and monitoring. However, the static file doesn&amp;#x27;t include all the Checkly information. The Checkly skill is only a thin wrapper around the new &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;npx checkly skills&lt;/code&gt; command. The new command that teaches your agent where to find construct documentation, other CLI commands, and monitoring workflows right in the CLI itself using &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;npx checkly skills&lt;/code&gt;.&lt;/p&gt;&lt;p class=&quot;block-img&quot;&gt;&lt;img src=&quot;https://images.prismic.io/checklyhq/acVhqJGXnQHGZAvZ_agentic-learn-ezgif.com-video-to-gif-converter.gif?auto=format,compress&quot;/&gt;&lt;/p&gt;&lt;p&gt;Once your agent discovers the &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;npx checkly skills&lt;/code&gt; it can access agent-optimized docs to initialize, configure and manage the entire testing and monitoring setup. There&amp;#x27;s no relying on training data, no docs browsing, no context window compacting. Agents access the right docs when they need them.&lt;/p&gt;&lt;p&gt;But what does this mean in practice?&lt;/p&gt;&lt;h3 id=&quot;creating-your-monitoring-checks&quot;&gt;&lt;a href=&quot;#creating-your-monitoring-checks&quot;&gt;Creating your Monitoring Checks&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The big difference between the agentic CLI layer and built-in product AI is that agents already understand and manage your codebase. They read and write files all day. With the right tools, coding agents have all the context they need to automatically set up and test your monitoring.&lt;/p&gt;&lt;p class=&quot;block-img&quot;&gt;&lt;img src=&quot;https://images.prismic.io/checklyhq/acVhqZGXnQHGZAva_agentic-product-create-ezgif.com-video-to-gif-converter.gif?auto=format,compress&quot;/&gt;&lt;/p&gt;&lt;p&gt;Your API endpoints, your login flows, your business logic; agents know about all of it. Task them to set up the monitoring and see your agent doing the work! In the previous world, you didn&amp;#x27;t have the time and energy to manage monitors for every page, endpoint, or application flow; now you do because your agent never gets tired.&lt;/p&gt;&lt;p&gt;Now, your agent can create, test, and deploy your entire monitoring!&lt;/p&gt;&lt;p&gt;More monitors also mean more alerts. Could your agent handle these, too?&lt;/p&gt;&lt;h3 id=&quot;investigating-failures-and-monitoring-results&quot;&gt;&lt;a href=&quot;#investigating-failures-and-monitoring-results&quot;&gt;Investigating Failures and Monitoring Results&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;If you received a monitoring alert in the old world, you usually log in to Checkly to understand what check failed and what triggered the alert. And while your agent could log in via a browser, it shouldn&amp;#x27;t need to do that to understand your monitoring setup.&lt;/p&gt;&lt;p&gt;A new set of read commands lets agents query and analyze your monitoring setup directly from the terminal:&lt;/p&gt;&lt;div class=&quot;code-block code-block-inline syntax-bash&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex pr-12&quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-comment)&quot;&gt;# List all production API checks&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checks&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;--tag=production&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;--type=API&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;--output=json&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-comment)&quot;&gt;# Get 7-day stats for a check, grouped by location&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checks&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;12345&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;--stats-range=last7Days&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;--group-by=location&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-comment)&quot;&gt;# Analytics across all checks tagged &amp;quot;critical&amp;quot; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checks&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;stats&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;--tag=critical&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;--range=last7Days&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;button type=&quot;button&quot; class=&quot;group bg-inherit absolute rounded flex items-center justify-center top-0 right-0  text-white bg-inherit h-14 w-14&quot; title=&quot;Copy code to clipboard&quot;&gt;&lt;svg viewBox=&quot;0 0 16 11&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; class=&quot;absolute h-5 w-5 transition duration-200 ease-out text-checkly-blue -translate-y-2 opacity-0 scale-90&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M15.1085 0.558056C15.3526 0.802133 15.3526 1.19786 15.1085 1.44194L5.94187 10.6086C5.82466 10.7259 5.66568 10.7917 5.49992 10.7917C5.33416 10.7917 5.17519 10.7259 5.05798 10.6086L0.891309 6.44194C0.647232 6.19786 0.647233 5.80213 0.891312 5.55806C1.13539 5.31398 1.53112 5.31398 1.7752 5.55806L5.49992 9.28281L14.2246 0.55806C14.4687 0.313981 14.8644 0.31398 15.1085 0.558056Z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;svg viewBox=&quot;0 0 18 19&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; class=&quot;absolute h-5 w-5 transition duration-200 ease-out translate-y-0 opacity-100 scale-100 text-white/30 group-hover:text-white/80&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M5.875 8.85929C5.875 7.59364 6.90101 6.56763 8.16667 6.56763H15.6667C16.9323 6.56763 17.9583 7.59365 17.9583 8.85929V16.3593C17.9583 17.6249 16.9323 18.651 15.6667 18.651H8.16667C6.901 18.651 5.875 17.6249 5.875 16.3593V8.85929ZM8.16667 7.81763C7.59137 7.81763 7.125 8.28399 7.125 8.85929V16.3593C7.125 16.9346 7.59138 17.401 8.16667 17.401H15.6667C16.2419 17.401 16.7083 16.9346 16.7083 16.3593V8.85929C16.7083 8.28398 16.2419 7.81763 15.6667 7.81763H8.16667Z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M2.33464 1.98438C2.05836 1.98438 1.79341 2.09412 1.59807 2.28946C1.59807 2.28946 1.59807 2.28946 1.59807 2.28946M1.59807 2.28946C1.40272 2.48482 1.29297 2.74978 1.29297 3.02604V10.5261C1.29297 10.8023 1.4027 11.0672 1.59809 11.2626C1.79343 11.458 2.05838 11.5678 2.33464 11.5678H3.16797C3.51315 11.5678 3.79297 11.8476 3.79297 12.1928C3.79297 12.5379 3.51315 12.8178 3.16797 12.8178H2.33464C1.72684 12.8178 1.14393 12.5763 0.714149 12.1465C0.284418 11.7167 0.0429688 11.1338 0.0429688 10.5261V3.02604C0.0429688 2.41826 0.284405 1.83537 0.71417 1.40559C1.14395 0.975814 1.72686 0.734375 2.33464 0.734375H9.8346C10.4424 0.734375 11.0253 0.9758 11.4551 1.40563C11.8849 1.8354 12.1263 2.41827 12.1263 3.02604V3.85938C12.1263 4.20455 11.8465 4.48438 11.5013 4.48438C11.1561 4.48438 10.8763 4.20455 10.8763 3.85938V3.02604C10.8763 2.74979 10.7666 2.48485 10.5712 2.28949C10.3759 2.09419 10.111 1.98438 9.8346 1.98438H2.33464&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;p&gt;Every command supports &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;--output table|json|md&lt;/code&gt; — table for humans, JSON and Markdown for programmatic agent consumption. Metric defaults adapt to check type: response time percentiles for API checks, Web Vitals for browser checks, latency and packet loss for ICMP.&lt;/p&gt;&lt;p class=&quot;block-img&quot;&gt;&lt;img src=&quot;https://images.prismic.io/checklyhq/acVX35GXnQHGZAjY_listimage.png?auto=format,compress&quot;/&gt;&lt;/p&gt;&lt;p&gt;With these new commands, your agent can access all the monitoring information you usually look at in the Checkly dashboard. Pair this ability with code access and let your agent figure out the issue.&lt;/p&gt;&lt;p class=&quot;block-img&quot;&gt;&lt;img src=&quot;https://images.prismic.io/checklyhq/acVhp5GXnQHGZAvY_agent-alert-ezgif.com-video-to-gif-converter.gif?auto=format,compress&quot;/&gt;&lt;/p&gt;&lt;p&gt;Detecting issues is only one part of the story. Could your agent communicate issues, too?&lt;/p&gt;&lt;h3 id=&quot;acting-on-incidents&quot;&gt;&lt;a href=&quot;#acting-on-incidents&quot;&gt;Acting On Incidents&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Agents can manage the full incident lifecycle on your status pages.&lt;/p&gt;&lt;div class=&quot;code-block code-block-inline syntax-bash&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex pr-12&quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;incidents&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;--status-page-id&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;d&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;--title=&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot;API degradation&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;--severity=minor&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;incidents&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;update&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;d&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;--message=&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot;Root cause identified&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;incidents&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;resolve&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;d&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;button type=&quot;button&quot; class=&quot;group bg-inherit absolute rounded flex items-center justify-center top-0 right-0  text-white bg-inherit h-14 w-14&quot; title=&quot;Copy code to clipboard&quot;&gt;&lt;svg viewBox=&quot;0 0 16 11&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; class=&quot;absolute h-5 w-5 transition duration-200 ease-out text-checkly-blue -translate-y-2 opacity-0 scale-90&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M15.1085 0.558056C15.3526 0.802133 15.3526 1.19786 15.1085 1.44194L5.94187 10.6086C5.82466 10.7259 5.66568 10.7917 5.49992 10.7917C5.33416 10.7917 5.17519 10.7259 5.05798 10.6086L0.891309 6.44194C0.647232 6.19786 0.647233 5.80213 0.891312 5.55806C1.13539 5.31398 1.53112 5.31398 1.7752 5.55806L5.49992 9.28281L14.2246 0.55806C14.4687 0.313981 14.8644 0.31398 15.1085 0.558056Z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;svg viewBox=&quot;0 0 18 19&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; class=&quot;absolute h-5 w-5 transition duration-200 ease-out translate-y-0 opacity-100 scale-100 text-white/30 group-hover:text-white/80&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M5.875 8.85929C5.875 7.59364 6.90101 6.56763 8.16667 6.56763H15.6667C16.9323 6.56763 17.9583 7.59365 17.9583 8.85929V16.3593C17.9583 17.6249 16.9323 18.651 15.6667 18.651H8.16667C6.901 18.651 5.875 17.6249 5.875 16.3593V8.85929ZM8.16667 7.81763C7.59137 7.81763 7.125 8.28399 7.125 8.85929V16.3593C7.125 16.9346 7.59138 17.401 8.16667 17.401H15.6667C16.2419 17.401 16.7083 16.9346 16.7083 16.3593V8.85929C16.7083 8.28398 16.2419 7.81763 15.6667 7.81763H8.16667Z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M2.33464 1.98438C2.05836 1.98438 1.79341 2.09412 1.59807 2.28946C1.59807 2.28946 1.59807 2.28946 1.59807 2.28946M1.59807 2.28946C1.40272 2.48482 1.29297 2.74978 1.29297 3.02604V10.5261C1.29297 10.8023 1.4027 11.0672 1.59809 11.2626C1.79343 11.458 2.05838 11.5678 2.33464 11.5678H3.16797C3.51315 11.5678 3.79297 11.8476 3.79297 12.1928C3.79297 12.5379 3.51315 12.8178 3.16797 12.8178H2.33464C1.72684 12.8178 1.14393 12.5763 0.714149 12.1465C0.284418 11.7167 0.0429688 11.1338 0.0429688 10.5261V3.02604C0.0429688 2.41826 0.284405 1.83537 0.71417 1.40559C1.14395 0.975814 1.72686 0.734375 2.33464 0.734375H9.8346C10.4424 0.734375 11.0253 0.9758 11.4551 1.40563C11.8849 1.8354 12.1263 2.41827 12.1263 3.02604V3.85938C12.1263 4.20455 11.8465 4.48438 11.5013 4.48438C11.1561 4.48438 10.8763 4.20455 10.8763 3.85938V3.02604C10.8763 2.74979 10.7666 2.48485 10.5712 2.28949C10.3759 2.09419 10.111 1.98438 9.8346 1.98438H2.33464&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;p&gt;Write commands implement a confirmation protocol designed for agent safety. When an agent runs a destructive or public-facing command, the CLI returns a JSON envelope describing the changes and provides a confirmation command.&lt;/p&gt;&lt;p class=&quot;block-img&quot;&gt;&lt;img src=&quot;https://images.prismic.io/checklyhq/acViRpGXnQHGZAwe_agent-incident-ezgif.com-video-to-gif-converter.gif?auto=format,compress&quot;/&gt;&lt;/p&gt;&lt;p&gt;This enforced confirmation is critical. Agents that can take action without guardrails are a liability. Agents with structured confirmation flows are a force multiplier.&lt;/p&gt;&lt;p&gt;If you put all these features together, your agent can handle your entire incident management while you drink your coffee. Don&amp;#x27;t believe me? &lt;a target=&quot;_blank&quot; href=&quot;https://www.youtube.com/watch?v=wkP21FuZx4c&quot; rel=&quot;noreferrer&quot;&gt;Here&amp;#x27;s a video showing it entirely&lt;/a&gt;.&lt;/p&gt;&lt;h2 id=&quot;the-agentic-layer-is-here&quot;&gt;&lt;a href=&quot;#the-agentic-layer-is-here&quot;&gt;The Agentic Layer is Here&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The shift to AI agents isn&amp;#x27;t coming. It&amp;#x27;s happening now. 50% percent of our active CLI users are already agents.&lt;/p&gt;&lt;p class=&quot;block-img&quot;&gt;&lt;img src=&quot;https://images.prismic.io/checklyhq/acVVrpGXnQHGZAdk_agentic-cli-users.png?auto=format,compress&quot; alt=&quot;Graph showing that 50% CLI users are human and 50% agents.&quot;/&gt;&lt;/p&gt;&lt;p&gt;Development teams are using Claude Code, Cursor, and Copilot to write, test, and ship code. The tools in their stack that can&amp;#x27;t participate in that workflow will be replaced by tools that can.&lt;/p&gt;&lt;p&gt;Checkly is built for this moment. Upgrade your CLI, install the skill, and point your agent at your monitoring.&lt;/p&gt;&lt;div class=&quot;code-block code-block-inline syntax-bash&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex pr-12&quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npm &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;install&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly@latest&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;skills&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;install&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;button type=&quot;button&quot; class=&quot;group bg-inherit absolute rounded flex items-center justify-center top-0 right-0  text-white bg-inherit h-14 w-14&quot; title=&quot;Copy code to clipboard&quot;&gt;&lt;svg viewBox=&quot;0 0 16 11&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; class=&quot;absolute h-5 w-5 transition duration-200 ease-out text-checkly-blue -translate-y-2 opacity-0 scale-90&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M15.1085 0.558056C15.3526 0.802133 15.3526 1.19786 15.1085 1.44194L5.94187 10.6086C5.82466 10.7259 5.66568 10.7917 5.49992 10.7917C5.33416 10.7917 5.17519 10.7259 5.05798 10.6086L0.891309 6.44194C0.647232 6.19786 0.647233 5.80213 0.891312 5.55806C1.13539 5.31398 1.53112 5.31398 1.7752 5.55806L5.49992 9.28281L14.2246 0.55806C14.4687 0.313981 14.8644 0.31398 15.1085 0.558056Z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;svg viewBox=&quot;0 0 18 19&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; class=&quot;absolute h-5 w-5 transition duration-200 ease-out translate-y-0 opacity-100 scale-100 text-white/30 group-hover:text-white/80&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M5.875 8.85929C5.875 7.59364 6.90101 6.56763 8.16667 6.56763H15.6667C16.9323 6.56763 17.9583 7.59365 17.9583 8.85929V16.3593C17.9583 17.6249 16.9323 18.651 15.6667 18.651H8.16667C6.901 18.651 5.875 17.6249 5.875 16.3593V8.85929ZM8.16667 7.81763C7.59137 7.81763 7.125 8.28399 7.125 8.85929V16.3593C7.125 16.9346 7.59138 17.401 8.16667 17.401H15.6667C16.2419 17.401 16.7083 16.9346 16.7083 16.3593V8.85929C16.7083 8.28398 16.2419 7.81763 15.6667 7.81763H8.16667Z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M2.33464 1.98438C2.05836 1.98438 1.79341 2.09412 1.59807 2.28946C1.59807 2.28946 1.59807 2.28946 1.59807 2.28946M1.59807 2.28946C1.40272 2.48482 1.29297 2.74978 1.29297 3.02604V10.5261C1.29297 10.8023 1.4027 11.0672 1.59809 11.2626C1.79343 11.458 2.05838 11.5678 2.33464 11.5678H3.16797C3.51315 11.5678 3.79297 11.8476 3.79297 12.1928C3.79297 12.5379 3.51315 12.8178 3.16797 12.8178H2.33464C1.72684 12.8178 1.14393 12.5763 0.714149 12.1465C0.284418 11.7167 0.0429688 11.1338 0.0429688 10.5261V3.02604C0.0429688 2.41826 0.284405 1.83537 0.71417 1.40559C1.14395 0.975814 1.72686 0.734375 2.33464 0.734375H9.8346C10.4424 0.734375 11.0253 0.9758 11.4551 1.40563C11.8849 1.8354 12.1263 2.41827 12.1263 3.02604V3.85938C12.1263 4.20455 11.8465 4.48438 11.5013 4.48438C11.1561 4.48438 10.8763 4.20455 10.8763 3.85938V3.02604C10.8763 2.74979 10.7666 2.48485 10.5712 2.28949C10.3759 2.09419 10.111 1.98438 9.8346 1.98438H2.33464&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;p&gt;… or, if you don’t have Checkly set up yet. Tell your agent the following:&lt;/p&gt;&lt;div class=&quot;code-block code-block-inline syntax-bash&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex pr-12&quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;Run &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;#39;npx checkly skills initialize&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;and&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;follow&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;the&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;instructions.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;button type=&quot;button&quot; class=&quot;group bg-inherit absolute rounded flex items-center justify-center top-0 right-0  text-white bg-inherit h-14 w-14&quot; title=&quot;Copy code to clipboard&quot;&gt;&lt;svg viewBox=&quot;0 0 16 11&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; class=&quot;absolute h-5 w-5 transition duration-200 ease-out text-checkly-blue -translate-y-2 opacity-0 scale-90&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M15.1085 0.558056C15.3526 0.802133 15.3526 1.19786 15.1085 1.44194L5.94187 10.6086C5.82466 10.7259 5.66568 10.7917 5.49992 10.7917C5.33416 10.7917 5.17519 10.7259 5.05798 10.6086L0.891309 6.44194C0.647232 6.19786 0.647233 5.80213 0.891312 5.55806C1.13539 5.31398 1.53112 5.31398 1.7752 5.55806L5.49992 9.28281L14.2246 0.55806C14.4687 0.313981 14.8644 0.31398 15.1085 0.558056Z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;svg viewBox=&quot;0 0 18 19&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; class=&quot;absolute h-5 w-5 transition duration-200 ease-out translate-y-0 opacity-100 scale-100 text-white/30 group-hover:text-white/80&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M5.875 8.85929C5.875 7.59364 6.90101 6.56763 8.16667 6.56763H15.6667C16.9323 6.56763 17.9583 7.59365 17.9583 8.85929V16.3593C17.9583 17.6249 16.9323 18.651 15.6667 18.651H8.16667C6.901 18.651 5.875 17.6249 5.875 16.3593V8.85929ZM8.16667 7.81763C7.59137 7.81763 7.125 8.28399 7.125 8.85929V16.3593C7.125 16.9346 7.59138 17.401 8.16667 17.401H15.6667C16.2419 17.401 16.7083 16.9346 16.7083 16.3593V8.85929C16.7083 8.28398 16.2419 7.81763 15.6667 7.81763H8.16667Z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M2.33464 1.98438C2.05836 1.98438 1.79341 2.09412 1.59807 2.28946C1.59807 2.28946 1.59807 2.28946 1.59807 2.28946M1.59807 2.28946C1.40272 2.48482 1.29297 2.74978 1.29297 3.02604V10.5261C1.29297 10.8023 1.4027 11.0672 1.59809 11.2626C1.79343 11.458 2.05838 11.5678 2.33464 11.5678H3.16797C3.51315 11.5678 3.79297 11.8476 3.79297 12.1928C3.79297 12.5379 3.51315 12.8178 3.16797 12.8178H2.33464C1.72684 12.8178 1.14393 12.5763 0.714149 12.1465C0.284418 11.7167 0.0429688 11.1338 0.0429688 10.5261V3.02604C0.0429688 2.41826 0.284405 1.83537 0.71417 1.40559C1.14395 0.975814 1.72686 0.734375 2.33464 0.734375H9.8346C10.4424 0.734375 11.0253 0.9758 11.4551 1.40563C11.8849 1.8354 12.1263 2.41827 12.1263 3.02604V3.85938C12.1263 4.20455 11.8465 4.48438 11.5013 4.48438C11.1561 4.48438 10.8763 4.20455 10.8763 3.85938V3.02604C10.8763 2.74979 10.7666 2.48485 10.5712 2.28949C10.3759 2.09419 10.111 1.98438 9.8346 1.98438H2.33464&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;p&gt;… and it will figure out the rest.&lt;/p&gt;]]&gt;</content:encoded></item><item><title><![CDATA[12,479 Applications, Zero Ghosting: A Look at Checkly's 2025 Hiring]]></title><description><![CDATA[In 2025, Checkly received 12,479 applications, of which we hired 24 people. Here's an honest look at our hiring funnel, speed, and data.]]></description><link>https://www.checklyhq.com/blog/checkly-2025-hiring-data</link><guid isPermaLink="false">abu-ihoAAEQAeYeX</guid><category><![CDATA[hiring]]></category><category><![CDATA[People]]></category><dc:creator><![CDATA[Lauren Singh]]></dc:creator><pubDate>Thu, 19 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;p&gt;Hiring is one of the most human things a company does, and one of the least transparent. We want to change that. Here&amp;#x27;s an honest look at what our hiring actually looked like in 2025: the volume, the speed, and the funnel.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;12 job postings. 24 people joined the team. 100% of applicants received a response.&lt;/strong&gt;&lt;/p&gt;&lt;h2 id=&quot;12-479-applications-12-job-postings-a-lot-of-trust-placed-in-us-&quot;&gt;&lt;a href=&quot;#12-479-applications-12-job-postings-a-lot-of-trust-placed-in-us-&quot;&gt;12,479 applications. 12 job postings. A lot of trust placed in us.&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;In 2025, we received 12,479 applications across 12 job postings, an average of 1,040 applicants per posting. It&amp;#x27;s worth noting that some postings covered roles we hired for multiple times: for example, we brought on three Enterprise Account Executives from a single posting. Engineering, product, and design postings attracted the most interest, averaging around 1,105 applicants each, while go-to-market postings averaged 909.&lt;/p&gt;&lt;p&gt;Our most competitive posting was Senior Backend Engineer, with a total of 4,578 applicants.&lt;/p&gt;&lt;h2 id=&quot;roughly-1-in-58-applicants-progressed-to-interviews&quot;&gt;&lt;a href=&quot;#roughly-1-in-58-applicants-progressed-to-interviews&quot;&gt;Roughly 1 in 58 applicants progressed to interviews&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;We try to be thoughtful about who we move forward, and honest about the odds. Of 12,479 applicants, 217 progressed to the Hiring Manager interview stage, that&amp;#x27;s approximately 1.7%, or roughly 1 in 58. That&amp;#x27;s a tight funnel, and we don&amp;#x27;t shy away from saying so. What we will say is this: every single person who applied heard back from us. No ghosting, no black hole. We know that&amp;#x27;s not the norm, and we think it should be. Job searching is hard enough without silence on the other end. What made the difference for those who progressed? A genuine fit with the role, relevant experience for a developer tools company, and clear, async-friendly communication. We&amp;#x27;re a remote-first team, how someone writes and communicates matters.&lt;/p&gt;&lt;h2 id=&quot;where-our-hires-came-from&quot;&gt;&lt;a href=&quot;#where-our-hires-came-from&quot;&gt;Where our hires came from&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Not every hire looks the same, and neither does every pipeline. Here&amp;#x27;s how our 24 hires broke down by source:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Actively applied: 60%&lt;/li&gt;&lt;li&gt;Referrals from the team: 20%&lt;/li&gt;&lt;li&gt;Sourced by a recruiter: 20%&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The majority of our hires came through inbound applications, which means a well-written application genuinely matters. That said, referrals and sourcing play a real role too, and we&amp;#x27;re proud that team referrals account for a meaningful share of who joins us.&lt;/p&gt;&lt;h2 id=&quot;what-candidates-said-about-the-experience&quot;&gt;&lt;a href=&quot;#what-candidates-said-about-the-experience&quot;&gt;What candidates said about the experience&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;We ask every candidate who goes through our process to share feedback. In 2025, when asked how likely they were to recommend Checkly as an employer, the average score was &lt;strong&gt;4.25 out of 5&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;Here&amp;#x27;s what a couple of candidates had to say:&lt;/p&gt;&lt;p&gt;&lt;em&gt;&amp;quot;The experience was overwhelmingly positive as I enjoyed speaking with all the stakeholders. Checkly is a place of high integrity that operates with the utmost professionalism.&amp;quot;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;&amp;quot;I am glad that even though I was not selected to continue the process, I got interviewed anyway. This is a good approach from the company and I hope you continue like that. The application form was unique and my time was respected. Thank you.&amp;quot;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;We don&amp;#x27;t share this to pat ourselves on the back, we share it because we think transparency should run both ways. Candidates trust us with their time, and we want to be accountable to that.&lt;/p&gt;&lt;h2 id=&quot;from-application-to-offer-22-5-days-(median)&quot;&gt;&lt;a href=&quot;#from-application-to-offer-22-5-days-(median)&quot;&gt;From application to offer: 22.5 days (median)&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;We know job searching is stressful, so we try to move quickly. Our median time from application to offer was 22.5 days, and our fastest? Just 4 days. Here&amp;#x27;s how the stages broke down:&lt;/p&gt;&lt;p class=&quot;block-img&quot;&gt;&lt;img src=&quot;https://images.prismic.io/checklyhq/abvB27bci2UF6QZp_checkly-hiring-stages.png?auto=format,compress&quot;/&gt;&lt;/p&gt;&lt;p&gt;The challenge stage, which applied to Engineering, Design, Support, and Customer Solutions roles only, naturally adds time, but it&amp;#x27;s an important part of how we assess real-world problem solving. Candidates are given up to 10 days to complete it, and we aim to make it focused and respectful of their time. If you&amp;#x27;re applying for a Product or GTM role, your process will typically be faster as there&amp;#x27;s no take-home challenge involved.&lt;/p&gt;&lt;h2 id=&quot;83%-offer-acceptance-rate&quot;&gt;&lt;a href=&quot;#83%-offer-acceptance-rate&quot;&gt;83% offer acceptance rate&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;In 2025, 24 offers were accepted, an 83% offer acceptance rate. We take this as a signal that the process works. By the time we get to an offer, both sides have had enough real conversation to feel confident. We hope that continues to be true.&lt;/p&gt;&lt;h2 id=&quot;what-s-next&quot;&gt;&lt;a href=&quot;#what-s-next&quot;&gt;What&amp;#x27;s next&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Sharing this data publicly is something we&amp;#x27;ll keep doing. Hiring is a two-way street, candidates invest real time and energy in applying, and the least we can do is be honest about what that process looks like from our side.&lt;/p&gt;&lt;p&gt;Looking ahead, 2026 is shaping up to be a big year for our go-to-market team. If you&amp;#x27;re in sales, solutions engineering or customer success and you&amp;#x27;re excited about the developer tools space, check out our &lt;a target=&quot;_blank&quot; href=&quot;https://jobs.ashbyhq.com/checkly?utm_source=cb&quot; rel=&quot;noreferrer&quot;&gt;open roles&lt;/a&gt; or join our &lt;a target=&quot;_blank&quot; href=&quot;https://jobs.ashbyhq.com/checkly/21acd589-f6eb-42cd-8c75-3eac4e3fb1e7?utm_source=cb&quot; rel=&quot;noreferrer&quot;&gt;talent community&lt;/a&gt;, we&amp;#x27;d love to hear from you. And if you&amp;#x27;ve been through our process, whether you joined us or not, we&amp;#x27;re always open to feedback. Hiring should feel human on both sides, and we&amp;#x27;re committed to keeping it that way.&lt;/p&gt;]]&gt;</content:encoded></item><item><title><![CDATA[Expanding Uptime Monitoring Down The Stack: ICMP Monitors Are Now Available In Checkly]]></title><description><![CDATA[Checkly's ICMP monitors ping any host or IP to measure reachability, latency, and packet loss, available on all plans and fully integrated with Monitoring as Code.]]></description><link>https://www.checklyhq.com/blog/icmp-monitoring</link><guid isPermaLink="false">aa_L7BoAAEUAwakg</guid><category><![CDATA[Product]]></category><category><![CDATA[Uptime Monitoring]]></category><category><![CDATA[Announcements]]></category><dc:creator><![CDATA[Susa Tünker,Pırıl Kavlak]]></dc:creator><pubDate>Tue, 10 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;p&gt;When we started building Checkly&amp;#x27;s uptime monitoring suite, the goal was to give engineering teams complete visibility across every layer of their stack, from application down to network, in one place. URL, TCP, DNS, and Heartbeat monitors covered a lot of that ground. But one fundamental piece was missing: the ability to simply ping a host and know if it&amp;#x27;s reachable.&lt;/p&gt;&lt;p&gt;We&amp;#x27;re now closing that gap by adding ICMP monitors to &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/product/uptime-monitoring/&quot; rel=&quot;noreferrer&quot;&gt;Checkly&amp;#x27;s uptime monitoring suite&lt;/a&gt;, available on all plans today, alongside URL, TCP, DNS, and Heartbeat.&lt;/p&gt;&lt;div data-oembed=&quot;https://www.youtube.com/watch?v=MKZm3iH9E4g&quot; data-oembed-type=&quot;video&quot; data-oembed-provider=&quot;YouTube&quot;&gt;&lt;iframe width=&quot;200&quot; height=&quot;113&quot; src=&quot;https://www.youtube.com/embed/MKZm3iH9E4g?feature=oembed&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen title=&quot;ICMP Monitors Are Now Available in Checkly&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;h2 id=&quot;what-is-icmp-monitoring-&quot;&gt;&lt;a href=&quot;#what-is-icmp-monitoring-&quot;&gt;What is ICMP monitoring?&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;ICMP monitors send scheduled ping requests to any host or IP address to measure reachability, latency, and packet loss. You can set assertions on any of these to define exactly what &amp;quot;healthy&amp;quot; means for each host.&lt;/p&gt;&lt;p class=&quot;block-img&quot;&gt;&lt;img src=&quot;https://images.prismic.io/checklyhq/abAHZVxvIZEnjhq0_creationscreenw%3Aoheader.png?auto=format%2Ccompress&amp;amp;rect=7%2C0%2C2380%2C1278&amp;amp;w=2380&amp;amp;h=1278&quot; alt=&quot;ICMP monitor creating screen&quot;/&gt;&lt;/p&gt;&lt;p&gt;No application logic. No open ports required. ICMP is a low-level monitor that provides a direct network-level signal, independent of what is running on the machine.&lt;/p&gt;&lt;h2 id=&quot;what-you-can-monitor-with-icmp-requests&quot;&gt;&lt;a href=&quot;#what-you-can-monitor-with-icmp-requests&quot;&gt;What you can monitor with ICMP requests&lt;/a&gt;&lt;/h2&gt;&lt;h3 id=&quot;infrastructure-without-an-http-endpoint&quot;&gt;&lt;a href=&quot;#infrastructure-without-an-http-endpoint&quot;&gt;&lt;strong&gt;Infrastructure without an HTTP endpoint&lt;/strong&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Databases, message queues, internal services, bare-metal servers, routers, and network devices don&amp;#x27;t serve web traffic, but they still need monitoring. TCP monitors cover many of these cases, but ICMP goes one level lower: no open port required. For hosts where no ports are intentionally exposed, ICMP is the right layer to monitor at. If a host can be pinged, it can be monitored in Checkly without adding extra tools to your stack.&lt;/p&gt;&lt;h3 id=&quot;private-networks-and-internal-hosts&quot;&gt;&lt;a href=&quot;#private-networks-and-internal-hosts&quot;&gt;&lt;strong&gt;Private networks and internal hosts&lt;/strong&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;ICMP monitors are useful for hosts that aren&amp;#x27;t exposed to the public internet, making them valuable for teams monitoring internal infrastructure alongside their public-facing checks. &lt;em&gt;This is possible via Checkly Private Locations, with ICMP support coming soon.&lt;/em&gt;&lt;/p&gt;&lt;h3 id=&quot;incident-triage&quot;&gt;&lt;a href=&quot;#incident-triage&quot;&gt;&lt;strong&gt;Incident triage&lt;/strong&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;When an alert fires, the first question is always: Is the machine down, or is the service down? ICMP gives you that answer immediately. If ICMP fails, it&amp;#x27;s a network issue. If ICMP passes and your HTTP check fails, the server is up, but the service is broken. The right team gets paged with the right context from the start.&lt;/p&gt;&lt;h3 id=&quot;regional-latency-comparison&quot;&gt;&lt;a href=&quot;#regional-latency-comparison&quot;&gt;&lt;strong&gt;Regional latency comparison&lt;/strong&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Run ICMP monitors from multiple locations to compare latency across regions. If one region is consistently slower than others, you can catch geographic performance issues before they affect users in that area.&lt;/p&gt;&lt;p&gt;Some failures don&amp;#x27;t show up as outages. Intermittent packet loss is one of them. One of our beta users ran into exactly this:&lt;/p&gt;&lt;blockquote class=&quot;bg-gray-100 p-4 border-l-2 my-4 border-blue-300 inline-block space-y-4&quot;&gt;&lt;p&gt;&amp;quot;We had a serious issue in which every third packet was dropped, and it went completely undetected until Checkly caught it at the network level. That&amp;#x27;s the kind of signal that stops a problem before it becomes a customer-facing incident.&amp;quot;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;You can set separate degraded and failure thresholds on packet loss, and add latency assertions to define when to trigger an alert.&lt;/p&gt;&lt;p class=&quot;block-img&quot;&gt;&lt;img src=&quot;https://images.prismic.io/checklyhq/abAJz1xvIZEnjhru_Healthywithpreviouspacketlossissue-white.png?auto=format,compress&quot;/&gt;&lt;/p&gt;&lt;h2 id=&quot;shipping-with-full-support-for-monitoring-as-code&quot;&gt;&lt;a href=&quot;#shipping-with-full-support-for-monitoring-as-code&quot;&gt;Shipping with full support for Monitoring as Code&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;ICMP monitors are fully integrated into Checkly&amp;#x27;s Monitoring as Code workflows, available in the CLI from &lt;strong&gt;v7.1.0&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;Define your ICMP monitors in code alongside your Playwright and API checks, version them in Git, and deploy through CI/CD:&lt;/p&gt;&lt;div class=&quot;code-block theme-light&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex pr-12&quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; { Frequency&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; IcmpAssertionBuilder&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; IcmpMonitor } &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot;checkly/constructs&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;IcmpMonitor&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;#39;cloudflare-dns-icmp&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  name&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;#39;Cloudflare DNS ICMP Monitor&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  activated&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  frequency&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;Frequency&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;EVERY_1M&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  maxPacketLossThreshold&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;20&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  degradedPacketLossThreshold&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  request&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    hostname&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;#39;1.1.1.1&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    pingCount&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;20&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    assertions&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;IcmpAssertionBuilder&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;.latency&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;#39;avg&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;.lessThan&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;IcmpAssertionBuilder&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;.latency&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;#39;max&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;.lessThan&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-constant)&quot;&gt;200&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-punctuation)&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;button type=&quot;button&quot; class=&quot;group bg-inherit absolute rounded flex items-center justify-center top-0 right-0  text-white bg-inherit h-16 w-16&quot; title=&quot;Copy code to clipboard&quot;&gt;&lt;svg viewBox=&quot;0 0 16 11&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; class=&quot;absolute h-5 w-5 transition duration-200 ease-out text-checkly-blue -translate-y-2 opacity-0 scale-90&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M15.1085 0.558056C15.3526 0.802133 15.3526 1.19786 15.1085 1.44194L5.94187 10.6086C5.82466 10.7259 5.66568 10.7917 5.49992 10.7917C5.33416 10.7917 5.17519 10.7259 5.05798 10.6086L0.891309 6.44194C0.647232 6.19786 0.647233 5.80213 0.891312 5.55806C1.13539 5.31398 1.53112 5.31398 1.7752 5.55806L5.49992 9.28281L14.2246 0.55806C14.4687 0.313981 14.8644 0.31398 15.1085 0.558056Z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;svg viewBox=&quot;0 0 18 19&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; class=&quot;absolute h-5 w-5 transition duration-200 ease-out translate-y-0 opacity-100 scale-100 text-gray-500/50 group-hover:text-gray-500/80&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M5.875 8.85929C5.875 7.59364 6.90101 6.56763 8.16667 6.56763H15.6667C16.9323 6.56763 17.9583 7.59365 17.9583 8.85929V16.3593C17.9583 17.6249 16.9323 18.651 15.6667 18.651H8.16667C6.901 18.651 5.875 17.6249 5.875 16.3593V8.85929ZM8.16667 7.81763C7.59137 7.81763 7.125 8.28399 7.125 8.85929V16.3593C7.125 16.9346 7.59138 17.401 8.16667 17.401H15.6667C16.2419 17.401 16.7083 16.9346 16.7083 16.3593V8.85929C16.7083 8.28398 16.2419 7.81763 15.6667 7.81763H8.16667Z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M2.33464 1.98438C2.05836 1.98438 1.79341 2.09412 1.59807 2.28946C1.59807 2.28946 1.59807 2.28946 1.59807 2.28946M1.59807 2.28946C1.40272 2.48482 1.29297 2.74978 1.29297 3.02604V10.5261C1.29297 10.8023 1.4027 11.0672 1.59809 11.2626C1.79343 11.458 2.05838 11.5678 2.33464 11.5678H3.16797C3.51315 11.5678 3.79297 11.8476 3.79297 12.1928C3.79297 12.5379 3.51315 12.8178 3.16797 12.8178H2.33464C1.72684 12.8178 1.14393 12.5763 0.714149 12.1465C0.284418 11.7167 0.0429688 11.1338 0.0429688 10.5261V3.02604C0.0429688 2.41826 0.284405 1.83537 0.71417 1.40559C1.14395 0.975814 1.72686 0.734375 2.33464 0.734375H9.8346C10.4424 0.734375 11.0253 0.9758 11.4551 1.40563C11.8849 1.8354 12.1263 2.41827 12.1263 3.02604V3.85938C12.1263 4.20455 11.8465 4.48438 11.5013 4.48438C11.1561 4.48438 10.8763 4.20455 10.8763 3.85938V3.02604C10.8763 2.74979 10.7666 2.48485 10.5712 2.28949C10.3759 2.09419 10.111 1.98438 9.8346 1.98438H2.33464&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;div class=&quot;card space-y-4 has-gradient&quot;&gt;&lt;div class=&quot;flex gap-2 items-center font-bold text-xl text-checkly-blue&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; class=&quot;w-5 h-5&quot; fill=&quot;none&quot; viewBox=&quot;0 0 81 85&quot;&gt;&lt;path fill=&quot;#0075FF&quot; d=&quot;M80.704 52.41V17.622C80.704 7.89 72.814 0 63.084 0H17.65C7.919 0 .029 7.89.029 17.621v34.79C-.818 78.54 17.219 77.375 19.9 77.375l20.433 1.352v.005h.068v-.005l20.433-1.352c2.682 0 20.719 1.168 19.872-24.964h-.002Z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#fff&quot; d=&quot;M52.193 40.889c19.825-13.637 21.334-2.36 13.37 14.757l.003.002c-2.474 4.385 2.946 6.17 7.528 6.783.002.003-2.767 8.498-8.727 13.34l-10.23 2.42-3.301 1.033c-.027.002-4.627 1.386-5.32 1.58l-10.29-.002c-.694-.195-5.294-1.58-5.32-1.58l-3.3-1.034-10.231-2.42c-5.96-4.842-8.73-13.337-8.727-13.34 4.579-.612 10.002-2.398 7.527-6.782C7.212 38.527 8.72 27.252 28.546 40.889c3.711-1.544 7.172-1.857 11.762-1.954a.13.13 0 0 0 .031.002h.092c4.59.098 8.048.408 11.762 1.952Z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#002F66&quot; d=&quot;M15.68 38.722c-.308.065-.618.155-.884.326-.857.555-.657 1.825-.586 2.69.137 1.655.5 3.314.933 4.929a22.657 22.657 0 0 0 1.147 3.306 18.673 18.673 0 0 1 1.744-2.29 22.039 22.039 0 0 1 1.546-1.579c2.838-2.625 5.663-3.93 5.663-3.93-2.725-1.959-6.05-4.21-9.56-3.455l-.003.003ZM65.053 38.722c.308.065.618.155.884.326.857.555.657 1.825.587 2.69-.137 1.655-.5 3.314-.934 4.929a22.657 22.657 0 0 1-1.147 3.306 18.673 18.673 0 0 0-1.743-2.29 22.039 22.039 0 0 0-1.547-1.579c-2.838-2.625-5.662-3.93-5.662-3.93 2.724-1.959 6.049-4.21 9.56-3.455l.002.003ZM45.502 80.784l-.04-.09c-.541-1.218-1.646-2.093-2.88-2.546a6.522 6.522 0 0 0-4.505.026c-1.21.46-2.27 1.326-2.809 2.52l-.039.09a.115.115 0 0 0-.008.018c1.086 1.775 2.98 3.174 5.113 3.198h.063c2.136-.021 4.026-1.418 5.115-3.195a.136.136 0 0 1-.008-.019l-.002-.002ZM37.74 63.057a8.05 8.05 0 0 0-1.654-1.373 10.12 10.12 0 0 0-2.093-.996 11.426 11.426 0 0 0-2.407-.542c-.862-.098-1.735-.1-2.598-.005-.907.097-1.804.302-2.664.607-.918.326-1.794.765-2.607 1.302a13.139 13.139 0 0 0-2.422 2.078c-.818.889-1.52 1.88-2.117 2.93a21.198 21.198 0 0 0-1.686 3.863 29.738 29.738 0 0 0-1.126 4.847c-.036.245-.073.487-.107.736v-.01c-.024.155-.087.51-.108.734 4.597.534 9.192 1.162 13.747 1.993-.079-.013.515-2.582.59-2.843.191-.678.425-1.349.751-1.975.458-.881 1.102-1.617 1.944-2.146.784-.492 1.654-.826 2.475-1.25.941-.486 1.846-1.072 2.603-1.817.745-.728.987-1.543.976-2.577a4.967 4.967 0 0 0-.405-1.888 6.063 6.063 0 0 0-1.091-1.67v.002ZM64.58 77.228c-.024-.227-.084-.579-.108-.734v.01c-.031-.25-.07-.491-.108-.736a29.727 29.727 0 0 0-1.125-4.847 21.35 21.35 0 0 0-1.686-3.864c-.597-1.049-1.3-2.04-2.117-2.93a13.24 13.24 0 0 0-2.423-2.077 11.947 11.947 0 0 0-2.606-1.302c-.86-.305-1.757-.51-2.664-.607a11.759 11.759 0 0 0-2.599.005 11.26 11.26 0 0 0-2.406.542c-.731.252-1.439.583-2.093.996a8.048 8.048 0 0 0-1.655 1.373 6.004 6.004 0 0 0-1.091 1.67 4.916 4.916 0 0 0-.405 1.889c-.01 1.033.231 1.846.975 2.577.758.744 1.663 1.33 2.604 1.817.82.424 1.691.755 2.475 1.25.842.528 1.486 1.265 1.944 2.146.323.626.56 1.296.752 1.975.073.26.668 2.83.589 2.843 4.555-.831 9.15-1.46 13.747-1.994v-.002Z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#fff&quot; d=&quot;M31.56 69.08a2.046 2.046 0 1 0 0-4.092 2.046 2.046 0 0 0 0 4.092ZM49.173 69.08a2.046 2.046 0 1 0 0-4.092 2.046 2.046 0 0 0 0 4.092Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;div&gt;Checkly Tip&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Or use an AI agent - copy this prompt to get started:&lt;br/&gt;&amp;quot;Create an ICMP monitor in Checkly for [your-hostname-or-ip]. Ping every minute from us-east-1 and eu-west-1. Set a degraded alert at 10% packet loss and a failure alert at 20% packet loss or average latency over 200ms.&amp;quot;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;ICMP monitors are also available in Terraform and Pulumi:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Terraform (v1.18.0+):&lt;/strong&gt; &lt;a target=&quot;_blank&quot; href=&quot;https://registry.terraform.io/providers/checkly/checkly/latest/docs/resources/icmp_monitor&quot; rel=&quot;noreferrer&quot;&gt;checkly_icmp_monitor&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Pulumi (v2.8.0):&lt;/strong&gt; &lt;a target=&quot;_blank&quot; href=&quot;https://www.pulumi.com/registry/packages/checkly/api-docs/icmpmonitor/&quot; rel=&quot;noreferrer&quot;&gt;checkly.IcmpMonitor&lt;/a&gt;&lt;/p&gt;&lt;h2 id=&quot;pricing-and-availability&quot;&gt;&lt;a href=&quot;#pricing-and-availability&quot;&gt;Pricing and availability&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;ICMP monitors are priced as uptime monitors: flat-rate per monitor, available on all plans today. Check out our &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/pricing/&quot; rel=&quot;noreferrer&quot;&gt;pricing page&lt;/a&gt; for full details.&lt;/p&gt;&lt;h2 id=&quot;get-started&quot;&gt;&lt;a href=&quot;#get-started&quot;&gt;Get started&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Try ICMP monitors in your &lt;a target=&quot;_blank&quot; href=&quot;https://app.checklyhq.com/checks/new/icmp&quot; rel=&quot;noreferrer&quot;&gt;Checkly dashboard&lt;/a&gt; or &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/detect/uptime-monitoring/icmp-monitors/overview/&quot; rel=&quot;noreferrer&quot;&gt;read the documentation&lt;/a&gt; to learn more about configuration, assertions, and alerting.&lt;/p&gt;&lt;p&gt;Questions? Find us in the &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/slack&quot; rel=&quot;noreferrer&quot;&gt;Checkly community on Slack&lt;strong&gt;→&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;]]&gt;</content:encoded></item><item><title><![CDATA[We Turned Our WireShark Wizard Into a Markdown File]]></title><description><![CDATA[Checkly's AI agent Rocky AI is now GA. Here are five lessons from building an AI root cause analysis agent into a SaaS product: data wrangling is still the hard part, model upgrades are nearly free, multi-model is as painful as multi-cloud, codifying human expertise into prompts works, and chat isn't always the right UI for AI.]]></description><link>https://www.checklyhq.com/blog/building-an-ai-agent</link><guid isPermaLink="false">aacqYxoAAEcAtQCi</guid><category><![CDATA[AI]]></category><category><![CDATA[Product]]></category><dc:creator><![CDATA[Tim Nolet]]></dc:creator><pubDate>Wed, 04 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;p&gt;Rocky AI — Checkly’s AI agent — is now Generally Available. We developed Rocky AI over the last ~6 to 8 months. This is an aeon in AI-years.&lt;/p&gt;&lt;p&gt;During this period, we learned a ton. About AI, but mostly about how to fit them into an existing SaaS product, not just another chat widget. This is my ramble…&lt;/p&gt;&lt;h2 id=&quot;something-with-ai&quot;&gt;&lt;a href=&quot;#something-with-ai&quot;&gt;Something with AI&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Like almost everyone in SaaS-land, we were pondering doing “something with AI” at least since late 2024. We went with some hunches, looked at competitors, talked to customers, hacked on some prototypes. But it was hard to pinpoint a shippable MVP. We were probably going too broad and promising a bit too much.&lt;/p&gt;&lt;h2 id=&quot;save-me-time-and-no-magic-please&quot;&gt;&lt;a href=&quot;#save-me-time-and-no-magic-please&quot;&gt;Save me time, and no magic please&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;So we did a hard reset on our AI ambitions. Instead of shipping the whole kitchen sink, what if we focus on one time consuming task in the critical path of our users? One repetitive, but critical taks that came to mind is triaging a failed Playwright Check test. Specifically, could we use LLMs to quickly create an analysis of a Playwright trace file?&lt;/p&gt;&lt;p&gt;We immediately bumped into two challenges:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;A Playwright trace file can easily be 100Mb+. We need to parse it, remove unneeded data and turn it into a plain text representation. Counterintuitively, giving MORE data to an LLM does doet always guarantee better results. Or it just blows up the input token limit.&lt;/li&gt;&lt;li&gt;When the data wrangling done, how do we guide the LLM to make sense of the data? Sure, it can do some basic summary by itself, but we want to give it guidelines on what is important to look at, what things are typically related. We essentially want these ingrained triaging steps that (senior) engineers hold in their heads to made explicit.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Over the months we expanded our AI analysis skills to cover all our check types (Playwright, HTTP, TCP, DNS, ICMP etc.). We took the same approach each time:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Look at how we can use artifacts like logs, traces etc. to build up a body of evidence for a specific failure root cause. Data wrangle it into submission so an LLM can use it.&lt;/li&gt;&lt;li&gt;Capture the skill of analyzing and interpreting said artefacts into a semi-structured markdown file.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This is now our Rocky AI Root Cause Analysis Agent. We did bump into some other learnings along the way, so I dumped them into a nice listicle. 👇&lt;/p&gt;&lt;h2 id=&quot;#1-just-do-what-the-humans-do&quot;&gt;&lt;a href=&quot;##1-just-do-what-the-humans-do&quot;&gt;#1. Just do what the humans do&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Again, this might be blatantly obvious, but we are using AI to &lt;strong&gt;just do things humans can do&lt;/strong&gt;. Example: we literally codified the Wireshark ICMP and PCAP analysis skills of one our engineers into a markdown file that now powers our AI driven ICMP and PCAP analysis. This looks a bit like this:&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;header class=&quot;flex py-2 px-16 items-center justify-center text-[13px] tracking-tight bg-blue-300/20 text&quot;&gt;&lt;div aria-hidden=&quot;true&quot; class=&quot;absolute left-4 flex gap-x-1&quot;&gt;&lt;div class=&quot;h-2.5 w-2.5 rounded-full bg-blue-300 opacity-20&quot;&gt;&lt;/div&gt;&lt;div class=&quot;h-2.5 w-2.5 rounded-full bg-blue-300 opacity-20&quot;&gt;&lt;/div&gt;&lt;div class=&quot;h-2.5 w-2.5 rounded-full bg-blue-300 opacity-20&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;span class=&quot;font-mono text-gray-300&quot;&gt;icmp-rca-skill.md&lt;/span&gt;&lt;/header&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;# ICMP Analysis Skill&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;## Classifications&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;The root cause can only be classified using the following classifications:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;### INFRASTRUCTURE_ERROR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;External issues like network errors, packet loss, host unreachable, DNS failures, firewall blocks, or routing issues. Examples: 100% packet loss, DNS resolution failure, ICMP destination unreachable&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;### CONFIGURATION_ERROR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;etc.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;## Artifacts&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;### ICMP_REQUEST&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;Description: ICMP request properties including hostname, target IP, IP family, and ping count. etc.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;## Common Failure Patterns&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;### PACKET_LOSS&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;Symptoms: High packet loss percentage, Packets sent but not received, Packet loss threshold exceeded&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;Causes: Network congestion along the route, Firewall dropping ICMP packets, Target host overloaded or rate limiting ICMP, Intermittent network issues&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;Analysis: Check packet loss percentage vs configured thresholds, Examine individual ping results for patterns, Compare results across different monitoring locations&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;### DNS_RESOLUTION_FAILURE&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;etc.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;#2-data-wrangling-is-still-the-thing&quot;&gt;&lt;a href=&quot;##2-data-wrangling-is-still-the-thing&quot;&gt;#2. Data wrangling is still the thing&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Even with extended context windows and increased quota’s on input tokens, we still do a ton of data wrangling. As mentioned above, Playwright trace files easily go over 100Mb, a network PCAP file parsed to text can also be very large. These are all data sources want the LLM to take into account.&lt;/p&gt;&lt;p&gt;Currently, we solve this problem by pre-parsing, filtering and summarising these large assets in tool calls. The tool returns the key data from these assets back to the LLM.&lt;/p&gt;&lt;h2 id=&quot;#3-model-updates-are-almost-a-free-lunch&quot;&gt;&lt;a href=&quot;##3-model-updates-are-almost-a-free-lunch&quot;&gt;#3. Model updates are almost a free lunch&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Just the last ~6 months, the upgrade from OpenAI GPT-4.1 to GPT-5.1 (let’s not mention the dreadful GPT-5) was night and day: better answers, more reliable tool calls, faster responses, less processing errors, better schema output. You can see similar patterns for the Opus 4.5 to Opus 4.6 and the Gemini upgrades.&lt;/p&gt;&lt;h2 id=&quot;#4-multi-model-is-like-multi-cloud-it-kinda-sucks-&quot;&gt;&lt;a href=&quot;##4-multi-model-is-like-multi-cloud-it-kinda-sucks-&quot;&gt;#4. Multi model is like multi cloud. It kinda sucks.&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;While building our Bring-Your-Own-Model (BYOM) feature, we allowed users to bring Gemini and Anthropic models next to our default OpenAI models. That was a mistake. Turns out that swapping models is quite hard right now if you want to keep some form of quality control and not have dedicated tests, fixtures and code paths.&lt;/p&gt;&lt;p&gt;This is even true with wrapper libraries like the Vercel AI SDK, which we use. In some way it reminds of how Terraform could in theory make your infra “multi cloud”. In practice, it really can’t.&lt;/p&gt;&lt;h2 id=&quot;#5-don-t-always-default-to-chat&quot;&gt;&lt;a href=&quot;##5-don-t-always-default-to-chat&quot;&gt;#5. Don’t always default to chat&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Obviously, chat is the de-facto UI paradigm for LLMs and generative AI. However, in our RCA case, it would be silly to force a user to go to some chat UI and asked Rocky “please analyse this failing check”. We can ask that question for the user, even when they are sleeping and just ship the initial analysis to their inbox. Chat can be a follow up.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;We are totally not done with expanding Rocky AI and adding more tools and features to its RCA skills. Watch this space.&lt;br/&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://feedback.checklyhq.com/changelog/rocky-ai-root-cause-automation-is-now-live&quot; rel=&quot;noreferrer&quot;&gt;Read the changelog here&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://checklyhq.com/product/ai-analysis/&quot; rel=&quot;noreferrer&quot;&gt;Check the product page here&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;&lt;/li&gt;&lt;/ul&gt;]]&gt;</content:encoded></item><item><title><![CDATA[Introducing Rocky AI to General Availability]]></title><description><![CDATA[After months of being available in Beta for our app users, Rocky AI is now generally available to all users and plans. Rocky AI is Checkly’s AI agent that works around the clock, 24/7, to make sure your application’s reliability is optimal. In this first release, Rocky AI ships with the ability to run continual Analysis on test and check failures, giving your teams AI-powered root cause analysis, impact analysis, and more. Since day 1 of the AI craze, Checkly has made it easy to work with your favorite LLMs and coding agents like Claude Code, Cursor, and OpenAI, allowing you to craft and manage your monitoring right from your IDE. Now, we’re bringing that power right into the Checkly workflow with Rocky AI. Root Cause Analysis When a test or monitor fails, Rocky AI analyzes multiple vectors across your application, including logs, traces, and more to understand what exactly caused the failure; and how to best fix it. For large teams with hundreds of monitors across their apps and services, Rocky AI can help engineers understand the context of the check itself, even if they didn’t create it, reducing cognitive overload in the heat of an outage. For individuals and smaller engineering teams, Rocky AI will cut down on hours of back and forth, working to replicate the problem, and other triage works that delay teams from getting a quick fix back in production. User Impact Rocky AI also tries to understand and surface who exactly is impacted during an outage. Are users impacted from logging into the application? Is a core workflow being blocked? Is it a network failure that causes the test to fail, but user impact is actually minimal? Rocky AI can help you get the answers you need, faster than humanly possible, so you can get your application back up and running. Automation For teams with heavy alerting systems, Rocky AI can tap in and automatically send its findings inside any alert, right to your inbox or Slack channel. You'll get highly relevant context to the downtim...]]></description><link>https://www.checklyhq.com/blog/introducing-rocky-ai</link><guid isPermaLink="false">aagzgxoAAEYAtpQF</guid><dc:creator><![CDATA[Dan Giordano]]></dc:creator><pubDate>Wed, 04 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;p&gt;After months of being available in Beta for our app users, &lt;a target=&quot;_self&quot; href=&quot;http://checklyhq.com/product/ai-analysis/&quot; rel=&quot;noreferrer&quot;&gt;&lt;strong&gt;Rocky AI&lt;/strong&gt;&lt;/a&gt; is now generally available to all users and plans. Rocky AI is Checkly’s AI agent that works around the clock, 24/7, to make sure your application’s reliability is optimal. In this first release, Rocky AI ships with the ability to run continual &lt;a target=&quot;_self&quot; href=&quot;https://www.checklyhq.com/docs/resolve/ai-root-cause-analysis/overview/&quot; rel=&quot;noreferrer&quot;&gt;&lt;strong&gt;Analysis&lt;/strong&gt;&lt;/a&gt; on test and check failures, giving your teams AI-powered root cause analysis, impact analysis, and more.&lt;/p&gt;&lt;p&gt;Since day 1 of the AI craze, Checkly has made it easy to work with your favorite LLMs and coding agents like Claude Code, Cursor, and OpenAI, allowing you to craft and manage your monitoring right from your IDE. Now, we’re bringing that power right into the Checkly workflow with Rocky AI.&lt;/p&gt;&lt;h2 id=&quot;root-cause-analysis&quot;&gt;&lt;a href=&quot;#root-cause-analysis&quot;&gt;Root Cause Analysis&lt;/a&gt;&lt;/h2&gt;&lt;p class=&quot;block-img&quot;&gt;&lt;img src=&quot;https://images.prismic.io/checklyhq/aag4HlxvIZEnjURm_RCA.png?auto=format,compress&quot;/&gt;&lt;/p&gt;&lt;p&gt;When a test or monitor fails, Rocky AI analyzes multiple vectors across your application, including logs, traces, and more to understand what exactly caused the failure; and how to best fix it.&lt;/p&gt;&lt;p&gt;For large teams with hundreds of monitors across their apps and services, Rocky AI can help engineers understand the context of the check itself, even if they didn’t create it, reducing cognitive overload in the heat of an outage. For individuals and smaller engineering teams, Rocky AI will cut down on hours of back and forth, working to replicate the problem, and other triage works that delay teams from getting a quick fix back in production.&lt;/p&gt;&lt;h2 id=&quot;user-impact&quot;&gt;&lt;a href=&quot;#user-impact&quot;&gt;User Impact&lt;/a&gt;&lt;/h2&gt;&lt;p class=&quot;block-img&quot;&gt;&lt;img src=&quot;https://images.prismic.io/checklyhq/aag4H1xvIZEnjURn_UserImpact.png?auto=format,compress&quot;/&gt;&lt;/p&gt;&lt;p&gt;Rocky AI also tries to understand and surface who exactly is impacted during an outage. Are users impacted from logging into the application? Is a core workflow being blocked? Is it a network failure that causes the test to fail, but user impact is actually minimal? Rocky AI can help you get the answers you need, faster than humanly possible, so you can get your application back up and running.&lt;/p&gt;&lt;h2 id=&quot;automation&quot;&gt;&lt;a href=&quot;#automation&quot;&gt;Automation&lt;/a&gt;&lt;/h2&gt;&lt;p class=&quot;block-img&quot;&gt;&lt;img src=&quot;https://images.prismic.io/checklyhq/aag4HVxvIZEnjURl_RCASlack.png?auto=format,compress&quot;/&gt;&lt;/p&gt;&lt;p&gt;For teams with heavy alerting systems, Rocky AI can tap in and automatically send its findings inside any alert, right to your inbox or Slack channel. You&amp;#x27;ll get highly relevant context to the downtime, directly inside your workflow, allowing you to break out, fix it, and get back to work.&lt;/p&gt;&lt;h2 id=&quot;getting-started&quot;&gt;&lt;a href=&quot;#getting-started&quot;&gt;Getting Started&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Rocky AI Error Analysis is available in Checkly Resolve today. To get started with Rocky AI right now in Checkly, just head over to &lt;a target=&quot;_blank&quot; href=&quot;http://app.checklyhq.com&quot; rel=&quot;noreferrer&quot;&gt;app.checklyhq.com&lt;/a&gt; and click Rocky AI Analysis.&lt;/p&gt;&lt;p&gt;Or read through our &lt;a target=&quot;_self&quot; href=&quot;https://www.checklyhq.com/docs/resolve/ai-root-cause-analysis/overview/&quot; rel=&quot;noreferrer&quot;&gt;documentation&lt;/a&gt; to get a better grasp of Rocky AI&lt;/p&gt;&lt;h2 id=&quot;what-s-next&quot;&gt;&lt;a href=&quot;#what-s-next&quot;&gt;What’s Next&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;With Rocky AI hitting general available with the ability Analyze results, we are only getting started. We will be adding other capabilities and skills to Rocky AI over time, to bring you native AI powered test generation, alert configuring, and more - right inside the Checkly dashboard. If you are a heavy user of LLMs or Agents, then check out Rocky AI or start using Checkly with tools like Claude Code today.&lt;/p&gt;]]&gt;</content:encoded></item><item><title><![CDATA[The Current State of Content Negotiation for AI Agents (Feb 2026)]]></title><description><![CDATA[Only 3 of 7 major AI agents request markdown via the Accept header. Learn which agents support content negotiation, why it cuts tokens by 99%, and how to make your site agent-friendly.]]></description><link>https://www.checklyhq.com/blog/state-of-ai-agent-content-negotation</link><guid isPermaLink="false">aZcoTBkAAEsAZcz-</guid><category><![CDATA[AI]]></category><dc:creator><![CDATA[Stefan Judis]]></dc:creator><pubDate>Thu, 19 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;p&gt;The web was built for humans, but now the agents are taking over.&lt;/p&gt;&lt;p&gt;Humans look at a web page and see content rendered by their browser. AI agents see 180,000 tokens of nav bars, footers, and div soup — burning through their context window on junk that makes them slower and stupider.&lt;/p&gt;&lt;p&gt;The web needs to evolve, and we as developers are driving the shift. AI agents like Claude Code, Cursor, Codex, and Gemini are how we interact with documentation, CLIs, and products today. Every time the robots fetch a page, they parse markup that adds no value.&lt;/p&gt;&lt;p&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://blog.cloudflare.com/markdown-for-agents/&quot; rel=&quot;noreferrer&quot;&gt;Cloudflare&lt;/a&gt; and &lt;a target=&quot;_blank&quot; href=&quot;https://vercel.com/blog/making-agent-friendly-pages-with-content-negotiation&quot; rel=&quot;noreferrer&quot;&gt;Vercel&lt;/a&gt; recently published posts about solving the context waste problem with good old content negotiation, and the &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;Accept&lt;/code&gt; header.&lt;/p&gt;&lt;p&gt;Both posts explain the concept well, but they&amp;#x27;re missing a crucial piece: which agents currently send these headers? And what&amp;#x27;s the best way to support the agentic web?&lt;/p&gt;&lt;p&gt;Let&amp;#x27;s fill those gaps.&lt;/p&gt;&lt;h2 id=&quot;the-problem-html-is-expensive-and-not-agent-friendly&quot;&gt;&lt;a href=&quot;#the-problem-html-is-expensive-and-not-agent-friendly&quot;&gt;The Problem: HTML Is Expensive and not Agent-friendly&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;When an AI agent fetches a URL, it doesn&amp;#x27;t see what you see. It sees this:&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot;wrapper&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;nav&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot;site-nav&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;aria-label&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot;Main&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;ul&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot;nav-list&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;      &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot;nav-item&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;href&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot;/docs&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;&amp;gt;Docs&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-comment)&quot;&gt;&amp;lt;!-- 47 more nav items --&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;ul&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;nav&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;main&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot;content-wrapper layout-default&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;article&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot;docs-content&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot;main-content&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;      &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;h1&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-function)&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot;title heading-1&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;&amp;gt;Getting Started&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;h1&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-comment)&quot;&gt;&amp;lt;!-- finally, some actual content --&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;All those &amp;lt;div&amp;gt; wrappers, class names, ARIA labels, and semantic markup have zero value for an LLM. But every character counts against its context window.&lt;/p&gt;&lt;p&gt;The numbers speak for themselves:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Cloudflare measured an &lt;strong&gt;80% token reduction&lt;/strong&gt; when serving markdown instead of HTML&lt;/li&gt;&lt;li&gt;Vercel saw page content drop from &lt;strong&gt;500KB to 2KB&lt;/strong&gt; — a 99.6% reduction&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The web wasn&amp;#x27;t always this heavy. But today, actual content only makes up a fraction of what gets sent over the wire. Users with limited mobile data feel it. So do people on slow connections. And now agents, paying by the token, feel it too.&lt;/p&gt;&lt;h2 id=&quot;the-solution-content-negotiation&quot;&gt;&lt;a href=&quot;#the-solution-content-negotiation&quot;&gt;The Solution: Content Negotiation&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;HTTP has had a mechanism for this since HTTP/1.1. It&amp;#x27;s called content negotiation, and it works through &lt;a target=&quot;_blank&quot; href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Accept&quot; rel=&quot;noreferrer&quot;&gt;the &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;Accept&lt;/code&gt; request header&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;When a client makes a request, it can say, &amp;quot;Hey! I&amp;#x27;d prefer markdown, but I&amp;#x27;ll take HTML if that&amp;#x27;s all you&amp;#x27;ve got.&amp;quot;:&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;Accept: text/markdown, text/html&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;If the server supports it, it responds with clean Markdown. If not, the client receives the HTML and handles it. This approach is simple, backwards-compatible, and elegant. And it&amp;#x27;s been part of HTTP since forever.&lt;/p&gt;&lt;p&gt;Here&amp;#x27;s what that approach looks like in practice, using &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;curl&lt;/code&gt;:&lt;/p&gt;&lt;div class=&quot;code-block code-block-inline syntax-bash&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-token-comment)&quot;&gt;# Request the Checkly docs with a proper `Accept` header&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;curl &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;https://www.checklyhq.com/docs/concepts/monitoring-as-code&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-keyword)&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; \\&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;-H&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string-expression)&quot;&gt;&amp;quot;Accept: text/markdown&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;If you request &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/&quot; rel=&quot;noreferrer&quot;&gt;the Checkly docs&lt;/a&gt; with a proper &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;Accept: text/markdown&lt;/code&gt; header, you get structured markdown that an LLM can actually use instead of a massive HTML document.&lt;/p&gt;&lt;section class=&quot;overflow-auto py-4&quot; data-slice-type=&quot;data_table&quot; data-slice-variation=&quot;default&quot;&gt;&lt;table class=&quot;w-full min-w-[500px] border-separate border-spacing-y-2&quot;&gt;&lt;thead&gt;&lt;tr class=&quot;font-bold&quot;&gt;&lt;td class=&quot;p-4 text-left&quot;&gt;Format&lt;/td&gt;&lt;td class=&quot;p-4&quot;&gt;Size / Used Tokens&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr class=&quot;[&amp;amp;:nth-child(even)]:bg-gray-100&quot;&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;HTML&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;615.4 KB / 180,573&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;[&amp;amp;:nth-child(even)]:bg-gray-100&quot;&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;Markdown&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;2.3 KB / 478&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;p&gt;That&amp;#x27;s a &lt;strong&gt;99.6% reduction in size&lt;/strong&gt; and &lt;strong&gt;99.7% fewer tokens&lt;/strong&gt; — independently measured on our own docs, and strikingly close to Vercel&amp;#x27;s numbers. And the best thing: it&amp;#x27;s the same content, but at a fraction of the cost.&lt;/p&gt;&lt;p&gt;We at Checkly believe agents are our next customers. When someone asks their agent, &amp;quot;How do I set up &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/detect/synthetic-monitoring/playwright-checks/overview/&quot; rel=&quot;noreferrer&quot;&gt;a Playwright Check Suite&lt;/a&gt; with Checkly?&amp;quot; we want them to receive clean, structured context, not a soup of HTML tags that burn through their context window. Our docs, of course, are at the center of supporting the agentic web.&lt;/p&gt;&lt;h2 id=&quot;what-agents-are-actually-sending-the-required-accept-header-&quot;&gt;&lt;a href=&quot;#what-agents-are-actually-sending-the-required-accept-header-&quot;&gt;What Agents Are Actually Sending The Required Accept Header?&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Here&amp;#x27;s the one-million-dollar question that Cloudflare and Vercel didn&amp;#x27;t cover in their posts: which agents use content negotiation today?&lt;/p&gt;&lt;p&gt;To answer this question, we let common agents request the URL https://httpbin.org/headers with their native webfetch tools. The page responds with the received request headers in JSON format. Easy to parse and analyze.&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;❯ Can you fetch &amp;lt;https://httpbin.org/headers&amp;gt;. What are the displayed headers?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;⏺ Fetch(&amp;lt;https://httpbin.org/headers&amp;gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;  ⎿  Received 254 bytes (200 OK)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Here are the request headers each agent sends (&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;Accept&lt;/code&gt; and &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;User-Agent&lt;/code&gt; for fun):&lt;/p&gt;&lt;h3 id=&quot;✅-fetch-in-claude-code-(v2-1-38)-requests-markdown&quot;&gt;&lt;a href=&quot;#✅-fetch-in-claude-code-(v2-1-38)-requests-markdown&quot;&gt;✅ &amp;quot;Fetch&amp;quot; in &lt;strong&gt;Claude Code&lt;/strong&gt; (v2.1.38) requests Markdown&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;Accept:  text/markdown, text/html, */*&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;User-Agent: axios/1.8.4&lt;/code&gt;&lt;/p&gt;&lt;h3 id=&quot;✅-webfetch-in-cursor-(2-4-28)-requests-markdown&quot;&gt;&lt;a href=&quot;#✅-webfetch-in-cursor-(2-4-28)-requests-markdown&quot;&gt;✅ &amp;quot;WebFetch&amp;quot; in &lt;strong&gt;Cursor&lt;/strong&gt; (2.4.28) requests Markdown&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;Accept: text/markdown,text/html;q=0.9,application/xhtml+xml;q=0.8,application/xml;q=0.7,image/webp;q=0.6,*/*;q=0.5&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;User-Agent: Mozilla/5.0 ... Chrome/139.0.0.0 Safari/537.36&lt;/code&gt;&lt;/p&gt;&lt;h3 id=&quot;✅-webfetch-in-opencode-(1-2-5)-requests-markdown&quot;&gt;&lt;a href=&quot;#✅-webfetch-in-opencode-(1-2-5)-requests-markdown&quot;&gt;✅ &amp;quot;webfetch&amp;quot; in &lt;strong&gt;OpenCode&lt;/strong&gt; (1.2.5) requests Markdown&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;Accept: text/markdown;q=1.0, text/x-markdown;q=0.9, text/plain;q=0.8, text/html;q=0.7, */*;q=0.1&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;User-Agent: Mozilla/5.0 ... Chrome/139.0.0.0 Safari/537.36&lt;/code&gt;&lt;/p&gt;&lt;h3 id=&quot;❌-unknown-tool-in-openai-codex-260203-1501-(523)-doesn-t-request-markdown&quot;&gt;&lt;a href=&quot;#❌-unknown-tool-in-openai-codex-260203-1501-(523)-doesn-t-request-markdown&quot;&gt;❌ &amp;quot;unknown tool&amp;quot; in &lt;strong&gt;OpenAI Codex&lt;/strong&gt; 260203.1501 (523) doesn&amp;#x27;t request Markdown&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;User-Agent: Mozilla/5.0 ... ChatGPT-User/1.0; +https://openai.com/bot&lt;/code&gt;&lt;/p&gt;&lt;h3 id=&quot;❌-webfetch-in-gemini-cli-(0-28-2)-doesn-t-request-markdown&quot;&gt;&lt;a href=&quot;#❌-webfetch-in-gemini-cli-(0-28-2)-doesn-t-request-markdown&quot;&gt;❌ &amp;quot;WebFetch&amp;quot; in &lt;strong&gt;Gemini CLI&lt;/strong&gt; (0.28.2) doesn&amp;#x27;t request Markdown&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;Accept: */*&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;User-Agent: GoogleAgent-URLContext&lt;/code&gt;&lt;/p&gt;&lt;h3 id=&quot;❌-fetch_webpage-in-github-copilot-(gpt-5-2-codex)-doesn-t-request-markdown&quot;&gt;&lt;a href=&quot;#❌-fetch_webpage-in-github-copilot-(gpt-5-2-codex)-doesn-t-request-markdown&quot;&gt;❌ &amp;quot;fetch_webpage&amp;quot; in &lt;strong&gt;GitHub Copilot&lt;/strong&gt; (GPT-5.2-Codex) doesn&amp;#x27;t request Markdown&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;Accept: text/html,application/xhtml+xml, ...&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;User-Agent: Mozilla/5.0 ... Code/1.109.3 ... Electron/39.3.0&lt;/code&gt;&lt;/p&gt;&lt;h3 id=&quot;❌-read_url_content-in-windsurf-(1-9552-21)-doesn-t-request-markdown&quot;&gt;&lt;a href=&quot;#❌-read_url_content-in-windsurf-(1-9552-21)-doesn-t-request-markdown&quot;&gt;❌ &amp;quot;read_url_content&amp;quot; in &lt;strong&gt;Windsurf&lt;/strong&gt; (1.9552.21) doesn&amp;#x27;t request Markdown&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;Accept: */*&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;User-Agent: colly - &amp;lt;https://github.com/gocolly/colly&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;h3 id=&quot;key-findings&quot;&gt;&lt;a href=&quot;#key-findings&quot;&gt;Key findings&lt;/a&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Only 3 out of 7 agents request markdown&lt;/strong&gt; — Claude Code, Cursor, and OpenCode are the only ones asking for &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;text/markdown&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Gemini CLI and Windsurf don&amp;#x27;t negotiate at all&lt;/strong&gt; — &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;*/*&lt;/code&gt; means &amp;quot;give me anything.&amp;quot; No markdown preference, no optimization.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;OpenCode and Cursor use the &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;q&lt;/code&gt; factor&lt;/strong&gt; — they set explicit quality factors (e.g., t&lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;ext/markdown;q=1.0, text/html;q=0.7&lt;/code&gt;) to prioritize markdown over HTML. The &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;q&lt;/code&gt; parameter is HTTP&amp;#x27;s way of expressing preference as a weight between 0 and 1. Claude Code skips q values and relies on the header value order instead.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The agents requesting markdown are already giving their users an advantage. What about the ones that are not, though? They&amp;#x27;re burning tokens on HTML that could have been avoided. We don&amp;#x27;t know why they haven&amp;#x27;t adopted content negotiation yet, but we expect them to follow suit soon. The benefits are too obvious to ignore.&lt;/p&gt;&lt;blockquote class=&quot;bg-gray-100 p-4 border-l-2 my-4 border-blue-300 inline-block space-y-4&quot;&gt;&lt;p&gt;&lt;em&gt;&lt;strong&gt;How do agents actually process fetched content?&lt;/strong&gt; &lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;We can&amp;#x27;t know exactly what closed-source agents do under the hood, but from what&amp;#x27;s publicly documented &lt;a target=&quot;_blank&quot; href=&quot;https://mikhail.io/2025/10/claude-code-web-tools/&quot; rel=&quot;noreferrer&quot;&gt;&lt;strong&gt;Claude Code&lt;/strong&gt;&lt;/a&gt; uses a two-stage architecture: the main conversation calls WebFetch, the response is converted to markdown, and a smaller, faster model summarizes it before injecting it into your conversation.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;This agent-side optimization is impressive — yet completely unnecessary. Converting HTML to markdown, truncating content, and spinning up secondary models to summarize the content is a lot of work to retrieve available online content. It&amp;#x27;s on us, the people running servers, creating products, and building the web, to meet agents where they are. &lt;a target=&quot;_blank&quot; href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Evolution_of_HTTP#http1.1_%E2%80%93_the_standardized_protocol&quot; rel=&quot;noreferrer&quot;&gt;Content negotiation has been in HTTP since 1997&lt;/a&gt;. When someone requests markdown, we all need to &amp;quot;just respond with markdown&amp;quot;.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;We at Checkly believe &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;text/markdown&lt;/code&gt; will become the standard for agent-to-server communication. The direction is clear, even if not all agent tools are yet on board. If your docs don&amp;#x27;t respect the Accept header, you&amp;#x27;re forcing agents to parse HTML, resulting in burned tokens, slow responses, and degraded-quality answers.&lt;/p&gt;&lt;h2 id=&quot;beyond-headers-the-full-picture&quot;&gt;&lt;a href=&quot;#beyond-headers-the-full-picture&quot;&gt;Beyond Headers: The Full Picture&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Content negotiation is an important step toward improving agentic workflows, but it&amp;#x27;s not the end goal. &lt;strong&gt;Ideally, agents shouldn&amp;#x27;t need to search the web at all.&lt;/strong&gt; The right context should be provided upfront, either by you as the agent user or by us as the developer tooling provider.&lt;/p&gt;&lt;p&gt;There are three emerging patterns that complete the picture:&lt;/p&gt;&lt;h3 id=&quot;llms-txt&quot;&gt;&lt;a href=&quot;#llms-txt&quot;&gt;llms.txt&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Another approach gaining traction is the use of &lt;a target=&quot;_blank&quot; href=&quot;https://llmstxt.org/&quot; rel=&quot;noreferrer&quot;&gt;llms.txt&lt;/a&gt; files. These file points agents to (markdown) versions of key pages, similar to how robots.txt guides crawlers. It&amp;#x27;s a good complement to content negotiation: the Accept header optimizes how content is served, while llms.txt helps agents discover what content exists in the first place.&lt;/p&gt;&lt;p&gt;We at Checkly opted for serving our doc’s key pages on &lt;a target=&quot;_blank&quot; href=&quot;http://checklyhq.com/llms.txt&quot; rel=&quot;noreferrer&quot;&gt;checklyhq.com/llms.txt&lt;/a&gt; because it’s most likely that agents want to set up or control the monitoring infrastructure, or help a user using the platform.&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;header class=&quot;flex py-2 px-16 items-center justify-center text-[13px] tracking-tight bg-blue-300/20 text&quot;&gt;&lt;div aria-hidden=&quot;true&quot; class=&quot;absolute left-4 flex gap-x-1&quot;&gt;&lt;div class=&quot;h-2.5 w-2.5 rounded-full bg-blue-300 opacity-20&quot;&gt;&lt;/div&gt;&lt;div class=&quot;h-2.5 w-2.5 rounded-full bg-blue-300 opacity-20&quot;&gt;&lt;/div&gt;&lt;div class=&quot;h-2.5 w-2.5 rounded-full bg-blue-300 opacity-20&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;span class=&quot;font-mono text-gray-300&quot;&gt;llms.txt&lt;/span&gt;&lt;/header&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;# Checkly Docs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;## Docs&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;- [Changing your email or password in Checkly](https://checklyhq.com/docs/admin/changing-your-email-password.md): Learn how to change your email address or password in your Checkly account&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;- [Creating an API key in Checkly](https://checklyhq.com/docs/admin/creating-api-key.md): Learn how to create and manage user and service API keys for the Checkly API and CLI&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;- ...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;agent-skills&quot;&gt;&lt;a href=&quot;#agent-skills&quot;&gt;Agent skills&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Skills are packaged, agent-readable instructions that tell an AI agent how to use a specific tool or product — no web search required. They go a step further than content negotiation: in addition to publishing our documentation online, &lt;a href=&quot;/blog/checkly-agent-skills/&quot;&gt;we also released a first agent skill to provide executable guidance.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Install the Checkly monitoring skill with:&lt;/p&gt;&lt;div class=&quot;code-block code-block-inline syntax-bash&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;skills&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly/checkly-cli&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Once installed, your favorite agent knows how to create checks, configure alerts, and deploy monitoring infrastructure — not because it read our docs or searched the web, but because we gave it structured and up-to-date instructions designed for the new world of AI agents.&lt;/p&gt;&lt;h3 id=&quot;agent-friendly-developer-platforms&quot;&gt;&lt;a href=&quot;#agent-friendly-developer-platforms&quot;&gt;Agent-friendly Developer Platforms&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Content negotiation with the &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;Accept&lt;/code&gt; header, &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;llms.txt&lt;/code&gt; and skills are the obvious choices to improve the agent experience today, but we&amp;#x27;re already working on the next iteration.&lt;/p&gt;&lt;p&gt;Here&amp;#x27;s what&amp;#x27;s coming to the Checkly Platform and Monitoring as Code:&lt;/p&gt;&lt;h4 id=&quot;markdown-first-cli-output&quot;&gt;&lt;a href=&quot;#markdown-first-cli-output&quot;&gt;Markdown-first CLI output&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;AI agents love CLIs, and we&amp;#x27;re improving the output of CLI commands like &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;checkly test &lt;/code&gt;and &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;checkly deploy&lt;/code&gt; to be structured and parseable. When an AI agent runs your checks, it should get clean, context-efficient results — not output designed for human eyes scanning a terminal. If the agent is facing issues, the CLI should provide context to help it get unstuck.&lt;/p&gt;&lt;p&gt;We&amp;#x27;re also exploring a new &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;checkly skills&lt;/code&gt; command that will provide all the required context and documentation inside the CLI itself to get your agent back on track.&lt;/p&gt;&lt;h4 id=&quot;markdown-first-core-features&quot;&gt;&lt;a href=&quot;#markdown-first-core-features&quot;&gt;Markdown-first Core Features&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Checkly&amp;#x27;s monitoring platform is designed to deliver critical information when your infrastructure experiences issues or outages. So far, you, as a human, needed to know what&amp;#x27;s broken in your infrastructure and since when. This will change — &lt;strong&gt;very soon, it won&amp;#x27;t be you asking for critical information about your platform&amp;#x27;s health&lt;/strong&gt;; it will be your agent, supervised by you.&lt;/p&gt;&lt;p&gt;As a result, our API responses and platform core features will become token-efficient and agent-friendly. Watch the space! We&amp;#x27;ve got many things in the works to make &amp;quot;Hey Agent, I received an alert. Can you fix it?&amp;quot; a reality.&lt;/p&gt;&lt;h2 id=&quot;wrapping-up&quot;&gt;&lt;a href=&quot;#wrapping-up&quot;&gt;Wrapping Up&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The web has a new class of visitors. They don&amp;#x27;t have eyes, they pay by the token, and they&amp;#x27;re how developers discover and interact with your product.&lt;/p&gt;&lt;p&gt;Not every agent requests markdown today, but the ones that do are already giving their users a better experience — faster responses, lower costs, higher quality answers. The direction is clear.&lt;/p&gt;&lt;p&gt;Here&amp;#x27;s what you can do right now:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Using agents?&lt;/strong&gt; — test what headers your agent tools send. Some agents optimize for you. Others don&amp;#x27;t. Know which one you&amp;#x27;re using. Consider a switch to save tokens.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Building for the web?&lt;/strong&gt; — support &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;Accept: text/markdown&lt;/code&gt;. Agents are your next users. Serve them well, or watch them struggle with your docs and product.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;If you&amp;#x27;re monitoring your sites, apps, and infrastructure while riding the agentic train, check out Checkly and &lt;em&gt;Monitoring as Code&lt;/em&gt;. It&amp;#x27;s AI-ready by design. &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/integrations/ai/overview/&quot; rel=&quot;noreferrer&quot;&gt;Get started with AI-powered monitoring&lt;/a&gt;.&lt;/p&gt;]]&gt;</content:encoded></item><item><title><![CDATA[Introducing: Checkly Agent Skills]]></title><description><![CDATA[Introducing Checkly Agent Skills: a new “monitoring” agent skill that lets AI coding agents set up, review, and ship production-ready monitoring as code. Learn what agent skills are, what’s inside the Checkly skill (API checks, Playwright browser checks, alerts, status pages, and more), and how its token-efficient design helps agents load best practices on demand.]]></description><link>https://www.checklyhq.com/blog/checkly-agent-skills</link><guid isPermaLink="false">aZWb8xkAAEQAY1JV</guid><category><![CDATA[AI]]></category><dc:creator><![CDATA[Stefan Judis]]></dc:creator><pubDate>Wed, 18 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;p&gt;AI coding agents are excellent at writing code. Ask Claude Code, Codex, or Cursor to add a feature, and it just works. At Checkly, &lt;strong&gt;we were ready for the new agentic world from the start&lt;/strong&gt;! &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/concepts/monitoring-as-code/&quot; rel=&quot;noreferrer&quot;&gt;Monitoring as Code&lt;/a&gt; means your entire monitoring setup lives in your repository. API Checks, Browser Checks, alert channels, status pages; everything is defined in code, managed with the &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/cli/overview/&quot; rel=&quot;noreferrer&quot;&gt;Checkly CLI&lt;/a&gt;, and version-controlled like any other part of your stack. &lt;strong&gt;Agents can write, review, and ship your monitoring infrastructure!&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;In 2026, &lt;strong&gt;we believe AI agents are our new power users.&lt;/strong&gt; And when developers ask their agents to set up end-to-end production monitoring, we want agents to generate code that not only runs but also follows best practices.&lt;/p&gt;&lt;p&gt;Today, we&amp;#x27;re releasing the first agent skill for Checkly, which includes best practices and patterns that teach your AI agent to control your monitoring the way Checkly engineers do.&lt;/p&gt;&lt;h2 id=&quot;what-are-agent-skills-&quot;&gt;&lt;a href=&quot;#what-are-agent-skills-&quot;&gt;What are agent skills?&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://agentskills.io/&quot; rel=&quot;noreferrer&quot;&gt;Agent skills&lt;/a&gt; are a standardized format for giving AI agents specialized knowledge. Think of them as documentation written for machines. Skills are structured instructions that agents discover and load on demand.&lt;/p&gt;&lt;p&gt;A skill is a directory containing a &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;SKILL.md&lt;/code&gt; file with instructions, plus optional reference files for detailed documentation:&lt;/p&gt;&lt;div class=&quot;code-block&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex &quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;monitoring/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;├── SKILL.md              # Core instructions (~1K tokens)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;└── references/           # Loaded on demand&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;    ├── api-checks.md&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;    ├── browser-checks.md&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;    ├── alert-channels.md&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: undefined&quot;&gt;    └── ...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The skill format works with Claude Code, Cursor, Codex, and other agents supporting the standard. Instead of hoping your agent learned the right patterns from training data, you give it explicit instructions to discover and follow.&lt;/p&gt;&lt;h2 id=&quot;what-s-inside-the-checkly-skill&quot;&gt;&lt;a href=&quot;#what-s-inside-the-checkly-skill&quot;&gt;What&amp;#x27;s inside the Checkly skill&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The new Checkly &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;monitoring&lt;/code&gt; skill covers everything you need to control your monitoring setup as code:&lt;/p&gt;&lt;section class=&quot;overflow-auto py-4&quot; data-slice-type=&quot;data_table&quot; data-slice-variation=&quot;default&quot;&gt;&lt;table class=&quot;w-full min-w-[500px] border-separate border-spacing-y-2&quot;&gt;&lt;caption class=&quot;caption-bottom w-max px-4 py-2 mt-8 mx-auto bg-gray-100 rounded-full&quot;&gt;Construct References&lt;/caption&gt;&lt;thead&gt;&lt;tr class=&quot;font-bold&quot;&gt;&lt;td class=&quot;p-4 text-left&quot;&gt;Construct&lt;/td&gt;&lt;td class=&quot;p-4&quot;&gt;What it covers&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr class=&quot;[&amp;amp;:nth-child(even)]:bg-gray-100&quot;&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;API Checks&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;HTTP assertions, authentication, setup scripts&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;[&amp;amp;:nth-child(even)]:bg-gray-100&quot;&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;Browser Checks&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;Playwright-based E2E monitoring&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;[&amp;amp;:nth-child(even)]:bg-gray-100&quot;&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;Playwright Checks&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;Multi-browser Playwright test suites for production monitoring&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;[&amp;amp;:nth-child(even)]:bg-gray-100&quot;&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;MultiStep Checks&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;Complex user flow API monitoring&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;[&amp;amp;:nth-child(even)]:bg-gray-100&quot;&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;Monitors&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;TCP, URL, DNS, and Heartbeat monitors&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;[&amp;amp;:nth-child(even)]:bg-gray-100&quot;&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;Check Groups&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;Organizing checks with shared configuration&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;[&amp;amp;:nth-child(even)]:bg-gray-100&quot;&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;Alert Channels&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;Email, Phone, Slack, and webhook notifications&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;[&amp;amp;:nth-child(even)]:bg-gray-100&quot;&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;Supporting Constructs&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;Status pages, dashboards, maintenance windows&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;p&gt;&lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/constructs/overview/&quot; rel=&quot;noreferrer&quot;&gt;Each construct type&lt;/a&gt; has its own reference file with examples and documentation links your agent can use directly.&lt;/p&gt;&lt;h2 id=&quot;how-agents-use-the-skill&quot;&gt;&lt;a href=&quot;#how-agents-use-the-skill&quot;&gt;How agents use the skill&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;When you ask your agent to set up monitoring, it discovers the Checkly skill and loads the relevant context. Need an API Check? It pulls in the API Check reference. Setting up alerts? It loads the alert channel documentation. The agent treats these files as the source of truth rather than improvising and hallucinating forward.&lt;/p&gt;&lt;p&gt;For example, the skill teaches your agent to:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Follow project conventions&lt;/strong&gt;: Put checks in &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;src/__checks__/&lt;/code&gt;, use &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;.check.ts&lt;/code&gt; for monitoring construct definitions and &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;.spec.ts&lt;/code&gt; for Playwright code&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Configure checks properly&lt;/strong&gt;: Set appropriate frequencies, choose the right runtime version, and configure locations that make sense for your users&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Set up alerting&lt;/strong&gt;: Wire up Slack, email, or phone alerts with the right escalation patterns&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;token-efficient-by-design&quot;&gt;&lt;a href=&quot;#token-efficient-by-design&quot;&gt;Token-efficient by design&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;A year ago, we shipped the &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;checkly.rules.md&lt;/code&gt; file that agents could load entirely. This file holds about 4,000 tokens of context, whether you needed it or not. It was a good first step, but the ecosystem has evolved toward more token-efficient approaches to avoid degraded performance and context rot.&lt;/p&gt;&lt;p&gt;The Agent skills format uses &lt;strong&gt;progressive disclosure&lt;/strong&gt; so that agents load only what they need for each task:&lt;/p&gt;&lt;section class=&quot;overflow-auto py-4&quot; data-slice-type=&quot;data_table&quot; data-slice-variation=&quot;default&quot;&gt;&lt;table class=&quot;w-full min-w-[500px] border-separate border-spacing-y-2&quot;&gt;&lt;thead&gt;&lt;tr class=&quot;font-bold&quot;&gt;&lt;td class=&quot;p-4 text-left&quot;&gt;Stage&lt;/td&gt;&lt;td class=&quot;p-4&quot;&gt;What is loaded&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr class=&quot;[&amp;amp;:nth-child(even)]:bg-gray-100&quot;&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;Discovery&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;Skill name and description (&lt;strong&gt;~100 tokens&lt;/strong&gt;) &lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;[&amp;amp;:nth-child(even)]:bg-gray-100&quot;&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;Activation&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;Core Skill.md instructions (&lt;strong&gt;~1,000 tokens&lt;/strong&gt;)&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr class=&quot;[&amp;amp;:nth-child(even)]:bg-gray-100&quot;&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;Specific Tasks&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;Individual reference files (&lt;strong&gt;on demand&lt;/strong&gt;)&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;p&gt;Your agent starts with consuming ~100 tokens just to know the skill exists. When monitoring becomes relevant, it loads ~1,000 tokens of core guidance. Detailed references about API Checks, Playwright Check Suites, alert channels, status pages, etc., are only loaded when the agent actually needs them.&lt;/p&gt;&lt;section class=&quot;overflow-auto py-4&quot; data-slice-type=&quot;data_table&quot; data-slice-variation=&quot;default&quot;&gt;&lt;table class=&quot;w-full min-w-[500px] border-separate border-spacing-y-2&quot;&gt;&lt;thead&gt;&lt;tr class=&quot;font-bold&quot;&gt;&lt;td class=&quot;p-4 text-left&quot;&gt;Checkly Rules&lt;/td&gt;&lt;td class=&quot;p-4&quot;&gt;Checkly Monitoring Skill&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr class=&quot;[&amp;amp;:nth-child(even)]:bg-gray-100&quot;&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;~4,000 tokens (always)&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div class=&quot;p-4&quot;&gt;&lt;p&gt;~100–1,000 tokens (typical)&lt;/p&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/section&gt;&lt;p&gt;This approach leads to faster responses, lower costs, and context that scales with your monitoring task.&lt;/p&gt;&lt;h2 id=&quot;get-started&quot;&gt;&lt;a href=&quot;#get-started&quot;&gt;Get started&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Install the Checkly skills with &lt;a target=&quot;_blank&quot; href=&quot;https://skills.sh/&quot; rel=&quot;noreferrer&quot;&gt;the Skills CLI&lt;/a&gt;:&lt;/p&gt;&lt;div class=&quot;code-block code-block-inline syntax-bash&quot;&gt;&lt;div class=&quot;overflow-auto w-full flex pr-12&quot;&gt;&lt;pre class=&quot;syntax&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt;npx &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;skills&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color: var(--shiki-color-text)&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: var(--shiki-token-string)&quot;&gt;checkly/checkly-cli&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;button type=&quot;button&quot; class=&quot;group bg-inherit absolute rounded flex items-center justify-center top-0 right-0  text-white bg-inherit h-14 w-14&quot; title=&quot;Copy code to clipboard&quot;&gt;&lt;svg viewBox=&quot;0 0 16 11&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; class=&quot;absolute h-5 w-5 transition duration-200 ease-out text-checkly-blue -translate-y-2 opacity-0 scale-90&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M15.1085 0.558056C15.3526 0.802133 15.3526 1.19786 15.1085 1.44194L5.94187 10.6086C5.82466 10.7259 5.66568 10.7917 5.49992 10.7917C5.33416 10.7917 5.17519 10.7259 5.05798 10.6086L0.891309 6.44194C0.647232 6.19786 0.647233 5.80213 0.891312 5.55806C1.13539 5.31398 1.53112 5.31398 1.7752 5.55806L5.49992 9.28281L14.2246 0.55806C14.4687 0.313981 14.8644 0.31398 15.1085 0.558056Z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;svg viewBox=&quot;0 0 18 19&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; class=&quot;absolute h-5 w-5 transition duration-200 ease-out translate-y-0 opacity-100 scale-100 text-white/30 group-hover:text-white/80&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M5.875 8.85929C5.875 7.59364 6.90101 6.56763 8.16667 6.56763H15.6667C16.9323 6.56763 17.9583 7.59365 17.9583 8.85929V16.3593C17.9583 17.6249 16.9323 18.651 15.6667 18.651H8.16667C6.901 18.651 5.875 17.6249 5.875 16.3593V8.85929ZM8.16667 7.81763C7.59137 7.81763 7.125 8.28399 7.125 8.85929V16.3593C7.125 16.9346 7.59138 17.401 8.16667 17.401H15.6667C16.2419 17.401 16.7083 16.9346 16.7083 16.3593V8.85929C16.7083 8.28398 16.2419 7.81763 15.6667 7.81763H8.16667Z&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M2.33464 1.98438C2.05836 1.98438 1.79341 2.09412 1.59807 2.28946C1.59807 2.28946 1.59807 2.28946 1.59807 2.28946M1.59807 2.28946C1.40272 2.48482 1.29297 2.74978 1.29297 3.02604V10.5261C1.29297 10.8023 1.4027 11.0672 1.59809 11.2626C1.79343 11.458 2.05838 11.5678 2.33464 11.5678H3.16797C3.51315 11.5678 3.79297 11.8476 3.79297 12.1928C3.79297 12.5379 3.51315 12.8178 3.16797 12.8178H2.33464C1.72684 12.8178 1.14393 12.5763 0.714149 12.1465C0.284418 11.7167 0.0429688 11.1338 0.0429688 10.5261V3.02604C0.0429688 2.41826 0.284405 1.83537 0.71417 1.40559C1.14395 0.975814 1.72686 0.734375 2.33464 0.734375H9.8346C10.4424 0.734375 11.0253 0.9758 11.4551 1.40563C11.8849 1.8354 12.1263 2.41827 12.1263 3.02604V3.85938C12.1263 4.20455 11.8465 4.48438 11.5013 4.48438C11.1561 4.48438 10.8763 4.20455 10.8763 3.85938V3.02604C10.8763 2.74979 10.7666 2.48485 10.5712 2.28949C10.3759 2.09419 10.111 1.98438 9.8346 1.98438H2.33464&quot; fill=&quot;currentColor&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/div&gt;&lt;p&gt;That&amp;#x27;s it. Your agent then has access to Checkly&amp;#x27;s monitoring patterns and will use them automatically when you work on your monitoring infrastructure.&lt;/p&gt;&lt;p&gt;Try asking your agent to:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&amp;quot;Set up monitoring for my API endpoints.&amp;quot;&lt;/li&gt;&lt;li&gt;&amp;quot;Configure Slack alerts for Playwright checks.&amp;quot;&lt;/li&gt;&lt;li&gt;&amp;quot;Update the core monitoring locations and add &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;eu-central-1&lt;/code&gt;.&amp;quot;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Your agent is now a Checkly monitoring expert!&lt;/p&gt;&lt;h2 id=&quot;what-s-next&quot;&gt;&lt;a href=&quot;#what-s-next&quot;&gt;What&amp;#x27;s next&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;monitoring&lt;/code&gt; skill is just the start. We&amp;#x27;re working on adding more skills:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Playwright&lt;/strong&gt; — Best practices for generating reliable, maintainable &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/docs/detect/synthetic-monitoring/playwright-checks/overview/&quot; rel=&quot;noreferrer&quot;&gt;Playwright end-to-end test code&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Resolution&lt;/strong&gt; — Patterns for incident analysis, debugging failing checks, and resolving core issues&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;We&amp;#x27;re also exploring embedding agent context directly into the Checkly CLI itself. Imagine running &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;npx checkly skills browser-check&lt;/code&gt; or &lt;code class=&quot;bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words&quot;&gt;npx checkly skills alert-channel&lt;/code&gt; to get the exact context your agent needs at the right time. No external installation will be required because we believe &lt;strong&gt;CLI tooling should be self-contained and self-documenting for humans and agents alike&lt;/strong&gt;.&lt;/p&gt;&lt;h2 id=&quot;try-it-out&quot;&gt;&lt;a href=&quot;#try-it-out&quot;&gt;Try it out&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The Checkly agent skill is available now. Install it, point your agent at your project, and let it set up production-ready monitoring.&lt;/p&gt;&lt;p&gt;Do you have questions or feedback? Find us on &lt;a target=&quot;_blank&quot; href=&quot;https://checklyhq.com/slack&quot; rel=&quot;noreferrer&quot;&gt;our community Slack&lt;/a&gt;.&lt;/p&gt;]]&gt;</content:encoded></item><item><title><![CDATA[How to Write a Cover Letter That Actually Helps You Get the Job]]></title><description><![CDATA[Learn how to write a cover letter that actually helps you get the job. Practical, concise tips from Checkly’s Director of People, Kaylie Boogaerts, on what hiring teams really want.]]></description><link>https://www.checklyhq.com/blog/how-to-write-a-cover-letter</link><guid isPermaLink="false">aS3HIRkAAEEA1Ulj</guid><category><![CDATA[hiring]]></category><category><![CDATA[People]]></category><dc:creator><![CDATA[Kaylie Boogaerts]]></dc:creator><pubDate>Mon, 01 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;p&gt;Cover letters are supposed to help you shine, but most of them blur together into the same polite, forgettable paragraphs.&lt;/p&gt;&lt;p&gt;The intention is good (“I want them to notice me!”), but the execution… not so much. So, here’s a simple, honest guide to writing a cover letter that &lt;em&gt;actually&lt;/em&gt; works, especially if you’re applying to Checkly.&lt;/p&gt;&lt;p&gt;Spoiler: shorter is better. And authenticity in this AI era is better than perfect polished perfection.&lt;/p&gt;&lt;p&gt;Hi, I’m Kaylie, Director of People at Checkly. I’ve read a lot of cover letters, and I want to help you write one that actually works.&lt;/p&gt;&lt;h2 id=&quot;what-most-cover-letters-end-up-being&quot;&gt;&lt;a href=&quot;#what-most-cover-letters-end-up-being&quot;&gt;&lt;strong&gt;What most cover letters end up being&lt;/strong&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;If you only knew how many times I’ve read the same sentence, slightly reworded, by hundreds of candidates…&lt;/p&gt;&lt;ul&gt;&lt;li&gt;A list of everything the job post mentions, with “I am excited about…” pasted in front.&lt;/li&gt;&lt;li&gt;Obviously AI-generated text that sounds nice but says absolutely nothing.&lt;/li&gt;&lt;li&gt;Claims about experience that don’t match the CV or LinkedIn profile at all.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;None of this helps.&lt;/strong&gt; &lt;strong&gt;It doesn’t tell us who you are or why you care about the role. And honestly? You’re wasting your own time writing something that isn’t going to move the needle.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Which brings me to…&lt;/p&gt;&lt;h2 id=&quot;what-makes-your-cover-letter-stand-out&quot;&gt;&lt;a href=&quot;#what-makes-your-cover-letter-stand-out&quot;&gt;&lt;strong&gt;What makes your cover letter stand out&lt;/strong&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Cover letters are totally optional at Checkly. But when they’re good, they can make your application stand out in a sea of hundreds.&lt;/p&gt;&lt;p&gt;Here’s what a great cover letter looks like:&lt;/p&gt;&lt;h3 id=&quot;1-keep-it-concise-and-specific&quot;&gt;&lt;a href=&quot;#1-keep-it-concise-and-specific&quot;&gt;&lt;strong&gt;1. Keep it concise and specific&lt;/strong&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;When we publish a new role, we get hundreds of applications, sometimes over a thousand! We read through every single one, but that also means that we don’t have time for essays. A sharp, 3-paragraph cover letter beats a 1.5-page essay every time.&lt;/p&gt;&lt;h3 id=&quot;2-tell-us-why-you-want-this-role&quot;&gt;&lt;a href=&quot;#2-tell-us-why-you-want-this-role&quot;&gt;&lt;strong&gt;2. Tell us &lt;em&gt;why&lt;/em&gt; you want this role&lt;/strong&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Not why you want &lt;em&gt;a&lt;/em&gt; job. Not why you want “a new challenge.”&lt;/p&gt;&lt;p&gt;Why &lt;strong&gt;this&lt;/strong&gt; role? What part of it sparks something for you? We want to hire people who choose us on purpose. If something about the company or role lights you up, say it.&lt;/p&gt;&lt;h3 id=&quot;3-share-a-real-example&quot;&gt;&lt;a href=&quot;#3-share-a-real-example&quot;&gt;&lt;strong&gt;3. Share a real example&lt;/strong&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Give us a story: a small, concrete example from your experience that shows you can do something this role needs.&lt;/p&gt;&lt;p&gt;Not a list of traits. Not “I am a great communicator.”&lt;/p&gt;&lt;p&gt;Something like: “In my last role, I rebuilt our onboarding flow from scratch and cut ramp-up time by 40%. I’d love to bring this kind of structured thinking to Checkly as you scale.”&lt;/p&gt;&lt;p&gt;That one example gives us far more than three paragraphs of adjectives ever could.&lt;/p&gt;&lt;h3 id=&quot;4-write-like-a-human&quot;&gt;&lt;a href=&quot;#4-write-like-a-human&quot;&gt;&lt;strong&gt;4. Write like a human&lt;/strong&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Drop the overly formal tone. We’re a friendly, direct, international team. It’s okay to sound like yourself.&lt;/p&gt;&lt;h3 id=&quot;5-check-your-facts&quot;&gt;&lt;a href=&quot;#5-check-your-facts&quot;&gt;&lt;strong&gt;5. Check your facts&lt;/strong&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;We compare what you write with what’s on your CV or LinkedIn. Make sure they align. If your cover letter mentions 10 years of Go experience but your CV lists one year of Java… we notice.&lt;/p&gt;&lt;h2 id=&quot;why-this-matters&quot;&gt;&lt;a href=&quot;#why-this-matters&quot;&gt;&lt;strong&gt;Why this matters&lt;/strong&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;A good cover letter isn’t about being poetic or impressive. It’s about helping us understand two simple things:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Why you want to work here&lt;/strong&gt;, and&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Why you think you can be great at this role.&lt;/strong&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;That’s it.&lt;/p&gt;&lt;p&gt;If you can answer those clearly and briefly, you’re already way ahead of most applicants.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Extra&lt;/strong&gt;: If you want real inspiration, check out &lt;a target=&quot;_blank&quot; href=&quot;https://www.checklyhq.com/blog/how-i-landed-my-dream-job-that-didnt-exist/&quot; rel=&quot;noreferrer&quot;&gt;the exact cover letter I submitted with my application&lt;/a&gt;.&lt;/p&gt;]]&gt;</content:encoded></item></channel></rss>