FeelConnect▍
ProductsDocsPricingChangelog
Sign inGet API keys

Search documentation

Fuzzy search across every docs page and section

Platform/Webhooks

Getting started

  • Overview
  • Quickstart
  • Authentication
  • Environments and sandbox
  • Link
  • Going live

API reference

  • Link tokens
  • Institutions
  • Items
  • Accounts
  • Transactions
  • Identity
  • Income
  • Assets
  • Investments
  • Liabilities
  • Recurring
  • Categories
  • AI products

Platform

  • Webhooks
  • Errors
  • Rate limits and quotas
  • SDKs
  • GraphQL
  • MCP and AI agents
  • Changelog
  1. Docs
  2. Platform
  3. Webhooks
PreviousAI productsNextErrors

On this page

  • Delivery format
  • Event types
  • Verifying signatures
  • Retries
  • Testing webhooks
FeelConnect▍

The developer-first financial data platform.

All systems operational

Products

Universal LinkData APIsAI enrichmentPricing

Developers

DocumentationAPI explorerDashboardGet API keys

Company

HomeChangelogfeels.moneySign in

Legal

PrivacyTermsSecurityData processing
© 2026 FeelConnect. All rights reserved./v1 · FC-Version 2026-07-01

Platform

Webhooks

Signed event deliveries: event types, FC-Signature verification in Node, Python, and Go, and the retry schedule.

Webhooks turn polling into events: FeelConnect POSTs signed JSON to your endpoint when something happens — new transactions, item errors, usage warnings. Configure endpoints per application in Dashboard → Webhooks; each endpoint gets a signing secret (whsec_…, shown once) and a subscribed event list (* for all).

Delivery format

Every delivery is POST with a JSON body and three headers:

HeaderContents
FC-Webhook-IdUnique delivery id — dedupe on it.
FC-TimestampUnix time in seconds at signing.
FC-Signaturev1= + lowercase hex of HMAC-SHA256(secret, timestamp + "." + rawBody).
Event body
{
"id": "evt_4tW7xQkV9nB2mZ5cRj8f",
"type": "transactions.sync_updates_available",
"created": 1753689601,
"environment": "test",
"data": {
"item_id": "item_7dJ3nWqZ5xC9vK1mTf4g"
}
}

Event types

TypeFires whendata
link.session_finishedA Link session ends (success or exit).link_session_id, status
item.connectedA new item connects successfully.item_id, institution_id
item.errorAn item enters login_required or error.item_id, error.code, error.message
item.removedAn item is removed via API or dashboard.item_id
transactions.initial_updateFirst transaction history for a new item is ready.item_id, new_transactions
transactions.sync_updates_availableNew changes are waiting — call /transactions/sync.item_id
recurring.updatedRecurring streams changed for an item.item_id
holdings.updatedInvestment holdings changed for an item.item_id
usage.limit_approachingYour app hits 80% of a monthly quota.metric, used, limit

Verifying signatures

Verify before parsing, using the raw request body — re-serialized JSON will not match. Reject deliveries whose timestamp is more than 300 seconds old (replay protection), and compare signatures in constant time. Every SDK ships a helper:

import { verifyWebhook } from "@feelconnect/node";
// Next.js route handler — read the RAW body
export async function POST(req: Request) {
const rawBody = await req.text();
let event;
try {
event = verifyWebhook({
rawBody,
signatureHeader: req.headers.get("FC-Signature"),
timestampHeader: req.headers.get("FC-Timestamp"),
secret: process.env.FEELCONNECT_WEBHOOK_SECRET!, // whsec_…
});
} catch {
return new Response("invalid signature", { status: 400 });
}
if (event.type === "transactions.sync_updates_available") {
await enqueueSync(event.data.item_id as string);
}
return new Response("ok"); // 2xx fast; do real work async
}

Retries

A delivery succeeds on any 2xx within 10 seconds. Anything else — timeouts, 4xx, 5xx — is retried with backoff, up to 5 attempts total:

AttemptDelay after previous failure
1immediate
21 minute
35 minutes
430 minutes
52 hours
  • Deliveries and their outcomes are visible per endpoint in Dashboard → Webhooks, including response codes and truncated bodies.
  • Handlers must be idempotent — retries and at-least-once delivery mean duplicates happen. Dedupe on the event id or FC-Webhook-Id header.
  • Return 2xx quickly and process asynchronously; slow handlers get cut off at 10 seconds and retried.
  • Events are not guaranteed to arrive in order. Use the created timestamp when ordering matters.

Testing webhooks

In the test environment, fire any event type on demand with POST /v1/sandbox/fire_webhook. For local development, point your endpoint at a tunnel (for example cloudflared or ngrok) and use the dashboard's delivery log to replay failures.