UK company data & identity

Building a Charity Lookup Tool with the Charity Commission API

Use the register to resolve a public charity record—not to make an eligibility, identity or authority decision it cannot support.

Guide cover: building a charity lookup tool with the Charity Commission API
By Ritesh Agarwal14 min read

Direct answer

Build an England and Wales charity lookup as a server-side registry adapter. Ask for jurisdiction first; prefer an exact registered-number lookup; preserve the registered number, group or subsidiary suffix and unique organisation number; show the recorded status and retrieval time; and require the user to confirm the selected record. Treat name results as candidates, removed records as review events and API failure as an operational state—not as evidence that an organisation is not charitable. The result proves only what the public register says. Identity, authority, bank ownership, programme eligibility and due diligence remain separate checks.

ResolveFind the right recordJurisdiction and stable identifiers come before a fuzzy name.
PreserveStore provenanceKeep the source, status, suffix, organisation number and retrieval time.
BoundSeparate the decisionA register match is not authority, eligibility, KYC or safeguarding.

Executive summary

  1. The Charity Commission API is for England and Wales, not a complete UK-wide charity source.
  2. A registered charity number can represent linked records; preserve the suffix and unique organisation number.
  3. “Not found” is inconclusive because other jurisdictions, exempt, excepted and small unregistered charities exist.
  4. Keep the API key server-side, cache carefully, retain provenance and provide a manual path during outages or ambiguity.

A real charity integration where the prototype changed the quote

Appycodes worked on a scoping engagement for a UK registered charity ahead of an invitation to tender. The work included a technical specification, a vendor-evaluation tool and a CRM recommendation. Instead of estimating the integration from sales documentation, the team built a working CRM-to-website prototype and exercised the flow end to end.

The prototype exposed three constraints that would have materially affected a fixed-price commitment: trial accounts did not provide API keys, payments used a connected-account model that could not be tested without live credentials, and the vendor offered a sandbox only on its highest plan. The hard decision was to spend delivery effort before bidding so the estimate described what could actually be proved, rather than assuming every vendor surface behaved like a conventional test API.

That project did not use the Charity Commission API, and we do not imply that it did. It provides the implementation lesson behind this guide: a public-register lookup is one bounded component in a charity product. It does not remove the need to prototype the CRM, payment, consent, eligibility and operational paths that sit around it. The verified, anonymised project summary is published in the Appycodes case-study register.

Evidence boundary. Repository-backed Appycodes case-study records verify the UK charity, the prototype-first decision and the three vendor constraints. They do not verify use of the Charity Commission API, a production launch, measured savings or a final procurement outcome. No client identity, credentials, commercial terms or private system details are published here.

What the Charity Commission API can—and cannot—prove

The Charity Commission for England and Wales says its beta API exposes the latest information shown on its Register of Charities and requires a developer-hub subscription and API key. It supports searches by name, registration date, registered number and removal date, plus detail operations for charity records, classifications, trustees, areas of operation and financial information. Charity Commission: API documentation · Charity Commission: current operations

QuestionUse the register?Product treatment
Does this exact record appear on the England and Wales register?YesShow source, registered number, suffix, organisation number, status and retrieved time.
Which similarly named charity did the user mean?PartlyReturn candidates and require confirmation; do not auto-select from name alone.
Is the charity currently recorded as registered or removed?YesStore the register status as a snapshot and route removed records to review.
Does this person control the charity or have authority to sign?NoUse an invitation to a known domain, authorised-contact workflow and documentary checks.
Is the organisation eligible for our grant, discount or marketplace?NoApply your separately reviewed rules and retain the evidence used for that decision.
Is a missing result proof that it is not charitable?NoCheck jurisdiction, spelling, alternative evidence and manual review.

The biggest data-model trap is assuming the public-facing registered number is always unique to one record. The Commission’s current data definition says organisation_number is unique to a single charity, while reg_charity_number can be shared by multiple charities; group_subsid_suffix distinguishes the main record from a linked or subsidiary record. It also defines R as registered and RM as removed, and warns that the removal date is not necessarily when the charity ceased to exist or operate. Charity Commission: API data definitions

Coverage is another hard boundary. GOV.UK states that the England and Wales register does not include some charities below £5,000 income, excepted charities or exempt charities, and points users to separate registers for Scotland and Northern Ireland. GOV.UK: search the charity register OSCR publishes a daily Scottish register download and a separate beta API; Northern Ireland maintains its own searchable register. OSCR: Scottish Charity Register APIs · CCNI: Northern Ireland charity search

The Appycodes Registry Fit Gate

Score five gates from 0 to 3: 0 unknown or absent, 1 user-asserted, 2 matched with unresolved ambiguity, 3 confirmed with retained evidence. The maximum is 15. Jurisdiction and Identifier are hard gates: if either scores zero, the product cannot describe the result as a confirmed register match.

