GiveLinkDocs
API ReferenceDonations

Create Donation

Create a donation and initiate payment processing.

POST /api/donations

Creates a donation record, calculates fees, and returns a Stripe PaymentIntent client secret for completing the payment on the frontend.

The campaign must be in ACTIVE status. The org must have completed Stripe Connect onboarding before donations can be processed.

Request Body

FieldTypeRequiredDefaultDescription
campaignIdstringYesThe ID of the campaign to attribute this donation to
amountintegerYesDonation amount in cents. Minimum 100 ($1.00)
currencystringNo"usd"Three-letter ISO currency code. Currently only "usd" supported
frequencystringYesOne of: "one_time", "monthly", "quarterly", "annual"
paymentMethodstringYesOne of: "card", "ach", "apple_pay", "google_pay"
coverFeesbooleanYesWhether the donor is covering processing and platform fees
donorobjectYesDonor contact information (see below)
dedicationobjectNoOptional tribute dedication (see below)
publicMessagestringNoPublic message shown on donor roll. Max 280 characters
emailOptInbooleanNofalseWhether donor opts in to future emails
customFieldResponsesarrayNoResponses to campaign custom fields
givingLevelIdstringNoID of a pre-configured giving level
ticketCountintegerNoFor events: number of tickets (1-20)
utmSourcestringNoUTM source for attribution. Max 100 chars
utmMediumstringNoUTM medium. Max 100 chars
utmCampaignstringNoUTM campaign. Max 100 chars
referrerUrlstringNoReferring page URL. Max 500 chars

Donor Object

FieldTypeRequiredDefaultDescription
emailstringYesDonor email for receipt delivery and record matching
firstNamestringYesDonor first name
lastNamestringYesDonor last name
anonymousbooleanNofalseHide donor name from public donor roll

Dedication Object

FieldTypeRequiredDescription
typestringYes"in_honor" or "in_memory"
namestringYesName of the person being honored. Max 200 chars
messagestringNoOptional tribute message. Max 500 chars
notifyNamestringNoName of person to notify. Max 200 chars
notifyEmailstringNoEmail to send tribute notification to

Response

donation object

FieldTypeDescription
idstringUnique donation ID
amountCentsintegerDonation amount in cents
statusstringAlways "PENDING" on creation
frequencystring"ONE_TIME", "MONTHLY", "QUARTERLY", or "ANNUAL"

clientSecret (string)

The Stripe PaymentIntent client secret. Pass to Stripe Elements or confirmPayment() on the frontend.

fees object

FieldTypeDescription
donationAmountintegerIntended donation amount in cents
processingFeeintegerStripe processing fee in cents
platformFeeintegerGiveLink platform fee in cents (1%, waived first $25K)
totalChargedintegerTotal charged to donor in cents
netToOrgintegerAmount nonprofit receives in cents

Example

curl -X POST https://givelink-api-production.up.railway.app/api/donations \
  -H "Content-Type: application/json" \
  -d '{
    "campaignId": "clx9876543210",
    "amount": 5000,
    "currency": "usd",
    "frequency": "monthly",
    "paymentMethod": "card",
    "coverFees": true,
    "donor": {
      "email": "jane@example.com",
      "firstName": "Jane",
      "lastName": "Smith",
      "anonymous": false
    },
    "publicMessage": "Happy to support this cause!",
    "emailOptIn": true,
    "utmSource": "email",
    "utmMedium": "newsletter",
    "utmCampaign": "spring-2026"
  }'
{
  "donation": {
    "id": "clx1111111111",
    "amountCents": 5000,
    "status": "PENDING",
    "frequency": "MONTHLY"
  },
  "clientSecret": "pi_1234_secret_5678",
  "fees": {
    "donationAmount": 5000,
    "processingFee": 142,
    "platformFee": 51,
    "totalCharged": 5193,
    "netToOrg": 5000
  }
}

Use the clientSecret with Stripe Elements on the frontend to collect payment details and confirm the PaymentIntent. The donation status remains PENDING until Stripe confirms payment via webhook.

Error Responses

StatusErrorDescription
400Campaign not foundThe campaignId does not exist
400Campaign is not activeThe campaign must be in ACTIVE status
400Minimum donation is $XAmount is below the campaign minimum
400Organization has not completed payment setupStripe Connect onboarding is incomplete
400Sorry, not enough tickets availableEvent is sold out or insufficient capacity
400Validation failedOne or more fields failed schema validation
How is this guide?

On this page