Hookbase Sources API

The Sources API from Hookbase — 15 operation(s) for sources.

Operations 18

POST /api/sources Create source #
GET /api/sources List sources #
GET /api/sources/{sourceId} Get source by id #
PATCH /api/sources/{sourceId} Update source #
POST /api/sources/{sourceId}/rotate-secret Rotate signing secret #
GET /api/sources/{sourceId}/reveal-secret Reveal signing secret #
GET /api/sources/{sourceId}/verify-token Get verify token #
POST /api/sources/{sourceId}/rotate-verify-token Rotate verify token #
GET /api/sources/{sourceId}/pending-verification Get pending verification token #
POST /api/sources/{sourceId}/pending-verification/adopt Adopt pending verification token #
POST /api/sources/{sourceId}/simulate Simulate webhook pipeline #
GET /api/sources/export Export sources #
POST /api/sources/import Import sources #
GET /api/sources/{sourceId}/schema-baseline Get schema baseline (Pro+) #
PATCH /api/sources/{sourceId}/schema-baseline Toggle schema drift detection (Pro+) #
POST /api/sources/{sourceId}/schema-baseline/refresh Refresh schema baseline (Pro+) #
GET /api/sources/{sourceId}/schema-drift-events List schema drift events (Pro+) #
DELETE /api/sources/bulk Bulk delete sources #

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/hookbase:hookbase-sources-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

hookbase-sources-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Hookbase Sources API
  version: 1.0.0
  description: Official OpenAPI 3.0 specification for the Hookbase webhook relay platform. Generated from the maintained Postman collection. Authenticate with an API key (whr_ prefix) as a Bearer token.
  contact:
    name: Hookbase
    url: https://www.hookbase.app
servers:
- url: https://api.hookbase.app
  description: Production
