Givebear LogoGivebear
Connect API

Embedded donations

Mint an embed session from your backend and render a client org's donation form in your product.

Render a connected organization's donation form inside your own product, with the target, amounts, donor prefill, and attribution controlled by your backend. The host page cannot change any of it: everything is pinned to a short-lived session you mint server-side, like Stripe's embedded checkout.

Prerequisites

  • Your app is connected to the organization through OAuth, or you hold the org's API key.
  • The credential has the payments:write scope.

Steps

Mint a session on your backend

Call POST /embed-sessions with your access token. All fields are optional; an empty body renders the org's standard form.

curl -X POST "https://givebear.io/api/v1/embed-sessions" \
  -H "Authorization: Bearer gba_..." \
  -H "Content-Type: application/json" \
  -d '{ "fund_id": "fnd_123", "preset_amounts_cents": [2500, 5000, 10000] }'
import { GivebearConnect } from "@givebear/connect";

const gb = new GivebearConnect({ token: "gba_..." });

const session = await gb.embedSessions.create({
  fund_id: "fnd_123",
  preset_amounts_cents: [2500, 5000, 10000],
  default_amount_cents: 5000,
  donor: { name: "Jane Doe", email: "[email protected]" },
});
import requests

session = requests.post(
    "https://givebear.io/api/v1/embed-sessions",
    headers={"Authorization": "Bearer gba_..."},
    json={"fund_id": "fnd_123", "preset_amounts_cents": [2500, 5000, 10000]},
).json()
<?php
$ch = curl_init("https://givebear.io/api/v1/embed-sessions");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Authorization: Bearer gba_...",
    "Content-Type: application/json",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    "fund_id" => "fnd_123",
    "preset_amounts_cents" => [2500, 5000, 10000],
]));
$session = json_decode(curl_exec($ch), true);
curl_close($ch);
require "net/http"
require "json"

uri = URI("https://givebear.io/api/v1/embed-sessions")
request = Net::HTTP::Post.new(uri)
request["Authorization"] = "Bearer gba_..."
request["Content-Type"] = "application/json"
request.body = {
  fund_id: "fnd_123",
  preset_amounts_cents: [2500, 5000, 10000],
}.to_json

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end
session = JSON.parse(response.body)
body := strings.NewReader(`{
  "fund_id": "fnd_123",
  "preset_amounts_cents": [2500, 5000, 10000]
}`)
req, _ := http.NewRequest("POST", "https://givebear.io/api/v1/embed-sessions", body)
req.Header.Set("Authorization", "Bearer gba_...")
req.Header.Set("Content-Type", "application/json")

resp, err := http.DefaultClient.Do(req)

The response includes session_token (gbes_...) exactly once, plus a ready-to-iframe embed_url and expires_at.

Hand the token to your frontend

Sessions expire after one hour and are reusable until then, so page reloads keep working. Mint a fresh session per checkout view; do not store tokens.

Render the form

<script src="https://givebear.io/sdk/givebear.js" async></script>
<div data-givebear-embed data-session-token="gbes_..."></div>
<div id="gb-checkout"></div>
<script>
  window.Givebear = window.Givebear || function (cb) {
    (window.Givebear.q = window.Givebear.q || []).push(cb);
  };
</script>
<script src="https://givebear.io/sdk/givebear.js" async></script>
<script>
  window.Givebear(function (gb) {
    gb.renderInline("#gb-checkout", { sessionToken: "gbes_..." });
  });
</script>
import { EmbeddedDonation } from "@givebear/react";

<EmbeddedDonation sessionToken={session.session_token} />;

Or iframe the returned embed_url directly.

What a session controls

FieldEffect
fund_id or campaign_idPins where donations go. Must belong to the connected org; pass one, not both.
preset_amounts_cents1 to 6 suggested amounts (each at least 50 cents).
default_amount_centsThe preselected amount.
amounts_lockedHides the custom-amount input; requires preset_amounts_cents.
default_recurringStarts the form on recurring giving.
recurring_lockedHides the one-time/recurring toggle.
donor.name, donor.emailPrefills the donor fields. The donor can still edit them.

Donations made through a session are attributed to your app automatically (app:<client_id>), with no spoofable query parameter involved. Expired or invalid tokens render a friendly "session expired" message inside the frame.

Was this page helpful?

On this page