Five registry gates × 0–3Maximum 15
JJurisdiction
England and Wales, Scotland, Northern Ireland, or evidence outside a public register.
IIdentifier
Registered number, suffix and unique organisation number rather than display name.
SStatus
Registered, removed or unresolved, with the status date and caveat preserved.
FFreshness
Source, retrieval time, cache age and a defined recheck trigger.
BBoundary
The product states what the match proves and which decision happens elsewhere.
13–15 · confirmed register recordUse the record in the workflow, while keeping authority and eligibility checks separate.
9–12 · confirm or reviewShow candidates, explain the weak gate and ask for user or operator evidence.
0–8 · no automated decisionRoute to the official register or manual review; do not infer non-charitable status.

The gate is a product-control model, not a legal or statistical risk score. Its purpose is to stop a clean API response from being promoted into a claim the source does not support.

Store a confirmed snapshot, not a mutable copy of the register

RESOLVE THE RECORD · PRESERVE THE SOURCE · BOUND THE DECISIONJurisdictionEngland + WalesScotland · N IrelandIdentifierregistered numbername = candidatesRegistry adapterserver-side keytimeout · rate limitCandidatenumber + suffixorganisation IDUser confirmsright organisationor manual reviewTWO RECORDS · TWO OWNERS · NO SILENT OVERWRITERegistry snapshotnative IDs · status · sourceretrieved time · cache ageCustomer recordoperational contacts · consentcustomer-confirmed factsBusiness decisioneligibility · authoritypayment · review evidenceNo match or outage = unresolvedsave draft · official register · manual evidence · retryA REGISTER MATCH IS NOT IDENTITY, AUTHORITY, BANK OWNERSHIP OR ELIGIBILITYFIG. 01BOUNDED CHARITY LOOKUP
Fig. 01 The register adapter resolves and snapshots a public record. User confirmation and the business decision stay downstream, so an API match cannot silently become proof of authority or eligibility.scroll →

Keep registry discovery, user confirmation and the business decision as separate records. A useful minimum model is:

FieldWhy it existsUpdate rule
jurisdictionSelects CCEW, OSCR, CCNI or manual evidenceNever inferred from a name or address alone
organisation_numberStable unique CCEW record identifierImmutable after user confirmation
registered_number + suffixPublic identifier and linked-record identityImmutable; conflicts create review
registry_snapshotName, status and only the fields the workflow needsAppend a new version; do not silently overwrite
retrieved_at + sourceProvenance and cache ageSet on every successful registry fetch
confirmed_by + confirmed_atSeparates user selection from machine retrievalRetain as auditable workflow evidence
decision + decision_basisGrant, discount, onboarding or marketplace outcomeOwned by the business policy, never the registry adapter

Refresh status at the point of consequence—for example, application submission or annual renewal—rather than on every keystroke. Keep the previous snapshot so an operator can see what changed. A removed status should pause the dependent decision and explain the next step; it should not delete the customer record or erase previously supplied evidence.

A resilient Next.js registered-number lookup

The server route below validates the input, keeps the key out of the browser, uses the documented registered-number route with main-record suffix 0, applies a timeout, preserves provenance and returns a manual-review state for no exact match. Configure the base URL, key and current header name from the API definition in your developer-hub subscription rather than copying credentials into source.

Server-side CCEW adapter with an explicit manual-review pathtypescript
// app/api/charities/[number]/route.ts
import { NextResponse } from "next/server";

type RegisterRow = {
  organisation_number: number;
  reg_charity_number: number;
  group_subsid_suffix: number;
  charity_name: string;
  reg_status: "R" | "RM";
  date_of_registration: string;
  date_of_removal: string | null;
};

const BASE_URL = process.env.CCEW_API_BASE_URL;
const API_KEY = process.env.CCEW_API_KEY;
const API_KEY_HEADER = process.env.CCEW_API_KEY_HEADER;

