GunSpec

My Webhooks

Register HTTPS endpoints to be told when GunSpec data changes, instead of polling for it. Subscribe to events such as firearm.created or firearm.updated and the changed record is delivered to your server in the same shape the API returns it, so a local mirror can be kept current without a second call. Requires Studio tier or higher.

Auth RequiredExplorer+

Returns the webhook endpoints registered on your account.

GET/v1/me/webhooks

  • stringheaderrequired

    Your API key. Authorization: Bearer <key> is accepted in its place.

  • integerdefault1

    Page number, from 1 to 10,000

    Range
    1 – 10000
    Example
  • integerdefault20

    Items per page (max 100)

    Range
    1 – 100
    Example

  • WebhookEndpoint[]

    One page of results

  • string

    Opaque endpoint id. Address it at /v1/me/webhooks/{endpointId}.

  • string

    Absolute, directly fetchable URL.

  • string[]

    Event types this endpoint is subscribed to. The full list is on the POST operation.

  • string | null

    Prose summary of the record, where one has been written.

  • boolean

    False while the endpoint is paused. A paused endpoint receives nothing and is not retried.

  • string

    When the record was first added, YYYY-MM-DD HH:MM:SS in UTC.

  • string

    When the endpoint was last changed, ISO 8601.

  • number

    Current page number

  • number

    Items per page

  • number

    Total matching records (Builder and above)

  • 400VALIDATION_ERRORValidation error
  • 401UNAUTHORIZEDAPI key required
  • 403FORBIDDENValid key, not permitted
  • 429RATE_LIMITEDRate limit exceeded
  • 500INTERNAL_ERRORUnexpected server error

Requires Studio tier or higher.

Webhook secrets are never returned in list or get responses for security.

Minimum tier
Explorer+
Monthly quota
200/mo
Rate limit
10/min
Daily cap
50

Figures shown are for this endpoint's minimum tier. Higher tiers raise every limit.

Auth RequiredExplorer+

Registers an HTTPS endpoint to receive event deliveries. The response includes a signing secret; it is shown once and cannot be retrieved later.

POST/v1/me/webhooks

  • stringheaderrequired

    Your API key. Authorization: Bearer <key> is accepted in its place.

  • stringrequired

    Where deliveries are POSTed. A public https hostname on port 443: no IP address, no credentials in the URL, and not a gunspec.io or workers.dev host. Redirects are not followed, so register the final URL. At most 2,048 characters.

  • string[]required

    Event types this endpoint is subscribed to. The full list is on the POST operation.

  • string

    Prose summary of the record, where one has been written.

  • WebhookEndpointCreated

    The response payload

  • string

    Opaque endpoint id. Address it at /v1/me/webhooks/{endpointId}.

  • string

    Absolute, directly fetchable URL.

  • string[]

    Event types this endpoint is subscribed to. The full list is on the POST operation.

  • string | null

    Prose summary of the record, where one has been written.

  • boolean

    False while the endpoint is paused. A paused endpoint receives nothing and is not retried.

  • string

    When the record was first added, YYYY-MM-DD HH:MM:SS in UTC.

  • string

    When the endpoint was last changed, ISO 8601.

  • string

    HMAC signing secret. Returned only here, on creation. No other endpoint will show it again.

  • 400VALIDATION_ERRORValidation error
  • 401UNAUTHORIZEDAPI key required
  • 403FORBIDDENValid key, not permitted
  • 413PAYLOAD_TOO_LARGERequest body too large
  • 429RATE_LIMITEDRate limit exceeded
  • 500INTERNAL_ERRORUnexpected server error

Requires Studio tier or higher.

The URL must be HTTPS. Plain HTTP URLs are rejected.

Supported events: firearm.created, firearm.updated, firearm.deleted, firearm.variant.updated, firearm.source.changed, firearm.confidence.changed, manufacturer.created, manufacturer.updated, manufacturer.deleted, caliber.created, caliber.updated, caliber.deleted, category.created, category.updated, category.deleted, image.created, image.deleted and catalog.resynced.

