Customer support screenshot API captures the URL a customer reports and returns exactly what that page looks like right now. No browser tabs to open, no "can you send a screenshot?" back-and-forth. One API call per ticket, and the agent sees what the customer sees.
This matters because most support tickets about visual issues (broken layout, wrong prices, missing content) start with a vague description. "The page looks weird on my end." That's it. The agent guesses, the customer clarifies, and two or three messages later you're still not sure what they're looking at. A screenshot of the reported URL, captured automatically when the ticket comes in, skips that entire loop.
Capture the URL from a support ticket
The simplest version of this workflow: extract the URL from the ticket body, pass it to the API, and attach the returned image to the ticket. The customer says "something is wrong with my account page at https://app.example.com/settings" and the agent immediately has a screenshot of that page without leaving their helpdesk.
curl "https://api.screenshotrun.com/v1/screenshots/capture" \
-H "Authorization: Bearer YOUR_API_KEY" \
-G \
--data-urlencode "url=https://app.example.com/settings" \
--data-urlencode "full_page=true" \
--data-urlencode "format=png" \
--data-urlencode "delay=1500" \
-o ticket-screenshot.png
Why full_page=true and a 1500ms delay? Support-relevant pages tend to be dashboards, account settings, or product pages with dynamic content. They load scripts, fetch user data, render tables. Without the delay, you might capture a half-loaded spinner instead of the actual content. And full_page gets the entire page, not just the visible viewport, which matters when the customer's complaint is about something below the fold.
If you need the mobile view (and you often do, since a lot of support tickets come from phone users), add device=mobile to see the responsive layout. The page might look fine on desktop and completely broken on a 375px screen.
Automate customer support screenshots on ticket creation
Doing this manually defeats the purpose. The real value comes when screenshots get captured automatically every time a new ticket arrives with a URL in it. Most helpdesk platforms (Zendesk, Freshdesk, Intercom, HubSpot) support outbound webhooks on ticket creation. Your handler parses the ticket body for URLs, captures each one, and attaches the screenshots back to the ticket.
const express = require('express');
const axios = require('axios');
const app = express();
app.use(express.json());
app.post('/new-ticket', async (req, res) => {
const { ticketId, body } = req.body;
const urls = body.match(/https?:\/\/[^\s)>"]+/g) || [];
for (const url of urls.slice(0, 3)) {
const screenshot = await axios.get(
'https://api.screenshotrun.com/v1/screenshots/capture',
{
headers: { Authorization: `Bearer ${process.env.SR_KEY}` },
params: {
url,
full_page: true,
delay: 1500,
format: 'png',
block_ads: true,
block_cookies: true,
},
responseType: 'arraybuffer',
timeout: 30000,
}
);
// Attach to ticket via your helpdesk API
await attachToTicket(ticketId, screenshot.data, url);
}
res.sendStatus(200);
});
app.listen(3000);
The .slice(0, 3) limit is intentional. Some tickets contain dozens of URLs (especially when customers paste entire email threads). Capturing all of them wastes time and clutters the ticket. Three is usually enough to understand what's going on.
block_ads and block_cookies clean up the capture. Cookie consent banners and chat widgets cover up the actual content the customer complained about. See ad blocking for the full list of what gets removed.
Visual bug reports that engineers won't send back
This is probably the most frustrating part of the support-to-engineering handoff. The agent writes up a bug report, the engineer reads it, and then asks: "Can you show me what this looks like?" Because text descriptions of visual bugs don't work. "The sidebar overlaps the main content" could mean a hundred different things depending on the viewport, browser, and page state.
A screenshot taken at the exact URL, with the exact viewport and device settings the customer reported, removes all that ambiguity. And if you add extract_metadata=true to your API call, the response includes the page title, status code, and loaded URL (after redirects). That's the kind of context engineers need to reproduce the issue without guessing.
import requests
resp = requests.get(
"https://api.screenshotrun.com/v1/screenshots/capture",
headers={"Authorization": "Bearer YOUR_API_KEY"},
params={
"url": "https://app.example.com/dashboard",
"width": 1280,
"height": 800,
"format": "png",
"extract_metadata": True,
"full_page": True,
},
timeout=30,
)
# Response includes both the screenshot and metadata
# Metadata: page title, final URL, status code, load time
Some teams go a step further and capture the same URL at two viewports (desktop 1280px + mobile 375px) before attaching both to the Jira ticket. Takes two API calls instead of one but eliminates the "works on my machine" problem before it even starts.
Before-and-after screenshots for QA
A customer reports a broken page. The engineer pushes a fix. How does the QA team verify that it actually worked? They open the URL, scroll around, compare what they see to the original report. That's fine for one ticket. It's not fine for 15 tickets on a Monday morning after a weekend deploy.
Automated before/after comparisons work better at scale. Capture the URL when the ticket is filed (that's your "before"). After the fix ships, capture it again. Store both screenshots in the ticket timeline. The QA reviewer sees them side by side without opening a browser.
The visual regression testing page covers pixel-diff approaches in depth if you want to take this further with automated comparison tools.
Capturing what logged-in users see
Things get tricky with authenticated pages. A lot of support tickets involve pages behind authentication: user dashboards, account settings, billing pages. The API can't just open those URLs and see what the customer sees because the page redirects to a login screen.
Two ways to handle this. If your app supports session tokens in cookies, you can pass them via the cookies parameter. That gives the API a logged-in session. For apps that use header-based authentication, the headers parameter does the same thing. Both approaches are covered in the screenshot behind login page.
The safer option for most teams: set up a read-only admin account or an impersonation endpoint. An agent clicks "view as this user" in the admin panel, and that URL is what gets passed to the screenshot API. No real user credentials needed, same visual result.
Helpdesk integration patterns
Every helpdesk does webhooks slightly differently, but the pattern is the same: listen for ticket creation events, extract URLs, capture screenshots, push them back as attachments or internal notes.
| Helpdesk | Trigger | Attach via |
|---|---|---|
| Zendesk | Trigger → webhook on ticket create | Tickets API → uploads endpoint |
| Freshdesk | Automation rule → webhook | Tickets API → attachments |
| Intercom | Conversation webhook | Reply API with attachment |
| HubSpot | Workflow → webhook on ticket create | Engagements API → note with file |
| Jira Service Management | Automation → webhook | Issue API → attachments |
For no-code teams, Zapier and Make.com can wire this up in about 10 minutes. Trigger: new Zendesk ticket. Action 1: extract URLs from ticket body. Action 2: call ScreenshotRun API. Action 3: upload the result back to Zendesk as an internal note. No server required.
Customer-facing visual guides
Screenshots aren't only useful for agents diagnosing problems. They work the other direction too: showing customers what they should see, step by step.
Say a customer asks "how do I change my billing plan?" Instead of typing out instructions that might not match what their screen looks like (different plan, different locale, A/B test variant), an agent could generate a live screenshot of the actual billing page and annotate it. Or better: include auto-captured screenshots of each step in your help center articles, so they always reflect the current UI. Every time your app ships a visual update, recapture the screenshots. The content stays fresh without anyone remembering to update it.
This is essentially what tools like ScreenshotAgent charge monthly for, but the underlying operation is a single API call per page. If you already have ScreenshotRun in your stack, it's one more thing it handles.
Performance at ticket volume
A support team handling 200 tickets a day, where maybe 30% contain a URL, means about 60 customer support screenshot requests. That's well within a standard API plan and takes about 2-3 minutes of total rendering time if you run the captures concurrently. The API handles concurrency natively, so you don't need a queue on your side unless your ticket volume is in the thousands per day.
For high-volume teams, the webhook parameter helps. Instead of waiting for each screenshot to render synchronously (which blocks your ticket handler), the API accepts the request immediately and POSTs the finished image to your endpoint when it's done. Your webhook handler stays fast, and the screenshot arrives a few seconds later.
Caching is worth mentioning too. If multiple tickets reference the same URL (common for site-wide outages or known bugs), cache_ttl=300 returns the cached screenshot instead of re-rendering. Five minutes of cache means the first ticket triggers a real capture, and every ticket after that gets the same image instantly.
What doesn't work well
Being upfront about the limits saves you setup time:
- Single-page apps with client-side routing sometimes show the home page instead of the reported route. Adding
delay=3000andwait_for_selectortargeting a known element on that route helps, but it's not always reliable if the app requires a logged-in state to render correctly. - Pages that depend on user-specific data (shopping carts, personalized dashboards) won't match exactly what the customer saw. The screenshot shows what the URL renders for an anonymous visitor or for whatever credentials you pass. Close, but not identical.
- PDF and file download URLs don't produce screenshots because there's nothing to render in the browser. Redirect URLs that land on a file download fall into this category too.
For authenticated pages and SPAs, the CSS/JS injection feature can help in edge cases, such as injecting a script that skips the login redirect or forces a specific route to render. But that requires knowing your app's internals, so it's more of a developer setup than something a support agent configures on their own.
The core customer support screenshot workflow (extract URL from ticket, capture, attach) works best with public-facing pages: marketing sites, product pages, pricing pages, documentation. Those are also the pages customers report most frequently, which is convenient.
Why ScreenshotRun for support teams
You could build this with Puppeteer or Playwright. We did — that's how this product started. But maintaining a headless browser fleet that stays up at 3 AM when your overnight support shift needs it is a different kind of problem than taking screenshots. Chrome updates break things every six weeks. Memory leaks pile up after a few hundred captures. And when your ticket handler times out because the browser process crashed, the support agent is back to opening tabs manually.
ScreenshotRun handles the browser infrastructure so your team doesn't have to. A few things that matter specifically for support workflows: block_ads and block_cookies strip overlays that hide the actual page content. device=mobile reproduces what phone users see without maintaining separate device profiles. cache_ttl prevents redundant renders when 40 customers report the same outage page. And the webhook delivery keeps your ticket handler responsive instead of blocking on each capture.
Plans start at 1,500 screenshots per month on the Starter tier — enough for most support teams to run automated capture on every URL-containing ticket. If your volume spikes during an incident (and it will), overage pricing is per-screenshot, not a surprise bill for the next tier. Check the pricing page for current numbers.
FAQ#
When a customer submits a ticket with a URL, the API automatically captures a screenshot of that page and attaches it to the ticket. The support agent sees exactly what the customer sees without opening a browser or asking for clarification. This cuts back-and-forth messages and speeds up resolution.
Any helpdesk that supports webhooks on ticket creation works, including Zendesk, Freshdesk, Intercom, HubSpot, and Jira Service Management. For no-code setups, Zapier and Make.com can connect your helpdesk to the API in about 10 minutes.
Yes. You can pass session cookies or authentication headers via the cookies and headers parameters. For a safer approach, many teams use admin impersonation endpoints so no real user credentials are shared with the API.
A team handling 200 tickets daily where 30% contain URLs needs about 60 screenshots. That is well within the Starter plan (1,500/month). The API handles concurrent requests natively, and caching prevents redundant captures when multiple tickets reference the same URL.
For public pages it is very close. The API captures the URL at the viewport and device you specify. For pages with user-specific data (shopping carts, personalized dashboards), the screenshot shows what the URL renders for the credentials you pass, which may differ slightly from what the individual customer saw.
Yes. Capture the reported URL with extract_metadata enabled to get the page title, HTTP status code, and final URL after redirects. Attach the screenshot and metadata to your Jira or Linear ticket. Some teams capture at both desktop and mobile viewports for complete bug documentation.