Endpoint reference
Every public API endpoint, its parameters, and its exact response shape.
All endpoints are GET, under https://api.ardent.africa/public/v1. List endpoints
return { data, page, limit, total }. Detail endpoints return the resource object.
Send x-api-key for the higher rate tier (optional).
Common list parameters:
| Param | Type | Default | Notes |
|---|---|---|---|
page | integer | 1 | 1-based page number |
limit | integer | 20 | max 50 |
All endpoints (generated)
Generated from apps/api/src/public/. Response shapes and examples are documented per resource in the sections below.
| Method | Path | Handler |
|---|---|---|
| GET | /public/v1/campaigns | List campaigns |
| GET | /public/v1/campaigns/:slug | Get campaign |
| GET | /public/v1/petitions | List petitions |
| GET | /public/v1/petitions/:slug | Get petition |
| GET | /public/v1/blog | List blog |
| GET | /public/v1/blog/:slug | Get blog post |
| GET | /public/v1/profiles/:username | Get profile |
| GET | /public/v1/stats | Get stats |
Campaigns
GET/public/v1/campaigns
Lists active and won fundraising campaigns. Extra params: category, country
(target country code, for example GH).
curl "https://api.ardent.africa/public/v1/campaigns?limit=2&category=Education"{
"data": [
{
"id": "c7ee417f-...",
"slug": "clean-water-for-tamale",
"title": "Clean water for Tamale",
"description": "...",
"category": "Education",
"status": "active",
"goal_amount": 50000,
"raised_amount": 12500,
"image_url": "https://.../image.jpg",
"country": "Ghana",
"target_country": "GH",
"target_country_name": "Ghana",
"progress": { "raised_amount": 12500, "goal_amount": 50000, "percent": 25 },
"goal_reached_at": null,
"deadline": null,
"created_at": "2026-06-13T23:31:27.767Z"
}
],
"page": 1,
"limit": 2,
"total": 6
}/public/v1/campaigns/:slug
A single campaign, plus its public updates. Same fields as above, with an updates
array (id, title, content (sanitized HTML), media_urls, created_at).
{
"id": "c7ee417f-...",
"slug": "clean-water-for-tamale",
"title": "Clean water for Tamale",
"progress": { "raised_amount": 12500, "goal_amount": 50000, "percent": 25 },
"updates": [
{ "id": "...", "title": "Drilling begins", "content": "<p>...</p>", "media_urls": [], "created_at": "2026-06-14T..." }
]
}There are no creator, donor, or internal fields. Only active or won campaigns are
returned; anything else gives 404.
Petitions
GET/public/v1/petitions
Lists active petitions. Extra params: category, country.
{
"data": [
{
"id": "6844cb10-...",
"slug": "pass-the-affirmative-action-bill",
"title": "Pass the Affirmative Action Bill",
"description": "...",
"category": "Governance",
"status": "active",
"petition_target": 10000,
"signatures_count": 3421,
"target_country": "GH",
"target_country_name": "Ghana",
"country": "Ghana",
"image_url": null,
"progress": { "signatures_count": 3421, "petition_target": 10000, "percent": 34 },
"created_at": "2026-06-10T..."
}
],
"page": 1,
"limit": 20,
"total": 4
}/public/v1/petitions/:slug
A single petition, plus aggregate momentum. Adds momentum.signatures_last_7_days.
Signer names, emails, and comments are never returned.
{
"slug": "pass-the-affirmative-action-bill",
"signatures_count": 3421,
"progress": { "signatures_count": 3421, "petition_target": 10000, "percent": 34 },
"momentum": { "signatures_last_7_days": 188 }
}Blog
GET/public/v1/blog
Lists published posts. Extra param: category (category id).
{
"data": [
{
"title": "How tipping works",
"slug": "how-tipping-works",
"excerpt": "A short explainer",
"published_at": "2026-06-13T23:54:21.892Z",
"featured_image_url": null,
"blog_categories": { "name": "Product", "slug": "product" }
}
],
"page": 1,
"limit": 20,
"total": 1
}/public/v1/blog/:slug
A single published post. content is sanitized HTML.
{
"title": "How tipping works",
"slug": "how-tipping-works",
"excerpt": "A short explainer",
"content": "<p>Sanitized HTML body.</p>",
"published_at": "2026-06-13T23:54:21.892Z",
"featured_image_url": null,
"category": { "name": "Product", "slug": "product" }
}Profiles
GET/public/v1/profiles/:username
A public supporter profile (only where the user has enabled a public profile). Returns aggregate signature count. Never returns email, phone, or internal ids.
{
"username": "ama",
"full_name": "Ama O.",
"bio": "Supporter of education causes",
"avatar_url": "https://.../avatar.jpg",
"country": "Ghana",
"account_type": "personal",
"signatures_count": 12
}A username with no public profile gives 404.
Stats
GET/public/v1/stats
Platform-level aggregates. No per-user or donor data.
{
"total_active_campaigns": 10,
"total_campaigns": 11,
"countries_reached": 1,
"total_funds_raised": 288460,
"total_signatures": 51
}Last updated: 18 June 2026
