Introduction
Give A Little provides Point of Donation (POD) software for charitable organisations, enabling quick and cost-effective acceptance of digital payments.
It's very early days for our developer interface however functionality exposed to 3rd parties is growing and if there are specific things you are wanting to achieve with your own integrations please do feel free to get in touch with us at hello@givealittle.co.
Service URLs
Depending on what you are doing you will interact with either our website, or our API. Generally, if you are interacting with us programmatically you will connect to the API, if your user needs to visit our site, you will interact with the website.
Test
Website: https://test-givealittle.cyb.dev
API: https://api.test-givealittle.cyb.dev
Production
Website: https://givealittle.co
API: https://api.givealittle.co
For Platforms with a custom domain you will use your custom domain as the 'Website' service URL
Testing
When testing, use our test system (see Service URLs). You can sign up for an account in test just as you would in production. You will still need to go through verification, but there's no need to upload evidence - just make sure you provide an email address we can contact you on.
Test payments
If you are using Stripe for payment processing, donations made on our test site will automatically be done in test mode. You can find Stripe test card details at https://stripe.com/docs/testing#cards.
If you are using SumUp you will need to request a test account from SumUp that you can then connect with your test Give A Little account. You can contact SumUp at support@sumup.com.
Web Donations
To enable you to create your own donation pages and widgets we expose two endpoints, one for retrieving web campaign configuration and another for initiating a web donation.
Retrieve Web Campaign configuration
Retrieving Web Campaign configuration is done via our REST API.
For a campaign to be available through the API it must be a web campaign (i.e. not an app campaign) and also be published. Campaigns can be published in the admin site.
Service: API
URL: /webdonations/campaigns/{campaignId}
Method: GET
Auth required: No
Request parameters:
campaignIdThe ID of the campaign to retrieve the configuration of
campaignIdcan be found either in the admin console or via a Platform's onboarding flow.
Successful response
Code: 200
Example payload:
{
"currency": "GBP",
"version": 3,
"charityName": "Example Charity",
"showCustomAmount": false,
"allowRecurring": true,
"heading": "Children's Cancer Trust UK",
"primaryColour": "#000000",
"accentColour": "#e70808",
"background": "https://test-givealittle.cyb.dev/files/abc-123/childrens-cancer-trust-mockup.jpg",
"buttonAlignment": "bottom",
"items": [
{
"amount": 3.0
},
{
"amount": 5.0
},
{
"amount": 10.0
}
],
"message": "Helping the next generation fight cancer.",
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"type": "webBackground"
}Response properties:
- currency: The ISO currency code this charity accepts donations in
- version: A number that is incremented when a campaign changes
- charityName: The name of the charity whose campaign this is
- showCustomAmount:
trueif a donor is allowed to donate an amount not specified initems,falseotherwise - allowRecurring:
trueif a donor is allowed to set up a monthly recurring donation,falseotherwise - heading: A heading message to display to donors
- primaryColour: A hex colour, used as the predominant colour of the campaign
- accentColour: A hex colour, used as the accent colour of the campaign
- background: The URL of an image to use as the background of the campaign
- banner: The URL of an image to use as the banner of the campaign
- imageSize: A hint as to how to size an image, can be one of 'cover', 'contain' or 'auto'
- buttonAlignment: A hint as to how to align any buttons, can be one of 'top', 'middle', 'bottom'
- items: An array of objects defining the donation amounts to offer. This will contain up to 6 amounts.
- message: A message to display to donors
- id: A unique identifier for this campaign, this will be the same as used in the request
- type: One of 'webBasic', 'webBanner' or 'webBackground'. These are templates chosen within Give A Little, the response body may be slightly different for each.
Error responses
- Code: 404
Reason: No campaign was found with the provided ID. This could mean the ID is wrong, or that the campaign has not been published. - Code: 500
Reason: There was an internal error in the API.
Initiate a Web Donation
A Web Donation is initiated by redirecting a donor to the Give A Little website along with some parameters describing what the donor is wanting to do.
Service: Website
URL: /{campaignId}/initiate-donation?amount=&recurring=&returnUrl=&tag=
Method: GET
Auth required: No
Request parameters:
campaignIdThe ID of the campaign to retrieve the configuration ofamountThe donation amount a donor has chosenrecurringWhether the donor has chosen to give every monthreturnUrlThe URL to return the donor to at the end of the donation flowtagA tag to set on the donation that will display in reporting and be passed back in webhook events. Can be up to 36 characters long.
Successful response
When successful, this call will redirect the donor to the payment form. The flow will continue based on the Web
Campaign's configuration until the donor gets to the Thank You page. Here, if included in the original request the donor
will have the chance to return to the returnUrl.
Error responses
- Code: 404
Reason: No campaign was found with the provided ID. This could mean the ID is wrong, or that the campaign has not been published. - Code: 500
Reason: There was an internal error in the API.
Platforms
If you have a website where you would like to host a full donation flow on behalf of your users you can register with us as a platform. As a platform you are able to set up a quick onboarding flow, enabling your users to link their Give A Little account with your service and automatically publish a template web campaign.
Features
- Initiate a registration flow to link your users with Give A Little and publish a campaign
- Host campaign pages on your own URL, e.g. https://giving.{yourdomain} (requires CNAME setup)
- Receive reporting on donations made to your users
Get started
To get started with this, please get in touch with us at hello@givealittle.co.
Webhooks
Webhooks are a way for you to receive events when things happen within Give A Little that you might be interested in.
Getting started
While we are building this functionality the setup for an event hook is hidden. When you would like a hook added please get in touch with as at hello@givealittle.co.
Receiving events
To begin receiving events you will need a target configured, e.g. https://example.org/events/2022-11-22.
Versioning
We recommend including the API version in your target's path to help with migrating to new versions when they are
available. You'll note above the example https target's URL is https://example.org/events/2022-11-22, where
'2022-11-22' is the API version it is expecting.
Targets
To configure a target you will need to provide an endpoint that accepts a POST and returns a 2XX response code when a request has been successful.
Each request to this endpoint will include a header, GiveALittle-Signature, containing a timestamp and HMAC-SHA512
signature. We will provide you with a shared secret that can be used to verify these signatures. The header
value will look something like:
t=1669272921,v1=107bb0e4b33378583863f02418e63bebb1addd16008a6485f234fae910ad2f82552593a08d7e9b5d51b565f6e821c8cad4c37f121db9adb008b1c4e627d5b58In this line, t= denotes the timestamp in seconds since the epoch. v1= denotes the signature.
To verify this signature you will need to generate the HMAC-SHA512 hash of the timestamp and the event data concatenated
together, e.g. {timestamp}.{event} using the shared secret we provide you. This data should be combined exactly as
received to ensure that the calculated signature matches the provided signature.
import com.google.common.hash.Hashing;
import java.nio.charset.StandardCharsets;
String payload = String.format("%d.%s", timestamp, data);
String signature = Hashing
.hmacSha512(secret.getBytes(StandardCharsets.UTF_8))
.newHasher()
.putString(payload, StandardCharsets.UTF_8)
.hash()
.toString();Order of events
We attempt to send events in the order that they happened. This is not always possible, for example if there is an error sending an event it will be retried but another event may occur and be successfully sent in the meantime.
Events
All events will have a type and a timestamp. The type tells you what event you've received and the timestamp when
the event was dispatched.
email-address-added
This is sent when a donor adds their email address.
{
"type": "email-address-added",
"timestamp": "2022-12-05T00:02:28.779440Z",
"donor": {
"id": "d917a5fa-ac22-4d7a-8880-ca8438b9cddc",
"emailAddress": "gal@example.org"
}
}donor.id: The unique identifier of the donor
donor.emailAddress: The email address of the donor
marketing-consent-given
This is sent when a donor gives marketing consent.
{
"type": "marketing-consent-given",
"timestamp": "2022-12-05T00:02:28.779440Z",
"donor": {
"id": "d917a5fa-ac22-4d7a-8880-ca8438b9cddc"
},
"email": true,
"phone": false,
"post": false
}donor.id: The unique identifier of the donor
email: Whether consent was given for email contact
phone: Whether consent was given for phone contact
post: Whether consent was given for postal contact
marketing-consent-revoked
This is sent when a donor revokes marketing consent.
{
"type": "marketing-consent-revoked",
"timestamp": "2022-12-05T00:02:28.779440Z",
"donor": {
"id": "d917a5fa-ac22-4d7a-8880-ca8438b9cddc"
}
}donor.id: The unique identifier of the donor
phone-number-added
This is sent when a donor adds their phone number.
{
"type": "phone-number-added",
"timestamp": "2022-12-05T00:02:28.779440Z",
"donor": {
"id": "d917a5fa-ac22-4d7a-8880-ca8438b9cddc",
"phoneNumber": "02212345678"
}
}donor.id: The unique identifier of the donor
donor.phoneNumber: The phone number of the donor
tax-scheme-joined
This is sent when a donor joins a tax scheme, for example Gift Aid.
{
"type": "tax-scheme-joined",
"timestamp": "2022-12-05T00:02:28.779440Z",
"donor": {
"id": "d917a5fa-ac22-4d7a-8880-ca8438b9cddc",
"firstName": "T",
"lastName": "Hawkins",
"address": {
"line1": "1 Phipp St",
"postcode": "EC2A 4DS"
}
},
"declaration": {
"createdAt": "2022-12-05T00:01:12.012320Z",
"type": "GIFT_AID",
"text": "I would like to ...",
"applyToPast": true,
"applyToFuture": true
}
}donor.id: The unique identifier of the donor who made this declaration
donor.firstName: The donor's first name
donor.lastName: The donor's last name
donor.address.line1: The first line of the donor's address
donor.address.postcode: The postcode of the donor's address
declaration.createdAt: When the declaration was made
declaration.type: The type of declaration, this will be consistent with the tax scheme in the country you operate in
declaration.text: The text of the declaration
declaration.applyToPast: Whether or not this declaration can be applied to historic donations this donor made
declaration.applyToFuture: Whether or not this declaration can be automatically applied to any future donations this donor makes
tax-scheme-left
This is sent when a donor leaves a tax scheme.
{
"type": "tax-scheme-left",
"timestamp": "2022-12-05T00:02:28.779440Z",
"donor": {
"id": "d917a5fa-ac22-4d7a-8880-ca8438b9cddc"
}
}donor.id: The unique identifier of the donor
transaction-created
This is sent when a donation payment has been made and verified. It is only sent for successful donations (payments or deposits); transactions that fail, are pending, or are not donations do not trigger this event.
{
"type": "transaction-created",
"timestamp": "2022-12-05T00:02:28.779440Z",
"transaction": {
"id": "150ba915-a845-488f-b999-67312efbbe13",
"amount": 2.0,
"tag": "abc",
"timestamp": "2022-12-05T00:02:24Z"
},
"donor": {
"id": "d917a5fa-ac22-4d7a-8880-ca8438b9cddc"
},
"campaign": {
"id": "00000000-0000-0000-0000-000000000001",
"name": "Web Basic"
}
}transaction.id: The unique identifier of the transaction
transaction.amount: The total amount of the transaction
transaction.tag: If a tag was set when initiating this donation it will be passed back here
transaction.timestamp: The time the transaction was made, this will be different to the timestamp of the event
donor.id: The unique identifier of the donor who made this transaction
campaign.id: The unique identifier of the campaign this transaction was made to
campaign.name: The name of the campaign this transaction was made to
The donor object is omitted entirely when the transaction has no identified donor, for example a cash deposit
recorded without a donor attached.
donors-merged
This is sent when a donor record is merged with another donor record. Records may be merged when an anonymous donor adds an email address that matches another email address in the system.
{
"type": "donors-merged",
"timestamp": "2022-12-05T00:02:28.779440Z",
"donorId": "d917a5fa-ac22-4d7a-8880-ca8438b9cddc",
"mergedId": "a9799e3e-d693-4bd2-92fd-b5b6ed3bf492"
}donorId: The unique identifier of the primary donor record that was matched with another record
mergedId: The unique identifier of the donor record that was merged into the primary donor record
Public API
The Public API gives you read-only, programmatic access to the transaction data recorded against your account.
Getting started
Create an API key in the Give A Little admin portal under Account → Integrations → Developers → Public API. Enable the Public API, then create a key and give it a name describing what it is for.
The key is shown to you once, at the moment you create it. We store only a hash of it, so we cannot show it to you again or recover it for you. Copy it somewhere safe. If you lose a key, revoke it and create another.
Treat a key like a password. Anyone holding it can read your donation data.
Authentication
Send your key as a bearer token on every request:
curl https://api.givealittle.co/2026-09-02/transactions \
-H "Authorization: Bearer gal_sk_..."A missing, unrecognised, or revoked key is rejected with a 401.
Your key determines which account's data you see. There is no parameter to select an account.
Versioning
The first path segment of every request is an API version, expressed as a date:
https://api.givealittle.co/2026-09-02/transactions| Version | Status |
|---|---|
2026-09-02 |
Current |
Dates are used rather than v1, v2 so it is clear how old an integration is, and so several versions can run
side by side. Pin the version you built against — the shape of a published version will not change beneath you.
When a new version ships, the older one keeps working and you can migrate when it suits you.
Requesting a version that does not exist returns 404:
{
"error": "unknown_version",
"message": "Unknown API version '2020-01-01'. Supported versions: 2026-09-02."
}Transactions
URL: /{version}/transactions
Method: GET
Returns your transactions, most recent first. Only successful donations appear — payments that failed or are still pending are never included.
Query parameters
| Parameter | Required | Description |
|---|---|---|
from |
No | ISO-8601 instant. Only transactions at or after this time. |
to |
No | ISO-8601 instant. Only transactions before this time. |
campaignId |
No | Only transactions for this campaign. |
includeTest |
No | Include test transactions. Defaults to false. |
limit |
No | Results per page, 1–200. Defaults to 50. |
cursor |
No | Continues from a previous response's nextCursor. |
Response
{
"data": [
{
"id": "150ba915-a845-488f-b999-67312efbbe13",
"code": "A1B2C3",
"amount": 2.0,
"currency": "GBP",
"timestamp": "2026-01-15T12:00:00Z",
"channel": "WEB",
"paymentType": "card",
"entryMode": "contactless",
"deviceName": "Reader 1",
"campaign": {
"id": "00000000-0000-0000-0000-000000000001",
"name": "Web Basic"
},
"donor": {
"id": "d917a5fa-ac22-4d7a-8880-ca8438b9cddc"
},
"test": false,
"offline": false
}
],
"nextCursor": "MTc2ODQ3NTIwMDAwMDo..."
}| Field | Description |
|---|---|
id |
Unique transaction identifier |
code |
Transaction reference |
amount |
Donation amount |
currency |
ISO currency code |
timestamp |
When the donation was made, in UTC |
channel |
Where the donation came from |
paymentType |
Payment method used |
entryMode |
How the payment was presented, for in-person donations |
deviceName |
The device that took the donation, where there was one |
campaign |
The campaign the donation was made to. Omitted when there is none. |
donor |
The donor, matching the donor.id used by webhooks. Omitted when the donation has no identified donor. |
test |
Whether this is a test transaction |
offline |
Whether the donation was taken offline |
These field names match the transaction-created webhook payload, so the same handling works for both.
Pagination
Follow nextCursor until it comes back null:
curl "https://api.givealittle.co/2026-09-02/transactions?limit=100&cursor=MTc2ODQ3NTIwMDAwMDo..." \
-H "Authorization: Bearer gal_sk_..."Do not construct cursors yourself — treat them as opaque. We use cursors rather than page numbers because donations arrive continuously, and a page number would cause you to miss or repeat transactions while you page through them.
Responses do not include a total count.
A single transaction
URL: /{version}/transactions/{transactionId}
Method: GET
Returns one transaction in the same shape as above, or 404 if no such transaction belongs to your account.
Errors
| Status | Meaning |
|---|---|
400 |
A parameter was missing or malformed. The response body explains which. |
401 |
The API key was missing, unrecognised, or revoked. |
404 |
Unknown API version, or no such transaction for your account. |
429 |
You have exceeded the rate limit. The Retry-After header says how long to wait. |
500 |
Something went wrong at our end. |
Errors are returned as JSON:
{
"error": "bad_request",
"message": "'from' must be an ISO-8601 instant, for example 2026-01-31T00:00:00Z."
}Rate limits
Requests are limited to 120 per minute per API key. Exceeding that returns 429 Too Many Requests with a
Retry-After header giving the number of seconds to wait.
If you are exporting a large amount of data, page through it steadily rather than in parallel. Contact hello@givealittle.co if you need a higher limit.
Revoking a key
Revoke a key in the admin portal under Account → Integrations → Developers → Public API. Revocation can take up to a minute to take effect across all our servers.