{"id":22391548,"url":"https://github.com/openstatushq/vercel-edge-ping","last_synced_at":"2025-07-31T09:31:19.260Z","repository":{"id":264151752,"uuid":"892515927","full_name":"openstatusHQ/vercel-edge-ping","owner":"openstatusHQ","description":"Lightweight uptime notification system build on top of Vercel's edge network.","archived":false,"fork":false,"pushed_at":"2024-11-29T09:52:55.000Z","size":53,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-11-29T10:44:27.107Z","etag":null,"topics":["edge","monitoring","ping","uptime","vercel"],"latest_commit_sha":null,"homepage":"https://light.openstatus.dev","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/openstatusHQ.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-22T09:04:21.000Z","updated_at":"2024-11-29T09:52:59.000Z","dependencies_parsed_at":"2024-11-29T10:38:58.129Z","dependency_job_id":null,"html_url":"https://github.com/openstatusHQ/vercel-edge-ping","commit_stats":null,"previous_names":["openstatushq/vercel-edge-ping"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openstatusHQ%2Fvercel-edge-ping","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openstatusHQ%2Fvercel-edge-ping/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openstatusHQ%2Fvercel-edge-ping/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openstatusHQ%2Fvercel-edge-ping/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/openstatusHQ","download_url":"https://codeload.github.com/openstatusHQ/vercel-edge-ping/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228230862,"owners_count":17888707,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["edge","monitoring","ping","uptime","vercel"],"created_at":"2024-12-05T04:10:22.975Z","updated_at":"2025-07-31T09:31:19.243Z","avatar_url":"https://github.com/openstatusHQ.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OpenStatus | Vercel Edge Ping\n\nNo library. No UI. No maintenance.\n\nWe want to provide you a lightweight version of [OpenStatus](https://openstatus.dev) to monitor your services.\n\nTherefore, we will be using Vercel's edge runtime to monitor your services across 18 regions as simple as possible. Read more about [vercel edge network regions](https://vercel.com/docs/edge-network/regions).\n\nChoose your [configuration](#configuration) and be ready in 5min to monitor your website or API services.\n\nYou can even one-click self-host the service by adding the stringified array to the `REQUESTS` environment variables. (see [here](#environment-variables))\n\n[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FopenstatusHQ%2Fvercel-edge-ping\u0026env=CRON_SECRET,PING_SECRET)\n\nCurrently supported [notification channels](#notification-channels) are:\n\n- Slack\n- Discord\n- Campsite\n- Telegram\n\nWe also provide a 6 min. [YouTube](https://www.youtube.com/watch?v=cpurWC9Co1U) video for more visual content. If you have any trouble, feel free to open an issue, join our [Discord](https://openstatus.dev/discord) or message us to [ping@openstatus.dev](mailto:ping@openstatus.dev)\n\nIf storing the data to [Tinybird](https://www.tinybird.co), you can use the [OpenStatus Light Viewer](https://data-table.openstatus.dev/light) to filter and learn from your pings.\n\n## Getting Started\n\nTo work/test it locally:\n\n```bash\npnpm install\npnpm start\n```\n\n### Vercel CLI\n\nMake sure to have the [Vercel CLI](https://vercel.com/docs/cli) running on your machine. When you first start the project, you will get asked to connect it to your vercel account.\n\nCheckout `.env.example` for the (required) environment variables. Use the Vercel CLI and the [`add env`](https://vercel.com/docs/cli/env) command:\n\n```bash\nvercel env add\n```\n\n### Tinybird CLI (optional)\n\nIf you want to ingest the data and keep track of the response times, add the `TINYBIRD_TOKEN` to your environment variables.\n\nInclude the [Tinybird CLI](https://www.tinybird.co/docs/cli) as well to easily set the pipe and datasource to ingest and get the data:\n\n```bash\npython3 -m venv .venv\nsource .venv/bin/activate\npip install tinybird-cli\ntb auth -i\n```\n\nAdd `--dry-run` to the commands if you want to first test them:\n\n```bash\ntb push tb/datasources/http_ping_responses.datasource\ntb push tb/pipes/endpoint__get_http.pipe\ntb push tb/pipes/endpoint__get_http_stats.pipe\ntb push tb/pipes/endpoint__get_http_facets.pipe\n```\n\n#### API endpoint\n\nIf you've connected your database to Tinybird, we provide you a some simple `GET` endpoint to query your pings.\n\nThe `/api/get` endpoint (`endpoint__get_http.pipe`) accepts the following query parameters:\n\n| **Parameter**    | **Type** | **Description**                                       |\n| ---------------- | -------- | ----------------------------------------------------- |\n| `pageIndex`      | `number` | The page number for pagination (starts at 0)          |\n| `pageSize`       | `number` | Number of results per page (defaults to 100)          |\n| `orderBy`        | `string` | Column to sort by (defaults to 'timestamp')           |\n| `orderDir`       | `string` | Sort direction - 'ASC' or 'DESC' (defaults to 'DESC') |\n| `latencyStart`   | `number` | Filter results with latency \u003e= this value (ms)        |\n| `latencyEnd`     | `number` | Filter results with latency \u003c= this value (ms)        |\n| `statuses`       | `string` | Filter by HTTP status codes (comma-separated list)    |\n| `regions`        | `string` | Filter by edge regions (comma-separated list)         |\n| `methods`        | `string` | Filter by HTTP methods (comma-separated list)         |\n| `url`            | `string` | Filter URLs containing this string                    |\n| `timestampStart` | `number` | Unix timestamp in ms (defaults to 30 days prior)      |\n| `timestampEnd`   | `number` | Unix timestamp in ms (defaults to now)                |\n\nMoreover, to make best use of the [OpenStatus Light Viewer](https://data-table.openstatus.dev/light), we support two more API endpoints. They both extend the above query params.\n\n- `/api/stats` endpoint (`endpoint__get_http_stats.pipe`) for the chart values (incl. `interval` param)\n\n| **Parameter** | **Type** | **Description**                                                                     |\n| ------------- | -------- | ----------------------------------------------------------------------------------- |\n| `interval`    | `number` | Interval of grouped data in minutes (defaults to 1_440 minutes equivalent to 1 day) |\n\n- `/api/facets` endpoint (`endpoint__get_http_facets.pipe`) for the table facets (no additional param)\n\nAll endpoints are just a layer to access the tinybird pipe responses. They share the following response object example:\n\n```json\n{\n  \"meta\": [],\n  \"data\": [],\n  \"rows\": 20,\n  \"rows_before_limit_at_least\": 100,\n  \"statistics\": {\n    \"elapsed\": 0.004015279,\n    \"rows_read\": 2845,\n    \"bytes_read\": 725311\n  }\n}\n```\n\n\u003e [!NOTE]\n\u003e The `/api/get`, `/api/stats`, `/api/facets` endpoints will be accessible by anyone if you are not securing it yourself.\n\n## Configuration\n\n### Monitors\n\nA `PingRequest` includes the below props:\n\n| **Property** | **Type**                 | **Description**                                                         |\n| ------------ | ------------------------ | ----------------------------------------------------------------------- |\n| `url`        | `string`                 | The URL to send the ping request to.                                    |\n| `method`     | `string`                 | The HTTP method to use for the request (e.g., GET, POST).               |\n| `body?`      | `string`                 | Optional request body.                                                  |\n| `headers?`   | `Record\u003cstring, string\u003e` | Optional headers to include in the request.                             |\n| `timeout?`   | `number`                 | Optional timeout in milliseconds for the request. Defaults to 50_000ms. |\n| `prewarm?`   | `boolean`                | Optional flag to prewarm the endpoint before timing the next request.   |\n\nThere are multiple ways to add your monitors:\n\n- via `./api/resources.json` file _but that would require a fork + changes_\n- via a fetch call using the `REQUEST_GET_URL` returning a type of `PingRequest[]` _but that would require you to maintain that connection_\n- via `.env` where we stringify the `PingRequest[]` array and read it out\n\nAll three options can work parallely.\n\nWe _roughly_ validate the external input. If they don't match the expected type, you'll see a `console.error` in your logs.\n\n#### Environment variables\n\nThe **fastest way to get started** without having to commit any code changes is to add the stringified list to your `REQUESTS` environment variables.\n\nFor example:\n\n```\n[{\"url\":\"https://openstat.us/200\",\"method\":\"GET\", \"prewarm\":true}]\n```\n\n\u003e [!NOTE]\n\u003e Whenever you change the environment variable, you'll need to rebuild/redeploy the app to included the latest changes.\n\n#### File reading\n\nAdd your endpoints statically to the list `./api/resources.json` file.\n\nFor example:\n\n```json\n[{ \"url\": \"https://openstat.us/200\", \"method\": \"GET\", \"prewarm\": true }]\n```\n\n#### Fetching resources\n\nCreate an endpoint that returns the list. Use the `EXTERNAL_REQUESTS_URL` to fetch the list dynamically on every ping.\n\nTo secure your endpoint, we provide the `EXTERNAL_REQUESTS_SECRET` environment variable that gets passed as property to the header `Authorization: Bearer EXTERNAL_REQUESTS_SECRET`.\n\n### vercel.json\n\nWe have made some configurations within `vercel.json`. Let's break them down.\n\nThe [maximum duration](https://vercel.com/docs/functions/configuring-functions/duration) of the serverless functions are set to the max of the _free plan_:\n\n```\n  \"functions\": {\n    \"api/cron.ts\": {\n      \"maxDuration\": 60\n    }\n  }\n```\n\nThe [cron jobs](https://vercel.com/docs/cron-jobs) are set to the maximum of the _free plan_ which is daily:\n\n```\n  \"crons\": [\n    {\n      \"path\": \"/api/cron\",\n      \"schedule\": \"0 0 * * *\"\n    }\n  ]\n```\n\nIf you are on a _pro plan_, update it to the cron expression you'd like to use.\n\nThe cron endpoint is automatically secured by including the [`CRON_SECRET`](https://vercel.com/docs/cron-jobs/manage-cron-jobs#securing-cron-jobs) environment variable.\n\n### GitHub Workflows (optional)\n\nOptionally, if you want to keep the vercel _free plan_ and increase the periodicity of the cron job, you can work it out by using github actions.\n\nGo to your _GitHub repository → Settings → Secrets and variables → Actions → New repository secret_ and add:\n\n- `CRON_SECRET` - the same one as in vercel envs\n- `BASE_URL` - the production URL from vercel\n\nYou can either trigger it manually via `workflow_dispatch` or uncomment and update the `schedule.cron` to the cron expression you'd like to periodically run the attached curl.\n\n## Notification Channels\n\nIf set, we will send a message if \u003e50% of the regions of a specific endpoint are failing. An endpoint fails, if the response status code **doesn't start with `2` or `3`**.\n\nNotifications to the different services will be send only if the environment variables are set.\n\n### Slack Webhook (optional)\n\nIf you want to get notified whenever an endpoint is not healthy, add the `SLACK_WEBHOOK_URL` to your environment variables.\n\nTo create a webhook for a specific channel you'd like to post the messages to, [follow the guide](https://api.slack.com/messaging/webhooks).\n\n### Discord Webhook (optional)\n\nIf you want to get notified whenever an endpoint is not healthy, add the `DISCORD_WEBHOOK_URL` to your environment variables.\n\nTo create a webhook for a specific channel you'd like to post the messages to, [follow the guide](https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks).\n\n### Campsite Post (optional)\n\nIf you want to get notified whenever an endpoint is not healthy, add the `CAMPSITE_API_KEY` and `CAMPSITE_CHANNEL_ID` to your environment variables.\n\nTo create an API key, [follow the docs](https://developers.campsite.com/api-reference/introduction). You will need to connect your integration to a channel and copy the channel id as well.\n\n### Telegram Bot (optional)\n\nIf you want to get notified whenever an endpoint is not healthy, add the `TELEGRAM_BOT_TOKEN` and `TELEGRAM_CHAT_ID` to your environment variables.\n\nTo create a telegram bot, [follow the gist](https://gist.github.com/nafiesl/4ad622f344cd1dc3bb1ecbe468ff9f8a#how-to-get-telegram-bot-chat-id).\n\n## Deployment\n\nCheck the Vercel CLI docs regarding [`deploy`](https://vercel.com/docs/cli/deploy) commands if you want to learn more. Otherwise:\n\n```bash\n# deploy to preview\nvercel\n# deploy to production\nvercel --prod\n```\n\n## More\n\n\u003e [!NOTE]  \n\u003e If you host your services on Vercel and want to make sure the provider is up, this is a bad idea as the edge ping depends on Vercel itself. Instead, it is good to keep uptime of your own services like hosted APIs, getting latency over time, or be informed whenever your services are not responding as expected.\n\nIf you are on a pro plan on vercel, you are allowed for _Unlimited cron invocations_ instead of _Triggered once a day_. Fork and change the `vercel.json` content to whatevery cron you'd like to. Use [crontab.guru](https://crontab.guru) to quickly edit and validate the cron expression.\n\nTest the notifications with [openstat.us](https://openstat.us) where you can define the returned status code with ease.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenstatushq%2Fvercel-edge-ping","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenstatushq%2Fvercel-edge-ping","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenstatushq%2Fvercel-edge-ping/lists"}