Monitive Announcements API

The Announcements API from Monitive — 2 operation(s) for announcements.

Operations 4

GET /api/v1/announcements List active system announcements #
POST /api/v1/announcements Create a system announcement (admin only) #
PUT /api/v1/announcements/{announcementID} Update a system announcement (admin only) #
DELETE /api/v1/announcements/{announcementID} Delete a system announcement (admin only) #

Work with this as data

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-announcements-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 Specification

uptimemonitoring-com-announcements-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: UptimeMonitoring.com Announcements 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: Announcements
paths:
  /api/v1/announcements:
    get:
      operationId: listAnnouncements
      summary: List active system announcements
      tags:
      - Announcements
      security:
      - bearerAuth: []
      responses:
        '200':
          description: Announcements
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AnnouncementListResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          $ref: '#/components/responses/AccountSuspended'
        '429':
          $ref: '#/components/responses/RateLimited'
    post:
      operationId: createAnnouncement
      summary: Create a system announcement (admin only)
      description: 'Admin-gated. Creates a new banner row.


        - `title` and `body` are required; both are TrimSpace''d and

        length-checked (1..200 / 1..2000 chars).

        - `published_at` is optional; when omitted the server defaults

        to `now()`.

        - `expires_at` is optional; when set must be strictly greater

        than the effective `published_at`.


        Decode is permissive — unknown top-level fields are silently

        ignored to match the rest of the API''s POST/PUT convention.

        `PATCH /api/v1/account` is the documented strict-decode

        exception, NOT the rule.'
      tags:
      - Announcements
      security:
      - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AnnouncementInput'
      responses:
        '201':
          description: Announcement created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Announcement'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '413':
          $ref: '#/components/responses/RequestEntityTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '429':
          $ref: '#/components/responses/RateLimited'
  /api/v1/announcements/{announcementID}:
    put:
      operationId: updateAnnouncement
      summary: Update a system announcement (admin only)
      description: 'Admin-gated. Body fields are all optional; only fields present

        in the request are mutated. An empty body `{}` returns 200

        with the row unchanged.


        `expires_at` carries three-state semantics:

        - **absent** → column is left unchanged.

        - **explicit `null`** → column is set to NULL (no expiry).

        - **concrete value** → column is set to the supplied

        timestamp; must be strictly greater than the effective

        `published_at` if both are supplied in the same request.


        `title` and `body`, when supplied, are TrimSpace''d and

        length-checked (1..200 / 1..2000 chars).


        Decode is permissive — unknown top-level fields are silently

        ignored to match the rest of the API''s POST/PUT convention.'
      tags:
      - Announcements
      security:
      - bearerAuth: []
      parameters:
      - $ref: '#/components/parameters/announcementID'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AnnouncementUpdate'
      responses:
        '200':
          description: Announcement updated (or unchanged on empty body).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Announcement'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: No announcement exists with the given ID.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '413':
          $ref: '#/components/responses/RequestEntityTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '429':
          $ref: '#/components/responses/RateLimited'
    delete:
      operationId: deleteAnnouncement
      summary: Delete a system announcement (admin only)
      description: 'Admin-gated. Hard-deletes the row. Returns 204 on success and

        404 when the id does not exist (a second DELETE against the

        same id therefore returns 404, mirroring the rest of the

        API).'
      tags:
      - Announcements
      security:
      - bearerAuth: []
      parameters:
      - $ref: '#/components/parameters/announcementID'
      responses:
        '204':
          description: Announcement deleted.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: No announcement exists with the given ID.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          $ref: '#/components/responses/RateLimited'
