API

Endpoint Reference

Every operation in the VitalSentinel public API, grouped by module, with the scope each one requires. 217 operations across 19 groups.

View as Markdown

217 operations across 19 groups. Every path below is relative to https://app.vitalsentinel.com/api/public/v1.

This page is a map. The OpenAPI document is the contract, and it carries the request and response schemas, the query parameters, and the per-operation notes that are too long to fit in a table.

Read the conventions first. Pagination, time ranges, and idempotency apply across the whole surface and are not repeated per endpoint.

Meta

No scope required. Both cost 0 credits.

MethodPathDescription
GET/healthService health. Unauthenticated.
GET/meDescribe the calling credential, its scopes, and its effective scopes

Workspaces and domains

Read-only. Creating or editing a workspace or a domain is a dashboard-only operation.

MethodPathScopeDescription
GET/workspacesread:workspacesList accessible workspaces
GET/workspaces/{workspace_id}read:workspacesGet a workspace
GET/domainsread:domainsList domains
GET/domains/{domain_id}read:domainsGet a domain
GET/domains/{domain_id}/limitsread:domainsGet plan limits and usage

/workspaces and /domains return the page envelope but always as a single page today, and both cost 0 credits.

Domain overview and health

The two cross-module summaries. Start here rather than fanning out across eight modules.

MethodPathScopeDescription
GET/domains/{domain_id}/overviewread:overviewCross-module summary with period comparison
GET/domains/{domain_id}/healthread:domainsCross-module health snapshot

Both cover the same eight modules over a fixed 28-day window that is not configurable. The differences that decide which you want:

/overview/health
Scope requiredread:overviewread:domains
WindowLast 28 daysLast 28 complete UTC days versus the 28 before
ComparisonThree modules: CrUX, Search Console, Web AnalyticsEvery configured module
Freshness controlNone. Always cached, up to an hour oldfreshness=cached (default) or freshness=live
Reports its own stalenessNoYes, meta.cache_age_seconds

/health is the one to reach for during an incident. Pass freshness=live to bypass the cache and recompute every module now. It is slower, and cache_age_seconds comes back as 0 so you know you got a fresh answer.

On the default freshness=cached, check meta.cache_age_seconds before trusting uptime.is_up. A snapshot up to an hour old is fine for a dashboard and wrong for "is the site up right now".

/overview has no freshness lever at all, so do not use it for a time-sensitive question. Use /health?freshness=live, or /uptime/status, which is never cached.

Credits

MethodPathScopeDescription
GET/creditsnoneWorkspace credit balance and your own cap
GET/credits/logread:credits for OAuth; admin or owner role alwaysThis cycle's spending, request by request
GET/credits/workspacesnoneOne balance per accessible workspace, each with its own cycle

All three cost 0 credits. /credits and /credits/log take an optional workspace_id; /credits/workspaces takes no parameters, because it already covers every workspace the credential can reach. A request is charged to the workspace whose data it read, so a connection covering several workspaces has a separate balance and a separate log for each. Omit the parameter for the connection's default workspace, which is the only one for an API key.

Workspaces do not share a billing cycle, so the balances /credits/workspaces returns each carry their own cycle_start and cycle_end. Adding their used figures together blends different date ranges into a number that describes no real cycle.

See API credits.

Uptime

Scope: read:uptime. There is no write:uptime; uptime configuration is dashboard-only.

MethodPathDescription
GET/domains/{domain_id}/uptime/statusCurrent uptime status. Never cached, so this is the right call for "is the site up right now"
GET/domains/{domain_id}/uptime/availabilityUptime availability percentage
GET/domains/{domain_id}/uptime/timelineUptime check timeline, bucketed
GET/domains/{domain_id}/uptime/incidentsDowntime incidents
GET/domains/{domain_id}/uptime/response-timesDNS, connect, TLS, and total response-time breakdown
GET/domains/{domain_id}/uptime/slow-checksSlow but successful checks
GET/domains/{domain_id}/uptime/stats-extraResponse-time percentiles, MTTR, and slow-check count
GET/domains/{domain_id}/uptime/configGet uptime monitoring configuration