export async function GET(
  _request: Request,
  context: { params: Promise<{ number: string }> },
) {
  const { number } = await context.params;
  if (!/^\d{6,8}$/.test(number)) {
    return NextResponse.json({ error: "invalid_charity_number" }, { status: 400 });
  }
  if (!BASE_URL || !API_KEY || !API_KEY_HEADER) {
    return NextResponse.json({ error: "register_not_configured" }, { status: 503 });
  }

  // suffix 0 asks for the main charity record. Do not silently pick a linked
  // record when the returned suffix or organisation number differs.
  const url = new URL(`charityRegNumber/${number}/0`, BASE_URL);
  const response = await fetch(url, {
    headers: { [API_KEY_HEADER]: API_KEY },
    cache: "no-store",
    signal: AbortSignal.timeout(4500),
  });

  if (response.status === 404) {
    return NextResponse.json({ match: null, next: "manual_review" });
  }
  if (!response.ok) {
    return NextResponse.json(
      { error: "register_unavailable", next: "retry_or_manual_review" },
      { status: 503 },
    );
  }

  const rows = (await response.json()) as RegisterRow[];
  const exact = rows.find(
    (row) => row.reg_charity_number === Number(number) && row.group_subsid_suffix === 0,
  );

  return NextResponse.json({
    match: exact
      ? {
          jurisdiction: "england-wales",
          organisationNumber: exact.organisation_number,
          registeredNumber: exact.reg_charity_number,
          suffix: exact.group_subsid_suffix,
          name: exact.charity_name,
          status: exact.reg_status === "R" ? "registered" : "removed",
          removedAt: exact.date_of_removal,
          source: "Charity Commission for England and Wales",
          retrievedAt: new Date().toISOString(),
        }
      : null,
    next: exact ? "confirm_with_user" : "manual_review",
  });
}

Do not proxy arbitrary path fragments from the browser. Expose a narrow endpoint for the operation your product needs, validate the number before the upstream call and log latency, HTTP status and request purpose without logging the API key or unnecessary personal data. Cache exact public-record responses for a bounded period, but bypass or revalidate that cache when a user is about to make a consequential submission.

The Commission’s terms require API keys to remain confidential, prohibit embedding them in code or an open-source tree, recommend environment or configuration storage, and permit quotas or rate limits. They also require source attribution under the Open Government Licence. Charity Commission API terms

Failure modes that matter in production

1. Treating a fuzzy name result as the charity

Common words, local branches and historical names produce plausible candidates. Display the number, status and enough non-sensitive context for the user to choose. Save only after explicit confirmation. If the user already has a registration number, skip name search.

2. Collapsing linked charities onto one registered number

If the product discards the suffix and organisation number, later refreshes can attach the wrong linked body to an application. Make the composite source identity unique in your database and reject a different organisation number as a conflict.

3. Calling every miss “not a charity”

A miss may mean the wrong jurisdiction, a small unregistered body, an excepted or exempt charity, a spelling problem, an API outage or a record not yet available. Give the user the official registers and a manual-evidence route. The absence of one registry row is not a legal conclusion.

4. Letting an upstream outage block the entire service

Separate “register unavailable” from “no match”. Use a short timeout, limited retries with jitter, a circuit breaker and an operator-visible queue. Let a user save a draft and resume; do not convert a 503 into a rejection.

5. Copying every public field into the CRM

Public does not mean purpose-free. The API can expose contact and trustee data, but the Commission’s terms make the consumer the controller of personal data it receives, require a lawful basis and security, and can require deletion following a register-data removal notice. Retrieve the minimum fields needed, document retention and avoid using trustee data for marketing. Charity Commission API terms: personal data duties

6. Mixing registry updates with customer-confirmed facts

Do not let a refresh overwrite the operational email, billing contact, bank evidence or delivery preferences supplied by the charity. Registry data and customer data have different sources and change rules. Show a comparison and ask an authorised user or operator to resolve material differences.

Recommendations by UK product type

Grant maker or foundationResolve first, assess separately

Freeze the confirmed registry snapshot onto the application, then run eligibility, conflicts, bank and due-diligence checks under a versioned programme policy.

UK SaaS charity discountDesign a renewal event

Use the register match as one signal, bind the account through a charity-controlled contact, and recheck status at renewal rather than querying on every login.

Donation or marketplace platformDo not confuse listing with payee verification

Registry data can label the organisation; payment onboarding, connected-account ownership, sanctions, fraud and payout controls belong to the payment and risk layers.

UK-wide directoryBuild three adapters

Route England and Wales to CCEW, Scotland to OSCR and Northern Ireland to CCNI. Normalise presentation, but retain each source’s native identifiers and status semantics.

After real integration discovery, Appycodes recommends proving the narrowest risky flow before estimating the whole system. For a charity lookup, that means testing authentication, exact-number and linked-record behaviour, outage handling, cache rules and the handoff into the CRM or eligibility workflow with non-production data. Our API and integration service covers that discovery, adapter design, security, observability and operational handover.

Our ruleA registry lookup should answer “which public record did the user confirm, from which source, at what time?” It should never silently answer “is this organisation trustworthy, eligible or authorised?”

Frequently asked questions

