HookPulse Endpoints API

The Endpoints API from HookPulse — 3 operation(s) for endpoints.

Operations 6

GET /api/endpoints Lists the owner's monitors, with the state of each one #
POST /api/endpoints Creates a dead-man switch: silence beyond the interval becomes an alert #
GET /api/endpoints/{id} State of one monitor — accepts the owner's token or the monitor's own token #
PATCH /api/endpoints/{id} Changes the monitor's name, interval or alert channels #
DELETE /api/endpoints/{id} Deactivates the owner's monitor; it stops taking pings and alerting #
GET /api/endpoints/{id}/events The latest pings received at this monitor's ingest #

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/hookpulse-endpoints-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

hookpulse-endpoints-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: HookPulse Endpoints API
  version: 2d690e87
  description: 'Dead-man switch for webhooks/cron. Index: GET /api/.'
servers:
- url: https://hookpulse.net
tags:
- name: Endpoints
paths:
  /api/endpoints:
    get:
      operationId: list_endpoints
      summary: Lists the owner's monitors, with the state of each one
      description: 'Returns: { endpoints[{id,name,interval_sec,alert_to,alert_url,last_event_at,last_status,last_latency_ms,miss_count,alerted_at,active,healthy,overdue,waiting_first_ping,created_at,ingest_url,token?,status_url?,events_url?,curl_example?,templates?}], guest, billing?{provider,mode,network,chain_id,pay_to,homolog,dev,dev_gate,facilitator,asset,asset_address,faucet,wallets,product,free_max_endpoints,free_min_interval_sec,free_email_alerts,prices,usage,trial} }'
      security:
      - bearerAuth: []
      responses:
        '200':
          description: '{ endpoints[{id,name,interval_sec,alert_to,alert_url,last_event_at,last_status,last_latency_ms,miss_count,alerted_at,active,healthy,overdue,waiting_first_ping,created_at,ingest_url,token?,status_url?,events_url?,curl_example?,templates?}], guest, billing?{provider,mode,network,chain_id,pay_to,homolog,dev,dev_gate,facilitator,asset,asset_address,faucet,wallets,product,free_max_endpoints,free_min_interval_sec,free_email_alerts,prices,usage,trial} }'
          content:
            application/json:
              schema:
                type: object
                properties:
                  endpoints:
                    type: array
                    items:
                      $ref: '#/components/schemas/Monitor'
                    description: The owner's monitors, without the secret fields.
                  guest:
                    type: string
                    description: The guest that owns this list.
                    nullable: true
                  billing:
                    allOf:
                    - $ref: '#/components/schemas/Billing'
                    description: Prices and allowance, to decide before creating the next one.
                required:
                - endpoints
                - guest
        '401':
          description: No credential, or an invalid one. See this endpoint's auth.
      tags:
      - Endpoints
    post:
      operationId: create_endpoint
      summary: 'Creates a dead-man switch: silence beyond the interval becomes an alert'
      description: 'This response is the only one that shows the monitor''s `token` and the `templates` — keep them. The second monitor, or an interval below the free minimum, answers **402 with `accepts[]`**: pay and repeat. A miss alerts at most once per 24h (or per interval, if it is longer).

        Returns: { id, name, interval_sec, alert_to, alert_url, last_event_at, last_status, last_latency_ms, miss_count, alerted_at, active, healthy, overdue, waiting_first_ping, created_at, ingest_url, token?, status_url?, events_url?, curl_example?, templates?{ingest_curl,ingest_cron,ingest_n8n,miss_json,miss_url_hint} }'
      security:
      - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  description: Name to recognise the monitor in the alert.
                interval_sec:
                  type: integer
                  description: Tolerated silence, in seconds. Below the free minimum, it costs.
                alert_to:
                  type: string
                  description: E-mail to alert on a miss; without it, the account is alerted.
                alert_url:
                  type: string
                  description: Public HTTPS URL that receives a POST on a miss (Slack Incoming, Discord, n8n).
              required:
              - name
            example:
              name: prod cron
              interval_sec: 900
              alert_to: optional@email.com
              alert_url: https://n8n.example/webhook/hp
      responses:
        '200':
          description: '{ id, name, interval_sec, alert_to, alert_url, last_event_at, last_status, last_latency_ms, miss_count, alerted_at, active, healthy, overdue, waiting_first_ping, created_at, ingest_url, token?, status_url?, events_url?, curl_example?, templates?{ingest_curl,ingest_cron,ingest_n8n,miss_json,miss_url_hint} }'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Monitor'
        '400':
          description: Empty name, invalid interval or an `alert_url` that is not public HTTPS.
        '401':
          description: No credential, or an invalid one. See this endpoint's auth.
        '402':
          description: 'Quota exceeded. The response carries `accepts[]` (x402, USDC on Base): pay and repeat the same call with `X-PAYMENT`.'
      tags:
      - Endpoints
  /api/endpoints/{id}:
    get:
      operationId: get_endpoint
      summary: State of one monitor — accepts the owner's token or the monitor's own token
      description: 'The monitor token only reads: it lets you put the state on a third-party dashboard without handing over the owner''s credential.

        Returns: { id, name, interval_sec, alert_to, alert_url, last_event_at, last_status, last_latency_ms, miss_count, alerted_at, active, healthy, overdue, waiting_first_ping, created_at, ingest_url, token?, status_url?, events_url?, curl_example?, templates?{ingest_curl,ingest_cron,ingest_n8n,miss_json,miss_url_hint} }'
      security:
      - bearerAuth: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - name: token
        in: query
        required: false
        schema:
          type: string
        description: Monitor token, alternative to the `X-Hook-Token` header.
      responses:
        '200':
          description: '{ id, name, interval_sec, alert_to, alert_url, last_event_at, last_status, last_latency_ms, miss_count, alerted_at, active, healthy, overdue, waiting_first_ping, created_at, ingest_url, token?, status_url?, events_url?, curl_example?, templates?{ingest_curl,ingest_cron,ingest_n8n,miss_json,miss_url_hint} }'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Monitor'
        '401':
          description: No credential, or an invalid one. See this endpoint's auth.
        '404':
          description: The resource does not exist (or is not yours — the API does not tell the two apart on purpose).
      tags:
      - Endpoints
    patch:
      operationId: patch_api_endpoints_by_id
      summary: Changes the monitor's name, interval or alert channels
      description: 'Lowering the interval below the free minimum costs: the response becomes 402 with `accepts[]` until paid.

        Returns: { ok, endpoint{id,name,interval_sec,alert_to,alert_url,last_event_at,last_status,last_latency_ms,miss_count,alerted_at,active,healthy,overdue,waiting_first_ping,created_at,ingest_url,token?,status_url?,events_url?,curl_example?,templates?} }'
      security:
      - bearerAuth: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  description: New monitor name, as it shows in the alert.
                interval_sec:
                  type: integer
                  description: New tolerated silence, in seconds.
                alert_to:
                  type: string
                  description: New alert e-mail; `null` turns it off.
                alert_url:
                  type: string
                  description: New alert URL; `null` turns it off.
            example:
              name: …
              interval_sec: 300
              alert_to: null
              alert_url: null
      responses:
        '200':
          description: '{ ok, endpoint{id,name,interval_sec,alert_to,alert_url,last_event_at,last_status,last_latency_ms,miss_count,alerted_at,active,healthy,overdue,waiting_first_ping,created_at,ingest_url,token?,status_url?,events_url?,curl_example?,templates?} }'
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                    description: Always `true`.
                  endpoint:
                    allOf:
                    - $ref: '#/components/schemas/Monitor'
                    description: The monitor with the change applied.
                required:
                - ok
                - endpoint
        '400':
          description: Invalid field in the body.
        '401':
          description: No credential, or an invalid one. See this endpoint's auth.
        '402':
          description: 'Quota exceeded. The response carries `accepts[]` (x402, USDC on Base): pay and repeat the same call with `X-PAYMENT`.'
        '404':
          description: The resource does not exist (or is not yours — the API does not tell the two apart on purpose).
      tags:
      - Endpoints
    delete:
      operationId: delete_endpoint
      summary: Deactivates the owner's monitor; it stops taking pings and alerting
      description: 'Returns: { ok }'
      security:
      - bearerAuth: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: '{ ok }'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Ok'
        '401':
          description: No credential, or an invalid one. See this endpoint's auth.
        '404':
          description: The resource does not exist (or is not yours — the API does not tell the two apart on purpose).
      tags:
      - Endpoints
  /api/endpoints/{id}/events:
    get:
      operationId: list_events
      summary: The latest pings received at this monitor's ingest
      description: 'Returns: { events[{at,status,latency_ms,source}] }'
      security:
      - bearerAuth: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - name: token
        in: query
        required: false
        schema:
          type: string
        description: Monitor token, alternative to the `X-Hook-Token` header.
      responses:
        '200':
          description: '{ events[{at,status,latency_ms,source}] }'
          content:
            application/json:
              schema:
                type: object
                properties:
                  events:
                    type: array
                    items:
                      $ref: '#/components/schemas/Ping'
                    description: The most recent pings, newest first.
                required:
                - events
        '401':
          description: No credential, or an invalid one. See this endpoint's auth.
        '404':
          description: The resource does not exist (or is not yours — the API does not tell the two apart on purpose).
      tags:
      - Endpoints