SSL

Scope: read:ssl.

MethodPathDescription
GET/domains/{domain_id}/ssl/summarySSL status summary
GET/domains/{domain_id}/ssl/latestLatest SSL certificate
GET/domains/{domain_id}/sslSSL certificate chain detail
GET/domains/{domain_id}/ssl/historySSL certificate history
GET/domains/{domain_id}/ssl/eventsSSL certificate change events
GET/domains/{domain_id}/ssl/domain-expirationDomain registration expiration

CrUX

Scopes: read:crux, write:crux.

MethodPathScopeDescription
GET/domains/{domain_id}/crux/overviewread:cruxLatest CrUX overview
GET/domains/{domain_id}/crux/timelineread:cruxCrUX metrics timeline
GET/domains/{domain_id}/crux/compareread:cruxCompare metrics between two periods
GET/domains/{domain_id}/crux/trends/{metric_name}read:cruxTrend for one metric
GET/domains/{domain_id}/crux/histogram/{metric_name}read:cruxDistribution histogram for one metric
GET/domains/{domain_id}/crux/urlsread:cruxList monitored URLs
GET/domains/{domain_id}/crux/urls/{url_id}read:cruxGet a monitored URL
POST/domains/{domain_id}/crux/urls/bulkwrite:cruxAdd multiple URLs. 25 credits
POST/domains/{domain_id}/crux/urls/bulk-deletewrite:cruxRemove multiple URLs
DELETE/domains/{domain_id}/crux/urls/{url_id}write:cruxRemove a URL

There is no way to trigger a CrUX refresh through the API. Collection draws from a shared platform-wide key pool, so a scripted refresh loop would degrade collection for every other customer.

Synthetic Monitoring

Scopes: read:synthetic, write:synthetic. There is no run:synthetic: a scripted "run it now" against the schedule is an unbounded test bill for data that was coming anyway.

MethodPathScopeDescription
GET/domains/{domain_id}/synthetic/overviewread:syntheticOverview
GET/domains/{domain_id}/synthetic/timelineread:syntheticTest timeline
GET/domains/{domain_id}/synthetic/trendsread:syntheticMetric trends over time
GET/domains/{domain_id}/synthetic/compareread:syntheticCompare performance between two periods
GET/domains/{domain_id}/synthetic/tests/{test_id}read:syntheticFull results for one test
GET/domains/{domain_id}/synthetic/opportunitiesread:syntheticRecurring Lighthouse opportunities, aggregated across recent runs
GET/domains/{domain_id}/synthetic/urlsread:syntheticList monitored URLs
GET/domains/{domain_id}/synthetic/urls/{url_id}read:syntheticGet a monitored URL
GET/domains/{domain_id}/synthetic/urls/{url_id}/locationsread:syntheticConfigured locations for a URL
GET/domains/{domain_id}/synthetic/locationsread:syntheticAvailable testing locations
GET/domains/{domain_id}/synthetic/locations-with-dataread:syntheticLocations with collected data
GET/domains/{domain_id}/synthetic/location-limitsread:syntheticLocation limits for this workspace
POST/domains/{domain_id}/synthetic/urls/bulkwrite:syntheticAdd multiple URLs. 25 credits
POST/domains/{domain_id}/synthetic/urls/bulk-deletewrite:syntheticRemove multiple URLs
POST/domains/{domain_id}/synthetic/urls/bulk-frequencywrite:syntheticUpdate frequency for multiple URLs
PUT/domains/{domain_id}/synthetic/urls/{url_id}/frequencywrite:syntheticUpdate the frequency for one URL
PUT/domains/{domain_id}/synthetic/urls/{url_id}/locationswrite:syntheticSet the locations for one URL
DELETE/domains/{domain_id}/synthetic/urls/{url_id}write:syntheticRemove a URL