security:
- bearerAuth: []
tags:
- name: Sources
paths:
  /api/sources:
    post:
      tags:
      - Sources
      summary: Create source
      operationId: sources_create_source
      responses:
        '200':
          description: Created source. Includes the full signingSecret (once) and, for WhatsApp, verifyToken.
          content:
            application/json:
              schema:
                type: object
                properties:
                  source:
                    $ref: '#/components/schemas/CreatedSource'
        '400':
          description: Invalid body, unknown provider, unknown field, missing/ill-formatted vendor-issued secret, a secret sent for a built-in-key provider, verifyToken for a non-Meta provider, or duplicate slug.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Plan limit reached or feature not on plan.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      description: 'Create an inbound source. Its `slug` becomes the public ingest path `/ingest/{orgSlug}/{slug}`. The body is strict: unknown fields are a 400.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  description: Required. Display name (1–100 chars).
                slug:
                  type: string
                  description: Required. URL-safe id (1–50 chars, [a-z0-9-]); becomes the ingest path.
                provider:
                  type: string
                  description: 'Optional. Provider id selecting the signature scheme: any provider Hookbase verifies, plus custom (and its alias generic). Unknown values are a 400. List them with GET /api/catalog/providers (use an entry''s hookbaseProvider). Omit to verify as custom.'
                description:
                  type: string
                  description: Optional. Freeform description.
                signingSecret:
                  type: string
                  description: 'Optional. Secret or public key the signature is checked against; rules depend on the provider (catalog signatureVerification.secretSource). provider-issued: paste the vendor value (Standard Webhooks/whsec_ providers, airtable, gitlab-signing-token, supabase-auth-hooks: required and format-checked). operator: omit to have one generated and returned once. public_key: required. built_in (wise, wise-sandbox, aws-sns): must be omitted (400). asana/notion: omit; the vendor issues it after registration.'
                verifyToken:
                  type: string
                  description: 'Optional. WhatsApp (Meta) only: the Verify token Meta checks at registration, 8-256 visible ASCII characters. Generated when omitted. 400 for any other provider.'
                rejectInvalidSignatures:
                  type: boolean
                  description: Optional. Reject events whose signature fails verification.
                rateLimitPerMinute:
                  type: integer
                  description: Optional. Max inbound events/min (1–100000); null = unlimited.
                ipFilterMode:
                  type: string
                  description: 'Optional. IP filtering: none | allowlist | denylist | both.'
                ipAllowlist:
                  type: array
                  items:
                    type: string
                  description: Optional. CIDRs/IPs allowed (used when ipFilterMode includes allowlist).
                ipDenylist:
                  type: array
                  items:
                    type: string
                  description: Optional. CIDRs/IPs blocked (used when ipFilterMode includes denylist).
                encryptFields:
                  type: array
                  items:
                    type: string
                  description: Optional. JSON paths encrypted at rest.
                maskFields:
                  type: array
                  items:
                    type: string
                  description: Optional. JSON paths masked in the dashboard.
                dedupEnabled:
                  type: boolean
                  description: Optional. Enable event deduplication.
                dedupStrategy:
                  type: string
                  description: Optional. auto | provider_id | payload_hash | idempotency_key | none.
                dedupWindowHours:
                  type: integer
                  description: Optional. Dedup look-back window in hours (1–168).
                dedupCustomHeader:
                  type: string
                  description: Optional. Header to dedupe on (max 100 chars).
                transientMode:
                  type: boolean
                  description: 'Optional. Process-and-forget: don''t persist payloads.'
                allowedMethods:
                  type: array
                  items:
                    type: string
                  description: 'Optional. Accepted ingest HTTP methods: GET, POST, PUT, PATCH, DELETE, HEAD. Empty/omitted = any.'
              required:
              - name
              - slug
              additionalProperties: false
            example:
              name: GitHub Webhooks
              slug: github-webhooks
              provider: github
              description: Production org webhooks
              signingSecret: whsec_xxx
              rejectInvalidSignatures: true
              rateLimitPerMinute: 1000
              ipFilterMode: none
              ipAllowlist:
              - 203.0.113.0/24
              ipDenylist:
              - 198.51.100.7
              encryptFields:
              - data.card.number
              maskFields:
              - data.email
              dedupEnabled: false
              dedupStrategy: auto
              dedupWindowHours: 24
              dedupCustomHeader: X-Idempotency-Key
              transientMode: false
              allowedMethods:
              - POST
    get:
      tags:
      - Sources
      summary: List sources
      operationId: sources_list_sources
      parameters:
      - name: page
        in: query
        required: false
        schema:
          type: string
        example: '1'
      - name: pageSize
        in: query
        required: false
        schema:
          type: string
        example: '20'
      responses:
        '200':
          description: Sources (without ingestUrl) and pagination.
          content:
            application/json:
              schema:
                type: object
                properties:
                  sources:
                    type: array
                    items:
                      $ref: '#/components/schemas/Source'
                  pagination:
                    type: object
                    properties:
                      total:
                        type: integer
                      page:
                        type: integer
                      pageSize:
                        type: integer
      description: List sources for the org (paginated), each with event and route counts.
  /api/sources/{sourceId}:
    get:
      tags:
      - Sources
      summary: Get source by id
      operationId: sources_get_source_by_id
      parameters:
      - name: sourceId
        in: path
        required: true
        schema:
          type: string
        description: Source ID or slug.
      responses:
        '200':
          description: The source.
          content:
            application/json:
              schema:
                type: object
                properties:
                  source:
                    $ref: '#/components/schemas/Source'
        '404':
          description: Source not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      description: Fetch a single source by id or slug (signing secret masked).
    patch:
      tags:
      - Sources
      summary: Update source
      operationId: sources_update_source
      parameters:
      - name: sourceId
        in: path
        required: true
        schema:
          type: string
        description: Source ID or slug.
      responses:
        '200':
          description: 'Acknowledged ({"success": true}); read the source back for the new state.'
        '400':
          description: Invalid body or secret/verify-token rule violated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Source not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      description: Update a source. All fields optional; omitted fields are unchanged.
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  description: Optional. Display name (1–100 chars).
                description:
                  type: string
                  description: Optional. Freeform description (null to clear).
                provider:
                  type:
                  - string
                  - 'null'
                  description: 'Optional. Provider id selecting the signature scheme: any provider Hookbase verifies, plus custom (and its alias generic). Unknown values are a 400. List them with GET /api/catalog/providers (use an entry''s hookbaseProvider). null falls back to custom.'
                isActive:
                  type: boolean
                  description: Optional. Enable/disable ingestion for this source.
                signingSecret:
                  type:
                  - string
                  - 'null'
                  description: Optional. Replace the signing secret; null or "" clears it. Validated against the provider the source will have after the update. Switching to a vendor-issued-secret provider requires the new secret in the same request.
                verifyToken:
                  type:
                  - string
                  - 'null'
                  description: 'Optional. WhatsApp (Meta) only: set the Verify token; null or "" generates a new one. 400 for any other provider.'
                rejectInvalidSignatures:
                  type: boolean
                  description: Optional. Reject events failing signature verification.
                rateLimitPerMinute:
                  type: integer
                  description: Optional. Max inbound events/min (1–100000); null = unlimited.
                ipFilterMode:
                  type: string
                  description: Optional. none | allowlist | denylist | both.
                ipAllowlist:
                  type: array
                  items:
                    type: string
                  description: Optional. Allowed CIDRs/IPs.
                ipDenylist:
                  type: array
                  items:
                    type: string
                  description: Optional. Blocked CIDRs/IPs.
                encryptFields:
                  type: array
                  items:
                    type: string
                  description: Optional. JSON paths encrypted at rest.
                maskFields:
                  type: array
                  items:
                    type: string
                  description: Optional. JSON paths masked in the dashboard.
                dedupEnabled:
                  type: boolean
                  description: Optional. Enable deduplication.
                dedupStrategy:
                  type: string
                  description: Optional. auto | provider_id | payload_hash | idempotency_key | none.
                dedupWindowHours:
                  type: integer
                  description: Optional. Dedup window hours (1–168).
                dedupCustomHeader:
                  type: string
                  description: Optional. Header to dedupe on (max 100).
                transientMode:
                  type: boolean
                  description: Optional. Process-and-forget mode.
                allowedMethods:
                  type: array
                  items:
                    type: string
                  description: Optional. Accepted ingest methods (empty/null = any).
              additionalProperties: false
            example:
              name: GitHub Webhooks
              description: Updated description
              provider: github
              isActive: true
              signingSecret: whsec_new
              rejectInvalidSignatures: true
              rateLimitPerMinute: 1000
              ipFilterMode: none
              ipAllowlist:
              - 203.0.113.0/24
              ipDenylist:
              - 198.51.100.7
              encryptFields:
              - data.card.number
              maskFields:
              - data.email
              dedupEnabled: false
              dedupStrategy: auto
              dedupWindowHours: 24
              dedupCustomHeader: X-Idempotency-Key
              transientMode: false
              allowedMethods:
              - POST
  /api/sources/{sourceId}/rotate-secret:
    post:
      tags:
      - Sources
      summary: Rotate signing secret
      operationId: sources_rotate_signing_secret
      parameters:
      - name: sourceId
        in: path
        required: true
        schema:
          type: string
        description: Source ID or slug.
      responses:
        '200':
          description: The new secret.
          content:
            application/json:
              schema:
                type: object
                properties:
                  signingSecret:
                    type: string
        '400':
          description: The provider has no secret Hookbase can generate.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Source not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      description: 'Generate a new signing secret and return it once. Meant for Hookbase-generated secrets (catalog secretSource operator, or custom sources); paste the new value into the vendor. Refused with 400 for built-in-key providers (wise, wise-sandbox, aws-sns), public-key providers (discord, sendgrid), vendor-issued base64 keys (Standard Webhooks/whsec_ providers, airtable, gitlab-signing-token, supabase-auth-hooks) and asana/notion: rotate those at the vendor and PATCH signingSecret.'
  /api/sources/{sourceId}/reveal-secret:
    get:
      tags:
      - Sources
      summary: Reveal signing secret
      operationId: sources_reveal_signing_secret
      parameters:
      - name: sourceId
        in: path
        required: true
        schema:
          type: string
        description: Source ID or slug.
      responses:
        '200':
          description: The secret.
          content:
            application/json:
              schema:
                type: object
                properties:
                  signingSecret:
                    type: string
        '404':
          description: Source not found or no signing secret stored.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      description: Return the source's current signing secret in plaintext. Requires a write-scoped API key.
  /api/sources/{sourceId}/verify-token:
    get:
      tags:
      - Sources
      summary: Get verify token
      operationId: sources_get_verify_token
      parameters:
      - name: sourceId
        in: path
        required: true
        schema:
          type: string
        description: Source ID or slug.
      responses:
        '200':
          description: The verify token.
          content:
            application/json:
              schema:
                type: object
                properties:
                  verifyToken:
                    type: string
        '400':
          description: The provider has no verify token.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Source not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      description: 'WhatsApp (Meta) only: return the Verify token Meta checks at registration. Requires a write-scoped API key.'
  /api/sources/{sourceId}/rotate-verify-token:
    post:
      tags:
      - Sources
      summary: Rotate verify token
      operationId: sources_rotate_verify_token
      parameters:
      - name: sourceId
        in: path
        required: true
        schema:
          type: string
        description: Source ID or slug.
      responses:
        '200':
          description: The verify token.
          content:
            application/json:
              schema:
                type: object
                properties:
                  verifyToken:
                    type: string
        '400':
          description: The provider has no verify token.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Source not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      description: 'WhatsApp (Meta) only: generate a new Verify token and return it. The old token stops working at once.'
  /api/sources/{sourceId}/pending-verification:
    get:
      tags:
      - Sources
      summary: Get pending verification token
      operationId: sources_get_pending_verification
      parameters:
      - name: sourceId
        in: path
        required: true
        schema:
          type: string
        description: Source ID or slug.
      responses:
        '200':
          description: The pending token.
          content:
            application/json:
              schema:
                type: object
                properties:
                  provider:
                    type: string
                  token:
                    type: string
                  receivedAt:
                    type: string
                    format: date-time
                  clientIp:
                    type:
                    - string
                    - 'null'
        '404':
          description: Source not found, or no verification token is waiting.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      description: Return a verification token the vendor (Notion) delivered to the ingest URL during registration and Hookbase is holding (24h) until adopted. Requires a write-scoped API key.
  /api/sources/{sourceId}/pending-verification/adopt:
    post:
      tags:
      - Sources
      summary: Adopt pending verification token
      operationId: sources_adopt_pending_verification
      parameters:
      - name: sourceId
        in: path
        required: true
        schema:
          type: string
        description: Source ID or slug.
      responses:
        '200':
          description: '{"success": true}'
        '404':
          description: Source not found, or no verification token is waiting.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      description: Make the pending verification token the source's signing secret (after the vendor shows the subscription verified). Deletes the pending entry.
  /api/sources/{sourceId}/simulate:
    post:
      tags:
      - Sources
      summary: Simulate webhook pipeline
      operationId: sources_simulate_webhook_pipeline
      parameters:
      - name: sourceId
        in: path
        required: true
        schema:
          type: string
        description: Source ID or slug.
      responses:
        '200':
          description: Successful response
      description: Dry-run the full ingest→route→transform pipeline for a source. Provide exactly one of payload, payloadString, or fromEventId.
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                payload:
                  type: object
                  description: Optional. Inline JSON payload to simulate.
                payloadString:
                  type: string
                  description: Optional. Raw string payload (alternative to payload).
                fromEventId:
                  type: string
                  description: Optional. Replay an existing event's payload by id (UUID).
                headers:
                  type: object
                  description: Optional. Request headers to simulate.
                eventType:
                  type: string
                  description: Optional. Event type label for the simulated event.
            example:
              payload:
                action: opened
                number: 1
              payloadString: '{"raw":"body"}'
              fromEventId: '{{eventId}}'
              headers:
                X-GitHub-Event: push
              eventType: push
  /api/sources/export:
    get:
      tags:
      - Sources
      summary: Export sources
      operationId: sources_export_sources
      parameters:
      - name: includeSensitive
        in: query
        required: false
        schema:
          type: string
        example: 'false'
      responses:
        '200':
          description: Successful response
      description: Export all sources (or a subset via ?ids=) as a portable JSON config document. `includeSensitive=true` includes signing secrets.
  /api/sources/import:
    post:
      tags:
      - Sources
      summary: Import sources
      operationId: sources_import_sources
      responses:
        '200':
          description: Successful response
      description: Import sources from the export format. Slugs that already exist are handled per `conflictStrategy`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                sources:
                  type: array
                  items:
                    type: object
                  description: Required. Array of source configs in the /export shape.
                conflictStrategy:
                  type: string
                  description: 'Required. On existing slug: skip | rename | overwrite.'
                validateOnly:
                  type: boolean
                  description: Optional. Validate without persisting.
              required:
              - sources
              - conflictStrategy
            example:
              sources:
              - name: GitHub Webhooks
                slug: github-webhooks
                provider: github
              conflictStrategy: skip
              validateOnly: false
  /api/sources/{sourceId}/schema-baseline:
    get:
      tags:
      - Sources
      summary: Get schema baseline (Pro+)
      operationId: sources_get_schema_baseline_pro
      parameters:
      - name: sourceId
        in: path
        required: true
        schema:
          type: string
        description: Source ID or slug.
      responses:
        '200':
          description: Successful response
      description: Return the inferred payload schema baseline used for drift detection (Pro plan and above).
    patch:
      tags:
      - Sources
      summary: Toggle schema drift detection (Pro+)
      operationId: sources_toggle_schema_drift_detection_pro
      parameters:
      - name: sourceId
        in: path
        required: true
        schema:
          type: string
        description: Source ID or slug.
      responses:
        '200':
          description: Successful response
      description: Enable or disable schema-drift detection for the source (Pro+).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                driftEnabled:
                  type: boolean
                  description: Required. Turn drift detection on/off.
              required:
              - driftEnabled
            example:
              driftEnabled: true
  /api/sources/{sourceId}/schema-baseline/refresh:
    post:
      tags:
      - Sources
      summary: Refresh schema baseline (Pro+)
      operationId: sources_refresh_schema_baseline_pro
      parameters:
      - name: sourceId
        in: path
        required: true
        schema:
          type: string
        description: Source ID or slug.
      responses:
        '200':
          description: Successful response
      description: Recompute the source's schema baseline from recent events (Pro+).
  /api/sources/{sourceId}/schema-drift-events:
    get:
      tags:
      - Sources
      summary: List schema drift events (Pro+)
      operationId: sources_list_schema_drift_events_pro
      parameters:
      - name: sourceId
        in: path
        required: true
        schema:
          type: string
        description: Source ID or slug.
      - name: limit
        in: query
        required: false
        schema:
          type: string
        example: '50'
      responses:
        '200':
          description: Successful response
      description: List recent schema-drift events detected for the source (Pro+).
  /api/sources/bulk:
    delete:
      tags:
      - Sources
      summary: Bulk delete sources
      operationId: sources_bulk_delete_sources
      responses:
        '200':
          description: Successful response
      description: Delete multiple sources by id in one call (max 100).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                ids:
                  type: array
                  items:
                    type: string
                  description: Required. Source ids to delete (max 100).
              required:
              - ids
            example:
              ids:
              - '{{sourceId}}'