components:
  schemas:
    AnnouncementInput:
      type: object
      required:
      - title
      - body
      properties:
        title:
          type: string
          minLength: 1
          maxLength: 200
          description: 'Short banner title. Server TrimSpace''s leading and

            trailing whitespace before length-checking.

            '
        body:
          type: string
          minLength: 1
          maxLength: 2000
          description: 'Banner body / paragraph. Server TrimSpace''s leading

            and trailing whitespace before length-checking.

            '
        published_at:
          type: string
          format: date-time
          description: 'RFC 3339 timestamp at which the banner becomes active.

            When omitted the server defaults to `now()`.

            '
        expires_at:
          type:
          - string
          - 'null'
          format: date-time
          description: 'RFC 3339 timestamp after which the banner is hidden.

            When set, must be strictly greater than the effective

            `published_at`. Omit (or send `null`) for no expiry.

            '
    Error:
      type: object
      required:
      - error
      properties:
        error:
          type: string
      example:
        error: something went wrong
    Announcement:
      type: object
      properties:
        id:
          type: integer
        title:
          type: string
        body:
          type: string
        published_at:
          type: string
          format: date-time
        expires_at:
          type:
          - string
          - 'null'
          format: date-time
        updated_at:
          type: string
          format: date-time
          description: 'Last time this row was mutated. For rows created after

            migration 025 (2026-08-01), this is exact creation time if

            never edited. For rows that already existed when that

            migration ran, no creation timestamp had ever been recorded,

            so the backfilled starting value is

            `LEAST(published_at, migration time)` instead — not the row''s

            actual original creation time. Bumped by any PUT that changes

            at least one field; an empty-body no-op PUT does not bump it.

            Strictly monotonic per row — never ties or regresses across

            concurrent writes.

            '
    AnnouncementUpdate:
      type: object
      description: "All fields optional. Only fields present in the request body\nare mutated; any field that is absent is left untouched on\nthe row.\n\n`expires_at` distinguishes three states:\n  - **absent**         → column unchanged.\n  - **explicit `null`** → column set to NULL (no expiry).\n  - **concrete value**  → column set to the supplied value.\n"
      properties:
        title:
          type: string
          minLength: 1
          maxLength: 200
        body:
          type: string
          minLength: 1
          maxLength: 2000
        published_at:
          type: string
          format: date-time
        expires_at:
          type:
          - string
          - 'null'
          format: date-time
    AnnouncementListResponse:
      type: object
      properties:
        announcements:
          type: array
          items:
            $ref: '#/components/schemas/Announcement'
  responses:
    RateLimited:
      description: 'Per-account dispatcher rate limit exceeded (200 requests/minute).

        The `Retry-After` header gives the integer seconds until at least

        one token has refilled. The `X-RateLimit-*` trio reflects the

        bucket whose rejection produced this response — usually the global

        200/min cap; on `POST /api/v1/monitors` a 429 may instead reflect

        the per-route 20/min creation limit.

        '
      headers:
        Retry-After:
          schema:
            type: integer
          description: Seconds until the next allowed request.
        X-RateLimit-Limit:
          $ref: '#/components/headers/XRateLimitLimit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/XRateLimitRemaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/XRateLimitReset'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: account rate limit exceeded; retry in 1s
    Forbidden:
      description: 'Authenticated but the caller is not permitted on this route.

        Body is the opaque `{"error":"forbidden"}` envelope used for

        every admin-gated 403 across the API; the same shape is used

        whether the caller is missing the admin role or the route

        otherwise denies them, so clients cannot distinguish the two.

        '
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: forbidden
    RequestEntityTooLarge:
      description: 'Request body exceeds the 64 KB hard limit. Per docs/SPEC.md

        §Hard Limits the dispatcher rejects any payload larger than

        65,536 bytes before it is decoded.

        '
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: request body exceeds 64 KB limit
    Unauthorized:
      description: Missing or invalid credentials.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: invalid credentials
    AccountSuspended:
      description: 'Account is currently suspended. On `POST /api/v1/monitors`, and on

        a `PUT /api/v1/monitors/{monitorID}` that changes `url` or `type`

        (issue #335), this can also be returned by the per-account

        port-scan heuristic when the triggering request crossed the

        port-fan threshold inside the sliding window (10 minutes by

        default; `SCAN_WINDOW`). A host-fan trip does NOT suspend the

        account — see the 429 response instead.

        '
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: account suspended; contact support
    UnsupportedMediaType:
      description: 'The request `Content-Type` is not `application/json`. Write

        operations (POST, PUT, PATCH) require that header; a missing or

        non-JSON media type is rejected before the body is read.

        The `charset` parameter is accepted and ignored, so

        `application/json; charset=utf-8` is valid.

        '
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: unsupported media type, expected application/json
    BadRequest:
      description: Invalid request.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  headers:
    XRateLimitReset:
      schema:
        type: integer
      description: 'Unix epoch seconds at which the bucket would be full again if no

        further requests are made. Sub-second fragments are rounded up so

        `Reset - now` is never less than the actual refill duration.

        '
    XRateLimitLimit:
      schema:
        type: integer
      description: 'Bucket capacity for the limiter that produced this response. `200`

        for the global per-account dispatcher cap; `20` on a 429 from the

        per-route monitor-create limiter.

        '
    XRateLimitRemaining:
      schema:
        type: integer
      description: 'Tokens left in the bucket after this request was charged

        (floor of the post-charge token count). `0` on a 429 means the

        request was rejected with the bucket empty.

        '
  parameters:
    announcementID:
      name: announcementID
      in: path
      required: true
      schema:
        type: integer
      description: Announcement ID.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'API key (`umk_live_*`) or session token from OAuth exchange.

        '