# Streak

2 endpoints.

## Get the workspace's weekly posting streak

```http
GET https://orbitwrite.com/api/v1/streak
```

Consecutive weeks in which the workspace published at least one post, with the longest run, the current week's status and a trailing week-by-week history. Weeks are anchored to the workspace timezone and start on Monday.

**Authentication:** bearer token or session cookie.

### Query parameters

- `organizationId` (string, optional) — Session callers only — an API key already determines the workspace.
- `weekStartsOn` (integer | null, optional) — First day of the week as a getDay() index (0=Sun, 1=Mon, 6=Sat). Defaults to Monday.

### Responses

#### 200

The workspace's posting streak

- `current` (integer, required) — Consecutive weeks with a published post, ending this week.
- `longest` (integer, required) — The workspace's longest run of consecutive posting weeks.
- `state` (string, required, one of `new`, `active`, `at_risk`, `broken`) — `new` (never published), `active` (this week satisfied), `at_risk` (streak alive but this week still empty), `broken` (a run ended and this week is empty).
- `currentWeekSatisfied` (boolean, required)
- `willExtendStreak` (boolean, required) — A scheduled post is set to fire this week, so an at-risk streak is already covered.
- `weekEndsAt` (string, required) — Instant the current week rolls over (ISO 8601).
- `history` (StreakWeek[], required)
  - `weekKey` (string, required) — Week-start date ("YYYY-MM-DD", Monday) in the workspace timezone.
  - `satisfied` (boolean, required)
  - `count` (integer, required) — Distinct posts (composer groups) published that week.
- `last7Days` (StreakDay[], required) — The trailing 7 days (oldest → today) with per-day counts.
  - `dateKey` (string, required) — "YYYY-MM-DD" of the day in the workspace timezone.
  - `count` (integer, required) — Distinct posts (composer groups) published that day.
- `lastPostAt` (string | null, required) — When the workspace most recently published (ISO), or null.

#### 400

Invalid request

- `error` (string, required)
- `issues` (any[], optional)

#### 401

Not signed in

- `error` (string, required)
- `issues` (any[], optional)

#### 403

Not a member of the organization

- `error` (string, required)
- `issues` (any[], optional)

#### 429

Rate limit exceeded

- `error` (string, required)
- `issues` (any[], optional)

## Posts published per day

```http
GET https://orbitwrite.com/api/v1/posting-activity
```

Posts published on each day of the last `weeks` whole weeks, ending today, in the workspace timezone: a synced multi-channel post counts once, thread replies don't count. Pass `userId` for one member's posts (the ones they wrote). Requires `analytics:read`, which covers your own `userId`; anyone else's takes `analytics:readAny` (manager and up). An API key is nobody's self, so any `userId` on a key takes `analytics:readAny`.

**Authentication:** bearer token or session cookie.

### Query parameters

- `organizationId` (string, optional) — Session callers only — an API key already determines the workspace.
- `userId` (string, optional) — A member's user id: only the posts they wrote.
- `weeks` (integer, optional) — Whole weeks ending with this one, 1–53. Defaults to 26.
- `weekStartsOn` (integer | null, optional) — First day of the week as a getDay() index (0=Sun, 1=Mon, 6=Sat). Defaults to Monday.

### Responses

#### 200

Posts per day

- `timezone` (string, required)
- `userId` (string | null, required) — The member the counts are for, or null for the whole workspace.
- `weekStartsOn` (integer, required)
- `from` (string, required) — First day of the first week (YYYY-MM-DD).
- `to` (string, required) — Today in the workspace timezone (YYYY-MM-DD).
- `days` (PostingActivityDay[], required) — Every day from `from` to `to`, oldest first, empty days included.
  - `dateKey` (string, required) — "YYYY-MM-DD" of the day in the workspace timezone.
  - `count` (integer, required) — Distinct posts (composer groups) published that day.
- `total` (integer, required)
- `activeDays` (integer, required)
- `longestStreakDays` (integer, required) — Longest run of consecutive posting days inside the window.
- `currentStreakDays` (integer, required) — Consecutive posting days ending today (or yesterday, while today has nothing yet).
- `busiestDay` (PostingActivityDay | any | null, required)

#### 400

Invalid request

- `error` (string, required)
- `issues` (any[], optional)

#### 401

Not signed in

- `error` (string, required)
- `issues` (any[], optional)

#### 403

Not a member of the organization

- `error` (string, required)
- `issues` (any[], optional)

#### 404

The resource does not exist

- `error` (string, required)
- `issues` (any[], optional)

#### 429

Rate limit exceeded

- `error` (string, required)
- `issues` (any[], optional)
