APIFuseAPIFuseDocs

Getting started

  • Overview
  • Quickstart

Authentication

  • Managed keys
  • Scopes

Errors

  • Error model
  • Retries

Webhooks

  • Overview
  • Signatures

API reference

  • Amazon Japan
  • Baemin Provider
  • Buyee
  • CatchTable Restaurant Search and Reservations
  • Charan Commerce
  • Daangn public listings
  • Daiso Product and Store Data
  • Danawa price comparison
  • Demaecan
  • Ekitan
  • Goodchoice Domestic Lodging
  • Google Flights
  • Han River Water Level
  • Hot Pepper Gourmet provider
  • Hyundai Card
  • Jalan
  • Japan National Diet Minutes
  • Japan Disaster Alerts
  • Japan EDINET Filings
  • Japan e-Gov Law
  • Japan e-Stat
  • Japan GSI Geocoding
  • Japan e-Gov Open Data
  • Japan Post ZIP
  • Japan Public Holidays
  • JMA Weather
  • KakaoMap Place Search and Directions
  • Kakao T Taxi Dispatch
  • Korea Address Search
  • AirKorea Real-time Air Pollution
  • Korea Apartment Rent Prices
  • Korea Apartment Sale Prices
  • Korea Bid Notices
  • Korea Building Register
  • Korea Business Verify
  • Korea Camping
  • Korea DART Corporate Finance
  • DART Corporate Info
  • Korea Culture Events
  • Korea Disaster Alert
  • Korea Emergency Hospital
  • Korea ETF
  • Korea EV Charger
  • Korea Fuel Price
  • Korea Holiday
  • Korea Hospital Info
  • Korea Land Price
  • Korea MFDS Drug Safety
  • Korea MFDS Food Safety
  • Korea Household Waste Disposal Guide
  • Korea National Law Search and Lookup
  • Korea NEIS School Meals
  • Carrier List and Delivery Tracking
  • Korea Pharmacy
  • Korea Population
  • Korea Stock Index
  • Korea Stock Price
  • Korea Train Schedule
  • Korea Weather Forecast Data
  • Korea Weather Forecast
  • Korea Welfare Service
  • K-Startup
  • LH Housing Notices
  • Market Kurly product data
  • Mercari
  • Modu Parking
  • Naver Blog Search
  • Naver Flight API
  • Naver Map
  • Naver News Search
  • NOL Stays
  • Ohouse Store and Contents
  • Rakuten Ichiba
  • Rakuten Travel
  • SEC EDGAR Filings
  • Seoul Bike
  • Seoul Live Crowd Density
  • Seoul Subway Arrivals
  • Shinhan Bank
  • Shinhan Card
  • Skiplagged
  • SUUMO
  • Swing Taxi
  • Tabelog
  • TableCheck
  • Weverse Provider
  • Yahoo! Shopping (Japan)
  • Yogiyo
  • ZOZOTOWN

Guides

  • APIFuse Docs
  • Getting started
  • Authentication and Connections
  • Playground
  • OpenAPI and schemas
  • MCP endpoint
  • Developer MCP guide
  • Schema bundles
  • Next.js App Router integration
  • FastAPI integration
  • Error Handling
  • FAQ
  • Resources

Changelog

  • Changelog
APIFuseAPIFuse
DocsServicesPlaygroundStatus
Log inSign up

Webhooks

Overview

Receive events such as reservation confirmations and delivery updates.

A reservation is not always confirmed at the moment you create it. Create reservation answers confirmed when the venue approves instantly, but it answers pending when the venue must approve, and that decision lands minutes or hours later. Chasing it by polling Get reservation burns calls and still lags behind. Webhooks invert the direction: the moment the state changes, APIFuse sends the event to your registered endpoint.

The same principle runs through the whole catalogue. Delivery orders move through kitchen and courier states, payments approve asynchronously, and a ride keeps updating while the car moves. Every one of these changes arrives as a push, in one envelope shape, signed the same way.