components:
  schemas:
    Ping:
      type: object
      properties:
        at:
          type: string
          description: When it arrived (UTC).
        status:
          type: integer
          description: Status reported by the caller, when it did.
          nullable: true
        latency_ms:
          type: integer
          description: Latency reported by the caller, in ms.
          nullable: true
        source:
          type: string
          description: 'Where it came from: `get` or `post`.'
          nullable: true
      required:
      - at
      - status
      - latency_ms
      - source
      description: A ping received at the ingest — the proof of life.
    Billing:
      type: object
      properties:
        provider:
          type: string
          description: Always `x402` — the only billing protocol accepted.
        mode:
          type: string
          description: 'Seller mode: `live` charges for real, `dev` lets calls through unpaid.'
        network:
          type: string
          description: 'USDC network: `base` in production, `base-sepolia` in staging.'
        chain_id:
          type: integer
          description: EVM chain ID of the network above, so the wallet signs on the right chain.
        pay_to:
          type: string
          description: Address that receives the payment.
          nullable: true
        homolog:
          type: boolean
          description: 'Staging seam on: the loop can be closed without spending USDC.'
        dev:
          type: boolean
          description: 'Development mode: the 402 is simulated.'
        dev_gate:
          type: string
          description: How dev mode is unlocked, when it exists.
          nullable: true
        facilitator:
          type: string
          description: URL of the facilitator that verifies and settles the payment.
        asset:
          type: string
          description: Accepted currency — always `USDC`.
        asset_address:
          type: string
          description: USDC contract on the network above.
        faucet:
          type: string
          description: Test-USDC faucet; only on base-sepolia.
          nullable: true
        wallets:
          type: object
          description: Links to wallets that speak x402 (metamask, coinbase, base_app).
        product:
          type: string
          description: Name of the product charging.
        free_max_endpoints:
          type: integer
          description: Free monitors per owner.
        free_min_interval_sec:
          type: integer
          description: Shortest interval that is still free. Below it, it costs.
        free_email_alerts:
          type: integer
          description: Free e-mail alert registrations; the rest is paid (it is SES cost per miss).
        prices:
          allOf:
          - $ref: '#/components/schemas/Precos'
          description: What each paid action costs, in USD.
        usage:
          type: object
          description: How much of the allowance the owner has used.
        trial:
          allOf:
          - $ref: '#/components/schemas/Trial'
          description: The account's trial, when there is a session.
      required:
      - provider
      - mode
      - network
      - chain_id
      - pay_to
      - homolog
      - dev
      - dev_gate
      - facilitator
      - asset
      - asset_address
      - faucet
      - wallets
      - product
      - free_max_endpoints
      - free_min_interval_sec
      - free_email_alerts
      - prices
      - usage
      - trial
      description: 'Everything that decides whether the next call will cost: x402 configuration, allowance, prices and trial.'
    Trial:
      type: object
      properties:
        days:
          type: integer
          description: Trial length in days.
        active:
          type: boolean
          description: Whether it is in force now.
        days_left:
          type: integer
          description: How many days remain.
        ends_at:
          type: string
          description: When it ends (UTC).
          nullable: true
        granted:
          type: boolean
          description: '`true` when THIS call granted the trial.'
      required:
      - days
      - active
      - ends_at
      description: The period without the usage paywall that confirming the e-mail grants. It is the alternative to paying.
    Precos:
      type: object
      properties:
        extra_endpoint_usd:
          type: number
          description: Monitor beyond the allowance.
        fast_interval_usd:
          type: number
          description: Interval below the free minimum.
        email_alert_usd:
          type: number
          description: E-mail alert registration beyond the first.
        contact_agent_usd:
          type: number
          description: Agent contact.
      required:
      - extra_endpoint_usd
      - fast_interval_usd
      - email_alert_usd
      - contact_agent_usd
      description: Prices in force, in dollars. Read them here, not from the documentation.
    Monitor:
      type: object
      properties:
        id:
          type: string
          description: Monitor ID; it is the `:id` of the ingest URL.
        name:
          type: string
          description: Name you gave it, to recognise it in the alert.
        interval_sec:
          type: integer
          description: Tolerated silence, in seconds. Past that, it is a miss.
        alert_to:
          type: string
          description: E-mail alerted on a miss.
          nullable: true
        alert_url:
          type: string
          description: HTTPS URL that receives a POST on a miss (Slack, Discord, n8n).
          nullable: true
        last_event_at:
          type: string
          description: Last ping received (UTC); `null` while it never pinged.
          nullable: true
        last_status:
          type: integer
          description: HTTP status the last ping sent, when it did.
          nullable: true
        last_latency_ms:
          type: integer
          description: Latency reported in the last ping, in ms.
          nullable: true
        miss_count:
          type: integer
          description: How many times this monitor has gone silent.
        alerted_at:
          type: string
          description: When the last alert went out — it is what holds the 1 alert/24h cap.
          nullable: true
        active:
          type: boolean
          description: Whether the monitor is on.
        healthy:
          type: boolean
          description: '`true` when it has pinged at least once and is not overdue.'
        overdue:
          type: boolean
          description: '`true` when the silence passed `interval_sec`.'
        waiting_first_ping:
          type: boolean
          description: '`true` while it never pinged. Neither healthy nor overdue: nobody has wired it yet.'
        created_at:
          type: string
          description: When the monitor was created (UTC).
        ingest_url:
          type: string
          description: The URL your cron/webhook calls to prove life.
        token:
          type: string
          description: Read token of this monitor. Only comes on creation and to the owner.
        status_url:
          type: string
          description: Status of this monitor with the token already in the query.
        events_url:
          type: string
          description: Latest pings with the token already in the query.
        curl_example:
          type: string
          description: The ingest `curl`, ready to paste in the cron.
        templates:
          allOf:
          - $ref: '#/components/schemas/Templates'
          description: Ingest snippets and the alert body, with this monitor already in them.
      required:
      - id
      - name
      - interval_sec
      - alert_to
      - alert_url
      - last_event_at
      - last_status
      - last_latency_ms
      - miss_count
      - alerted_at
      - active
      - healthy
      - overdue
      - waiting_first_ping
      - created_at
      - ingest_url
      description: 'A dead-man switch: the thing you make ping. If the ping stops for longer than `interval_sec`, it becomes `overdue` and the alert goes out.'
    Templates:
      type: object
      properties:
        ingest_curl:
          type: string
          description: A `curl` that works as proof of life.
        ingest_cron:
          type: string
          description: The equivalent crontab line.
        ingest_n8n:
          type: string
          description: How to call the ingest from n8n.
        miss_json:
          type: string
          description: The exact JSON we POST to `alert_url` when the silence becomes a miss.
        miss_url_hint:
          type: string
          description: What works as `alert_url` — public HTTPS only.
      required:
      - ingest_curl
      - ingest_cron
      - ingest_n8n
      - miss_json
      - miss_url_hint
      description: How to ping and what we send when it fails. It is what saves guessing the format.
    Ok:
      type: object
      properties:
        ok:
          type: boolean
          description: Always `true` — failure comes as a 4xx/5xx status, not as `ok:false`.
      required:
      - ok
      description: Write confirmation with no body of its own to return.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'Guest token (`POST /api/guest`) in `X-Guest-Token: hp_…` or `Authorization: Bearer hp_…`. A `sess_…` session also works.'