Files
kvitt/web/src/api/schema.d.ts
T
jacobh2 2ae65a5a9f
Build Kvitt images / build (push) Failing after 1h14m5s
W0 web foundation: Vite + React SPA under /app/, sync-pull ledger, auth, tokens, shared components
web/ is the browser client's scaffold: Vite 8, React 19, TypeScript 5.9 strict, React Router 7 (basename /app, every
fixed route with a lazy placeholder page), TanStack Query 5 (refetch on focus and every 60 s), openapi-typescript
types generated from contracts/openapi.yaml with openapi-fetch. Reads go through GET /sync (no REST reads exist for
the ledger, SPEC §7): useLedger() pulls from cursor 0 and then incrementally, restarting on a new epoch or
cursor_ahead. Login pairs the browser as "Web · <browser>" with an invite code (E-3); every call sends the SPEC
§14.3.1 headers, a 401 signs out. kvitt-domain's split, balances, allocation and settlement rules are ported to
web/src/lib and pass every case of contracts/test-vectors. Design tokens from design-spec §2 in tokens.css
(light-dark()), Material Symbols Rounded (Apache-2.0) as generated inline SVG, sv/en catalogs generated from
docs/ux/strings.csv plus web-strings.csv. Gate: cd web && npm run check.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B
2026-10-21 21:03:25 +02:00

