Reconciliation

Two dedicated reconciliation endpoints let you audit funds allocation records in the ekko Climate API. The impact recon endpoint shows what credits and contributions were delivered per allocation. The profit share recon endpoint shows how the service fee was distributed across your organisation hierarchy.

Both endpoints require a date range, support cursor-based pagination and return reversal records inline.

📘

Prerequisites

You need at least one completed funds allocation before these endpoints return data.

Settlement models

How funds move after a consumer makes a contribution depends on your settlement configuration. There are three models, each determining which party calls POST /v3/funds/allocations and how the service fee and profit share are settled.

Net split settlement

The PSP calls POST /v3/funds/allocations and handles the payment split at settlement. The merchant's settlement amount includes the purchase total minus the contribution, with the organisation hierarchy's profit share already netted in. ekko receives the impact amount plus its share of the service fee. No separate profit share return from ekko is required.

Net split settlement sequence diagram

Gross split settlement

The PSP calls POST /v3/funds/allocations and splits the payment at settlement. The merchant receives the purchase total minus the contribution amount. ekko receives the impact amount plus the full service fee and tax, then returns the organisation hierarchy's profit share in a separate payment.

Gross split settlement sequence diagram

Invoice settlement

The merchant calls POST /v3/funds/allocations after the PSP confirms payment. ekko invoices the merchant at the end of the billing period for the impact amount and service fee, with the organisation hierarchy's profit share credited against the invoice total.

Invoice settlement sequence diagram

Impact reconciliation

Use GET /v3/funds/allocations/impact to retrieve a per-allocation record of what credits and contributions were delivered: which projects received carbon credits, which impact partners received contributions and in what quantities.

For the difference between credits and contributions, see Allocate funds to a project.

Query parameters

dateTimeFrom and dateTimeTo are required. You can narrow results further with three optional filters:

ParameterDescription
consumerReferenceFilter by the consumer reference you passed when creating the quote
impactPartnerIdFilter to records involving a specific impact partner
fundsOrganisationIdFilter to a specific organisation within your hierarchy

Reading the response

Each record in the data array represents one funds allocation. The credits array breaks down carbon credits by project, and the contribution array breaks down contributions by impact partner. Each line item includes the amounts paid and the unit of positive impact delivered (e.g. kgCO2e, bottles).

The allocation-level amounts object mirrors the quote response structure, so you can compare actuals against the original quote using quoteId.

{
  "hasMore": false,
  "data": [
    {
      "fundsAllocationId": "b7e9c4a2-8f31-4d6e-a529-3c7b8e1f0d42",
      "quoteId": "a6711057-1b63-41e0-81c3-24c02c5ef63b",
      "fundsDateTime": "2024-01-15T14:30:00Z",
      "consumerReference": "consumer_123",
      "fundsOrganisationId": "2f6d6b1f-1c6a-4e9a-9c15-7b8a0db1a2c3",
      "fundsOrganisationReference": "MID12345",
      "collectionOrganisationId": "9e1d3a52-0e3d-4a9f-8b6e-1c2d3e4f5a6b",
      "fundsCurrencyCode": "GBP",
      "reversal": false,
      "taxLiability": "platform",
      "amounts": {
        "total": 12.60,
        "impact": 10.00,
        "impactTax": 0.00,
        "serviceFee": 2.00,
        "serviceFeeTax": 0.40
      },
      "merchant": {
        "name": "Blossom & Bloom",
        "mcc": "5992",
        "address": {
          "line1": "Ground floor",
          "line2": "45 Rosewood Avenue",
          "city": "London",
          "state": null,
          "postalCode": "SW1A 1AA",
          "countryCode": "GBR"
        }
      },
      "credits": [
        {
          "impactPartnerId": "250636c2-8702-47c1-9720-7c3f93395790",
          "projectId": "dfa40a8a-8c24-404d-bed9-6bc3ee60b2b6",
          "amounts": {
            "impact": 1.21,
            "impactTax": 0.00,
            "impactTaxRate": 0.00
          },
          "unit": {
            "description": "kgCO2e",
            "quantity": 1000
          }
        }
      ],
      "contribution": [
        {
          "impactPartnerId": "9405545f-a850-4427-ab0d-10b5b734e925",
          "amounts": {
            "impact": 0.34,
            "impactTax": 0.00,
            "impactTaxRate": 0.00
          },
          "unit": {
            "description": "bottles",
            "quantity": 112
          }
        }
      ]
    }
  ]
}

