Skip to main content
The donation form’s behavior is configured in the Raise admin UI, but partner integrations can still customize the donor’s path through the form in meaningful ways. Pre-populating donor identity from URL parameters, generating fully personalized hosted pages, overriding designations per-link, and shaping the post-donation experience are all patterns that partner integrations use to lift conversion and produce a smoother donor experience. This recipe covers the four main customization surfaces and the patterns that combine them into typical integration scenarios.

What you can and can’t customize

SurfaceAPI-customizable?Mechanism
Donor identity (pre-population)PartiallyURL parameters on the form’s landing URL; POST /api/Donor/{id}/generate-page for fully personalized pages
Designation defaultsYesprojectOverrideCode on POST /api/Raise/give; URL parameter on the form’s landing URL
Campaign / Segment attributionYesURL parameters; explicit fields on POST /api/Raise/give
Amount defaults / suggested amountsNo (admin UI)Configured per-form in the Raise admin UI
Form fields and validationNo (admin UI)Configured per-form in the Raise admin UI
Branding and stylingNo (admin UI)Configured per-form in the Raise admin UI
Success message / redirect URLNo (admin UI)Configured per-form in the Raise admin UI
UTM and marketing attributionYesStandard UTM URL parameters on the landing URL
The pattern: partner integrations control the donor’s path to the form and the parameters they arrive with, but the form’s actual appearance and validation are admin-team concerns.

Pattern 1: URL parameter pre-population

The simplest customization. Pass donor identity, designation defaults, or attribution data as query parameters on the form’s landing URL. The form reads these on load and pre-fills the relevant fields.
JavaScript
function buildRenewalUrl(donor, formLandingUrl) {
  const params = new URLSearchParams({
    firstName: donor.firstName,
    lastName: donor.lastName,
    email: donor.email,
    amount: donor.lastGiftAmount || 50,        // Suggested amount based on last gift
    utm_source: 'renewal-email',
    utm_campaign: '2025-annual-renewal',
  });
  return `${formLandingUrl}?${params.toString()}`;
}

// In your email templating
const renewalUrl = buildRenewalUrl(donor, 'https://customer.raisedonors.com/donate/general');
await emailService.send({
  to: donor.email,
  template: 'annual-renewal',
  data: { donor, renewalUrl },
});
The donor clicks the link, lands on the form with their identity already filled in, and only needs to confirm the amount and complete payment.
The exact URL parameter names the form accepts depend on the form’s configuration in the Raise admin UI. Common conventions include firstName, lastName, email, amount, and the standard UTM parameters — but the form team controls which parameters are honored and how. Coordinate with the customer’s admin team to confirm the supported parameters for each form.

Designation override

For donors arriving through a specific campaign or appeal, override the form’s default Project designation:
JavaScript
function buildCampaignUrl(formLandingUrl, projectCode) {
  const params = new URLSearchParams({
    projectOverrideCode: projectCode,
  });
  return `${formLandingUrl}?${params.toString()}`;
}

// A "Support the Gotham Outreach" link from a specific appeal email
const supportingUrl = buildCampaignUrl(
  'https://customer.raisedonors.com/donate/general',
  'GOTHAM-OUTREACH'
);
Combined with UTM parameters, this lets the customer track which channels drove which designations.

Segment attribution

The segmentOverrideCode URL parameter sets the segment attribution for the resulting gift:
JavaScript
const params = new URLSearchParams({
  segmentOverrideCode: 'EMAIL-Q1-2025',
  utm_source: 'email',
  utm_medium: 'newsletter',
  utm_campaign: 'q1-appeal',
});
The gift records the segment attribution in gift.segment (visible in the webhook payload and via API queries). Useful for per-channel reporting.

Pattern 2: personalized hosted pages via generate-page

