---
title: "Everything the app shell needs, in one request"
method: GET
path: "/api/v1/bootstrap"
tags: ["bootstrap"]
---

# Everything the app shell needs, in one request

`GET /api/v1/bootstrap`

## Request

- Base URL: `https://api.cadencz.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.cadencz.com/api/v1/bootstrap`
- Auth: HTTP bearer

Returns the payloads of `/me`, `/me/preferences`, `/channels`, `/billing/subscription`, `/billing/usage`, `/strategy`, `/plans/current`, `/brains` and `/media` in a single response, each byte-identical to what its own endpoint returns.

Only `me` is required: it gates the shell, so if it fails the request fails. Every other section degrades to `null` with its name listed in `failed`, which the client should read as *fetch this one yourself*. A `null` section absent from `failed` is a genuine empty — today only `plan`, when the workspace has not generated one yet.

## Response `200`

Successful Response

- BootstrapResponse: Everything the app shell needs to render, in one round trip. Each field carries exactly the payload its own endpoint returns, so the client can seed its cache key-for-key and never learns a second shape. A `null` section means one of two different things, and `failed` is what tells them apart: a name listed there could not be read and the client should fetch that one endpoint itself, while a `null` that is *not* listed is a real absence (no content plan yet). Without that split, an outage in one section would be indistinguishable from an empty workspace.
  - `me` CurrentUserResponse, required
    - `user` CurrentUserProfile, required
      - `id` string, required
      - `email` string, required
      - `name` string, required
      - `avatarUrl` string, nullable, required
      - `timezone` string, required
      - `isAdmin` boolean
      - `createdAt` string, nullable
    - `workspace` CurrentWorkspaceProfile, required
      - `id` string, required
      - `ownerId` string, required
      - `name` string, required
      - `handle` string, required
      - `avatarUrl` string, nullable, required
    - `workspaces` CurrentWorkspaceProfile[], required
      - `id` string, required
      - `ownerId` string, required
      - `name` string, required
      - `handle` string, required
      - `avatarUrl` string, nullable, required
    - `role` string
    - `accountId` string
    - `permissions` string[]
    - `workspaceCap` integer
    - `setupComplete` boolean
  - `preferences` UserPreferences
    - `timezone` string, required
    - `weekStart` string
    - `quietHours` unknown
  - `channels` ChannelRead[], nullable
    - `id` string, required
    - `workspace_id` string, required
    - `platform` string, required
    - `handle` string, required
    - `display_name` string, nullable, required
    - `avatar_url` string, nullable, required
    - `status` string, required
    - `byo_app` boolean, required
    - `token_expires_at` string, date-time, nullable, required
    - `followers` integer, required
    - `capabilities` object
    - `plan_entitled` boolean
    - `entitlement_status` 'available' | 'plan_paused' | 'disconnected'
    - `plan_pause_reason` 'plan_required' | 'workspace_limit' | 'platform_limit', nullable
  - `subscription` SubscriptionRead
    - `id` string, required
    - `workspace_id` string, required
    - `tier` string, required
    - `plan_state` string, required
    - `plan_label` string, required
    - `status` string, required
    - `renews_at` string, nullable, required
    - `cancel_at_period_end` boolean, required
    - `billing_period` 'monthly' | 'yearly', nullable, required
    - `has_provider_subscription` boolean
    - `trial_eligible` boolean, required
    - `included_credits` integer, required
    - `channel_cap` integer, required
  - `usage` CreditUsageResponse
    - `user_id` string, required
    - `workspace_id` string, required
    - `balance` integer, required
    - `granted` integer, required
    - `used` integer, required
    - `workspace_balance` integer, required
    - `workspace_granted` integer, required
    - `workspace_used` integer, required
    - `cost_usd_micros` integer, required
    - `workspace_cost_usd_micros` integer, required
    - `categories` CreditCategoryUsageRead[], required
      - `reason` string, required
      - `label` string, required
      - `granted` integer, required
      - `used` integer, required
      - `balance` integer, required
      - `cost_usd_micros` integer, required
    - `projects` CreditProjectUsageRead[], required
      - `project_id` string, required
      - `project_type` 'workspace' | 'brain', required
      - `name` string, required
      - `workspace_id` string, required
      - `granted` integer, required
      - `used` integer, required
      - `balance` integer, required
      - `cost_usd_micros` integer, required
  - `strategy` StrategyRead
    - `workspace_id` string, required
    - `niche` string, nullable, required
    - `goals` string[], required
    - `whats_new` string, nullable
    - `tags` string[], required
    - `tone_profile` object, required
    - `voice_profile` VoiceProfile, required: The whole authored document. Empty is valid — it just means untouched.
      - `personas` VoicePersona[]
        - `id` string, required
        - `name` string
        - `audience` string
        - `context` string
        - `mission` string
        - `traits` string[]
        - `goals` string[]
        - `tone` ToneAxis[]
          - `id` string, required
          - `low` string, required
          - `high` string, required
          - `value` integer
        - `vocabulary` string[]
        - `banned_words` string[]
        - `ctas` string[]
        - `formatting` string[]
        - `active` boolean
        - `created_at` string, date-time, nullable
        - `updated_at` string, date-time, nullable
      - `versions` VoiceVersion[]
        - `id` string, required
        - `persona_id` string, required
        - `label` string
        - `saved_at` string, date-time, required
        - `snapshot` VoicePersona, required: A named way of speaking. Exactly one persona is active at a time.
          - `id` string, required
          - `name` string
          - `audience` string
          - `context` string
          - `mission` string
          - `traits` string[]
          - `goals` string[]
          - `tone` ToneAxis[]
            - `id` string, required
            - `low` string, required
            - `high` string, required
            - `value` integer
          - `vocabulary` string[]
          - `banned_words` string[]
          - `ctas` string[]
          - `formatting` string[]
          - `active` boolean
          - `created_at` string, date-time, nullable
          - `updated_at` string, date-time, nullable
    - `voice_samples` string[], required
    - `voice_sample_platforms` object
    - `voice_platforms_learned` string[]
    - `cadence_per_week` integer, required
    - `platforms` string[], required
    - `automation` AutomationSettings, required: When the agents plan, and when the posts they produce go out.
      - `enabled` boolean: Off by default. Auto-planning spends credits, so it's opt-in.
      - `suspended_by_plan` boolean: Cadencz turned automation off after plan access was lost. The saved schedule remains, but the customer must explicitly enable it again.
      - `auto_write_week` boolean: Write the week's posts on their own at the planning hour, so the stack always has a fresh week on it. Every plan; bounded by the tier's weekly number and the monthly pool. Distinct from `enabled`, which is the paid Automation feature (rules, auto-approve).
      - `plan_weekday` integer: 0 = Monday.
      - `plan_hour` integer: Local hour, 24h.
      - `timezone` string: IANA zone.
      - `posting_weekdays` integer[]: Days posts may be scheduled on. 0 = Monday.
      - `posting_times` string[]: HH:MM slots, cycled through in order.
      - `day_platforms` object: Which channel each weekday posts to, keyed by weekday index as a string ('0' = Monday). A day with no entry falls back to the workspace's platform rotation.
      - `platform_quota` object: How many posts each channel gets per batch, keyed by platform id. The batch is their sum. Zero (or absent) means the channel gets none; empty means the planner decides per post from cadence.
      - `brain_id` string, nullable: Ground posts in this Brain. None = the most recently updated.
      - `auto_approve` boolean: Schedule straight to the calendar instead of holding for review.
    - `updated_at` string, date-time, required
  - `plan` PlanRead
    - `id` string, required
    - `workspace_id` string, required
    - `week_of` string, date-time, required
    - `goal` string, required
    - `niche` string, required
    - `status` string, required
    - `items` PlanItemRead[], required
      - `id` string, required
      - `theme` string, nullable, required
      - `angle` string, nullable, required
      - `platforms` string[], required
      - `why` string, nullable, required
      - `prompt` string, required
      - `scheduled_for` string, date-time, nullable, required
      - `status` string, required
      - `format` string, nullable
      - `publish_mode` string
      - `content_metadata` object
      - `body_parts` string[]
      - `media_ids` string[]
      - `media` MediaRead[]
        - `id` string, required
        - `kind` string, required
        - `url` string, required
        - `alt_text` string, nullable
        - `width` integer, nullable
        - `height` integer, nullable
        - `bytes` integer, nullable
      - `created_at` string, date-time, nullable
    - `created_at` string, date-time, required
  - `brains` BrainRead[], nullable
    - `id` string, required
    - `workspace_id` string, required
    - `name` string, required
    - `tagline` string, required
    - `emoji` string, required
    - `accent` string, required
    - `source_count` integer, required
    - `fact_count` integer, required
    - `site_url` string, nullable
    - `updated_at` string, date-time, required
    - `created_at` string, date-time, required
  - `media` object[], nullable
  - `failed` string[]

## Other responses

- `401`: Missing or invalid Supabase bearer token.
- `503`: Required infrastructure or provider config is unavailable.

---

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