Classify foreground activity
Classify bounded foreground text using Jev and the API key owner's assigned project profiles without recording time.
POST /api/v1/activity/classify
Required scope: activity:classify
Request
POST https://www.tracktimer.app/api/v1/activity/classify with Authorization: Bearer YOUR_API_KEY and Content-Type: application/json. Requires activity:classify; replace older keys that lack this scope.
JSON fields: application (required nonblank string, at most 256 characters), windowTitle (required string, at most 500 characters), screenText (required string, at most 12000 characters). Empty windowTitle and screenText are allowed. Unknown fields are rejected. The complete UTF-8 request body is limited to 65536 bytes. The desktop must redact sensitive text before sending. Do not submit screenshots or provider keys.
Example body:
{"application":"Terminal","windowTitle":"Website refresh","screenText":"Running project tests"}
Response — 200
Returns model, answers, usage, and projects. answers contains category, context, and project; each is {type:choice,choice:string,probabilities:{option:number},confidence:number}. Probability/confidence values range from 0 to 1, probabilities cover exactly the offered choices and sum approximately to 1, and the selected choice has a highest probability. Confidence is model output, not a guarantee of correctness.
Category choices: development, design, writing, research, communication, meetings, planning, administration, sales, marketing, support, training, review, personal, unknown. Context choices: work, personal, uncertain. Project choices: one of the returned canonical project IDs or none. usage contains nonnegative integer input_tokens and output_tokens.
projects contains up to 100 {id,name,context} profiles, derived only from assigned active projects/clients in the key's workspace, sorted by client and project name. These are the canonical profiles used for this call; clients should use them instead of a stale local list. Provider criteria are truncated at Unicode boundaries to a shared 14000-byte UTF-8 JSON budget, including project IDs and escaping, with at most 2048 bytes of descriptive text per project. Long names/descriptions may therefore lose matching context.
Privacy and side effects
Foreground text and project labels are sent through Vercel AI Gateway to the configured Jev provider for classification. TrackTimer does not persist this request or response as activity history and does not log the foreground payload. Provider handling is separate from TrackTimer storage. Responses are no-store. This endpoint never starts, stops, or edits a timer, and a classification is not proof of work or billable time. Review locally before recording time.
Errors, limits, and retries
All public operations share 120 requests per key per 60 seconds. Calls are bounded by a 25-second provider timeout and a 256KiB provider response limit. No Idempotency-Key is required. Retrying may repeat paid model processing and may return a different classification; it cannot duplicate time entries. Use bounded exponential backoff rather than retrying continuously.
400 INVALID_REQUEST: malformed JSON or field validation. 401/403: API authentication or scope failure. 413 ACTIVITY_BODY_TOO_LARGE: request exceeds byte limit. 415 UNSUPPORTED_MEDIA_TYPE: JSON required. 429 API_KEY_RATE_LIMITED: honor Retry-After. 502 ACTIVITY_CLASSIFICATION_FAILED: network interruption, timeout, or provider HTTP failure; retry with bounded backoff. 502 ACTIVITY_CLASSIFICATION_INVALID_RESPONSE: malformed JSON, oversized payload, invalid schema or probability distribution; apply a finite retry limit, then leave the interval for review and continue later intervals. 503 ACTIVITY_CLASSIFICATION_UNAVAILABLE: server Gateway authentication unavailable; keep capture local and retry later. See shared errors.
The server resolves Vercel platform OIDC authentication on each request through the official @vercel/oidc helper, using runtime context on Vercel and the platform environment token locally. Missing credentials or failed local refresh return 503; account connection and local capture remain available. No shared provider credential belongs in the desktop app.