firearm.variant.updated carries the same payload as firearm.updated and is sent only for records that have a parent, so a family can be tracked without taking the whole catalog's traffic. firearm.source.changed and firearm.confidence.changed say which kind of change it was and arrive alongside firearm.updated.

catalog.resynced replaces a flood: when more records change at once than can be described individually, such as a re-derivation of the whole catalog, one event is sent instead of thousands, and the right response is to re-sync rather than to apply per-record updates. It reaches every endpoint subscribed to any event, ticked or not.

Catalog events carry the record in the same shape GET /v1/firearms/{id} returns it, version included, so a cache can be updated without a second call. A deletion carries the id alone.

Deliveries also carry X-Webhook-Id (the event, stable across retries, so dedupe on it), X-Webhook-Event, and X-Webhook-Delivery (this attempt). A non-2xx response is retried three times, 1, 5 and 15 minutes apart.

The secret is shown only in this create response. It cannot be retrieved later, so store it immediately. Delete and recreate the endpoint to rotate it.

Verify deliveries with the X-Webhook-Signature header. See the Verifying deliveries note on the Test endpoint for the exact scheme.

Minimum tier
Explorer+
Monthly quota
200/mo
Rate limit
10/min
Daily cap
50

Figures shown are for this endpoint's minimum tier. Higher tiers raise every limit.

Auth RequiredExplorer+

Returns one of your webhook endpoints.

GET/v1/me/webhooks/{endpointId}

  • stringheaderrequired

    Your API key. Authorization: Bearer <key> is accepted in its place.

  • stringrequired

    Webhook endpoint id

    Example

  • WebhookEndpoint

    The response payload

  • string

    Opaque endpoint id. Address it at /v1/me/webhooks/{endpointId}.

  • string

    Absolute, directly fetchable URL.

  • string[]

    Event types this endpoint is subscribed to. The full list is on the POST operation.

  • string | null

    Prose summary of the record, where one has been written.

  • boolean

    False while the endpoint is paused. A paused endpoint receives nothing and is not retried.

  • string

    When the record was first added, YYYY-MM-DD HH:MM:SS in UTC.

  • string

    When the endpoint was last changed, ISO 8601.

  • 400VALIDATION_ERRORValidation error
  • 401UNAUTHORIZEDAPI key required
  • 403FORBIDDENValid key, not permitted
  • 404NOT_FOUNDResource not found
  • 429RATE_LIMITEDRate limit exceeded
  • 500INTERNAL_ERRORUnexpected server error

Requires Studio tier or higher.

You can only retrieve webhook endpoints registered to your own API key.

Minimum tier
Explorer+
Monthly quota
200/mo
Rate limit
10/min
Daily cap
50

Figures shown are for this endpoint's minimum tier. Higher tiers raise every limit.

Auth RequiredExplorer+

Updates the URL, subscribed events, description, or active state of one of your endpoints.

PUT/v1/me/webhooks/{endpointId}

  • stringheaderrequired

    Your API key. Authorization: Bearer <key> is accepted in its place.

  • stringrequired

    Webhook endpoint id

    Example

  • string

    Where deliveries are POSTed. A public https hostname on port 443: no IP address, no credentials in the URL, and not a gunspec.io or workers.dev host. Redirects are not followed, so register the final URL. At most 2,048 characters.

  • string[]

    Event types this endpoint is subscribed to. The full list is on the POST operation.

  • string

    Prose summary of the record, where one has been written.

  • boolean

    False while the endpoint is paused. A paused endpoint receives nothing and is not retried.

  • WebhookEndpoint

    The response payload

  • string

    Opaque endpoint id. Address it at /v1/me/webhooks/{endpointId}.

  • string

    Absolute, directly fetchable URL.

  • string[]

    Event types this endpoint is subscribed to. The full list is on the POST operation.

  • string | null

    Prose summary of the record, where one has been written.

  • boolean

    False while the endpoint is paused. A paused endpoint receives nothing and is not retried.

  • string

    When the record was first added, YYYY-MM-DD HH:MM:SS in UTC.

  • string

    When the endpoint was last changed, ISO 8601.

  • 400VALIDATION_ERRORValidation error
  • 401UNAUTHORIZEDAPI key required
  • 403FORBIDDENValid key, not permitted
  • 404NOT_FOUNDResource not found
  • 413PAYLOAD_TOO_LARGERequest body too large
  • 429RATE_LIMITEDRate limit exceeded
  • 500INTERNAL_ERRORUnexpected server error