components:
  schemas:
    Error:
      type: object
      properties:
        error:
          type: string
          description: Human-readable reason.
    CreatedSource:
      allOf:
      - $ref: '#/components/schemas/Source'
      - type: object
        properties:
          signingSecret:
            type:
            - string
            - 'null'
            description: The full secret, returned only here. Hookbase-generated when omitted for providers that take an operator-chosen secret. null for built-in-key providers and for asana/notion until the vendor issues it.
          verifyToken:
            type: string
            description: 'WhatsApp only: the Meta Verify token, returned in full only here.'
    Source:
      type: object
      description: A source. The full signing secret is never included except in the create response.
      properties:
        id:
          type: string
          format: uuid
        organizationId:
          type: string
          format: uuid
        name:
          type: string
        slug:
          type: string
        provider:
          type:
          - string
          - 'null'
          description: Provider id selecting the signature scheme. null verifies as custom.
        description:
          type:
          - string
          - 'null'
        hasSigningSecret:
          type: boolean
          description: A signing secret is stored.
        signingSecretLast4:
          type:
          - string
          - 'null'
          description: Last four characters of the stored secret, e.g. "...a1b2".
        awaitingSigningSecret:
          type: boolean
          description: true when the provider issues its secret only after the ingest URL is registered (asana, notion) and none is set yet. Events are accepted unverified until it is.
        verifiesWithoutSecret:
          type: boolean
          description: true when the provider is verified with a key Hookbase already has (wise, wise-sandbox, aws-sns); no secret is stored or needed.
        rejectInvalidSignatures:
          type: boolean
        rateLimitPerMinute:
          type:
          - integer
          - 'null'
        isActive:
          type: boolean
        customDomainId:
          type:
          - string
          - 'null'
        ipFilterMode:
          type: string
          enum:
          - none
          - allowlist
          - denylist
          - both
        ipAllowlist:
          type: array
          items:
            type: string
        ipDenylist:
          type: array
          items:
            type: string
        encryptFields:
          type: array
          items:
            type: string
        maskFields:
          type: array
          items:
            type: string
        dedupEnabled:
          type: boolean
        dedupStrategy:
          type: string
          enum:
          - auto
          - provider_id
          - payload_hash
          - idempotency_key
          - none
        dedupWindowHours:
          type: integer
        dedupCustomHeader:
          type:
          - string
          - 'null'
        transientMode:
          type: boolean
        allowedMethods:
          type: array
          items:
            type: string
          description: '[] = any method.'
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        eventCount:
          type: integer
        routeCount:
          type: integer
        ingestUrl:
          type: string
          description: Get and create responses only.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: Hookbase API key with the whr_ prefix.