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

Authentication

Scopes

Scopes define which services and APIs a key may call.

A managed key defaults to full scope, meaning it may read and write every service in the catalogue. Scopes narrow that surface per key, so a leaked or misused key can never do more than you granted it.

Scope format

A scope is <providerId>:read or <providerId>:write. The <providerId> part is the service id, matching the first path segment in the API reference, for example catch-table or baemin. You set scopes when issuing a key, and one key can combine several. The read and write split follows the HTTP method: GET is read, and mutating calls such as POST and DELETE are write.

  • <providerId>:read allows the service's read APIs.
  • <providerId>:write allows the mutating APIs and implies read for the same service. A key with only write can still look things up.
  • *:read is the only wildcard. It allows reads on every service, current and future, and never allows a write. There is no write wildcard.
  • A key with no scopes set carries full scope: read and write on every service.

Example scope sets

Scope setAllowsDenies
catch-table:readCatch Table reads such as Search restaurants and Get availabilityCatch Table writes and every other service
catch-table:writeAll of Catch Table, including Create reservation, since write implies readEvery other service
*:readReads on every serviceEvery write
*:read, catch-table:writeReads everywhere plus Catch Table writesWrites on any other service
(none set)Full scope: reads and writes on every serviceNothing

Reacting to scope_denied

When a key calls outside its scopes, the gateway answers 403 before anything reaches the service. The error envelope carries code scope_denied and retryable is false, so retrying the same request with the same key never changes the outcome. The response has no provider field because this error originates at the gateway, not at a service.

A write attempted with a read only key
# This key only carries catch-table:read.
curl -X POST "https://api.frism.dev/v1/catch-table/reservations" \
  -H "Authorization: Bearer frism_test_k3xample" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: idem_b1f7c2d0" \
  -d '{
    "restaurant_id": "res_01J8Q9W3TE",
    "slot_id": "slt_1900_2",
    "party_size": 2,
    "contact_name": "Han Jiwoo"
  }'
403 response
{
  "error": {
    "code": "scope_denied",
    "message": "This key does not carry catch-table:write.",
    "request_id": "req_01J8QGX2M4",
    "retryable": false
  }
}

Treat scope_denied as a configuration bug, not a runtime condition. Log the request_id, then fix either the key's scopes or the code path. Always branch on error.code; never parse the message.

Branching on the envelope code
const response = await fetch(
  "https://api.frism.dev/v1/catch-table/reservations",
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.FRISM_API_KEY}`,
      "Content-Type": "application/json",
      "Idempotency-Key": "idem_b1f7c2d0",
    },
    body: JSON.stringify({
      restaurant_id: "res_01J8Q9W3TE",
      slot_id: "slt_1900_2",
      party_size: 2,
      contact_name: "Han Jiwoo",
    }),
  },
);

if (!response.ok) {
  const { error } = await response.json();
  if (error.code === "scope_denied") {
    // Configuration problem: check the key's scopes instead of retrying.
    throw new Error(`Missing scope for catch-table (${error.request_id})`);
  }
  throw new Error(`${error.code}: ${error.message}`);
}

const reservation = await response.json();

Least privilege in production

In the sandbox a full scope key is fine for experiments. On a live key, the blast radius of a leak is exactly the scope you granted. Before going live, apply the following.

  • Issue one key per workload, scoped to exactly the services that workload calls. A reporting job fits *:read; a booking backend fits catch-table:write.
  • Grant only read until a code path actually mutates something. Adding write later is a dashboard change plus a , not a code change.
  • When a service moves from beta to available, check the and review your keys' scopes again.
Scopes gate services and APIs; they do not filter response fields. A read scoped key receives the same payloads a full scope key does.

The service ids used in scopes appear in each service's API reference, for example . The 403 mapping and every other status code live in the .

key rotation
changelog
Catch Table
error model