Integrate with ET Checker
ET Checker verifies job candidates for Ethiopian employers — identity, criminal record, employment history, education, and compliance — against official sources. This is for the institutions that hold those sources: what a partnership looks like, what we ask for, and the API we already expose for verifying a report.
What is ET Checker?
ET Checker is a background-screening platform for Ethiopian employers. A company submits a candidate; our verification office checks their identity, criminal record, employment history, and other selected checks by hand against official sources; the employer receives one signed, shareable report.
Today that verification is manual — an officer confirms each data point directly with the relevant institution. This page describes the partnership model we're building toward: a standing data-sharing relationship with the institutions that hold the source records, so verification stays accurate as it scales, and those institutions get one documented, auditable channel instead of ad-hoc calls and letters.
Why this is worth doing
- One verified report instead of chasing five institutions themselves.
- A documented, dated, auditable hiring decision — not a phone call nobody recorded.
- Faster, more consistent onboarding across every role they hire for.
- Every request comes through one accountable, identifiable channel — not scattered individual inquiries.
- Only the minimum fields needed per request, with the requesting employer and purpose on record.
- A single integration serves every employer on the platform, instead of fielding each one separately.
How integration works
The verification flow, end to end:
- 1Employer submits a candidateFull name, national ID, and the specific checks needed (criminal record, education, etc.).
- 2Candidate authorizes screeningConsent is recorded before anything is checked — required for every check, every time.
- 3ET Checker requests verificationToday: a verification officer confirms each data point with the relevant institution. With a partnership: a structured, logged request through the shared channel.
- 4Result recorded and reportedEach check gets a result and a finding; once every check is in, the report generates and is delivered to the employer.
Federal Police — Criminal Record Bureau
The highest-volume check on the platform, and our priority partnership.
- Candidate full name
- As it appears on their government ID.
- National ID or Fayda ID
- Primary lookup key.
- Date of birth
- Disambiguation for common names.
- Clearance status
- Clear, or record found.
- Reference number
- Tied to this specific request.
- Checked on
- Date the record was verified.
Ministry of Education
For roles requiring a verified academic credential.
- Candidate full name
- As enrolled.
- Institution & program
- As declared by the candidate.
- Graduation year
- Certificate number
- If the candidate has one on hand.
- Credential status
- Confirmed, not found, or mismatch.
- Institution & program
- As verified against records.
- Verified on
- Date of confirmation.
Fayda — National ID Program
Planned — pending partnershipFayda identity verification runs on VeriFayda 2.0's eSignet — the same OpenID Connect (OIDC) system every relying party integrates with. The phone number is the anchor: HR starts a request with the candidate's phone number, Fayda confirms it belongs to a real FAN (Fayda ID Number) by sending a one-time code straight to that number, and the candidate authenticates directly with Fayda — ET Checker never sees or handles the OTP, a password, or biometric data.
- 1HR enters a phone numberThe employer submits the candidate along with the phone number registered to their Fayda account — nothing else is needed to start.
- 2ET Checker requests identity verificationWe redirect to VeriFayda's authorization endpoint using the Authorization Code + PKCE flow, with acr_values=mosip:idp:acr:generated-code to require OTP authentication, and request only the claims we need: name, phone_number, birthdate, gender.
- 3Fayda sends the OTP — not usThe candidate enters the code on Fayda's own hosted page. ET Checker only ever receives an authorization code, never the OTP itself.
- 4ET Checker exchanges the code for tokensThe callback code is exchanged for an ID token and access token, authenticated with a client assertion JWT signed by our private key — no client secret is transmitted.
- 5Identity is recorded against the requestWe call the UserInfo endpoint, decode the verified claims, and attach them to that specific screening request — the requester and the verified subject are shown side by side, everywhere the request appears.
ET Checker builds this URL and sends the candidate to it — code_challenge is the SHA-256 hash of a per-request code_verifier we hold onto for the token exchange in step 2.
GET https://esignet.fayda.et/authorize ?client_id=<et_checker_client_id> &response_type=code &redirect_uri=https://www.etcheckers.com/api/fayda/callback &scope=openid%20profile &acr_values=mosip:idp:acr:generated-code &code_challenge=<sha256_of_code_verifier> &code_challenge_method=S256 &state=<request_code> &claims=%7B%22userinfo%22%3A%7B%22name%22%3A%7B%22essential%22%3Atrue%7D%2C%22phone_number%22%3A%7B%22essential%22%3Atrue%7D%2C%22birthdate%22%3A%7B%22essential%22%3Atrue%7D%2C%22gender%22%3A%7B%22essential%22%3Atrue%7D%7D%7DFayda authenticates the client with a signed JWT instead of a client secret. Ours is built the same way as the official eSignet integration guide's Node.js example, since our API already runs on TypeScript:
lib/fayda.tsimport { SignJWT, importJWK } from "jose"; async function faydaClientAssertion() { const jwk = JSON.parse( Buffer.from(process.env.FAYDA_PRIVATE_KEY_BASE64!, "base64").toString("utf8"), ); const privateKey = await importJWK(jwk, "RS256"); return new SignJWT({ iss: process.env.FAYDA_CLIENT_ID, sub: process.env.FAYDA_CLIENT_ID, aud: process.env.FAYDA_TOKEN_ENDPOINT, }) .setProtectedHeader({ alg: "RS256", typ: "JWT" }) .setIssuedAt() .setExpirationTime("2h") .sign(privateKey);}What we attach to the screening request after the UserInfo call — only the claims we asked for, nothing else.
{ "sub": "6140798523917519", "name": "Tesfaye Alemu", "phone_number": "+251911223344", "birthdate": "1994-03-12", "gender": "male", "verifiedAt": "2026-09-21T09:14:02.000Z"}Both sides of the request stay visible everywhere it appears — the ops console, the employer portal, and the final report:
The OTP, and any password or biometric step, happens entirely on Fayda's own hosted page — it never passes through ET Checker's servers, browser, or logs.
Other sectors
The screening catalog isn't fixed to ride-hailing or general employment — the same request/response shape extends to any sector with its own verification need.
A new sector doesn't need a new platform — it needs a new check type and a partner on the other end of it. Reach out (see Getting Started) and we'll scope the fields together.
Authentication
The report-verification API below is unauthenticated by URL — the link itself is an unguessable token — but the result is gated behind sign-in: the viewer proves they're either ET Checker staff or that specific employer's own HR account before the API returns anything beyond who the report is for.
A dedicated partner API key for the sector integrations above is issued per partnership once a data-sharing agreement is in place — not self-serve. See Getting Started.
Report verification API
Live todayEvery completed report gets a short, unguessable public link. Anyone holding it can look up who the report is for; seeing the actual result requires signing in as ET Checker staff or that employer's own HR account.
The snippets below use placeholders. Want a sandbox login and a real report link to run them against? .
Returns a locked preview — enough to confirm the link is real, nothing more.
/r/:tokencurl https://www.etcheckers.com/api/r/$TOKEN{ "locked": true, "preview": { "requestCode": "EC-2026-00006", "candidateFullName": "Tesfaye Alemu", "companyName": "Feres Transport" }}Sign in with an ET Checker account to view the report.
emailThe signed-in account's email — must belong to the requesting employer, or ET Checker staff.passwordThat account's password./r/:token/unlockcurl -X POST https://www.etcheckers.com/api/r/$TOKEN/unlock \ -H "Content-Type: application/json" \ -d '{"email":"you@company.com","password":"YOUR_PASSWORD"}'{ "report": { "requestCode": "EC-2026-00006", "candidate": { "fullName": "Tesfaye Alemu", "nationalIdMasked": "████—9012" }, "job": { "positionTitle": "Driver", "department": "Ride-Hailing Operations" }, "company": { "name": "Feres Transport" }, "services": [ { "code": "S-01", "result": "clear", "findings": "No criminal record found." } ], "overallResult": "clear", "validUntil": "2027-03-21T19:01:24.680Z", "expired": false }}Status codes
200OK — request succeeded.401Invalid email or password.403Valid account, but it doesn't have access to this report.404The link is invalid, or the report isn't ready yet.429Too many unlock attempts — try again later.Data protection
- Purpose-bound — every request names the employer, the candidate, and which check it's for. No open-ended lookups.
- Consent-gated — nothing is checked until the candidate has authorized screening, recorded with a timestamp and method.
- Minimum necessary — we ask for the fields that answer one question, not the full underlying record.
- Results, not raw records — a partnership returns a verification result (match / no match / not found), never a copy of the source document.
- Auditable — every request and result is logged against the request code that created it.
Getting started
If you represent an institution that holds records ET Checker verifies against — or a new sector that needs its own check type — start with a conversation, not a contract:
- Email us with who you represent and which check(s) you'd cover.
- We scope the exact fields together — request shape, response shape, expected volume.
- A partner API key is issued once a data-sharing agreement is signed.
- We integrate, test against real requests, then go live.