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
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.
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.