See the List impact recon records endpoint for the full field reference.

Profit share reconciliation

Use GET /v3/funds/allocations/profit-share to retrieve a per-allocation record of how the service fee was distributed across your organisation hierarchy.

Query parameters

dateTimeFrom and dateTimeTo are required. You can optionally filter by fundsOrganisationId to narrow results to a specific organisation in your hierarchy.

Reading the response

Each record contains a profitShareAllocations array with one entry per beneficiary organisation, including ekko. Organisations in the hierarchy may bill in different currencies, so each entry includes billingCurrencyCode and billingCurrencyExchangeRate.

The allocation-level amounts object mirrors the quote response structure, giving you the totals from which shares are distributed. Use quoteId to cross-check against the original quote.

{
  "hasMore": false,
  "data": [
    {
      "fundsAllocationId": "b7e9c4a2-8f31-4d6e-a529-3c7b8e1f0d42",
      "quoteId": "a6711057-1b63-41e0-81c3-24c02c5ef63b",
      "fundsDateTime": "2024-01-15T14:30:00Z",
      "consumerReference": "consumer_123",
      "fundsOrganisationId": "2f6d6b1f-1c6a-4e9a-9c15-7b8a0db1a2c3",
      "fundsOrganisationReference": "MID12345",
      "billingOrganisationId": "9e1d3a52-0e3d-4a9f-8b6e-1c2d3e4f5a6b",
      "fundsCurrencyCode": "GBP",
      "reversal": false,
      "taxLiability": "platform",
      "amounts": {
        "total": 12.60,
        "impact": 10.00,
        "impactTax": 0.00,
        "serviceFee": 2.00,
        "serviceFeeTax": 0.40
      },
      "merchant": {
        "name": "Blossom & Bloom",
        "mcc": "5992"
      },
      "profitShareAllocations": [
        {
          "beneficiaryOrganisationId": "9e1d3a52-0e3d-4a9f-8b6e-1c2d3e4f5a6b",
          "beneficiaryOrganisationReference": "PSP_001",
          "billingCurrencyCode": "USD",
          "billingCurrencyExchangeRate": 1.27,
          "amounts": {
            "profitShare": 0.11,
            "profitShareTax": 0.003,
            "profitShareTaxRate": 0.20
          }
        },
        {
          "beneficiaryOrganisationId": "4ab96e75-6828-5673-c4ed-3d074e77beb7",
          "beneficiaryOrganisationReference": "EKKO",
          "billingCurrencyCode": "GBP",
          "billingCurrencyExchangeRate": 1.00,
          "amounts": {
            "profitShare": 0.22,
            "profitShareTax": 0.006,
            "profitShareTaxRate": 0.20
          }
        }
      ]
    }
  ]
}

See the List profit share recon records endpoint for the full field reference.

Date range

Both endpoints require dateTimeFrom and dateTimeTo as ISO 8601 timestamps. The interval is half-open: dateTimeFrom is inclusive, dateTimeTo is exclusive.

GET /v3/funds/allocations/impact?dateTimeFrom=2024-01-01T00:00:00Z&dateTimeTo=2024-02-01T00:00:00Z
❗️

The API returns a 400 error if dateTimeFrom is missing, dateTimeTo is missing or dateTimeFrom is after dateTimeTo.

Pagination

Both endpoints use cursor-based pagination. Pass startingAfter with the fundsAllocationId of the last record on your current page to retrieve the next page. Pass endingBefore with the fundsAllocationId of the first record to page backwards. Use limit to control page size (1 to 100).

The response includes hasMore. When hasMore is true, take the fundsAllocationId from the last record in data and pass it as startingAfter to fetch the next page.

GET /v3/funds/allocations/impact?dateTimeFrom=2024-01-01T00:00:00Z&dateTimeTo=2024-02-01T00:00:00Z&limit=25&startingAfter=b7e9c4a2-8f31-4d6e-a529-3c7b8e1f0d42

Reversals

When a funds allocation is reversed, the reversal record appears inline in the recon response. Reversal records are identified by reversal: true and all amounts are negated. Use fundsAllocationId to match a reversal to its original allocation.