Node.js integration
Node.js ≥ 18 (native fetch). This is the exact
pattern behind the mini-SDK.
1. Set up the client
const BASE = 'https://api.ethiolink-consent.et';
async function call(method, path, body, apiKey) {
const res = await fetch(BASE + path, {
method,
headers: {
'Content-Type': 'application/json',
...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}),
},
body: body ? JSON.stringify(body) : undefined,
});
const json = await res.json().catch(() => ({}));
if (!res.ok) throw new Error(`${json.error?.code}: ${json.error?.message}`);
return json;
}
2. Request consent
// "Please show me 30 days of Alemu's transaction history"
const request = await call('POST', '/api/consent/request', {
user_fayda_id: 'FAYDA-847291', // or user_email / user_id
purpose: 'Loan eligibility assessment',
data_categories_requested: ['transaction_history', 'mobile_money'],
duration_days: 30,
// Required ONLY for automated decision-making (PDPP Art. 24(1)(m)):
// involves_automation: true,
// automation_description: 'A scoring model estimates eligibility.',
}, process.env.ETHIOLINK_API_KEY);
const consentId = request.request.public_id; // cr_...
// Alemu now reviews it in her dashboard or by SMS reply.
3. Verify a token before touching data
const q = new URLSearchParams({ token: consentToken, reason: 'loan_application' });
const verdict = await call('GET', `/api/consent/active?${q}`, undefined, apiKey);
if (!verdict.active) {
// status: 'revoked' | 'expired' | 'not_found' | 'wrong_institution'
throw new Error(`Consent not usable: ${verdict.status}`);
}
// verdict.automation?.objection === true -> route to human review
// verdict.data_categories -> exactly the granted categories
4. Retrieve encrypted data
const q = new URLSearchParams({ token: consentToken, reason: 'loan_application' });
const data = await call('GET', `/api/data/retrieve?${q}`, undefined, apiKey);
// data.transfers[].encrypted_data -> opaque blob, decrypt with your key
// data.transfers[].source_institution
5. Webhook signature verification
import crypto from 'node:crypto';
function verifyWebhook(reqBody, signature, timestamp, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(`${timestamp}.${JSON.stringify(reqBody)}`)
.digest('hex');
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}
// Headers: X-EthioLink-Timestamp, X-EthioLink-Signature
← All guides · Need the full reference? docs/API.md