Givebear LogoGivebear
Connect API

Build a Connect integration

Walk through a complete example: connect an org with OAuth, read its donations, and receive webhooks.

This walks through a complete Connect integration end to end, the way a CRM or church tool would build it: a "Connect with Givebear" button that runs OAuth, a dashboard that reads the connected org's donations, and a live webhook feed. It uses the @givebear/connect client for every call.

The snippets here are TypeScript because the example repo is a Next.js app. Building in another language? The same flow is plain HTTP: authentication and webhooks show every call in curl, Python, PHP, Ruby, and Go.

This example lives in its own repo you can fork and run end to end:

Prefer a single call with no setup? The quickstart has a paste-and-run snippet.

1. Connect an organization with OAuth

Register an OAuth app under Dashboard -> OAuth apps in your personal dashboard, then add a "Connect with Givebear" button. The flow is: send the admin to /api/auth/oauth2/authorize, they approve the scopes for one organization, and you exchange the returned code for an access token. See authentication for the full flow and the scopes to request (donations:read, reference:read, webhooks:write for this example).

Bind a client to the org's token once you have it:

lib/givebear.ts
import { GivebearConnect } from "@givebear/connect";

/** A Connect client bound to the session's access token. */
export function givebear(token: string) {
  return new GivebearConnect({ token });
}

2. Read the connected org's data

With the client, list the organization and its donations. Every credential is scoped to one org, so there is no org id to pass.

app/dashboard/page.tsx
const gb = givebear(session.token);
const org = await gb.organization.get();
const { data: donations } = await gb.donations.list({ limit: 25 });

Use donations.listAll() to walk every page automatically. See the API reference for every endpoint.

3. Receive webhooks

Register an endpoint with the client, then verify every delivery with verifyWebhook. The signing secret is returned once, on creation.

register the endpoint
const endpoint = await gb.webhooks.create({
  url: "https://your-app.example.com/api/webhooks",
  events: ["donation.created"],
});
// Store endpoint.secret now: it is shown only once.
app/api/webhooks/route.ts
import { verifyWebhook, WebhookVerificationError } from "@givebear/connect";

export async function POST(req: Request) {
  const body = await req.text();
  try {
    const event = await verifyWebhook({
      secret,
      signature: req.headers.get("x-givebear-signature") ?? "",
      body,
    });
    // event.data.id resolves via the read API, e.g. gb.donations.get(event.data.id)
    return new Response("ok");
  } catch (err) {
    if (err instanceof WebhookVerificationError) {
      return new Response("Invalid signature", { status: 400 });
    }
    throw err;
  }
}

See webhooks for the full event catalog and delivery behavior.

Test webhooks locally

Givebear must reach your app to deliver events, so expose your local server with a tunnel (cloudflared tunnel --url http://localhost:3000 or ngrok http 3000), point the endpoint URL at the tunnel, then make a test donation and watch the event arrive.

Next steps

Was this page helpful?

On this page