---
title: "Render an aggregated report as a social image"
method: POST
path: "/v1/report-render"
tags: ["Report Render"]
---

# Render an aggregated report as a social image

`POST /v1/report-render`

Accepts only a versioned aggregate payload. Raw task entries, notes, rates, location, and invoice data are not part of this contract. The image is rendered in memory and is not persisted. No authentication is required, so the apps can share a report before the user has an account; requests are rate limited per client IP.

## Request body

- ReportRenderRequest
  - `templateId` string
  - `templateVersion` integer
  - `platform` 'instagram' | 'facebook' | 'tiktok' | 'youtube' | 'threads' | 'linkedin' | 'generic'
  - `placement` 'post' | 'reel' | 'story' | 'short'
  - `payload` ReportRenderPayload
    - `schemaVersion` integer
    - `reportType` 'month' | 'year'
    - `period` ReportPeriod
      - `start` string
      - `end` string
      - `label` string
    - `locale` string
    - `timeZone` string
    - `stats` ReportStats
      - `trackedSeconds` integer
      - `activeDays` integer
      - `projectCount` integer
      - `tagCount` integer
      - `averageSecondsPerActiveDay` integer
      - `longestStreak` integer
      - `mostActiveWeekday` integer
    - `distribution` ReportDistributionItem[]
      - `id` string
      - `label` string
      - `percentage` number, double
      - `trackedSeconds` integer
    - `activity` ReportActivity
      - `days` ReportActivityDay[]
        - `date` string
        - `intensity` integer
    - `achievements` ReportAchievement[]
      - `id` string
      - `type` string
      - `value` integer
    - `comparison` ReportComparison
      - `trackedTimeChangePercent` number, double
      - `activeDaysChange` integer
      - `projectCountChange` integer
    - `visibility` ReportVisibilitySettings
      - `showTrackedTime` boolean
      - `showProjectNames` boolean
      - `showActivity` boolean
      - `showAchievements` boolean
      - `showComparison` boolean

## Response `200`

PNG image rendered successfully

## Other responses

- `400` — Unsupported preset or invalid aggregate payload
- `429` — Render rate limit exceeded

## Changes

> 8 revisions in range; 1 not diffed.

- **2026-09-08** `217ee0d372af` — 1 info
  - removed the non-success response with the status `401`
- **2026-09-06** `24f693bd6f1f` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/timesheet/apis/timesheet-api/changes/v1/report-render/post.md)

---

[API](https://skmtc.dev/timesheet/apis/timesheet-api.md) · [All operations](https://skmtc.dev/timesheet/apis/timesheet-api/llms.txt) · [OpenAPI document](https://skmtc.dev/timesheet/apis/timesheet-api/revisions/a3d2f44e7345?raw)