Is the Charity Commission API a UK-wide charity register API?
No. The Charity Commission for England and Wales API covers its Register of Charities. Scotland has the OSCR register and beta API, while Northern Ireland has the Charity Commission for Northern Ireland register. A UK-wide product needs an explicit jurisdiction choice and separate adapters.
Can a Charity Commission API result verify that an organisation is a charity?
It can show that a matching record appears on the England and Wales register and expose its recorded status and public details. It cannot prove that the user controls the charity, may act for it, satisfies your programme rules, owns a bank account or passes safeguarding, fraud, sanctions or due-diligence checks.
Which identifier should a charity lookup tool store?
Store the registered charity number, group or subsidiary suffix, and the API's organisation number. The Charity Commission data definition says the organisation number is unique to a single charity, while a registered charity number can be shared across linked records. Keep the displayed name as a snapshot, not the key.
What should happen when a charity is not found?
Do not label it non-charitable. Ask the user to check the jurisdiction and identifier, then offer the official register link and a manual-review route. Some England and Wales charities are not registered because they are below the registration threshold, excepted or exempt, and Scotland and Northern Ireland use different registers.
Should a charity lookup tool store trustee names?
Only if a documented business decision genuinely needs them. Trustee names are personal data. The API terms make the API consumer responsible for lawful, fair and secure processing, and may require deletion when the Commission notifies users that register personal data has been removed.

Primary sources

Published 7 Oct 2026Reviewed 7 Oct 2026Reviewer Appycodes Editorial Team

Technical and operational guidance, not legal, regulatory, tax, safeguarding, fraud, sanctions or due-diligence advice. Confirm your decision policy and data use with qualified advisers where required.

Our clients

UK · Europe · Worldwide

Selected case studies

What we built, how it works and the results for our clients.

Creoate product interface01
B2B commerce

Eight years behind a wholesale marketplace

Next.js storefront, Python ingestion pipelines, DynamoDB data layer and AWS infrastructure.

8+ yearsdevelopment and support
Ontick product interface02
Event technology

Ticketing owned by the event team

Multi-organiser commerce, Stripe instalments and two native apps in one connected platform.

£2M+ticket sales processed
Easyship product interface03
Global logistics

Helping shippers compare their options

Rate, tax and duty calculators, server-rendered courier pages and a custom MongoDB CMS.

550+couriers in the calculator
TEFL.ie product interface04
Education & training

Connecting course sales to the classroom

WordPress and WooCommerce, a Moodle LMS, Stripe deposits and Zoho CRM, tied together with Zapier automation.

Since 2017development and support
All White Laser product interface05
Medical aesthetics

From equipment finance to clinic support

A lead-to-billing system on GoCardless Direct Debit, provider certification, and a React Native app for machine owners.

9 yrsdevelopment and support
Decofetch product interface06
Luxury commerce

A custom home for designer furniture

Server-rendered Next.js commerce over a Laravel API, bespoke operations tooling and re-architected AWS infrastructure.

0→livemarketplace development
BA Engine Room product interface07
AI operations

Connecting discovery, contracts and delivery

Discovery briefs, e-signed contracts, Stripe deposits, delivery milestones and time tracking in one operational system.

0→1custom platform development
PlusHeat product interface08
Home services

Helping customers choose their boiler cover

Custom plan configuration, postcode-qualified lead journeys, CRM synchronisation and campaign landing pages.

5 yrswebsite development and support
Léonia product interface09
Beauty commerce

Shopify shaped around a beauty brand

Custom theme, customer accounts, loyalty rewards, referrals and gift-with-purchase offers.

5 yrsShopify development and support
Shutters 365 product interface10
Home improvement

From window measurements to a priced order

A seven-step product builder with live previews, sample orders and supplier tools.

7-stepproduct configurator
Bloc Ads Manager product interface11
Advertising

From targeted ads to venue check-ins

Campaign creation, audience targeting, in-app ads and reporting linked to venue check-ins.

check-inscampaign attribution
Bloc product interface12
Social events

Four years across the app and operations

Mobile app, backend, advertising tools, a digital marketplace and website.

4+ yrssupport across five codebases
Zonely product interface13
Social mobile

Two apps, one real-time conversation marketplace

Customer and buddy apps with per-minute billing, wallets, moderation and admin tools.

2 appsfor iOS and Android
Player Profile Hub product interface14
Grassroots football

Helping grassroots players get discovered

Verified profiles, video highlights, coach discovery and safeguarding on web and mobile.

0→1custom platform development
DeepSpatial product interface15
Geospatial AI

Connecting clients, investors and emerging talent

Corporate and investor pages, the Xploor talent platform and ongoing releases on AWS Amplify.

2 yrsdevelopment and support
Yippee Malta product interface16
Travel

A booking journey the tour team owns

A multilingual website connected to the booking API, with deposits, coupons and affiliate tracking.

6languages across the booking journey
Professional Energy product interface17
Energy brokerage

Tenders, contracts and accounts brought together

Supplier tenders, contract management, brokerage accounting and client records.

100+suppliers per tender

Tell us what you are trying to build.

A thirty-minute call with the engineer who would run it.