Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/uptimemonitoring-com:uptimemonitoring-com-email-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: UptimeMonitoring.com Email API
version: 0.1.0
description: 'API-first uptime monitoring for developers, deploy pipelines, and AI agents.
## Authentication
All `/api/v1` endpoints require a Bearer token — either an API key (`umk_live_*`)
or a session token obtained via GitHub OAuth. The `/mcp` endpoint additionally
accepts OAuth 2.1 JWT access tokens (`eyJ...`) issued via the self-hosted
authorization server documented under the `OAuth` tag.
```
Authorization: Bearer umk_live_abc123...
```
## Rate limits
200 requests/minute per account. Exceeding the limit returns `429` with a
`Retry-After` header.
Responses that pass through the per-account rate-limiter carry the
`X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset`
headers (decimal integers; `Reset` is a Unix epoch second at which
the bucket would be full again). In practice this is every
authenticated response under `/api/v1/*` whose request reached the
handler — earlier failures from the auth middleware (e.g. 401 missing
credentials, 403 suspended account) return before the limiter runs
and do NOT carry the trio. Routes mounted outside `/api/v1`
(notably `GET /api/v1/events/stream`, which has its own SSE
middleware stack) are not subject to this limiter and likewise do
not emit these headers. Successful responses on
`POST /api/v1/monitors` reflect the **global** 200/min bucket; the
per-route 20/min creation limit only surfaces its own headers when
it 429s. The trio is documented once here rather than referenced
into every individual response — see `components.headers` for the
schemas.
One exception: once a request presenting an API key enters an
authenticated route group through a registered route or mounted
subtree, while that key remains in the bounded pre-auth cache
(entries expire after 5 minutes, but may be evicted sooner once the
cache is at capacity), the global bucket is charged BEFORE
authentication and authorization run (issue #47) — so for that
cached key only, a `401` (key revoked while still cached), `403`,
`500`, or a `404` for an unmatched path inside a mounted subtree
also carries the `X-RateLimit-*` trio and spends one token. `429`
still comes first whenever the bucket is already empty. An uncached
key (first seen, expired, or evicted early at capacity), a session
token, an OAuth JWT, and any path outside every authenticated group
are all unaffected.
## Browser push notifications
Subscriptions registered via `POST /api/v1/push/subscribe` receive
fire-and-forget Web Push notifications on monitor state transitions
(down/up/flapping); per-monitor 5-minute throttle. No public API change
in this release — dispatch is internal to `internal/push.Dispatcher`.'
contact:
name: UptimeMonitoring.com
url: https://uptimemonitoring.com
license:
name: Proprietary
identifier: LicenseRef-Proprietary
servers:
- url: https://api.uptimemonitoring.com
description: Production
tags:
- name: Email
paths:
/email/confirm/{token}:
parameters:
- name: token
in: path
required: true
schema:
type: string
get:
operationId: confirmEmailRecipientPage
security: []
summary: Render the email-confirmation page (issue
description: 'Public, unauthenticated. Renders a plain HTML page with a form
that POSTs to this same URL. Never consumes the token — only
`POST` does, so a link scanner or mail-client prefetcher that
merely opens the link cannot burn the one-time confirmation.'
responses:
'200':
description: HTML page
content:
text/html: {}
'429':
description: Rate-limited (60/hour per caller IP)
content:
text/html: {}
tags:
- Email
post:
operationId: confirmEmailRecipient
security: []
summary: Confirm an email recipient (issue
description: 'Public, unauthenticated. Consumes the 64-hex confirmation token.
Unknown, expired, malformed, and already-consumed tokens all
render the identical response, so a caller cannot distinguish any
of those cases.'
responses:
'200':
description: Confirmed.
content:
text/html: {}
'404':
description: 'Unknown, expired, malformed, or already-consumed token.
Renders the identical not-found page in every case, so a
caller cannot distinguish them.
'
content:
text/html: {}
'429':
description: Rate-limited (60/hour per caller IP; confirm and unsubscribe are tracked separately).
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Store failure.
content:
text/html: {}
tags:
- Email
/email/unsubscribe/{token}:
parameters:
- name: token
in: path
required: true
schema:
type: string
get:
operationId: unsubscribeRecipientPage
security: []
summary: Render the unsubscribe page (issue
description: 'Public, unauthenticated. Renders a plain HTML page with a form
that POSTs to this same URL. Never consumes the token.'
responses:
'200':
description: HTML page
content:
text/html: {}
'429':
description: Rate-limited (60/hour per caller IP)
content:
text/html: {}
tags:
- Email
post:
operationId: unsubscribeRecipient
security: []
summary: Unsubscribe an email recipient (issue
description: 'Public, unauthenticated. Also the target of RFC 8058 one-click
unsubscribe (`List-Unsubscribe-Post: List-Unsubscribe=One-Click`),
which POSTs here with no human interaction — the token lives in
the path, so no request body is required. Idempotent: a second
POST still returns the success page. A well-formed token''s own
traffic never charges the rate limiter — RFC 8058 one-click
requests for many unrelated recipients commonly share one
mail-provider egress IP, and a genuinely valid unsubscribe is
never throttled by that shared traffic alone. But the lookup is
skipped, and this returns 429, if the caller''s IP or the
process-wide backstop is already exhausted by PRIOR invalid
requests — checked before the store call — so a well-formed,
genuinely valid token can still be temporarily rejected once that
budget is already spent. Only a confirmed-invalid token (or
malformed input, rejected up front) actually charges the limiter,
60/hour per caller IP plus a process-wide backstop across every
IP.'
responses:
'200':
description: Unsubscribed.
content:
text/html: {}
'404':
description: Unknown or malformed token. Renders the not-found page.
content:
text/html: {}
'429':
description: 'Rate-limited — reachable for an unknown/malformed token, OR
for a well-formed, genuinely valid token whose caller IP or
the process-wide backstop is already exhausted by prior
invalid attempts (checked before the store lookup). A valid
token''s own traffic never trips this, but it is not immune to
an already-spent budget. Confirm and unsubscribe are tracked
separately.
'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Store failure.
content:
text/html: {}
tags:
- Email
/email/reports/{type}/unsubscribe/{token}:
parameters:
- name: type
in: path
required: true
schema:
type: string
enum:
- weekly
- monthly
- name: token
in: path
required: true
schema:
type: string
get:
operationId: reportUnsubscribePage
security: []
summary: Render the report-unsubscribe page (issue
description: 'Public, unauthenticated. Renders a plain HTML page with a form
that POSTs to this same URL. Never consumes the token. An
invalid `type` segment renders the identical not-found page a
confirmed-invalid token would — the two are indistinguishable.'
responses:
'200':
description: HTML page
content:
text/html: {}
'404':
description: Invalid type segment.
content:
text/html: {}
'429':
description: Rate-limited (60/hour per caller IP; tracked separately from the recipient confirm/unsubscribe routes)
content:
text/html: {}
tags:
- Email
post:
operationId: reportUnsubscribe
security: []
summary: Unsubscribe from a weekly or monthly report (issue
description: 'Public, unauthenticated. Also the target of RFC 8058 one-click
unsubscribe. Idempotent: a second POST still returns the success
page. Flips only the named `type`''s report preference on the one
membership the token identifies — a weekly-report unsubscribe
never touches the monthly preference, and vice versa. An invalid
`type` or an unknown token both render the identical not-found
page.'
responses:
'200':
description: Unsubscribed.
content:
text/html: {}
'404':
description: Invalid type, or unknown/malformed token. Renders the not-found page.
content:
text/html: {}
'429':
description: 'Rate-limited — reachable for an invalid type, an
unknown/malformed token, OR a well-formed, genuinely valid
token/type pair whose caller IP or the process-wide backstop
is already exhausted by prior invalid attempts (checked
before the store lookup). A valid token/type pair''s own
traffic never trips this, but it is not immune to an
already-spent budget. Tracked separately from the recipient
confirm/unsubscribe routes.
'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Store failure.
content:
text/html: {}
tags:
- Email
components:
schemas:
Error:
type: object
required:
- error
properties:
error:
type: string
example:
error: something went wrong
securitySchemes:
bearerAuth:
type: http
scheme: bearer
description: 'API key (`umk_live_*`) or session token from OAuth exchange.
'