Platform para sa Developer
Mga API at Widget
Mag-embed ng live na metrics ng Espiritu at Tubig sa anumang site, o direktang kumonekta sa aming REST API at SSE stream. Hindi kailangan ng authentication para sa mga pampublikong read endpoint.
Mabilis na pagsisimula
Ang pinakamabilis na paraan para ipakita ang data ng 238 Global sa iyong site ay iframe o ang aming drop-in na embed.js script. Parehong naglo-load ang mga ito ng mga nakahandang widget mula sa mga route na /embed/* na may kaunting chrome.
Live na preview — Metrics widget
Mag-embed ng mga widget
May tatlong uri ng widget: metrics (4 na counter), feed (nag-i-scroll na listahan ng aktibidad), at globe (interactive na 3-D globe na may mga marker ng live na ulat).
<iframe
src="https://238global.com/embed/metrics"
width="100%"
height="120"
frameborder="0"
title="238 Global Metrics"
></iframe><script src="https://238global.com/embed.js" data-base="https://238global.com"></script>
<div data-238="metrics" data-width="100%" data-height="120"></div>
<div data-238="feed" data-width="100%" data-height="320"></div>
<div data-238="globe" data-width="100%" data-height="400"></div>function MetricsWidget() {
return (
<iframe
src="/embed/metrics"
width="100%"
height="120"
style={{ border: 0 }}
title="238 Global Metrics"
/>
);
}Mga attribute
- data-238
- Uri ng widget: metrics, feed, o globe
- data-base
- Base URL sa script tag (para sa mga cross-origin embed)
- data-src
- Ganap na palitan ang src ng iframe
- data-width / data-height
- Mga sukat (default: 100% × 120 o 320)
REST API
Nagbabalik ng JSON ang lahat ng pampublikong read endpoint. Base path: /api/v1
/api/v1/metricsPinagsama-samang mga counter para sa pagkapuno ng Espiritu, bautismo sa tubig, pinagsamang event, at mga kabuuan — kasama ang mga bilang ngayong araw.
{
"spirit": 14832,
"water": 9451,
"both": 7206,
"total": 31489,
"spiritToday": 127,
"waterToday": 84,
"bothToday": 63,
"totalToday": 274,
"countries": 42,
"cities": 186,
"updatedAt": "2026-07-09T18:00:00.000Z"
}/api/v1/reportsMga bagong aprubadong ulat. Mga query param: limit (max 100), since (ISO datetime).
GET /api/v1/reports?limit=10&since=2026-07-01T00:00:00Z
{
"reports": [
{
"id": "clx…",
"city": "Lagos",
"country": "Nigeria",
"peopleCount": 23,
"type": "spirit",
"createdAt": "2026-07-09T17:45:00.000Z"
}
]
}/api/v1/streamSSEServer-Sent Events stream. Kapag kumonekta at kada 5 segundo, dalawang pinangalanang event ang ipinapadala:
metricsMga pinagsama-samang counter na kapareho ng GET /api/v1/metrics.reportsObject { reports: [...] } — ang 20 pinakabagong aprubadong ulat.errorIpinapadala lamang kapag pumalya ang server-side tick; { message: string }.
const es = new EventSource('/api/v1/stream');
es.addEventListener('metrics', (e) => {
const metrics = JSON.parse(e.data);
console.log('Total:', metrics.total);
});
es.addEventListener('reports', (e) => {
const { reports } = JSON.parse(e.data);
console.log('Latest city:', reports[0]?.city);
});
es.addEventListener('error', (e) => {
// native EventSource error (connection lost) — reconnects automatically
// named 'error' events from server indicate a tick failure
});Pag-authenticate
Gumagana ang mga pampublikong read endpoint nang walang credential. Para sa mas mataas na rate limit, isama ang iyong API key bilang Bearer token sa Authorization header.
GET /api/v1/metrics HTTP/1.1
Authorization: Bearer 238_<your-api-key>
GET /api/v1/reports?limit=100 HTTP/1.1
Authorization: Bearer 238_<your-api-key>Ang team ng 238 Global ang nagbibigay ng mga API key. Makipag-ugnayan sa [email protected] para humiling ng partner key.
Mga rate limit
Inilalapat ang mga rate limit kada IP para sa request na walang authentication, o kada API key para sa request na authenticated. Kapag lumampas sa limit, ibinabalik ang 429 Too Many Requests.
Mga halimbawa
const res = await fetch('https://238global.com/api/v1/metrics');
const { total, spiritToday } = await res.json();
document.getElementById('count').textContent = total.toLocaleString();async function poll() {
const res = await fetch('/api/v1/reports?limit=5');
const { reports } = await res.json();
renderFeed(reports);
}
setInterval(poll, 30_000);
poll();Mga webhook
Maaaring mag-subscribe ang mga partner key sa mga real-time event webhook. Kapag may event, nagpo-POST ang 238 Global ng signed JSON payload sa iyong endpoint. Irehistro ang mga subscription sa pamamagitan ng API.
Mga suportadong event
- report.created
- Ipinapadala kapag na-publish ang isang ulat. Nasa payload ang buong report object.
- metrics.updated
- Ipinapadala matapos aprubahan ang bawat ulat, kasama ang na-update na pinagsama-samang metrics.
POST /api/v1/webhooks
Authorization: Bearer 238_<your-api-key>
Content-Type: application/json
{
"url": "https://yourapp.example.com/webhooks/238",
"events": ["report.created", "metrics.updated"]
}
// Response — save the secret, shown once
{
"subscription": {
"id": "sub_…",
"url": "https://yourapp.example.com/webhooks/238",
"events": ["report.created", "metrics.updated"],
"secret": "abc123…",
"createdAt": "2026-07-09T22:00:00.000Z"
}
}GET /api/v1/webhooks
Authorization: Bearer 238_<your-api-key>DELETE /api/v1/webhooks?id=sub_…
Authorization: Bearer 238_<your-api-key>Pag-verify ng mga signature
Kasama sa bawat webhook request ang X-238-Signature header. Ang value ay sha256=<hex> na kinukuwenta bilang HMAC-SHA256 ng raw request body gamit ang secret ng iyong subscription.
import { createHmac, timingSafeEqual } from 'crypto';
function verifyWebhook(body: string, header: string, secret: string): boolean {
const expected = 'sha256=' + createHmac('sha256', secret).update(body).digest('hex');
return timingSafeEqual(Buffer.from(header), Buffer.from(expected));
}
// Express / Next.js route handler
app.post('/webhooks/238', express.raw({ type: 'application/json' }), (req, res) => {
const sig = req.headers['x-238-signature'] as string;
if (!verifyWebhook(req.body.toString(), sig, process.env.WEBHOOK_SECRET!)) {
return res.status(401).send('Invalid signature');
}
const { event, data } = JSON.parse(req.body.toString());
console.log('Received event:', event, data);
res.sendStatus(200);
});Istruktura ng webhook payload
{
"event": "report.created",
"timestamp": "2026-07-09T22:00:00.000Z",
"data": {
"id": "clx…",
"city": "Lagos",
"country": "Nigeria",
"peopleCount": 23,
"type": "spirit",
"status": "APPROVED",
"createdAt": "2026-07-09T22:00:00.000Z"
}
}