Skip to content

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_SECRET
  • MATR_IOS_APP_SECRET
  • LAST1_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"}'

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.