API contracts / App Service v2 / Telemetry

Screen events and sync-health counters (no PII)

OperationpostTelemetry
Call
POST /gateway/urvi-app-service/api/v2/telemetry
Group
Telemetry
Features
Sync error log, Pending sync, Home and bottom bar, Settings
Replaces today

Use case. Called by a low-priority worker (batched, every few hours on unmetered or any network) with screen views, actions, error codes and sync-health counters (pending ops, failed ops, oldest pending age, conflict / rejection counts). Replaces the raw queue upload, clickstream and Firestore logs. The server drops events that look like PII.

Rules.

  • Strict schema (additionalProperties: false); free text is not accepted.
  • Events resembling names, phone numbers or Aadhaar are dropped and counted in dropped; a batch made only of such events -> 422 TELEMETRY_PII_DETECTED.

Error codes. TELEMETRY_PII_DETECTED

Parameters

NameInTypeRequiredMeaningExample
X-App-VersionheaderstringYesApp version `major.minor.patch+build`. Too old -> 426 `VERSION_TOO_OLD`. · pattern ^\d+\.\d+\.\d+(\+\d+)?$2.0.0+200
X-Device-Idheaderstring (uuid)YesApp-scoped device UUID (not ANDROID_ID).6b1f2c3d-0000-4000-8000-00000000d001
X-Request-Idheaderstring (uuid)NoClient-generated request id for tracing; echoed in responses and problems.0e0c5a1b-0000-4000-8000-0000000000a1
Accept-LanguageheaderstringNoLanguage for messages and labels. · one of en, te, ta; default "en"te
X-TenantheaderstringNoTenant code; must match the token. Urvi: `ap.gov`. · one of ap.govap.gov
Idempotency-Keyheaderstring (uuid)YesUUID per write request; retained >= 30 days. Reusing a key with a different body -> 422 `IDEMPOTENCY_KEY_REUSED`.9c8b7a6d-0000-4000-8000-0000000000b1

Request

Body schema TelemetryBatch.

Example request body
{
  "sessionId": "d36e0bc1-0000-4000-8000-000000000001",
  "events": [
    {
      "type": "screen_view",
      "at": "2025-10-14T09:30:00+05:30",
      "screen": "crop_actual_list",
      "durationMs": 5400
    },
    {
      "type": "sync_health",
      "at": "2025-10-14T09:31:02+05:30",
      "counters": {
        "pendingOps": 3,
        "failedOps": 1,
        "oldestPendingAgeMinutes": 95
      }
    },
    {
      "type": "error",
      "at": "2025-10-14T09:31:02+05:30",
      "screen": "crop_actual_edit",
      "errorCode": "PART_OF_COMPACT_BLOCK"
    }
  ]
}
FieldTypeRequiredRulesMeaning
sessionIdstring (uuid)NoRandom per app session; not linked to the user.
eventsTelemetryEvent[]Yesmin items 1; max items 500

Responses

202 Accepted.

Schema TelemetryAck.

Example 202 body
{
  "accepted": 3,
  "dropped": 0
}
FieldTypeRequiredRulesMeaning
acceptedintegerYes≥ 0
droppedintegerYes≥ 0

400 Malformed request or schema violation.

Schema Problem.

Example 400 body
{
  "type": "https://urvi.example.invalid/problems/validation-failed",
  "title": "Validation failed",
  "status": 400,
  "detail": "One or more fields are invalid.",
  "code": "VALIDATION_FAILED",
  "requestId": "0e0c5a1b-0000-4000-8000-0000000000a1",
  "errors": [
    {
      "field": "/mobile",
      "code": "INVALID_MOBILE",
      "message": "Mobile must be 10 digits starting 6-9."
    }
  ]
}

401 Missing, invalid or expired access token. Refresh once, then ask the user to log in; pending outbox ops stay intact.

Schema Problem.

Example 401 body
{
  "type": "https://urvi.example.invalid/problems/token-expired",
  "title": "Session expired",
  "status": 401,
  "detail": "The access token has expired.",
  "code": "TOKEN_EXPIRED",
  "requestId": "0e0c5a1b-0000-4000-8000-0000000000a1"
}

422 Only PII-like events.

Schema Problem.

Example 422 body
{
  "type": "https://urvi.example.invalid/problems/telemetry-pii-detected",
  "title": "Rejected",
  "status": 422,
  "detail": "Telemetry must not contain personal data.",
  "code": "TELEMETRY_PII_DETECTED",
  "requestId": "0e0c5a1b-0000-4000-8000-0000000000a1"
}

426 App version below the minimum; block the UI with an update prompt. Pending outbox ops are kept.

Schema Problem.

Example 426 body
{
  "type": "https://urvi.example.invalid/problems/version-too-old",
  "title": "Update required",
  "status": 426,
  "detail": "Please update Urvi to continue.",
  "code": "VERSION_TOO_OLD",
  "requestId": "0e0c5a1b-0000-4000-8000-0000000000a1",
  "minAppVersion": "2.0.0"
}

429 Rate limited per device / user. Respect `Retry-After`.

Schema Problem.

Example 429 body
{
  "type": "https://urvi.example.invalid/problems/rate-limited",
  "title": "Too many requests",
  "status": 429,
  "detail": "Slow down and retry later.",
  "code": "RATE_LIMITED",
  "requestId": "0e0c5a1b-0000-4000-8000-0000000000a1",
  "retryAfterSeconds": 30
}

500 Unexpected server error; retry with backoff (writes are idempotent).

Schema Problem.

Example 500 body
{
  "type": "https://urvi.example.invalid/problems/internal-error",
  "title": "Server error",
  "status": 500,
  "detail": "Something went wrong. Please try again.",
  "code": "INTERNAL_ERROR",
  "requestId": "0e0c5a1b-0000-4000-8000-0000000000a1"
}