# Summarize captured activity

Source: https://www.tracktimer.app/docs/summarize-activity

Create a short factual recap from a bounded episode of foreground text without changing tracked time.

`POST /api/v1/activity/summarize`

Required scope: `activity:classify`

## Request

POST https://www.tracktimer.app/api/v1/activity/summarize with Authorization: Bearer YOUR_API_KEY and Content-Type: application/json. Requires activity:classify. Unknown fields are rejected.

Supply episodeId (UUID), revision (64 lowercase hexadecimal characters identifying the evidence revision), and samples (1–24 unique samples). Each sample has id (UUID), start and end (ISO 8601 datetimes with timezone, end not before start), application (nonblank, at most 256 characters), windowTitle (at most 500 characters), screenText (at most 2000 UTF-8 bytes), and category (one of the activity classification categories). The sum of application, windowTitle and screenText UTF-8 bytes across samples must not exceed 32768; the complete request body must not exceed 98304 bytes. No images or provider credentials are accepted.

## Response — 200

Returns episodeId and revision unchanged, title (1–100 characters), summary (1–600 characters), referencedObservationIds (a nonempty, unique subset of submitted sample IDs), model, promptVersion (activity-summary-v2), and usage {inputTokens,outputTokens} with nonnegative integer counts. The model is asked for a concise activity title and a grounded 1–2 sentence recap. Consumers must match episodeId and revision to the current local evidence before saving; a revision is an opaque client fingerprint, not a server-authenticated hash.

```json
{"episodeId":"11111111-1111-4111-8111-111111111111","revision":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","title":"Reviewing project tests","summary":"A terminal displayed project test output.","referencedObservationIds":["22222222-2222-4222-8222-222222222222"],"model":"google/gemini-2.5-flash-lite","promptVersion":"activity-summary-v2","usage":{"inputTokens":100,"outputTokens":25}}
```

## Privacy and side effects

Bounded foreground text is sent through Vercel AI Gateway to google/gemini-2.5-flash-lite. Known credential patterns are redacted on input and output as a best-effort measure, not a guarantee. Screenshots stay local. TrackTimer does not persist or log the submitted evidence or generated recap. Responses are no-store. Summaries cannot create or modify time entries, measured durations, categories, or projects; review generated descriptions for accuracy.

## Errors, limits, and retries

The shared quota is 120 requests per API key per 60 seconds. The provider deadline is 25 seconds and its response is capped at 32768 bytes. Authentication and scope failures return 401/403; malformed JSON or fields return 400; oversized requests return 413; non-JSON content returns 415; rate limits return 429 with Retry-After. Provider network/HTTP failures return 502 ACTIVITY_SUMMARY_FAILED. Malformed, truncated, oversized, or unsupported-evidence responses return 502 ACTIVITY_SUMMARY_INVALID_RESPONSE. Unavailable platform Gateway credentials return 503 ACTIVITY_SUMMARY_UNAVAILABLE. Error bodies never include provider response content.

No Idempotency-Key is required and summaries are not stored by this endpoint. Retrying can repeat paid inference and return different text; use a finite retry budget with exponential backoff. Keep captured evidence locally when unavailable. See [authentication](https://www.tracktimer.app/docs/authentication) and [errors and retries](https://www.tracktimer.app/docs/errors-and-retries).

Examples use illustrative IDs and data. Use the values returned by your own workspace. [Review error handling and retry behavior.](https://www.tracktimer.app/docs/errors-and-retries)
