API documentation


Welcome to OnlineFundraising REST API documentation.

OnlineFundraising is an API-first approach to offering a one-stop Payment Engine to NGOs. This means that though you may be familiar with OnlineFundraising as a webinterface all functionalities are also available as direct API calls. These pages aim to describe how you may integrate our API with your services.

To the left we have split our entities into what we consider the basic and extended use of our API which you may prefer configuring in our interface.

We recommend that you start by reading through the basic entities to gain an immediate understanding of how the data is structured. Afterwards you should begin by implementing the Contact, Agreement, Payment, and Subscription entity in your project, so you are able to listen for their related webhooks triggered at certain events and handle the data as you please. You may wish to limit your webhook listener to the entities and events relevant for your project.

If you are looking for deprecated API documentation, please visit these:

A quick link to our latest API documentation can be found at:


Get started:
  1. Get an OnlineFundraising Account
    We also offer Sandbox with Test Data and Test Payment Solution. Please contact our offices on +45 3529 4855

  2. Build a Form in OnlineFundraising

  3. Configure a Data Receiver

  4. Get an API key

  5. Good to go


API key and IP address

Create your own API key in OnlineFundraising under Settings providing the IP address you will be connecting from.


Make sure to apply your API key in your HTTP Header:

HTTP Header
Content-Type: application/json; charset=utf-8
Authorization: 5664792646e1f55f959caa7d3729bf79xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

POST, PUT and PATCH requests

HTTP Headers for POST, PUT and PATCH requests must contain a MD5 checksum of request body as Content-MD5 or RequestMD5:

HTTP Header
Content-Type: application/json; charset=utf-8
Authorization: 5664792646e1f55f959caa7d3729bf79xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-MD5: 17959D7C2468EEB218096A63ACD802C4


Across our entities, properties, endpoints, and webhooks we have tried our best to name things as specific as possible to avoid confusion. However you may afterall find the following parlour helpful.

Understanding agents

The agents you will get to know are:




The organisation or company using OnlineFundraising.

Payment Gateway

The Payment Gateway providing Payment Services accessed by OnlineFundraising.


The Payee and/or End User.


The User of OnlineFundraising with optionally different access levels.


OnlineFundraising's automatic Payment Solution.

Understanding entities

The main entities are:




The Payee and/or End User.


Defines what is being paid, how often, from when, and how much.

Payment Method

Defines how payments are charged.


The connection between Agreement, Payment Method, and Contact representing the Contact's engagement of the Agreement.


Describes the individual Payment (single, one-off and recurring).

The relation between the main entities can be described with this diagram:


For old timers you may find an entity missing in the diagram above. We have chosen to deprecate a "Project" entity, which contained various informations on the type of Agreement and Payments, in favor of the following split responsibility:

Deprecated project property

API handling

Donation purpose

Metadata stored on the related DataSet.

Tax deductibility

The Agreement property: "taxDeductable".

Fixation of amount

The Agreement property: "amount" accompanied by properties for quantity and VAT.

Accounting Code

The Agreement property: "purposeAccountingCode" accompanied by the Payment property: "paymentMethodAccountingCode" which combined will help accounting keep track of transactions across purposes and payment methods.

General notes

All API access is over HTTPS, and accessed from:

All data is sent and received as JSON, so please ensure Content-Type: application/json; charset=utf-8 HTTP header is provided.

All entities carry a 128-bit globally unique identifier (GUID), such as: a863d62e-d53b-4651-9b7b-c80792ee1343

All timestamps are returned as yyyy-MM-dd HH:mm:ss Z in Europe/Copenhagen timezone, such as: 2019-12-31 15:59:59 +0100

Amounts use a 0.0 format, decimals separated with a dot. No thousand separator.

You may find the following resources helpful in your work:

  • DAWA - public API providing Danish address verification and sanitation

  • Download of DK post codes - static files

  • CVR API - public API for verification of Danish Business Codes

  • CPR explanation. Please see below for CPR validation and testing

HTTP Status Codes

OnlineFundraising will return the following HTTP Status Codes:

200 - OK


201 - Created

Resource was created as requested.

202 - Accepted

Request will be processed asynchronously.

400 - Bad Request

If request data is invalid.

	"errorCode" : "10001",
	"errorDescription" : "..."

404 - Not Found

If the resource cannot be found.

429 - Too Many Requests

If the resource have been requested too often over a short interval.

501 - Not Implemented

The service is not implemented.

500 - Internal Server Error

Something went really wrong in our end.

For error codes regarding entities, please see: Error and Cancel Codes

Testing with CPR

As your testning progress you may find yourself in need of this set of valid Danish NationalIDs (source sundhed.dk):

Valid Danish NationalIDs (CPR) for testing purposes
You may use these dates combined with any four digits e.g. 0101601234:

CPR validation in JavaScript
//  Validate CPR-nr.
function is_cpr_valid(cpr) {

    var res = cpr.replace(/[^0-9]/ig, "");
    if (res.length !== 10) {
        return false;

    var validDates = ['010160', '010164', '010165', '010166', '010169', '010170', '010180', '010182', '010184', '010185', '010186', '010187', '010188', '010189', '010190', '010192'];

    var value = res.substr(0, 6);

    if (contains(validDates, value)) {
        return true;

    var cpr_arr = res.split('');
    var mul_arr = "4327654321".split('');
    var sum = 0;
    for (var i = 0; i < cpr_arr.length; i++) {
        sum += cpr_arr[i] * mul_arr[i];

    if (sum % 11 === 0) {
        return true;
    } else {
        return false;

    return true;

CPR validation in PHP
//  Validate CPR-nr.
function is_cpr_valid($cpr) {

    $cleaned = preg_replace("/[^0-9]/", "", $cpr);

    if (strlen($cleaned) != 10) {
        return FALSE;

    $valid_dates = Array('010160', '010164', '010165', '010166', '010169', '010170', '010180', '010182', '010184', '010185', '010186', '010187', '010188', '010189', '010190', '010192');

    if (in_array(substr($cleaned, 0, 6), $valid_dates)) {
        return TRUE;

    $cpr_arr = str_split($cleaned, 1);
    $mul_arr = str_split("4327654321", 1);

    $sum = 0;
    for ($i = 0; $i < count($cpr_arr); $i++) {
        $sum += $cpr_arr[$i] * $mul_arr[$i];

    if ($sum % 11 == 0) {
        return TRUE;
    } else {
        return FALSE;


How do I skip a scheduled Payment?

You cannot skip a scheduled Payment directly, but you may send an Inactive request to a Subscription immediately followed by a Restart request containing a scheduleStartDate for the next scheduled Payment.

How do we keep track of UTM parameters?

Metadata such as UTM parameters submitted to OnlineFundraising will be kept in our DataSet.