Over the past 18 months I’ve been building a website to help victim/survivors of domestic abuse find their local support service. My main focus has been developing the frontend of the site with a user friendly interface that helps people quickly find support.
But alongside that, I’ve been thinking about how to make the backend API public so that other developers and organisations can benefit from the same data.
Some examples of this could be:
- A local authority could embed support services into their own site
- A researcher could analyse geographical coverage of services
- Other community projects could build apps on top of the data
The data for the services is stored in an Airtable database and my Next.js backend acts as a middle layer between Airtable and the frontend. My backend ensures only approved services are shown and converts location data into GeoJson which is a common format used for mapping.

Making a public route
The first step was to expose a public GET route at https://domesticabuseservices.uk/api/airtable
This endpoint returns all approved services in GeoJSON format. This is an example of the response:
{
"type": "Feature",
"properties": {
"name": "Example Service",
"description": "Support for women experiencing domestic abuse",
"address": "123 Main St",
"postcode": "AB12 3CD",
"email": "info@example.com",
"website": "https://example.com",
"phone": "0123456789",
"donate": "https://donate.example.com",
"serviceType": ["Support"],
"serviceSpecialism": ["Women"],
"approved": true,
"localAuthority": "London Borough"
},
"geometry": {
"type": "Point",
"coordinates": [-0.1276, 51.5072]
}
}
Protecting the API with rate limiting
When you make a service public you need to think about the possibility of somebody abusing it. I added rate limiting with Upstash Redis to prevent people from overwhelming the API with too many requests.
const ratelimit = new Ratelimit({
redis,
limiter: Ratelimit.slidingWindow(5, '10 s'),
analytics: true,
});
This means that a client can only make 5 requests every 10 seconds. If they exceed that they’ll get a 429 Too Many Requests response.
POST Requests with Authentication
The API also supports POST requests so that new services can be added. At the moment this is restricted so that only requests with a Bearer token will be authenticated. This is available on request from hello@domesticabuseservices.uk.
New services that are created in Airtable are unapproved by default, so I can review them before publishing them on the site.
Here’s an example of a request:
curl -X POST https://domesticabuseservices.uk/api/airtable \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"Service name": "New Support Line",
"Service address": "456 High St",
"Service postcode": "XY99 1ZZ",
"Service description": "Helpline for survivors",
"Service email address": "support@helpline.org",
"Service website": "https://helpline.org",
"Service phone number": "0800123456",
"Service type": ["Helpline"],
"Specialist services for": ["Young people"],
"Local authority": "Wandsworth"
}'
Documentation
I’ve documented the API with Swagger/Open API to make it easier to use. Anyone can visit That means anyone can visit https://domesticabuseservices.uk/api-docs and see an interactive interface where they can try out making requests and read the schema.
I hope that the API will allow more people and services to use and interact with my database of domestic abuse services across the UK. It’s also been a great learning opportunity for me to learn how to design and build a REST API.