URL parameters are convenient but limited — they expose the donor’s identity in the URL (visible in browser histories, server logs, etc.) and can produce ugly links. For higher-stakes outreach, the POST /api/Donor/{donorId}/generate-page endpoint creates a personalized page tied to the donor by an opaque token.

When to use generate-page over URL parameters

Use generate-page whenUse URL parameters when
Donor identity should not appear in the URLIdentity in the URL is acceptable
You’re sending a payment-update promptFirst-time donor outreach
The link should be donor-specific and not reusableThe link is broadly shareable
You want shorter, cleaner URLsURL ugliness is acceptable
The generate-page approach is the standard pattern for payment-method-update prompts (see Handle Failed Payments: notifying the donor) and for major-donor cultivation messages.

Generating a personalized page

JavaScript
async function generatePersonalizedPage(donorId, raiseToken) {
  const response = await fetch(
    `https://prod-api.raisedonors.com/api/Donor/${donorId}/generate-page`,
    {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${raiseToken}`,
        'Content-Type': 'application/json',
      },
    }
  );

  if (!response.ok) {
    throw new Error(`generate-page failed: ${response.status}`);
  }

  const result = await response.json();
  return result.pageUrl; // The URL to send to the donor
}
The exact request body shape for POST /api/Donor/{donorId}/generate-page is not detailed in the spec (the body schema is empty). The endpoint likely accepts parameters like campaignId or formId to identify which form to personalize. Confirm against the live API before relying on specific request body fields.

Embedding the personalized URL in an email

JavaScript
async function sendPersonalizedRenewalEmail(donor, raiseToken) {
  const pageUrl = await generatePersonalizedPage(donor.id, raiseToken);

  await emailService.send({
    to: donor.email,
    template: 'personalized-renewal',
    data: {
      firstName: donor.firstName,
      lastGiftAmount: donor.lastGiftAmount,
      pageUrl,
    },
  });
}
The donor receives an email like:
Hi Bruce, Last year you gave $250 to our Gotham Outreach Program. Would you renew your support? Renew now Thank you for your generosity.
When the donor clicks the link, they land on a form fully pre-filled with their identity. They confirm the amount and complete payment — typically a much higher conversion rate than a generic “donate now” email.

Pattern 3: explicit fields on POST /api/Raise/give

For integrations that submit donations directly (rather than embedding a form), the DonatePaymentRequest body fields provide the richest customization surface. Any field on the request shapes the resulting Gift record.

Pre-attributed donations

For partner integrations that capture donations through their own UI and submit to Raise, set the attribution fields explicitly:
JavaScript
async function processCustomDonation({ donor, amount, paymentMethodId, source }) {
  return fetch('https://prod-api.raisedonors.com/api/Raise/give', {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.RAISE_API_TOKEN}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      amount,
      paymentMethodId,
      paymentMethodType: 'CreditCard',
      donor,
      segment: source.segment,
      segmentOverrideCode: source.segmentCode,
      motivationCodeId: source.motivationCodeId,
      googleUtmSource: source.utmSource,
      googleUtmCampaign: source.utmCampaign,
      googleUtmMedium: source.utmMedium,
      comments: source.donorComment,
    }),
  }).then((r) => r.json());
}
The resulting Gift carries all of this attribution in its fields — visible in subsequent queries and webhook payloads.

Tribute giving

Donors giving in honor or memory of someone can include tribute information:
JavaScript
const donation = {
  amount: 100.00,
  paymentMethodId: 'tok_abc123',
  paymentMethodType: 'CreditCard',
  donor: { firstName: 'Bruce', lastName: 'Wayne', email: 'bruce@wayne.example' },
  tribute: {
    type: 'memorial',          // Or 'honor' — confirm valid values against live API
    firstName: 'Thomas',
    lastName: 'Wayne',
    notifyName: 'Martha Wayne',
    notifyAddress: { /* ... */ },
    notifyEmail: 'martha@wayne.example',
  },
};
The resulting Gift carries the tribute information in gift.tribute. Useful for memorial giving workflows where the gift’s purpose is to honor someone other than the donor.

Recurring gift setup with custom designation

For recurring schedules created through POST /api/Raise/give with isRecurring: true, the designation applies to each subsequent payment:
JavaScript
const recurringDonation = {
  amount: 25.00,
  paymentMethodId: 'tok_abc123',
  paymentMethodType: 'CreditCard',
  isRecurring: true,
  frequency: 12,                 // Monthly (per working hypothesis)
  donor: { /* ... */ },
  projects: [
    { projectId: 12, amount: 15.00 },   // 60% to Project A
    { projectId: 47, amount: 10.00 },   // 40% to Project B
  ],
};
Every monthly payment produced by this schedule splits the same way — gift.projects[] on each gift mirrors the schedule’s split.

Pattern 4: combining customizations for specific use cases

The four customization surfaces combine into a few common integration scenarios. Each scenario uses two or three of the surfaces.

Major donor cultivation outreach

A high-touch personalized outreach for a previously-large donor:
JavaScript
async function sendMajorDonorCultivation(donor, customerId) {
  const settings = customerSettings[customerId];

  // 1. Generate a personalized page (Pattern 2)
  const pageUrl = await generatePersonalizedPage(donor.id, settings.raiseApiToken);

  // 2. Fetch the donor's giving history for context (Donors page)
  const giftHistory = await fetchDonorGifts(donor.id, settings.raiseApiToken);
  const lastGift = giftHistory[0];

  // 3. Personalize the email with the donor's history
  await emailService.send({
    to: donor.email,
    template: 'major-donor-cultivation',
    data: {
      firstName: donor.firstName,
      lastGiftAmount: lastGift?.formattedAmount,
      lastGiftDate: lastGift?.date,
      totalLifetimeGiving: donor.giftsum,
      pageUrl,
      contactPersonName: settings.majorDonorContactName,
      contactPersonEmail: settings.majorDonorContactEmail,
    },
  });
}
The recipient sees an email with their actual giving history mentioned and a personalized link to give again. Combines pattern 2 (personalized page) with rich personalization data from the donor’s API record.

Multi-channel attribution

Different links for different channels — each producing distinct attribution in the Gift records:
JavaScript
function buildAttributedUrl(formLandingUrl, channel, campaign) {
  const channelConfigs = {
    email: {
      segmentOverrideCode: `EMAIL-${campaign}`,
      utm_source: 'email',
      utm_medium: 'newsletter',
    },
    social: {
      segmentOverrideCode: `SOCIAL-${campaign}`,
      utm_source: 'social',
      utm_medium: 'organic',
    },
    paid: {
      segmentOverrideCode: `PAID-${campaign}`,
      utm_source: 'google',
      utm_medium: 'cpc',
    },
  };

  const params = new URLSearchParams({
    ...channelConfigs[channel],
    utm_campaign: campaign,
  });
  return `${formLandingUrl}?${params}`;
}

// Build channel-specific URLs
const emailUrl = buildAttributedUrl('https://customer.raisedonors.com/donate', 'email', 'q1-2025');
const socialUrl = buildAttributedUrl('https://customer.raisedonors.com/donate', 'social', 'q1-2025');
const paidUrl = buildAttributedUrl('https://customer.raisedonors.com/donate', 'paid', 'q1-2025');
Each URL produces gifts with distinct segment and UTM attribution — visible in per-channel reporting via POST /api/Gift/query.

Pre-filled multi-step flow

A two-step flow where the partner captures donor details first, then redirects to the Raise form for payment:
1

Donor fills out the partner's pre-form

Captures name, email, and intent (one-time vs. recurring). Lets the partner do its own validation and styling.
2

Partner generates the Raise form URL with pre-populated parameters

URL parameters carry the captured details forward into the Raise form.
3

Donor redirects to the Raise form, identity already pre-filled

They only need to enter payment details and confirm the amount.
4

Form submits to Raise, completing the donation

The webhook fires with the captured attribution intact.
JavaScript
// In the partner's pre-form handler
app.post('/start-donation', async (req, res) => {
  const { firstName, lastName, email, amount, recurring } = req.body;

  const formUrl = recurring
    ? customerSettings.recurringFormUrl
    : customerSettings.oneTimeFormUrl;

  const params = new URLSearchParams({
    firstName,
    lastName,
    email,
    amount,
    utm_source: 'partner-preform',
    utm_campaign: 'partner-integration',
  });

  res.redirect(`${formUrl}?${params}`);
});
This pattern is useful when the partner needs to capture additional information beyond what the Raise form supports — for example, a partner-specific source tracking field, or a custom consent step.

Post-donation customization

The post-donation experience is largely admin-UI-configured (success page, redirect URL, etc.). What partner integrations can customize:

Custom thank-you content via webhook

After the donation completes, the webhook fires and the partner integration can send custom thank-you content separate from the form’s built-in success display:
JavaScript
async function handleGiftCreated(customerId, gift) {
  // Send custom thank-you email matching the partner's branding
  await sendCustomThankYou(customerId, gift);

  // Display a custom message in the partner's UI on the donor's next visit
  await flagDonorForCustomMessage(gift.donor.email, {
    message: 'Thank you for your generous gift!',
    expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000),
  });
}
See Post-Donation Thank-You Flows for the complete patterns.

Form return URL customization

The form’s “where to go after success” behavior is configured in the Raise admin UI. The partner integration can request specific redirect URLs from the customer:
Coordinate with the customer’s admin team to set the form’s post-submission redirect to a partner-controlled URL, like https://partner.example.com/thank-you?giftId={giftId}.
Once configured, the partner can render a customized thank-you page when the donor lands there:
JavaScript
app.get('/thank-you', async (req, res) => {
  const giftId = req.query.giftId;

  // Look up the gift for personalization
  const gift = await fetchGift(giftId);

  res.render('custom-thank-you', {
    firstName: gift.donor?.firstName,
    amount: gift.formattedAmount,
    project: gift.projects?.[0]?.projectName,
    nextStepCta: buildNextStepCta(gift),
  });
});
The donor sees a fully partner-branded thank-you page with their gift details — a smoother experience than a generic “Thank you!” message.
The exact mechanism by which the Raise form passes the gift ID to the redirect URL (query parameter, fragment, etc.) is configured per-form in the admin UI and not documented in the API spec. Confirm against the actual form configuration before parsing the URL.

Anti-patterns to avoid

A few customization patterns that look attractive but cause issues:
Anti-patternWhy it’s bad
Iframe-wrapping the form on a custom pageTwo layers of iframes typically break the form’s resize behavior, payment processor integration, and 3DS authentication flows. Use the embed code as-is.
Capturing card details on the partner’s side and submitting via APIPuts the partner in PCI DSS scope. Use Raise’s tokenization.
Hardcoding URL parameter namesThe parameter names depend on the form’s admin-UI configuration. Coordinate with the customer rather than hardcoding.
Storing donor identity in URL parameters across redirectsURL parameters appear in browser histories and server logs. Use the personalized-page endpoint for sensitive flows.
Trying to customize the form’s appearance via partner-side CSSThe form is on Raise’s domain — partner CSS can’t reach into it. Coordinate styling with the customer’s admin team.
The general principle: customize around the form (the donor’s path to it, the post-donation flow) rather than inside it.

Where to go next

Post-Donation Thank-You Flows

The deep dive on customizing what happens after the donation completes.

Embed a Form on a Website

The complete integration recipe that this customization layer fits into.

Process a Donation

The POST /api/Raise/give reference for direct-submission customization.

Recurring Giving Portal

A donor-self-service portal that combines several customization patterns.
Last modified on May 19, 2026