Registering an endpoint

You register a single HTTPS endpoint in the APIFuse console and pick the event types it subscribes to. All subscribed events for the account arrive at that one endpoint, so you branch on the type field in the body instead of registering one URL per service. When registration completes, the console shows the endpoint secret exactly once. It starts with whsec_ and is what you use to verify signatures, so store it in the same secret store as your managed key.

The endpoint secret is displayed once at registration and cannot be read again. If you lose it, issue a new secret in the console and update your verifier.

The event envelope

Every delivery is a POST request with a JSON body, and the body always has the same shape.

A reservation.confirmed event
{
  "id": "evt_01J8QH5R7T",
  "type": "reservation.confirmed",
  "created_at": "2026-09-01T10:15:27Z",
  "data": {
    "object": {
      "id": "rsv_01J8QDGT2K",
      "status": "confirmed",
      "restaurant_id": "res_01J8Q9W3TE",
      "starts_at": "2026-09-02T19:00:00+09:00",
      "party_size": 2
    }
  }
}

data.object has exactly the shape the API returns for the resource. For reservation.confirmed it is the same reservation object that returns, field for field, as documented in the . You never need a second fetch to hydrate an event.

Event names

Event types follow the <domain>.<event> convention. The domain names the resource, not the service, so a reservation.confirmed from Catch Table and one from Tabelog share the same envelope structure. Representative events:

EventFires whenServices
reservation.confirmedThe venue confirms a reservation, tabelog
reservation.cancelledThe venue or the caller cancels a reservation, tabelog
waitlist.calledA queued party is called in
order.updatedA delivery order changes statebaemin
payment.approvedA payment is approvedtoss-pay
ride.updatedA requested ride changes statekakao-t

Delivery, retries and dedupe

  • At-least-once: the same event can arrive more than once. Dedupe on the Frism-Event-Id header, which stays stable across redeliveries.
  • Retries: any non-2xx response, timeouts included, is retried with backoff for 24 hours. It is the same idea as , performed by APIFuse in the other direction.
  • Acknowledge fast: return 2xx before you start real work. A slow handler counts as a timeout and the event is delivered again.
A handler that acknowledges fast and processes later
const seenEventIds = new Set<string>();
const queue: unknown[] = [];

export async function handleFrismEvent(request: Request): Promise<Response> {
  const rawBody = await request.text();
  // 1. Verify the signature first, always. The code lives in the signatures guide.

  // 2. Dedupe on Frism-Event-Id: delivery is at-least-once.
  const eventId = request.headers.get("Frism-Event-Id");
  if (eventId === null) return new Response(null, { status: 400 });
  if (seenEventIds.has(eventId)) return new Response(null, { status: 200 });
  seenEventIds.add(eventId);

  // 3. Enqueue only, then return 2xx right away. A worker does the heavy part.
  queue.push(JSON.parse(rawBody));
  return new Response(null, { status: 200 });
}
The Set in the example lives in process memory and vanishes on restart. In production, record Frism-Event-Id in a persistent store to dedupe.

Save the envelope example above to a file and you can rehearse the handler locally.

Simulate a delivery against a local endpoint
# See the local testing example in the signatures guide for computing a real signature value.
curl -X POST http://localhost:3000/webhooks/frism \
  -H "Content-Type: application/json" \
  -H "Frism-Event-Id: evt_01J8QH5R7T" \
  -H "Frism-Signature: t=1788257727,v2=d7e16839f487db479fa277fb11c2d6139225ea837c672df8a68e0452fd7ea772" \
  --data @reservation-confirmed.json

Next: verify signatures

Everything above rests on the assumption that the request really came from APIFuse. That assumption only holds when you of every payload, so read that guide before you deploy the endpoint. If you need a call that produces your first event, the reservation flow in the is a good fit.

Get reservation
Catch Table reference
catch-table
catch-table
catch-table
client retries
verify the signature
quickstart