RUM

Scope: read:rum. Read-only, and redacted more strictly than the dashboard.

MethodPathDescription
GET/domains/{domain_id}/rum/overviewRUM overview
GET/domains/{domain_id}/rum/has-dataWhether this domain has any RUM data at all
GET/workspaces/{workspace_id}/rum/has-dataWhether each domain in a workspace has any RUM data
GET/domains/{domain_id}/rum/vitalsCore Web Vitals, by device type
GET/domains/{domain_id}/rum/vitals/timelineCore Web Vitals over time
GET/domains/{domain_id}/rum/vitals/distribution-timelineGood, needs-improvement, and poor split over time
GET/domains/{domain_id}/rum/vitals/lcp/subpartsLCP timing breakdown
GET/domains/{domain_id}/rum/vitals/lcp/subparts/timelineLCP timing breakdown, daily
GET/domains/{domain_id}/rum/vitals/lcp/element-typesLCP breakdown by element type
GET/domains/{domain_id}/rum/vitals/lcp/element-types/timelineLCP element types, daily
GET/domains/{domain_id}/rum/vitals/lcp/resourcesTop LCP resources
GET/domains/{domain_id}/rum/vitals/inp/subparts/timelineINP timing breakdown, daily
GET/domains/{domain_id}/rum/vitals/inp/script-domainsTop INP script sources
GET/domains/{domain_id}/rum/vitals/ttfb/subparts/timelineTTFB timing breakdown, daily
GET/domains/{domain_id}/rum/pagesPage performance breakdown
GET/domains/{domain_id}/rum/pageviewsAggregated page views
GET/domains/{domain_id}/rum/eventsIndividual RUM events
GET/domains/{domain_id}/rum/errorsError counts by type
GET/domains/{domain_id}/rum/errors/groupsDistinct error kinds
GET/domains/{domain_id}/rum/errors/detailsDetailed error records with stack traces
GET/domains/{domain_id}/rum/engagementUser engagement metrics
GET/domains/{domain_id}/rum/engagement/correlationPerformance versus engagement correlation histogram
GET/domains/{domain_id}/rum/geographicGeographic distribution of RUM metrics

/workspaces/{workspace_id}/rum/has-data is the one workspace-scoped route in this group, so it takes a workspace_id rather than a domain_id. It reports every domain in the workspace in one call, which is how to find out which of your sites are reporting RUM at all without asking domain by domain.

Web Analytics

Scopes: read:analytics, write:analytics, run:analytics.