2725 lines
118 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* This file was auto-generated by openapi-typescript.
* Do not make direct changes to the file.
*/
export interface paths {
"/health": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** E-1 Liveness and DB check */
get: operations["getHealth"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/setup/status": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** E-2 Whether the household has been bootstrapped */
get: operations["getSetupStatus"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/invites/accept": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/** E-3 Pair a device with an invite code (all three invite kinds) */
post: operations["acceptInvite"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/i/{code}": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/**
* E-4 Invite landing page (HTML)
* @description HTML per AC-2.5 for any `code` of 1 to 32 characters; validity is not checked. Swedish when
* `Accept-Language` prefers `sv`, English otherwise.
*/
get: operations["getInviteLanding"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/apk/latest": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** E-5 Latest APK metadata */
get: operations["getApkLatest"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/apk/files/{file_name}": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** E-6 APK download */
get: operations["getApkFile"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/me": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** E-7 Current user, device and household users */
get: operations["getMe"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
/** E-8 Change own display name */
patch: operations["patchMe"];
trace?: never;
};
"/me/picture": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
/**
* E-9 Upload own picture
* @description JPEG, PNG or WebP up to 5 MiB and 8000 × 8000 px; processed per AC-4.4.
*/
put: operations["putMePicture"];
post?: never;
/**
* E-10 Remove own picture
* @description Idempotent.
*/
delete: operations["deleteMePicture"];
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/users/{user_id}/picture": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** E-11 Download a user's picture */
get: operations["getUserPicture"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/invites": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** E-13 List pending invites (admin) */
get: operations["listInvites"];
put?: never;
/**
* E-12 Create a partner or device invite (admin)
* @description Creating a `partner` invite cancels any pending one (AC-2.1).
*/
post: operations["createInvite"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/invites/{invite_id}": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
post?: never;
/**
* E-14 Cancel an invite (admin)
* @description Idempotent for an already cancelled invite.
*/
delete: operations["cancelInvite"];
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/devices": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/** E-15 List devices (admin all, member own) */
get: operations["listDevices"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/devices/{device_id}": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
post?: never;
/**
* E-16 Revoke a device
* @description Revoking an already revoked device is 204. Admin any device except the current one; member own devices except the current one (SPEC §8.4).
*/
delete: operations["revokeDevice"];
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/devices/current/push-token": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
/** E-17 Set or clear this device's FCM token */
put: operations["putPushToken"];
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/accounts": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/** E-18 Create account */
post: operations["createAccount"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/accounts/{account_id}": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
post?: never;
/**
* E-22 Soft delete when empty
* @description Refused while a non-deleted expense, an allocation of a non-deleted settlement or a non-deleted recurring template references the account (AC-6.5).
*/
delete: operations["deleteAccount"];
options?: never;
head?: never;
/** E-19 Rename, change default ratio */
patch: operations["patchAccount"];
trace?: never;
};
"/accounts/{account_id}/archive": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* E-20 Archive account
* @description No body. Idempotent.
*/
post: operations["archiveAccount"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/accounts/{account_id}/unarchive": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* E-21 Unarchive account
* @description No body. Idempotent.
*/
post: operations["unarchiveAccount"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/categories": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* E-23 Create category
* @description New categories get `sort_order` = current maximum + 10 (AC-7.3). `icon` and `color` are tokens of SPEC §9.7.
*/
post: operations["createCategory"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/categories/{category_id}": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
post?: never;
/** E-27 Soft delete when unused and not default */
delete: operations["deleteCategory"];
options?: never;
head?: never;
/**
* E-24 Rename, icon, colour, order, reset name
* @description `name: null` resets a default category's name. Reordering several categories is one PATCH per category whose
* `sort_order` changes.
*/
patch: operations["patchCategory"];
trace?: never;
};
"/categories/{category_id}/archive": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* E-25 Archive category
* @description No body.
*/
post: operations["archiveCategory"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/categories/{category_id}/unarchive": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* E-26 Unarchive category
* @description No body.
*/
post: operations["unarchiveCategory"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/recurring-templates": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* E-28 Create recurring template
* @description If a period is already due (SPEC §9.5), the server generates it before responding.
*/
post: operations["createRecurringTemplate"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/recurring-templates/{template_id}": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
post?: never;
/** E-30 Soft delete recurring template */
delete: operations["deleteRecurringTemplate"];
options?: never;
head?: never;
/**
* E-29 Edit, pause, resume
* @description Any subset of the E-28 fields; `split_mode` and `splits` must be sent together.
*/
patch: operations["patchRecurringTemplate"];
trace?: never;
};
"/sync": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/**
* E-31 Pull changes since a cursor
* @description SPEC §14.4.2.
*/
get: operations["syncPull"];
put?: never;
/**
* E-32 Push local expense and settlement changes
* @description SPEC §14.4.3 and §14.4.4. 1 to 100 mutations, body at most 1 MiB. One result per mutation, in request order.
*/
post: operations["syncPush"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/settlements/proposal": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
get?: never;
put?: never;
/**
* E-33 Server-side allocation proposal
* @description Computed with `kvitt-domain::propose_allocation` (SPEC §9.4) over the server's non-deleted rows.
*/
post: operations["proposeSettlement"];
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/analytics/trends": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/**
* E-34 Spending trends and category averages
* @description D-133, SPEC §14.5.7. The last `months` whole calendar months before the current one (Europe/Stockholm), for
* the household and per category: each month's spend, the trailing 3-month moving average (the first months
* average what exists, D-128), the total, the average per month (half-up to öre, empty months count), the last
* whole month against the average in whole percent (half-up; null when the average is 0), and the current month
* so far. Non-deleted expenses only; settlements never count; archived and deleted categories count.
*/
get: operations["getAnalyticsTrends"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
"/analytics/forecast": {
parameters: {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
/**
* E-35 Spending forecast per account
* @description D-133, SPEC §14.5.7. For every non-deleted account (archived included) and each of the two calendar months
* after the current one (Europe/Stockholm): `recurring_ore` = the amounts of the account's non-paused,
* non-deleted recurring templates due in that month (one per template and month, within `start_period` and
* `end_period`); `baseline_ore` = the account's spend over the last 3 whole months (the window of D-128's moving
* average), expenses generated from a recurring template excluded, divided by 3 (half-up to öre; months without
* spend count, so a new account has a lower baseline); `forecast_ore = recurring_ore + baseline_ore`. `current_month_ore` is the current month so
* far, generated expenses included. `my_share` uses the shares a generation would write today.
*/
get: operations["getAnalyticsForecast"];
put?: never;
post?: never;
delete?: never;
options?: never;
head?: never;
patch?: never;
trace?: never;
};
}
export type webhooks = Record<string, never>;
export interface components {
schemas: {
/**
* Format: uuid
* @description Lowercase, hyphenated, 36 characters (UUIDv7).
*/
Uuid: string;
/**
* Format: date-time
* @description RFC 3339 UTC, millisecond precision, literal Z.
*/
Timestamp: string;
/** Format: date */
Date: string;
/** @description A month, YYYY-MM. */
Period: string;
/**
* Format: int64
* @description Money in öre (1/100 SEK).
*/
Ore: number;
/**
* Format: int64
* @description From the one global, strictly increasing sequence (SPEC §5.2).
*/
ServerVersionNumber: number;
/** @enum {string} */
Role: "admin" | "member";
/** @enum {string} */
InviteKind: "admin_setup" | "partner" | "device";
/** @enum {string} */
DefaultCategoryKey: "groceries" | "restaurants" | "home" | "utilities" | "transport" | "travel" | "entertainment" | "health" | "shopping" | "other" | "housing" | "insurance" | "children" | "fees";
/** @enum {string} */
SplitMode: "default" | "ratio" | "exact" | "full";
/**
* @description AC-14.4. `household` sums full expense amounts, whoever paid; `my_share` the calling user's shares.
* @enum {string}
*/
AnalyticsMeasure: "household" | "my_share";
/** @enum {string} */
EntityType: "expense" | "settlement";
/** @enum {string} */
AuditAction: "create" | "update" | "delete";
/** @enum {string} */
AuditSource: "app" | "recurring" | "import";
/**
* @description Exhaustive (SPEC §14.3.2). The app maps `code` (and `field`) to localised strings.
* @enum {string}
*/
ErrorCode: "invalid_request" | "invite_invalid" | "unauthorized" | "device_revoked" | "forbidden" | "not_found" | "household_full" | "household_incomplete" | "name_taken" | "account_not_empty" | "category_in_use" | "category_is_default" | "cannot_revoke_current_device" | "no_accounts" | "cursor_ahead" | "payload_too_large" | "unsupported_media_type" | "validation_failed" | "image_invalid" | "batch_too_large" | "protocol_unsupported" | "rate_limited" | "internal" | "not_implemented" | "unavailable";
/**
* @description Exhaustive (SPEC §14.4.6).
* @enum {string}
*/
RejectionReason: "stale" | "deleted" | "validation_failed" | "reference_not_found" | "clock_skew";
User: {
id: components["schemas"]["Uuid"];
role: components["schemas"]["Role"];
display_name: string;
picture_version: number | null;
created_at: components["schemas"]["Timestamp"];
updated_at: components["schemas"]["Timestamp"];
server_version: components["schemas"]["ServerVersionNumber"];
};
/** @description Only in /me, /devices and /invites/accept. */
Device: {
id: components["schemas"]["Uuid"];
user_id: components["schemas"]["Uuid"];
name: string;
app_version_code: number | null;
/** @description The app's `versionName` from `X-Kvitt-App-Version-Name`; null until a request carried it. */
app_version_name: string | null;
created_at: components["schemas"]["Timestamp"];
last_seen_at: components["schemas"]["Timestamp"];
revoked_at: components["schemas"]["Timestamp"] | null;
is_current: boolean;
};
/** @description `code` and `link` only in the POST /invites response; null in GET /invites. */
Invite: {
id: components["schemas"]["Uuid"];
kind: components["schemas"]["InviteKind"];
target_user_id: components["schemas"]["Uuid"] | null;
code: string | null;
link: string | null;
created_at: components["schemas"]["Timestamp"];
expires_at: components["schemas"]["Timestamp"];
};
/** @description A share of an account default. */
Share: {
user_id: components["schemas"]["Uuid"];
share_bp: number;
};
Account: {
id: components["schemas"]["Uuid"];
name: string;
/** @description Sorted by `user_id`. */
default_shares: components["schemas"]["Share"][];
created_by_user_id: components["schemas"]["Uuid"];
created_at: components["schemas"]["Timestamp"];
updated_at: components["schemas"]["Timestamp"];
archived_at: components["schemas"]["Timestamp"] | null;
deleted_at: components["schemas"]["Timestamp"] | null;
server_version: components["schemas"]["ServerVersionNumber"];
};
Category: {
id: components["schemas"]["Uuid"];
default_key: components["schemas"]["DefaultCategoryKey"] | null;
name: string | null;
/** @description An icon token of SPEC §9.7. */
icon: string;
/** @description A colour token of SPEC §9.7. */
color: string;
sort_order: number;
created_at: components["schemas"]["Timestamp"];
updated_at: components["schemas"]["Timestamp"];
archived_at: components["schemas"]["Timestamp"] | null;
deleted_at: components["schemas"]["Timestamp"] | null;
server_version: components["schemas"]["ServerVersionNumber"];
};
/** @description A split of an expense; `share_bp` null for mode exact. */
Split: {
user_id: components["schemas"]["Uuid"];
share_ore: components["schemas"]["Ore"];
share_bp: number | null;
};
/** @description Exactly one of `share_bp` / `share_ore` non-null. */
TemplateSplit: {
user_id: components["schemas"]["Uuid"];
share_bp: number | null;
/** Format: int64 */
share_ore: number | null;
};
Expense: {
id: components["schemas"]["Uuid"];
account_id: components["schemas"]["Uuid"];
category_id: components["schemas"]["Uuid"];
amount_ore: components["schemas"]["Ore"];
description: string;
notes: string;
expense_date: components["schemas"]["Date"];
payer_user_id: components["schemas"]["Uuid"];
split_mode: components["schemas"]["SplitMode"];
/** @description Sorted by `user_id`. */
splits: components["schemas"]["Split"][];
recurring_template_id: components["schemas"]["Uuid"] | null;
recurring_period: components["schemas"]["Period"] | null;
created_by_user_id: components["schemas"]["Uuid"];
updated_by_user_id: components["schemas"]["Uuid"];
created_at: components["schemas"]["Timestamp"];
updated_at: components["schemas"]["Timestamp"];
deleted_at: components["schemas"]["Timestamp"] | null;
server_version: components["schemas"]["ServerVersionNumber"];
};
Allocation: {
account_id: components["schemas"]["Uuid"];
amount_ore: components["schemas"]["Ore"];
};
Settlement: {
id: components["schemas"]["Uuid"];
from_user_id: components["schemas"]["Uuid"];
to_user_id: components["schemas"]["Uuid"];
amount_ore: components["schemas"]["Ore"];
settlement_date: components["schemas"]["Date"];
note: string;
/** @description Sorted by `account_id`. */
allocations: components["schemas"]["Allocation"][];
created_by_user_id: components["schemas"]["Uuid"];
updated_by_user_id: components["schemas"]["Uuid"];
created_at: components["schemas"]["Timestamp"];
updated_at: components["schemas"]["Timestamp"];
deleted_at: components["schemas"]["Timestamp"] | null;
server_version: components["schemas"]["ServerVersionNumber"];
};
RecurringTemplate: {
id: components["schemas"]["Uuid"];
account_id: components["schemas"]["Uuid"];
category_id: components["schemas"]["Uuid"];
amount_ore: components["schemas"]["Ore"];
description: string;
notes: string;
payer_user_id: components["schemas"]["Uuid"];
split_mode: components["schemas"]["SplitMode"];
/** @description Sorted by `user_id`; empty for mode default. */
splits: components["schemas"]["TemplateSplit"][];
day_of_month: number;
start_period: components["schemas"]["Period"];
end_period: components["schemas"]["Period"] | null;
paused: boolean;
last_generated_period: components["schemas"]["Period"] | null;
/** @description Computed by the server (SPEC §9.5); null when paused, deleted or past `end_period`. */
next_occurrence_date: components["schemas"]["Date"] | null;
created_by_user_id: components["schemas"]["Uuid"];
updated_by_user_id: components["schemas"]["Uuid"];
created_at: components["schemas"]["Timestamp"];
updated_at: components["schemas"]["Timestamp"];
deleted_at: components["schemas"]["Timestamp"] | null;
server_version: components["schemas"]["ServerVersionNumber"];
};
/** @description One field of the audit diff (SPEC §14.4.7). `old` and `new` are JSON values of the field's type, or null. */
AuditChange: {
field: string;
old: unknown;
new: unknown;
};
AuditEntry: {
id: components["schemas"]["Uuid"];
entity_type: components["schemas"]["EntityType"];
entity_id: components["schemas"]["Uuid"];
action: components["schemas"]["AuditAction"];
source: components["schemas"]["AuditSource"];
actor_user_id: components["schemas"]["Uuid"];
client_at: components["schemas"]["Timestamp"];
server_at: components["schemas"]["Timestamp"];
changes: components["schemas"]["AuditChange"][];
server_version: components["schemas"]["ServerVersionNumber"];
};
/** @description `message` is English developer text, never shown to users. `field` is the JSON key concerned or null. */
Error: {
code: components["schemas"]["ErrorCode"];
message: string;
field: string | null;
};
Health: {
/** @enum {string} */
status: "ok" | "degraded";
server_version: string;
schema_version: number;
db_ok: boolean;
};
SetupStatus: {
initialized: boolean;
};
AcceptInviteRequest: {
/** @description Normalised per SPEC §8.3 by the app before sending. */
code: string;
device_name: string;
/** @description Required for `admin_setup` and `partner` invites (`invalid_request` if missing), ignored for `device`. */
display_name?: string;
};
AcceptInviteResponse: {
/** @description `kvt_` + base64url without padding of 32 random bytes (47 characters, SPEC §8.2). */
token: string;
/** @description The kind of the accepted invite; the app shows the profile step only after `partner` (AC-2.10). */
invite_kind: components["schemas"]["InviteKind"];
user: components["schemas"]["User"];
device: components["schemas"]["Device"];
household: components["schemas"]["User"][];
};
/** @description `latest.json` (SPEC §10.6). */
ApkLatest: {
version_code: number;
version_name: string;
file_name: string;
/** Format: int64 */
size_bytes: number;
sha256: string;
released_at: components["schemas"]["Timestamp"];
};
MeResponse: {
user: components["schemas"]["User"];
device: components["schemas"]["Device"];
household: components["schemas"]["User"][];
public_url: string;
};
PatchMeRequest: {
display_name?: string;
};
CreateInviteRequest: {
/** @enum {string} */
kind: "partner" | "device";
/** @description Required for `device`, must be null for `partner`. */
target_user_id?: components["schemas"]["Uuid"] | null;
};
InviteList: {
invites: components["schemas"]["Invite"][];
};
DeviceList: {
devices: components["schemas"]["Device"][];
};
PushTokenRequest: {
fcm_token: string | null;
};
CreateAccountRequest: {
name: string;
default_shares: components["schemas"]["Share"][];
};
PatchAccountRequest: {
name?: string;
default_shares?: components["schemas"]["Share"][];
};
CreateCategoryRequest: {
name: string;
icon: string;
color: string;
};
PatchCategoryRequest: {
/** @description null resets a default category's name (`category_is_default` on a non-default category). */
name?: string | null;
icon?: string;
color?: string;
sort_order?: number;
};
/**
* @description `splits` per SPEC §9.1: none for `default`; two bp entries for `ratio` and `full`; two öre entries summing to the
* amount for `exact`.
*/
CreateRecurringTemplateRequest: {
account_id: components["schemas"]["Uuid"];
category_id: components["schemas"]["Uuid"];
amount_ore: components["schemas"]["Ore"];
description: string;
notes: string;
payer_user_id: components["schemas"]["Uuid"];
split_mode: components["schemas"]["SplitMode"];
splits: components["schemas"]["TemplateSplit"][];
day_of_month: number;
start_period: components["schemas"]["Period"];
end_period: components["schemas"]["Period"] | null;
paused: boolean;
};
/** @description Any subset of the E-28 fields; `split_mode` and `splits` must be sent together. */
PatchRecurringTemplateRequest: {
account_id?: components["schemas"]["Uuid"];
category_id?: components["schemas"]["Uuid"];
amount_ore?: components["schemas"]["Ore"];
description?: string;
notes?: string;
payer_user_id?: components["schemas"]["Uuid"];
split_mode?: components["schemas"]["SplitMode"];
splits?: components["schemas"]["TemplateSplit"][];
day_of_month?: number;
start_period?: components["schemas"]["Period"];
end_period?: components["schemas"]["Period"] | null;
paused?: boolean;
};
ProposalRequest: {
payer_user_id: components["schemas"]["Uuid"];
amount_ore: components["schemas"]["Ore"];
/** @description The settlement being edited, excluded from the balances. */
exclude_settlement_id?: components["schemas"]["Uuid"] | null;
};
ProposalResponse: {
/** @description In the order produced by SPEC §9.4. */
allocations: components["schemas"]["Allocation"][];
excess_ore: components["schemas"]["Ore"];
over_settled_account_ids: components["schemas"]["Uuid"][];
};
TrendPoint: {
month: components["schemas"]["Period"];
amount_ore: components["schemas"]["Ore"];
/** @description Trailing over 3 months; the first points average what exists (D-128). */
moving_average_ore: components["schemas"]["Ore"];
};
Trend: {
/** @description Sum over the whole months. */
total_ore: components["schemas"]["Ore"];
/** @description `total_ore` ÷ months, half-up to öre (empty months count). */
average_ore: components["schemas"]["Ore"];
/** @description The last whole month (the month before the current one). */
last_month_ore: components["schemas"]["Ore"];
/** @description `last_month_ore` against `average_ore`, whole percent of the average, half-up; null when the average is 0. */
last_month_vs_average_pct: number | null;
/** @description The current month from its first day to today (Europe/Stockholm); not one of the whole months. */
current_month_ore: components["schemas"]["Ore"];
/** @description One point per whole month, oldest first, empty months as zero. */
points: components["schemas"]["TrendPoint"][];
};
CategoryTrend: {
category_id: components["schemas"]["Uuid"];
trend: components["schemas"]["Trend"];
};
TrendsResponse: {
measure: components["schemas"]["AnalyticsMeasure"];
/** @description Today in Europe/Stockholm. */
today: components["schemas"]["Date"];
current_month: components["schemas"]["Period"];
/** @description The number of whole months in every series. */
months: number;
household: components["schemas"]["Trend"];
/** @description Every category with spending in the whole months or the current month (archived and deleted included), by `total_ore` descending, then `category_id`. */
categories: components["schemas"]["CategoryTrend"][];
};
ForecastMonth: {
month: components["schemas"]["Period"];
recurring_ore: components["schemas"]["Ore"];
baseline_ore: components["schemas"]["Ore"];
/** @description `recurring_ore + baseline_ore`. */
forecast_ore: components["schemas"]["Ore"];
};
AccountForecast: {
account_id: components["schemas"]["Uuid"];
/** @description The current month so far, recurring-generated expenses included. */
current_month_ore: components["schemas"]["Ore"];
/** @description The two months after the current one, in order. */
months: components["schemas"]["ForecastMonth"][];
};
ForecastResponse: {
measure: components["schemas"]["AnalyticsMeasure"];
/** @description Today in Europe/Stockholm. */
today: components["schemas"]["Date"];
current_month: components["schemas"]["Period"];
/** @description Every non-deleted account, archived included, by `created_at`, then `account_id`. */
accounts: components["schemas"]["AccountForecast"][];
};
SyncPullResponse: {
/** @description `meta.sync_epoch`, 32 lowercase hex characters. */
epoch: string;
/** Format: int64 */
since: number;
/**
* Format: int64
* @description The highest `server_version` in the page, or `since` when the page is empty.
*/
next_since: number;
has_more: boolean;
server_time: components["schemas"]["Timestamp"];
users: components["schemas"]["User"][];
categories: components["schemas"]["Category"][];
accounts: components["schemas"]["Account"][];
recurring_templates: components["schemas"]["RecurringTemplate"][];
expenses: components["schemas"]["Expense"][];
settlements: components["schemas"]["Settlement"][];
audit_entries: components["schemas"]["AuditEntry"][];
};
/**
* @description Exactly the client-writable fields (SPEC §14.4.3). Server-owned fields are ignored if sent. A delete is the full
* entity with `deleted_at` set.
*/
PushedExpense: {
id: components["schemas"]["Uuid"];
account_id: components["schemas"]["Uuid"];
category_id: components["schemas"]["Uuid"];
amount_ore: components["schemas"]["Ore"];
description: string;
notes: string;
expense_date: components["schemas"]["Date"];
payer_user_id: components["schemas"]["Uuid"];
split_mode: components["schemas"]["SplitMode"];
splits: components["schemas"]["Split"][];
created_at: components["schemas"]["Timestamp"];
updated_at: components["schemas"]["Timestamp"];
deleted_at: components["schemas"]["Timestamp"] | null;
};
/** @description Exactly the client-writable fields (SPEC §14.4.3). */
PushedSettlement: {
id: components["schemas"]["Uuid"];
from_user_id: components["schemas"]["Uuid"];
to_user_id: components["schemas"]["Uuid"];
amount_ore: components["schemas"]["Ore"];
settlement_date: components["schemas"]["Date"];
note: string;
allocations: components["schemas"]["Allocation"][];
created_at: components["schemas"]["Timestamp"];
updated_at: components["schemas"]["Timestamp"];
deleted_at: components["schemas"]["Timestamp"] | null;
};
ExpenseMutation: {
mutation_id: components["schemas"]["Uuid"];
/**
* @description discriminator enum property added by openapi-typescript
* @enum {string}
*/
entity_type: "expense";
entity: components["schemas"]["PushedExpense"];
};
SettlementMutation: {
mutation_id: components["schemas"]["Uuid"];
/**
* @description discriminator enum property added by openapi-typescript
* @enum {string}
*/
entity_type: "settlement";
entity: components["schemas"]["PushedSettlement"];
};
Mutation: components["schemas"]["ExpenseMutation"] | components["schemas"]["SettlementMutation"];
SyncPushRequest: {
/** @description 1 to 100 mutations (more is 422 `batch_too_large`). */
mutations: components["schemas"]["Mutation"][];
};
AcceptedResult: {
mutation_id: components["schemas"]["Uuid"];
entity_type: components["schemas"]["EntityType"];
entity_id: components["schemas"]["Uuid"];
/**
* @description discriminator enum property added by openapi-typescript
* @enum {string}
*/
status: "accepted";
server_version: components["schemas"]["ServerVersionNumber"];
/** @description The full wire object after processing, of the type named by `entity_type`. */
entity: components["schemas"]["Expense"] | components["schemas"]["Settlement"];
};
RejectedResult: {
mutation_id: components["schemas"]["Uuid"];
entity_type: components["schemas"]["EntityType"];
entity_id: components["schemas"]["Uuid"];
/**
* @description discriminator enum property added by openapi-typescript
* @enum {string}
*/
status: "rejected";
reason: components["schemas"]["RejectionReason"];
/** @description For validation failures, the domain error token of SPEC §14.5.3. */
message: string;
/** @description The stored row as a full wire object of the type named by `entity_type`, or null when the server has no row with that id. */
current: components["schemas"]["Expense"] | components["schemas"]["Settlement"] | null;
};
MutationResult: components["schemas"]["AcceptedResult"] | components["schemas"]["RejectedResult"];
SyncPushResponse: {
server_time: components["schemas"]["Timestamp"];
/** @description One result per mutation, in request order. */
results: components["schemas"]["MutationResult"][];
};
};
responses: {
/** @description `invalid_request` or `invite_invalid`. */
BadRequest: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["Error"];
};
};
/** @description `unauthorized` or `device_revoked`. */
Unauthorized: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["Error"];
};
};
/** @description `forbidden`. */
Forbidden: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["Error"];
};
};
/** @description `not_found`. */
NotFound: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["Error"];
};
};
/** @description A 409 error code of SPEC §14.3.2. */
Conflict: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["Error"];
};
};
/** @description `payload_too_large`. */
PayloadTooLarge: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["Error"];
};
};
/** @description `unsupported_media_type`. */
UnsupportedMediaType: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["Error"];
};
};
/** @description A 422 error code of SPEC §14.3.2. */
Unprocessable: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["Error"];
};
};
/** @description `protocol_unsupported`. */
ProtocolUnsupported: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["Error"];
};
};
/** @description `rate_limited` (SPEC §8.6). */
RateLimited: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
"Retry-After": components["headers"]["RetryAfter"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["Error"];
};
};
/** @description `internal` (logged with a request id, returned in `message`). */
Internal: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["Error"];
};
};
/** @description `not_implemented` (route registered but not yet implemented; only during milestones M2a to M4). */
NotImplemented: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["Error"];
};
};
/** @description `unavailable` (database busy beyond `busy_timeout`, or server shutting down). */
Unavailable: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["Error"];
};
};
};
parameters: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
Protocol: "1";
/** @description Sent by the app on every call; not enforced on unauthenticated endpoints. */
ProtocolOptional: "1";
/** @description The app's `versionCode`, sent by the app on every call. */
AppVersion: number;
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
AppVersionName: string;
/** @description The device locale. */
AcceptLanguage: string;
/** @description Not a UUID is 404 `not_found`. */
UserId: components["schemas"]["Uuid"];
/** @description Not a UUID is 404 `not_found`. */
InviteId: components["schemas"]["Uuid"];
/** @description Not a UUID is 404 `not_found`. */
DeviceId: components["schemas"]["Uuid"];
/** @description Not a UUID is 404 `not_found`. */
AccountId: components["schemas"]["Uuid"];
/** @description Not a UUID is 404 `not_found`. */
CategoryId: components["schemas"]["Uuid"];
/** @description Not a UUID is 404 `not_found`. */
TemplateId: components["schemas"]["Uuid"];
};
requestBodies: never;
headers: {
/** @description The server crate version. */
ServerVersion: string;
/** @description Seconds until the client may retry. */
RetryAfter: number;
};
pathItems: never;
}
export type $defs = Record<string, never>;
export interface operations {
getHealth: {
parameters: {
query?: never;
header?: {
/** @description Sent by the app on every call; not enforced on unauthenticated endpoints. */
"X-Kvitt-Protocol"?: components["parameters"]["ProtocolOptional"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Server and database are up. */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["Health"];
};
};
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
/**
* @description The database check (`SELECT 1`) failed: the `Health` shape with `status` `degraded` and `db_ok` false.
* An `Error` with code `unavailable` when the server is shutting down.
*/
503: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["Health"] | components["schemas"]["Error"];
};
};
};
};
getSetupStatus: {
parameters: {
query?: never;
header?: {
/** @description Sent by the app on every call; not enforced on unauthenticated endpoints. */
"X-Kvitt-Protocol"?: components["parameters"]["ProtocolOptional"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description `initialized` is true once the admin_setup invite has been accepted (AC-1.5). */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["SetupStatus"];
};
};
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
acceptInvite: {
parameters: {
query?: never;
header?: {
/** @description Sent by the app on every call; not enforced on unauthenticated endpoints. */
"X-Kvitt-Protocol"?: components["parameters"]["ProtocolOptional"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json; charset=utf-8": components["schemas"]["AcceptInviteRequest"];
};
};
responses: {
/** @description Paired. The token is shown only here. */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["AcceptInviteResponse"];
};
};
/** @description `invalid_request` (also a missing `display_name` for admin_setup and partner), `invite_invalid`. */
400: components["responses"]["BadRequest"];
/** @description `household_full`. */
409: components["responses"]["Conflict"];
/** @description `validation_failed`. */
422: components["responses"]["Unprocessable"];
/** @description `rate_limited`, also after more than 10 failed accepts from one IP within 60 minutes (AC-2.12). */
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
getInviteLanding: {
parameters: {
query?: {
/** @description The inviting admin's display name (E-12 link), passed on into the `kvitt://invite` link; an invalid value is ignored. */
from?: string;
};
header?: {
/** @description Sent by the app on every call; not enforced on unauthenticated endpoints. */
"X-Kvitt-Protocol"?: components["parameters"]["ProtocolOptional"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path: {
code: string;
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Landing page. */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"text/html; charset=utf-8": string;
};
};
/** @description `code` not 1 to 32 characters: an HTML 404 page. */
404: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"text/html; charset=utf-8": string;
};
};
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
getApkLatest: {
parameters: {
query?: never;
header?: {
/** @description Sent by the app on every call; not enforced on unauthenticated endpoints. */
"X-Kvitt-Protocol"?: components["parameters"]["ProtocolOptional"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description The content of `latest.json` (SPEC §10.6), read on every request. */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["ApkLatest"];
};
};
/** @description `not_found` (nothing published). */
404: components["responses"]["NotFound"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
getApkFile: {
parameters: {
query?: never;
header?: {
/** @description Sent by the app on every call; not enforced on unauthenticated endpoints. */
"X-Kvitt-Protocol"?: components["parameters"]["ProtocolOptional"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path: {
/** @description Served only when it matches `^kvitt-[0-9]+\.apk$` and exists (SPEC §10.6). */
file_name: string;
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description The APK bytes. */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
"Content-Length": number;
[name: string]: unknown;
};
content: {
"application/vnd.android.package-archive": string;
};
};
/** @description `not_found` (unknown APK file). */
404: components["responses"]["NotFound"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
getMe: {
parameters: {
query?: never;
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description The caller's user and device. */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["MeResponse"];
};
};
401: components["responses"]["Unauthorized"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
patchMe: {
parameters: {
query?: never;
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json; charset=utf-8": components["schemas"]["PatchMeRequest"];
};
};
responses: {
/** @description The updated user. */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["User"];
};
};
/** @description `invalid_request`. */
400: components["responses"]["BadRequest"];
401: components["responses"]["Unauthorized"];
/** @description `validation_failed`. */
422: components["responses"]["Unprocessable"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
putMePicture: {
parameters: {
query?: never;
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path?: never;
cookie?: never;
};
requestBody: {
content: {
"image/jpeg": string;
"image/png": string;
"image/webp": string;
};
};
responses: {
/** @description The user with the new `picture_version`. */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["User"];
};
};
401: components["responses"]["Unauthorized"];
/** @description `payload_too_large` (over 5 MiB). */
413: components["responses"]["PayloadTooLarge"];
/** @description `unsupported_media_type`. */
415: components["responses"]["UnsupportedMediaType"];
/** @description `image_invalid`. */
422: components["responses"]["Unprocessable"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
deleteMePicture: {
parameters: {
query?: never;
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description The user with `picture_version` null. */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["User"];
};
};
401: components["responses"]["Unauthorized"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
getUserPicture: {
parameters: {
query?: {
/** @description Other values are `invalid_request`. */
size?: 128 | 512;
/** @description The `picture_version`; a cache key only, ignored by the server. */
v?: number;
};
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path: {
/** @description Not a UUID is 404 `not_found`. */
user_id: components["parameters"]["UserId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description The square JPEG. */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
/** @description `"<picture_version>"` */
ETag: string;
/** @description `private, max-age=31536000, immutable` */
"Cache-Control": string;
[name: string]: unknown;
};
content: {
"image/jpeg": string;
};
};
/** @description `invalid_request` (bad `size`). */
400: components["responses"]["BadRequest"];
401: components["responses"]["Unauthorized"];
/** @description `not_found` (unknown user or no picture). */
404: components["responses"]["NotFound"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
listInvites: {
parameters: {
query?: never;
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Pending invites only (not accepted, not cancelled, not expired), `code` and `link` null. */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["InviteList"];
};
};
401: components["responses"]["Unauthorized"];
/** @description `forbidden`. */
403: components["responses"]["Forbidden"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
createInvite: {
parameters: {
query?: never;
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json; charset=utf-8": components["schemas"]["CreateInviteRequest"];
};
};
responses: {
/** @description The invite with `code` (12 characters, no hyphens) and `link` (`<public_url>/i/<code>?from=<admin display name, percent-encoded>`). */
201: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["Invite"];
};
};
/** @description `invalid_request`. */
400: components["responses"]["BadRequest"];
401: components["responses"]["Unauthorized"];
/** @description `forbidden` (caller is not the admin). */
403: components["responses"]["Forbidden"];
/** @description `not_found` (target user). */
404: components["responses"]["NotFound"];
/** @description `household_full`. */
409: components["responses"]["Conflict"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
cancelInvite: {
parameters: {
query?: never;
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path: {
/** @description Not a UUID is 404 `not_found`. */
invite_id: components["parameters"]["InviteId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Cancelled. */
204: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content?: never;
};
401: components["responses"]["Unauthorized"];
/** @description `forbidden`. */
403: components["responses"]["Forbidden"];
/** @description `not_found`. */
404: components["responses"]["NotFound"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
listDevices: {
parameters: {
query?: never;
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Ordered by `created_at`, revoked devices included (with `revoked_at`). */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["DeviceList"];
};
};
401: components["responses"]["Unauthorized"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
revokeDevice: {
parameters: {
query?: never;
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path: {
/** @description Not a UUID is 404 `not_found`. */
device_id: components["parameters"]["DeviceId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description Revoked. */
204: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content?: never;
};
401: components["responses"]["Unauthorized"];
/** @description `forbidden`. */
403: components["responses"]["Forbidden"];
/** @description `not_found`. */
404: components["responses"]["NotFound"];
/** @description `cannot_revoke_current_device`. */
409: components["responses"]["Conflict"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
putPushToken: {
parameters: {
query?: never;
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json; charset=utf-8": components["schemas"]["PushTokenRequest"];
};
};
responses: {
/** @description Stored (or cleared). */
204: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content?: never;
};
/** @description `invalid_request`. */
400: components["responses"]["BadRequest"];
401: components["responses"]["Unauthorized"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
createAccount: {
parameters: {
query?: never;
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json; charset=utf-8": components["schemas"]["CreateAccountRequest"];
};
};
responses: {
/** @description The new account. */
201: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["Account"];
};
};
/** @description `invalid_request`. */
400: components["responses"]["BadRequest"];
401: components["responses"]["Unauthorized"];
/** @description `name_taken`, `household_incomplete`. */
409: components["responses"]["Conflict"];
/** @description `validation_failed`. */
422: components["responses"]["Unprocessable"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
deleteAccount: {
parameters: {
query?: never;
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path: {
/** @description Not a UUID is 404 `not_found`. */
account_id: components["parameters"]["AccountId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description The tombstone. */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["Account"];
};
};
401: components["responses"]["Unauthorized"];
/** @description `not_found`. */
404: components["responses"]["NotFound"];
/** @description `account_not_empty`. */
409: components["responses"]["Conflict"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
patchAccount: {
parameters: {
query?: never;
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path: {
/** @description Not a UUID is 404 `not_found`. */
account_id: components["parameters"]["AccountId"];
};
cookie?: never;
};
requestBody: {
content: {
"application/json; charset=utf-8": components["schemas"]["PatchAccountRequest"];
};
};
responses: {
/** @description The updated account. */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["Account"];
};
};
/** @description `invalid_request`. */
400: components["responses"]["BadRequest"];
401: components["responses"]["Unauthorized"];
/** @description `not_found`. */
404: components["responses"]["NotFound"];
/** @description `name_taken`. */
409: components["responses"]["Conflict"];
/** @description `validation_failed`. */
422: components["responses"]["Unprocessable"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
archiveAccount: {
parameters: {
query?: never;
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path: {
/** @description Not a UUID is 404 `not_found`. */
account_id: components["parameters"]["AccountId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description The account. */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["Account"];
};
};
401: components["responses"]["Unauthorized"];
/** @description `not_found`. */
404: components["responses"]["NotFound"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
unarchiveAccount: {
parameters: {
query?: never;
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path: {
/** @description Not a UUID is 404 `not_found`. */
account_id: components["parameters"]["AccountId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description The account. */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["Account"];
};
};
401: components["responses"]["Unauthorized"];
/** @description `not_found`. */
404: components["responses"]["NotFound"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
createCategory: {
parameters: {
query?: never;
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json; charset=utf-8": components["schemas"]["CreateCategoryRequest"];
};
};
responses: {
/** @description The new category. */
201: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["Category"];
};
};
/** @description `invalid_request`. */
400: components["responses"]["BadRequest"];
401: components["responses"]["Unauthorized"];
/** @description `validation_failed`. */
422: components["responses"]["Unprocessable"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
deleteCategory: {
parameters: {
query?: never;
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path: {
/** @description Not a UUID is 404 `not_found`. */
category_id: components["parameters"]["CategoryId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description The tombstone. */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["Category"];
};
};
401: components["responses"]["Unauthorized"];
/** @description `not_found`. */
404: components["responses"]["NotFound"];
/** @description `category_in_use`, `category_is_default`. */
409: components["responses"]["Conflict"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
patchCategory: {
parameters: {
query?: never;
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path: {
/** @description Not a UUID is 404 `not_found`. */
category_id: components["parameters"]["CategoryId"];
};
cookie?: never;
};
requestBody: {
content: {
"application/json; charset=utf-8": components["schemas"]["PatchCategoryRequest"];
};
};
responses: {
/** @description The updated category. */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["Category"];
};
};
/** @description `invalid_request`. */
400: components["responses"]["BadRequest"];
401: components["responses"]["Unauthorized"];
/** @description `not_found`. */
404: components["responses"]["NotFound"];
/** @description `category_is_default` (`name: null` on a non-default category). */
409: components["responses"]["Conflict"];
/** @description `validation_failed`. */
422: components["responses"]["Unprocessable"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
archiveCategory: {
parameters: {
query?: never;
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path: {
/** @description Not a UUID is 404 `not_found`. */
category_id: components["parameters"]["CategoryId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description The category. */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["Category"];
};
};
401: components["responses"]["Unauthorized"];
/** @description `not_found`. */
404: components["responses"]["NotFound"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
unarchiveCategory: {
parameters: {
query?: never;
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path: {
/** @description Not a UUID is 404 `not_found`. */
category_id: components["parameters"]["CategoryId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description The category. */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["Category"];
};
};
401: components["responses"]["Unauthorized"];
/** @description `not_found`. */
404: components["responses"]["NotFound"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
createRecurringTemplate: {
parameters: {
query?: never;
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json; charset=utf-8": components["schemas"]["CreateRecurringTemplateRequest"];
};
};
responses: {
/** @description The new template. */
201: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["RecurringTemplate"];
};
};
/** @description `invalid_request`. */
400: components["responses"]["BadRequest"];
401: components["responses"]["Unauthorized"];
/** @description `household_incomplete`. */
409: components["responses"]["Conflict"];
/** @description `validation_failed` (also for an unknown or deleted `account_id` or `category_id`, with `field`). */
422: components["responses"]["Unprocessable"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
deleteRecurringTemplate: {
parameters: {
query?: never;
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path: {
/** @description Not a UUID is 404 `not_found`. */
template_id: components["parameters"]["TemplateId"];
};
cookie?: never;
};
requestBody?: never;
responses: {
/** @description The tombstone. */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["RecurringTemplate"];
};
};
401: components["responses"]["Unauthorized"];
/** @description `not_found`. */
404: components["responses"]["NotFound"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
patchRecurringTemplate: {
parameters: {
query?: never;
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path: {
/** @description Not a UUID is 404 `not_found`. */
template_id: components["parameters"]["TemplateId"];
};
cookie?: never;
};
requestBody: {
content: {
"application/json; charset=utf-8": components["schemas"]["PatchRecurringTemplateRequest"];
};
};
responses: {
/** @description The updated template. */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["RecurringTemplate"];
};
};
/** @description `invalid_request`. */
400: components["responses"]["BadRequest"];
401: components["responses"]["Unauthorized"];
/** @description `not_found`. */
404: components["responses"]["NotFound"];
/** @description `validation_failed`. */
422: components["responses"]["Unprocessable"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
syncPull: {
parameters: {
query: {
/** @description The highest `server_version` the phone has applied (0 initially). */
since: number;
/** @description Rows per page, 1 to 1000 (`invalid_request` otherwise). */
limit?: number;
};
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description One page. Every array is present (possibly empty) and sorted by `server_version`. */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["SyncPullResponse"];
};
};
/** @description `invalid_request`. */
400: components["responses"]["BadRequest"];
401: components["responses"]["Unauthorized"];
/** @description `cursor_ahead`. */
409: components["responses"]["Conflict"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
syncPush: {
parameters: {
query?: never;
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json; charset=utf-8": components["schemas"]["SyncPushRequest"];
};
};
responses: {
/** @description Per-mutation results. */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["SyncPushResponse"];
};
};
/** @description `invalid_request`. */
400: components["responses"]["BadRequest"];
401: components["responses"]["Unauthorized"];
/** @description `household_incomplete` (whole request, before any mutation). */
409: components["responses"]["Conflict"];
/** @description `payload_too_large`. */
413: components["responses"]["PayloadTooLarge"];
/** @description `batch_too_large` (more than 100 mutations). */
422: components["responses"]["Unprocessable"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
proposeSettlement: {
parameters: {
query?: never;
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path?: never;
cookie?: never;
};
requestBody: {
content: {
"application/json; charset=utf-8": components["schemas"]["ProposalRequest"];
};
};
responses: {
/** @description The proposal. */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["ProposalResponse"];
};
};
/** @description `invalid_request`. */
400: components["responses"]["BadRequest"];
401: components["responses"]["Unauthorized"];
/** @description `no_accounts`. */
409: components["responses"]["Conflict"];
/** @description `validation_failed`. */
422: components["responses"]["Unprocessable"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
getAnalyticsTrends: {
parameters: {
query?: {
/** @description Whole months, 1 to 24 (`invalid_request` otherwise). */
months?: number;
/** @description `household` (full amounts, whoever paid) or `my_share` (the calling user's shares), AC-14.4; other values are `invalid_request`. */
measure?: "household" | "my_share";
};
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description The trends. */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["TrendsResponse"];
};
};
/** @description `invalid_request` (bad `months` or `measure`, with `field`). */
400: components["responses"]["BadRequest"];
401: components["responses"]["Unauthorized"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
getAnalyticsForecast: {
parameters: {
query?: {
/** @description `household` (full amounts, whoever paid) or `my_share` (the calling user's shares), AC-14.4; other values are `invalid_request`. */
measure?: "household" | "my_share";
};
header: {
/** @description Sync protocol version. Missing or other than `1` on an authenticated endpoint is 426 `protocol_unsupported`. */
"X-Kvitt-Protocol": components["parameters"]["Protocol"];
/** @description The app's `versionCode`, sent by the app on every call. */
"X-Kvitt-App-Version"?: components["parameters"]["AppVersion"];
/** @description The app's `versionName`, sent by the app on every call; stored per device like `X-Kvitt-App-Version` (1 to 32 characters, anything else ignored). */
"X-Kvitt-App-Version-Name"?: components["parameters"]["AppVersionName"];
/** @description The device locale. */
"Accept-Language"?: components["parameters"]["AcceptLanguage"];
};
path?: never;
cookie?: never;
};
requestBody?: never;
responses: {
/** @description The forecast. */
200: {
headers: {
"X-Kvitt-Server-Version": components["headers"]["ServerVersion"];
[name: string]: unknown;
};
content: {
"application/json; charset=utf-8": components["schemas"]["ForecastResponse"];
};
};
/** @description `invalid_request` (bad `months` or `measure`, with `field`). */
400: components["responses"]["BadRequest"];
401: components["responses"]["Unauthorized"];
426: components["responses"]["ProtocolUnsupported"];
429: components["responses"]["RateLimited"];
500: components["responses"]["Internal"];
503: components["responses"]["Unavailable"];
};
};
}