Ironfang · AsyncAPI Specification

Ironfang Webhooks

Version

View Spec View on GitHub Developer ToolsScreenshot APIWebsite ScreenshotHTML-to-PDFPDF APIImage APIOG Image APIQR Code APIWebsite-to-VideoRendering InfrastructureMCPUK-hostedAsyncAPIEvents

AsyncAPI Specification

Raw ↑
generated: '2026-09-02'
method: searched
source: https://ironfang.uk/renderwolf/docs#delivery
docs: https://ironfang.uk/renderwolf/docs#delivery
asyncapi_published: false
asyncapi_note: >-
  Ironfang publishes no AsyncAPI document. /asyncapi.yaml and /asyncapi.json are not served on
  api.ironfang.uk, and the webhooks: block of the OpenAPI 3.1 contract is empty even though the
  contract is 3.1 and could carry them. The event surface below was read from the API
  reference prose and is captured as a webhook catalog, not fabricated as a spec.
transport: HTTPS POST to a customer-registered destination
registration:
  operation: createDestination
  body_example: '{ "type": "webhook", "name": "Production", "url": "https://hooks.example.com/renderwolf" }'
  response: '201 with id and signing_secret (shown exactly once)'
  scope_required: 'renderwolf:destinations'
  types: [webhook, s3]
  binding: >-
    A destination is named by id on a job's or a batch's `delivery` block
    (webhook_destination / storage_destination / storage_key).
security:
  signature_header: Renderwolf-Signature
  algorithm: 'v1=hmac_sha256(signing_secret, timestamp + "." + raw_body) hex'
  verification_rule: >-
    Compute over the raw bytes received, never over a parsed and re-serialised body. Compare in
    constant time.
  timestamp_header: Renderwolf-Timestamp
  timestamp_format: Unix seconds
  replay_protection: Reject a timestamp more than a few minutes old.
  dedupe_header: Renderwolf-Event-Id
  dedupe_rule: Stable across retries of the same delivery - use it to make the handler idempotent.
  secret_rotation: >-
    Not supported. The secret is returned once, stored encrypted, and has no read endpoint; a
    lost secret means creating a new destination.
delivery_semantics:
  guarantee: at-least-once
  retry_ladder: one minute out to a day, with jitter
  honours_retry_after: true (bounded)
  retried_on: [408, 429, '5xx']
  terminal_on: other 4xx - a retry will not help
  auto_disable: after 10 consecutive failures, until re-enabled in the portal
  isolation: >-
    A delivery failure never changes a render. A job that rendered is succeeded whatever the
    receiver did; an unreachable webhook does not spend a render attempt, hold a render slot, or
    turn a successful job into a failed one.
  observability:
    - listDeliveries
    - getDelivery
    - redeliverDelivery
events:
  - name: render.job.succeeded
    description: A durable render job completed successfully.
    payload:
      - the job
      - credits (reserved, charged)
      - 'result: content type, byte size, SHA-256'
      - 'result url: signed, valid 15 minutes from the moment of sending (not from job completion)'
  - name: render.job.failed
    description: A durable render job failed. The reason accompanies the job.
    payload: [the job, credits]
  - name: render.job.cancelled
    description: A durable render job was cancelled cooperatively.
    payload: [the job, credits]
  - name: render.delivery.failed
    description: >-
      A storage delivery gave up. Sent to the webhook destination, naming the storage
      destination and the error - how a customer learns a bucket stopped accepting uploads
      without watching for absent files.
    payload: [destination, error]
storage_delivery:
  type: s3
  compatible_with: [AWS S3, Cloudflare R2, MinIO, Ceph]
  fields: [bucket, region, credentials, endpoint (optional), prefix (optional)]
  key_template:
    default: 'renderwolf/{date}/{job_id}'
    placeholders: ['{job_id}', '{external_id}', '{date} (YYYY/MM/DD)']
    rules: >-
      Fixed text plus those three placeholders only; nothing else is evaluated. A key that would
      climb out of the prefix is refused at job submission rather than silently rewritten.
  integrity: >-
    Uploads are checksummed and verified after writing; an object already present with the same
    checksum is left alone, so a retried delivery is a no-op.
  credential_handling: >-
    Sent once at destination creation and never carried in a job body. Ironfang advises scoping
    the credentials to the given prefix - they only need write there.
  agent_restriction: Storage destinations are registered in the portal, never through an MCP assistant.
x-findings:
  - id: no-asyncapi
    detail: >-
      A real, signed, retrying, four-event webhook surface with documented dedupe and replay
      protection exists with no machine-readable event contract. The OpenAPI is 3.1, so the
      `webhooks:` block would carry it with no new document required.

Work with this as data

Every AsyncAPI spec 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 asyncapi

4 MCP tools reach this
  • find_asyncapisBrowse and filter every AsyncAPI spec in the catalog.
  • 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 AsyncAPI spec
curl "https://apis.io/api/v1/asyncapis/ironfang-webhooks"
All asyncapi
curl "https://apis.io/api/v1/asyncapis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no email required.

A second provider on the same verified email joins the account you already have.