MethodPathScopeDescription
GET/domains/{domain_id}/analytics/overviewread:analyticsTraffic overview
GET/domains/{domain_id}/analytics/timelineread:analyticsVisitors and pageviews timeline
GET/domains/{domain_id}/analytics/realtimeread:analyticsLive activity
GET/domains/{domain_id}/analytics/pagesread:analyticsTop, entry, or exit pages
GET/domains/{domain_id}/analytics/sourcesread:analyticsTraffic source breakdown
GET/domains/{domain_id}/analytics/devicesread:analyticsDevice, browser, and OS breakdown
GET/domains/{domain_id}/analytics/geographicread:analyticsGeographic breakdown
GET/domains/{domain_id}/analytics/eventsread:analyticsCustom events
GET/domains/{domain_id}/analytics/searchread:analyticsSite search queries
GET/domains/{domain_id}/analytics/outboundread:analyticsOutbound link clicks
GET/domains/{domain_id}/analytics/downloadsread:analyticsFile download clicks
GET/domains/{domain_id}/analytics/ecommerce/overviewread:analyticsEcommerce overview
GET/domains/{domain_id}/analytics/ecommerce/productsread:analyticsEcommerce products. 25 credits, never discounted
GET/domains/{domain_id}/analytics/configread:analyticsGet analytics configuration
PUT/domains/{domain_id}/analytics/configwrite:analyticsUpdate analytics configuration
GET/domains/{domain_id}/analytics/funnelsread:analyticsList funnels
GET/domains/{domain_id}/analytics/funnels/{funnel_id}read:analyticsGet a funnel
POST/domains/{domain_id}/analytics/funnelswrite:analyticsCreate a funnel
PUT/domains/{domain_id}/analytics/funnels/{funnel_id}write:analyticsUpdate a funnel
DELETE/domains/{domain_id}/analytics/funnels/{funnel_id}write:analyticsDelete a funnel
GET/domains/{domain_id}/analytics/experimentsread:analyticsList experiments
GET/domains/{domain_id}/analytics/experiments/{experiment_id}read:analyticsGet an experiment
GET/domains/{domain_id}/analytics/experiments/{experiment_id}/evaluationsread:analyticsList evaluations
GET/domains/{domain_id}/analytics/experiments/{experiment_id}/evaluations/latestread:analyticsLatest evaluation
POST/domains/{domain_id}/analytics/experimentswrite:analyticsCreate an experiment
PUT/domains/{domain_id}/analytics/experiments/{experiment_id}write:analyticsUpdate an experiment
DELETE/domains/{domain_id}/analytics/experiments/{experiment_id}write:analyticsDelete an experiment
POST/domains/{domain_id}/analytics/experiments/{experiment_id}/evaluaterun:analyticsEvaluate an experiment. 25 credits, needs Idempotency-Key
GET/domains/{domain_id}/analytics/reports/_registeredread:analyticsList registered report keys
GET/domains/{domain_id}/analytics/reports/_summaryread:analyticsLatest run per registered report
GET/domains/{domain_id}/analytics/reports/{key}/latestread:analyticsLatest completed run for a report
GET/domains/{domain_id}/analytics/reports/runs/{run_id}read:analyticsGet a report run
GET/domains/{domain_id}/analytics/reports/runs/{run_id}/rowsread:analyticsPaginated slice of a run's rows
POST/domains/{domain_id}/analytics/reports/{report_key}/runrun:analyticsRun an on-demand report. 25 credits, needs Idempotency-Key

Google Search Console

Scopes: read:gsc, write:gsc, run:gsc.

MethodPathScopeDescription
GET/domains/{domain_id}/gsc/overviewread:gscOverview statistics
GET/domains/{domain_id}/gsc/performanceread:gscPerformance time series. 25 credits, never discounted
GET/domains/{domain_id}/gsc/queriesread:gscQuery-level performance
GET/domains/{domain_id}/gsc/pagesread:gscPage-level performance
GET/domains/{domain_id}/gsc/countriesread:gscPerformance by country
GET/domains/{domain_id}/gsc/devicesread:gscPerformance by device
GET/domains/{domain_id}/gsc/search-appearanceread:gscPerformance by search appearance type
GET/domains/{domain_id}/gsc/ctr-benchmarkread:gscActual versus expected CTR across this domain's own position distribution
GET/domains/{domain_id}/gsc/new-rankingsread:gscQueries or pages new to this domain's rankings
GET/domains/{domain_id}/gsc/known-eventsread:gscKnown events annotated on this domain's traffic
GET/domains/{domain_id}/gsc/brand-patternsread:gscBrand-query patterns
GET/domains/{domain_id}/gsc/url-patternsread:gscURL-template pattern overrides
GET/domains/{domain_id}/gsc/locale-configread:gscLocale-detection configuration
GET/domains/{domain_id}/gsc/experimentsread:gscList experiments
GET/domains/{domain_id}/gsc/experiments/{experiment_id}/evaluations/latestread:gscLatest evaluation
POST/domains/{domain_id}/gsc/experimentswrite:gscCreate an A/B experiment
PUT/domains/{domain_id}/gsc/experiments/{experiment_id}write:gscUpdate an experiment
DELETE/domains/{domain_id}/gsc/experiments/{experiment_id}write:gscDelete an experiment
POST/domains/{domain_id}/gsc/experiments/{experiment_id}/evaluaterun:gscEvaluate an experiment. 25 credits, needs Idempotency-Key
GET/domains/{domain_id}/gsc/reports/_registeredread:gscReports available to run
GET/domains/{domain_id}/gsc/reports/_summaryread:gscReports hub summary
GET/domains/{domain_id}/gsc/reports/{report_key}/latestread:gscLatest completed run for a report
GET/domains/{domain_id}/gsc/reports/runs/{run_id}read:gscGet a report run
GET/domains/{domain_id}/gsc/reports/runs/{run_id}/rowsread:gscPaginated slice of a run's rows
POST/domains/{domain_id}/gsc/reports/{report_key}/runrun:gscRun a report. 25 credits, needs Idempotency-Key

