- Tools
- Chainhooks
- Migration
Migration guide
Guide for migrating legacy chainhooks to v2
The legacy Platform API and Chainhooks UI have been retired. This guide shows how to convert saved v1 definitions to v2. If you need help recovering a definition or retiring an existing v1 chainhook, contact support.
What you'll learn
Prerequisites
- Hiro API key for the Chainhooks API.
- Saved v1 chainhook definitions, including filters and webhook URLs.
- (optional) If you use TypeScript and Node.js, you can install the Chainhooks client library to easily parse incoming Chainhooks v2 payloads
Gather your v1 definitions
Use your saved configurations or exports to identify the filters, networks, and webhook URLs you want to migrate. If you do not have a copy, contact support before proceeding.
Start mapping to the new v2 format
Translate v1 structures to v2 formats before creating new hooks. The following table shows the mapping between v1 and v2 structures:
| v1 | v2 | Notes |
|---|---|---|
if_this.scope | filters.events[].type | Replace scope/action combos with a single event type. |
if_this.actions | type | transfer maps to *_transfer. |
then_that.http_post.url | action.url | v2 handles secrets automatically. |
networks.mainnet | network: "mainnet" | Create one v2 hook per network. |
authorization_header | Webhook secret management | Use rotateConsumerSecret() after registration. |
Example
{"name": "stx-transfers","networks": {"mainnet": {"if_this": { "scope": "stx_event", "actions": ["transfer"] },"then_that": { "http_post": { "url": "https://example.com/webhooks" } }}}}
For more details on the format changes, see the Filters reference guide.
Create v2 chainhooks
Register each chainhook with the SDK or REST API, mirroring the mapped filters.
const v2Chainhook = {"version": "1","name": "stx-transfers","chain": "stacks","network": "mainnet","filters": {"events": [{ "type": "stx_transfer" }]},"action": {"type": "http_post","url": "https://example.com/webhooks"},"options": {"decode_clarity_values": true,"enable_on_registration": true}};const response = await fetch('https://api.hiro.so/chainhooks/v1/me/', {method: 'POST',headers: {'x-api-key': process.env.HIRO_API_KEY!,'content-type': 'application/json',},body: JSON.stringify(v2Chainhook),});
Validate v2 chainhooks
Confirm that each chainhook is enabled and that your webhook receives the expected events. Update your application to handle the v2 payload format.
Enablement checks on v2
const response = await fetch(`https://api.hiro.so/chainhooks/v1/me/${uuid}`, {method: 'GET',headers: {'x-api-key': process.env.HIRO_API_KEY!,'content-type': 'application/json',},});const chainhook = await response.json();console.log(chainhook.status.enabled);
Filter reference
Common scopes
| v1 | Typical Actions | v2 | Extras |
|---|---|---|---|
stx_event | transfer | stx_transfer | Include sender or recipient filters as needed. |
contract_call | n/a | contract_call | Add contract_identifier and function_name. |
ft_event | transfer | ft_transfer | Specify asset_identifier. |
nft_event | transfer, mint | nft_transfer · nft_mint | Provide asset_identifier. |
For more details, check out the Filters reference page.
Replaying past blocks
Chainhooks v2 does not have the ability to specify a start block in a hook’s configuration for past block scans.
However, you can use the Replay Block API endpoint to request any block replay you need at any time. Once requested, you will receive that block’s information through the same webhook payload endpoint you use for real-time updates within a couple seconds.
This method ensures you have complete control over which blocks you need to replay whenever you need to.