Send a sample delivery now

POST/v1/webhooks/{id}/test

Sends a signed sample change to your webhook's URL now and reports what your endpoint answered, free.

View as MarkdownOpenAPI specAll docs for LLMs

  • Auth: API key (Authentication)
  • Scope: events:read
  • Cost: Free; never charged or retried.

Use it after creating a webhook to check your endpoint is reachable and your signature check passes. The sample has data.test: true and the domain example.com.

POSTs a signed sample (data.domain example.com, data.test: true) to the webhook's URL now and reports what came back, so you can check your endpoint and signature check. Free, never retried.

Request

curl -X POST "https://api.installgraph.com/v1/webhooks/6731b2e4c9a1f20d8e4b7c15/test" \
  -H "Authorization: Bearer $INSTALLGRAPH_API_KEY"

Path parameters

Name Type Required Description
id string Yes

Response

200. The example's stores are fictional.

{
  "data": {
    "delivered": true,
    "status": 204,
    "error": null,
    "body": {
      "id": "test_6733d2f17be42c19f5a8e3a9",
      "type": "technology.removed",
      "subscriptionId": "6731b2e4c9a1f20d8e4b7c15",
      "createdAt": "2026-11-10T12:01:00.000Z",
      "data": {
        "id": "test",
        "type": "removed",
        "domain": "example.com",
        "app": {
          "slug": "klaviyo",
          "name": "Klaviyo",
          "category": "email-sms"
        },
        "detectedAt": "2026-11-10T12:01:00.000Z",
        "previousScanAt": "2026-11-03T12:01:00.000Z",
        "lastSeenAt": null,
        "country": "US",
        "region": "north-america",
        "industry": null,
        "pricePoint": null,
        "test": true
      }
    }
  },
  "meta": {
    "requestId": "6f1c2a9e-4b7d-4e2a-9c51-0d3b8e7f2a14",
    "creditsUsed": 0,
    "creditsCharged": 0,
    "creditsRemaining": 2480,
    "freeRepulls": 0
  }
}

Fields

Field Type Description
data.delivered boolean
data.status integer | null
data.error string | null
data.body WebhookPayload
data.body.id string The delivery id; the same on every retry. Deduplicate on it.
data.body.type string One of technology.installed, technology.removed.
data.body.subscriptionId string
data.body.createdAt string (date-time) When this attempt was sent.
data.body.data Event
data.body.data.id string
data.body.data.type string One of installed, removed.
data.body.data.domain string
data.body.data.app AppSummary
data.body.data.detectedAt string (date-time) The scan that saw the change.
data.body.data.previousScanAt string (date-time) | null The healthy scan before it.
data.body.data.lastSeenAt string (date-time) | null For a removal, the last scan that still saw the app.
data.body.data.country string | null The store's current country.
data.body.data.region Region | null One of north-america, latin-america, europe, middle-east-africa, asia-pacific.
data.body.data.industry Industry | null Our reading of what the store sells, from its homepage, in the Store Leads taxonomy.
data.body.data.pricePoint PricePoint | null The store's typical order value, in USD bands so it reads the same in every country. Our own reading of the homepage: the product prices shown there (converted from the store's currency), and what is sold.

Every keyed response also carries meta (requestId, creditsUsed, creditsRemaining, freeRepulls) and the X-Credits-* and X-RateLimit-* headers. See Credits and Rate limits.

Errors

Status Code Meaning What to do
404 not_found No such endpoint, app, or store (or not scanned yet). Check the slug or domain. Store 404s are free within the lookup-miss allowance.

All codes: Errors.