Search Console data hangs off the domain its property is linked to. Connecting or disconnecting a Google account is a dashboard-only operation.

Indexing Monitoring

Scopes: read:indexing, write:indexing.

MethodPathScopeDescription
GET/domains/{domain_id}/indexing/timelineread:indexingCoverage-state timeline
GET/domains/{domain_id}/indexing/issue-summaryread:indexingAggregate issue counts
GET/domains/{domain_id}/indexing/inspectionsread:indexingURL Inspection results
GET/domains/{domain_id}/indexing/url-historyread:indexingEvery past inspection for one URL
GET/domains/{domain_id}/indexing/state-changesread:indexingRecent per-URL coverage-state transitions
GET/domains/{domain_id}/indexing/sitemapsread:indexingSearch Console sitemap coverage stats
GET/domains/{domain_id}/indexing/diagnosticsread:indexingCollection diagnostics
GET/domains/{domain_id}/indexing/groupsread:indexingList URL groups
GET/domains/{domain_id}/indexing/priority-urlsread:indexingList priority-queue URLs
GET/domains/{domain_id}/indexing/propertiesread:indexingList enrolled Search Console properties
POST/domains/{domain_id}/indexing/groupswrite:indexingCreate a URL group
PATCH/domains/{domain_id}/indexing/groups/{group_id}write:indexingUpdate a URL group
DELETE/domains/{domain_id}/indexing/groups/{group_id}write:indexingDelete a URL group
POST/domains/{domain_id}/indexing/priority-urlswrite:indexingAdd a URL to the priority inspection queue
DELETE/domains/{domain_id}/indexing/priority-urls/{priority_url_id}write:indexingRemove a URL from the priority queue
POST/domains/{domain_id}/indexing/properties/{property_id}write:indexingEnroll a property. 25 credits
DELETE/domains/{domain_id}/indexing/properties/{property_id}write:indexingRemove a property

Robots.txt Monitoring

Scopes: read:robots, write:robots. There is no run:robots; robots.txt is fetched on a schedule.

MethodPathScopeDescription
GET/domains/{domain_id}/robots/latestread:robotsLatest fetched robots.txt
GET/domains/{domain_id}/robots/healthread:robotsFetch health
GET/domains/{domain_id}/robots/timelineread:robotsFetched versions
GET/domains/{domain_id}/robots/changesread:robotsList changes
GET/domains/{domain_id}/robots/diff-impactsread:robotsPer-change before and after impact
GET/domains/{domain_id}/robots/crawler-accessread:robotsPer-crawler allow and disallow matrix
GET/domains/{domain_id}/robots/ai-botsread:robotsAI-bot governance view
GET/domains/{domain_id}/robots/test-urlread:robotsTest whether a URL is allowed for one crawler
POST/domains/{domain_id}/robots/test-urls/queryread:robotsTest a batch of URLs. Read-only POST
POST/domains/{domain_id}/robots/simulate/queryread:robotsSimulate a candidate robots.txt. Read-only POST
GET/domains/{domain_id}/robots/overlapping-rulesread:robotsOverlapping rules in the stored file
POST/domains/{domain_id}/robots/overlapping-rules/queryread:robotsOverlapping rules in a candidate file. Read-only POST
GET/domains/{domain_id}/robots/sitemap-conflictsread:robotsSitemap URLs blocked by robots.txt
GET/domains/{domain_id}/robots/sitemap-conflicts/summaryread:robotsConflict summary
GET/domains/{domain_id}/robots/top-blockedread:robotsHigh-traffic URLs blocked by robots.txt
GET/domains/{domain_id}/robots/validation/historyread:robotsValidation results
GET/domains/{domain_id}/robots/annotationsread:robotsList change annotations
POST/domains/{domain_id}/robots/annotationswrite:robotsAdd a note to a change
PATCH/domains/{domain_id}/robots/annotations/{annotation_id}write:robotsUpdate an annotation
DELETE/domains/{domain_id}/robots/annotations/{annotation_id}write:robotsDelete an annotation
POST/domains/{domain_id}/robots/sitemap-conflicts/recomputewrite:robotsRecompute the sitemap conflict check. Needs Idempotency-Key. Priced as an ordinary write

