Read verified employment
How to read the employment verifications that Sifa issues, from the issuer repository or from the profile query, and how to trust them.
Sifa verifies employment in more than one way. An organization can confirm a position from its own account, and other methods follow. When Sifa verifies a position, it writes one public record about it from a dedicated issuer account. Your app can read that record with no Sifa account and no API key.
This page tells you where the records are, what they contain, and which rule decides if a record counts.
The one trust rule
Only a record that the Sifa issuer account wrote counts. This table shows the issuer DID:
| Issuer | DID |
|---|---|
| Sifa verification issuer | did:plc:TBD |
A copy of the same record in any other repository has no meaning. Check the repository DID before you use the record. Bluesky clients check the verifier of an app.bsky.graph.verification record in the same way.
The record
The collection is id.sifa.verification.employment. The lexicon is in singi-labs/sifa-lexicons.
{
"$type": "id.sifa.verification.employment",
"subject": "did:plc:45uheisi25szrjvjurfpritx",
"position": { "uri": "at://did:plc:45uheisi25szrjvjurfpritx/id.sifa.profile.position/3abc" },
"status": "id.sifa.defs#employmentCurrent",
"methods": ["id.sifa.defs#verifiedByOrg"],
"title": "Founder",
"startedAt": "2025-11",
"organization": "did:plc:2f2ahswozqy4v5lvu676375y",
"evidence": [
{ "uri": "at://did:plc:2f2ahswozqy4v5lvu676375y/id.sifa.org.employmentAttestation/3xyz" }
],
"verifiedAt": "2026-09-30T12:00:00.000Z",
"createdAt": "2026-09-30T12:00:00.000Z"
}The fields that matter to a reader:
subjectis the person.positionpoints at their own position record.statusisemploymentCurrentoremploymentPast.methodslists what backs the verification.verifiedByOrgmeans the organization confirmed it from its own account.verifiedByDirectorymeans the organization's directory sync did. Sifa reservesverifiedByEmailandverifiedByPeerfor later methods.titleandstartedAtare snapshots. Compare them with the live position record. A difference means the person changed the position after the verification.evidencelinks to public records that back the verification, such as the organization's attestation.expiresAt, when present, means the verification lapses at that time unless Sifa renews it. Treat a record after that time as lapsed.
The record never contains an email address or an email domain.
A deleted record is a revocation. No record for a position means "not verified by Sifa", and that is not a negative signal.
Option 1: read the issuer repository
Every record lives in the issuer's own repository. List the collection, or follow it live.
# every record the issuer wrote, paginated
curl "https://<issuer-pds>/xrpc/com.atproto.repo.listRecords?repo=<issuer-did>&collection=id.sifa.verification.employment"
# live: subscribe to the issuer DID on Jetstream
wss://jetstream2.fr.hose.cam/subscribe?wantedDids=<issuer-did>&wantedCollections=id.sifa.verification.employmentTo find every verification about one person, query backlinks on subject with Constellation and keep only the records whose repository is the issuer DID.
Option 2: call the profile query
The AppView adds a verification object to each verified position in id.sifa.getProfileView:
{
"positions": [
{
"title": "Founder",
"company": "Singi Labs",
"startedAt": "2025-11",
"verification": {
"methods": ["id.sifa.defs#verifiedByOrg"],
"status": "id.sifa.defs#employmentCurrent",
"verifiedAt": "2026-09-30T12:00:00.000Z",
"uri": "at://<issuer-did>/id.sifa.verification.employment/3def"
}
}
]
}uri points at the issued record, so you can go from the query to the record on the protocol.
Option 3: use the SDK
import { resolveEmploymentVerification } from '@singi-labs/sifa-sdk'
const result = resolveEmploymentVerification(record, { repoDid, issuerDid })
// result.ok === true only when repoDid is the issuer and the record parsesThe helper applies the trust rule and returns a typed record, or a reason when the record does not count.
Be a good neighbour
- Cache reads for a minute or so and read from your server.
- A person can hide a position or turn sharing off at any time. Then Sifa deletes the record. Treat a missing record as "no data now".
- When you show a verification, link to the person's Sifa profile page.
Show Sifa profiles in your app
How to read a headline, a current role, an employer, and skills from a Sifa profile and render them in your own app. Public data, no account, no API key.
Contributing
How to contribute code to Sifa. Finding an issue, local setup, the review flow, and the standards we hold.