Requires Studio tier or higher.

Set active: false to pause deliveries without deleting the endpoint configuration.

At least one field (url, events, or active) must be provided.

Minimum tier
Explorer+
Monthly quota
200/mo
Rate limit
10/min
Daily cap
50

Figures shown are for this endpoint's minimum tier. Higher tiers raise every limit.

Auth RequiredExplorer+

Removes a webhook endpoint. Past delivery history is retained.

DELETE/v1/me/webhooks/{endpointId}

  • stringheaderrequired

    Your API key. Authorization: Bearer <key> is accepted in its place.

  • stringrequired

    Webhook endpoint id

    Example

  • object

    The response payload.

  • boolean

    Always true: the endpoint is gone once this returns.

  • string

    Id of the deleted endpoint.

  • 400VALIDATION_ERRORValidation error
  • 401UNAUTHORIZEDAPI key required
  • 403FORBIDDENValid key, not permitted
  • 404NOT_FOUNDResource not found
  • 429RATE_LIMITEDRate limit exceeded
  • 500INTERNAL_ERRORUnexpected server error

Requires Studio tier or higher.

Deletion is permanent and cannot be undone.

In-flight webhook deliveries at the time of deletion may still be attempted once.

Minimum tier
Explorer+
Monthly quota
200/mo
Rate limit
10/min
Daily cap
50

Figures shown are for this endpoint's minimum tier. Higher tiers raise every limit.

Auth RequiredExplorer+

Sends a signed test event to the endpoint so you can verify your receiver and signature check before relying on real events.

POST/v1/me/webhooks/{endpointId}/test

  • stringheaderrequired

    Your API key. Authorization: Bearer <key> is accepted in its place.

  • stringrequired

    Webhook endpoint id

    Example

  • object

    The response payload.

  • boolean

    Whether your endpoint answered with a 2xx.

  • integer | null

    The status your endpoint returned. Null when the request never got a response: DNS failure, timeout, TLS error.

  • string | null

    Why the calculation could not be completed, or null when it succeeded.

  • 400VALIDATION_ERRORValidation error
  • 401UNAUTHORIZEDAPI key required
  • 403FORBIDDENValid key, not permitted
  • 404NOT_FOUNDResource not found
  • 429RATE_LIMITEDRate limit exceeded
  • 500INTERNAL_ERRORUnexpected server error

Requires Studio tier or higher.

The test payload is a synthetic test.ping event and will not affect your application data.

A delivered: false result with status 422 means your server responded but with a non-2xx code.

Connection timeouts after 10 seconds are reported as delivery failures.

Payload envelope: every delivery (test or real) is a JSON body shaped { "id": "evt_...", "type": "firearm.updated", "created_at": "<ISO 8601>", "data": { ... } }. data is the affected record. The request also carries Content-Type: application/json and User-Agent: GunSpec-Webhooks/1.0.

Verifying deliveries: each request includes an X-Webhook-Signature: t=<unix_timestamp>,v1=<hex> header. Recompute v1 as the lowercase hex HMAC-SHA256 of the string t.rawRequestBody (the timestamp, a literal dot, then the raw body) keyed with your endpoint secret, then compare in constant time. Reject the delivery if it does not match, or if t is more than ~5 minutes old (replay protection).

Always hash the raw request body before any JSON parsing or re-serialisation, otherwise the signature will not match.

Delivery and retries: a 2xx response marks the delivery successful. Non-2xx responses and timeouts are retried up to 3 times with a 1m, 5m, 15m backoff, after which the delivery is marked failed.

Minimum tier
Explorer+
Monthly quota
200/mo
Rate limit
10/min
Daily cap
50

Figures shown are for this endpoint's minimum tier. Higher tiers raise every limit.