write:robots edits VitalSentinel's own annotations on a change, and triggers the sitemap-conflict recompute. It does not, and cannot, edit the robots.txt file on your site.

The recompute re-diffs the sitemap URLs VitalSentinel has already stored against the current robots.txt. It returns straight away and does the work in the background, so poll /robots/sitemap-conflicts/summary for the result. It does not fetch a fresh sitemap, so it clears the staleness caused by the check lagging behind a stored sitemap, but not the staleness caused by the sitemap scan itself being old. Only a new scan clears that, and starting one is a dashboard-only action.

Sitemap

Scope: read:sitemap. Read-only.

MethodPathDescription
GET/domains/{domain_id}/sitemap/statsScan statistics
GET/domains/{domain_id}/sitemap/urlsExport every discovered sitemap URL
GET/domains/{domain_id}/sitemap/configScan configuration
GET/domains/{domain_id}/sitemap/rate-limitWhether a scan can be started

To find sitemap URLs blocked by robots.txt, either read the stored result at /robots/sitemap-conflicts, refreshing it first with POST /robots/sitemap-conflicts/recompute if it is stale, or export the full URL list here plus the latest robots.txt and compute the intersection yourself.

Alerts

Scopes: read:alerts, write:alerts. Members can create and edit alert rules, because a rule belongs to whoever created it.

MethodPathScopeDescription
GET/alerts/metricsread:alertsAvailable alert metrics. Costs 0 credits
GET/alerts/rulesread:alertsAccount-wide: rules on every accessible domain. Optional workspace_id, module, and enabled filters. Costs 0 credits
GET/alerts/historyread:alertsAccount-wide: fired alerts on every accessible domain, newest first. Optional workspace_id and domain_id filters. Costs 0 credits
GET/domains/{domain_id}/alerts/rulesread:alertsPer domain: rules on this one domain
GET/domains/{domain_id}/alerts/rules/{rule_id}read:alertsGet a rule
GET/domains/{domain_id}/alerts/historyread:alertsPer domain: fired alerts on this one domain
POST/domains/{domain_id}/alerts/ruleswrite:alertsCreate a rule
PUT/domains/{domain_id}/alerts/rules/{rule_id}write:alertsUpdate a rule
DELETE/domains/{domain_id}/alerts/rules/{rule_id}write:alertsDelete a rule

The account-wide /alerts/rules and /alerts/history answer "what do I have set up" and "what has fired lately" across every workspace the credential can reach, without looping over /domains first. Every row names its own domain and workspace, so nothing has to be correlated against a second call. Both cost 0 credits, because a call that reads every accessible workspace has no single workspace to charge. Narrowing one with workspace_id or domain_id does not change that, since those are query filters rather than part of the path.

Read /alerts/metrics before building a rule. It is free and it is what tells you which metric and comparison combinations are valid.

