Trust Event Ingestion API¶
Apps with trust_events:write scope and user consent can submit trust events to Last1 ID.
Authentication¶
Option 1: Basic auth (user-registered apps)¶
Use client_id:client_secret as Basic auth credentials. The client_id is the app client UUID from /api/app-clients.
curl -X POST https://auth.last1.id/api/trust-events \
-u "<client_id>:<client_secret>" \
-H "Content-Type: application/json" \
-d '{"identity_id":"...","event_type":"verification_completed"}'
Option 2: Bearer + X-App-Id (system apps)¶
For system apps (last1, radiocheck, matr-ios, etc.), set per-app secrets in env:
RADIOCHECK_APP_SECRETMATR_IOS_APP_SECRETLAST1_APP_SECRET- etc. (uppercase app_id,
-→_)
curl -X POST https://auth.last1.id/api/trust-events \
-H "Authorization: Bearer $RADIOCHECK_APP_SECRET" \
-H "X-App-Id: radiocheck" \
-H "Content-Type: application/json" \
-d '{"identity_id":"...","event_type":"verification_completed"}'
Option 3: Basic auth with app_id (system apps)¶
curl -X POST https://auth.last1.id/api/trust-events \
-u "radiocheck:$RADIOCHECK_APP_SECRET" \
-H "Content-Type: application/json" \
-d '{"identity_id":"...","event_type":"verification_completed"}'
Consent requirement¶
The identity must have granted trust_events:write consent to the app via the consent UI. Without consent, requests return 403.
Endpoints¶
POST /api/trust-events¶
Submit a single trust event.
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
| identity_id | UUID | Yes | Identity the event relates to |
| event_type | string | Yes | Event type (e.g. verification_completed, credential_issued) |
| issuer_id | UUID | No | Credential issuer if applicable |
| source_session_id | string | No | Session or request ID for idempotency |
| source_organization_id | UUID | No | Organization context |
| metadata | object | No | Additional event data |
Response: 201 with { "id": "<uuid>" }
POST /api/trust-events/batch¶
Submit up to 100 events in one request.
Request body:
{
"events": [
{ "identity_id": "...", "event_type": "verification_completed" },
{ "identity_id": "...", "event_type": "credential_issued", "metadata": {} }
]
}
Response: 201 with { "created": 2, "ids": ["...", "..."], "errors": [] }
Events that fail (e.g. missing consent) are reported in errors with index and error.
Partner event catalog¶
Privacy-safe event types emitted by integrated apps. Metadata must never include free text, PHI, or PII blobs. Unlinked users are skipped at the partner outbox (Last1, RadioCheck) — no false ingest.
last1.app (X-App-Id: last1)¶
| event_type | Dimensions | Allowed metadata |
|---|---|---|
last1.program.enrolled |
participation | program_id, organization_id |
last1.program.completed |
participation | program_id, organization_id |
last1.outcome.recorded |
participation, reliability | program_id, organization_id, milestone_id, outcome_category |
last1.validation.passed |
verification_strength | program_id, organization_id, milestone_id, outcome_event_id |
last1.validation.failed |
verification_strength | same as passed |
last1.org.member_joined |
participation | organization_id, role |
Drained from Last1 last1_trust_event_outbox via POST /api/internal/cron/drain-last1-trust-events.
RadioCheck (X-App-Id: radiocheck)¶
| event_type | Dimensions | Notes |
|---|---|---|
radio_check_sent |
responsiveness | Check-in initiated |
radio_check_completed |
responsiveness, reliability | Categorical response_category only |
radio_check_response_latency |
responsiveness | Latency metadata |
radio_check_escalation_triggered |
reliability | Escalation reason enum |
radio_check_responder_added |
peer_attestations | responder_role enum; no message content |
Drained from check_in_audit_events proof pipeline (check-in-proof-events Edge Function).
Trust dimensions (private summary)¶
Server computes from event counts in reputation_snapshots.snapshot_data:
reliability,responsiveness,participation,verification_strength,peer_attestations
Peer attestation scoring (same dimension, partner-specific weight):
| Source event | Weight per event (toward 100 cap) |
|---|---|
matr_peer_attestation_added, matr.peer.attestation.added |
25 |
radio_check_responder_added |
10 |
Both event families also contribute to participation (×15, shared participation formula).
Users opt in per dimension via identities.public_trust_dimensions; public profile exposes only selected keys.
LastVet (X-App-Id: lastvet)¶
| event_type | Side effects | Notes |
|---|---|---|
lastvet.account_linked |
verification_strength; issues veteran_verified credential |
Emitted when a veteran completes Last1 ID OAuth inside LastVet. LastVet requires ID.me or Login.gov for VA access, so this link attests confirmed veteran status — last1.id does not run a separate ID.me flow. |
Drained from last1_proof_events outbox in last.vet-api.
Disconnecting LastVet revokes the LastVet-attested veteran_verified credential.