There is no endpoint to test-fire a rule. The dashboard does not expose one either.

Notifications

Scopes: read:notifications, write:notifications. Scoped to the calling user, not to the workspace. Members keep write access here, because these are personal preferences.

Because they are user-scoped rather than workspace-scoped, every route in this group costs 0 credits. The one exception is GET /notifications/{notification_id}/trend, which recomputes a series from live data and costs 1.

MethodPathScopeDescription
GET/notificationsread:notificationsList notifications
GET/notifications/unread-countread:notificationsUnread count
GET/notifications/statsread:notificationsNotification statistics
GET/notifications/{notification_id}/trendread:notificationsLive trend behind a fired alert
GET/notifications/preferencesread:notificationsGet preferences
GET/notifications/domain-subscriptionsread:notificationsPer-domain email subscriptions
POST/notifications/readwrite:notificationsMark notifications as read
POST/notifications/{notification_id}/readwrite:notificationsMark one as read
POST/notifications/{notification_id}/unreadwrite:notificationsMark one as unread
DELETE/notifications/{notification_id}write:notificationsDelete a notification
PUT/notifications/preferenceswrite:notificationsUpdate preferences
PUT/notifications/domain-subscriptionswrite:notificationsUpdate a per-domain subscription

Fired alerts arrive as notifications carrying the alert rule and alert history identifiers, so this is where you watch for an alert firing.

Reports

Scopes: read:reports, write:reports, run:reports.

MethodPathScopeDescription
GET/domains/reports/sections-catalogread:reportsAvailable sections and widgets. Costs 0 credits
GET/domains/reports/default-configread:reportsDefault sections_config for a new template. Costs 0 credits
GET/domains/{domain_id}/reports/templatesread:reportsList templates
GET/domains/{domain_id}/reports/templates/{template_id}read:reportsGet a template
POST/domains/{domain_id}/reports/data/{template_id}read:reportsCollect report data as JSON. Read-only POST
POST/domains/{domain_id}/reports/templateswrite:reportsCreate a template
PUT/domains/{domain_id}/reports/templates/{template_id}write:reportsUpdate a template
POST/domains/{domain_id}/reports/templates/{template_id}/duplicatewrite:reportsDuplicate a template
DELETE/domains/{domain_id}/reports/templates/{template_id}write:reportsDelete a template
POST/domains/{domain_id}/reports/{template_id}/generaterun:reportsGenerate a PDF. 25 credits, needs Idempotency-Key
GET/domains/{domain_id}/reports/jobs/{job_id}run:reportsCheck a PDF job. Priced as a read
GET/domains/{domain_id}/reports/jobs/{job_id}/downloadrun:reportsDownload a completed PDF. Priced as a read

PDF generation is asynchronous. POST .../generate returns a job identifier; poll /reports/jobs/{job_id} until it completes, then download. Polling is priced as an ordinary read, so watching a report never costs more than starting one.

If you want the numbers rather than a PDF, use POST /reports/data/{template_id}. It returns the same content as JSON, needs only read:reports, and costs a read rather than 25 credits.

OAuth

The authorization server. See Authentication for the full flow.

MethodPathDescription
POST/oauth/registerRegister a client (RFC 7591)
GET/oauth/authorizeStart an authorization request
GET/oauth/authorize/requestResolve an authorization request handle
POST/oauth/authorize/consentRecord a consent decision
POST/oauth/tokenExchange an authorization code or refresh token
POST/oauth/revokeRevoke a token (RFC 7009)

Two discovery documents sit at the site root rather than under the API prefix:

GET https://app.vitalsentinel.com/.well-known/oauth-authorization-server
GET https://app.vitalsentinel.com/.well-known/oauth-protected-resource

On this page

VitalSentinel

Catch issues before they cost you

Track SEO, performance, and uptime in one place and get alerted the moment something breaks – hours before it hits your traffic.

  • Free plan for 1 domain
  • Set up in minutes
  • No credit card required