{"openapi":"3.0.0","info":{"title":"Beancount.io v1 API","version":"1.0.0","description":"The public REST API for Beancount.io ledgers.\n\nEvery endpoint addresses a ledger as two path segments — `/api-gateway/v1/ledgers/{owner}/{name}` —\nand returns JSON. Errors share one shape: `{ \"ok\": false, \"error\": { \"code\", \"message\" } }`.\n\n## Authentication\n\nSend a bearer token: an OAuth 2.1 access token from this server's OIDC provider,\nor a session token. Each operation is classified `read`, `write`, or `admin`, and a\ntoken is refused when its scopes (`ledger.read`, `ledger.write`, `ledger.admin`)\ndo not cover the operation's class.\n\nThe one exception is the archive download, which takes a single-use ticket in the\nquery string instead — a browser following a download link cannot send a header.","contact":{"name":"Beancount.io","url":"https://github.com/bex-co/beancount-io"}},"servers":[{"url":"http://localhost:4104","description":"Development server"},{"url":"https://api.v3.beancount.io","description":"Production server"}],"tags":[{"name":"Ledger v1","description":"Ledger resources: query, journal, accounts, statements, files, entries, archives"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT Bearer token for authenticated user endpoints"},"adminToken":{"type":"apiKey","in":"header","name":"x-admin-token","description":"Admin API token for administrative operations"},"apiKey":{"type":"apiKey","in":"header","name":"x-api-key","description":"API key for authenticated endpoints"}},"schemas":{"V1Error":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"object","properties":{"code":{"type":"string","description":"Canonical error category","example":"VALIDATION_FAILED"},"message":{"type":"string"},"metadata":{"type":"object","additionalProperties":{"nullable":true}}},"required":["code","message"]}},"required":["ok","error"],"description":"Standard v1 error body"},"BqlQuery":{"type":"object","properties":{"query":{"type":"string","minLength":1,"description":"A Beancount Query Language statement","example":"SELECT account, sum(position) GROUP BY account"}},"required":["query"],"description":"A BQL query to run against the ledger"},"LedgerDirEntry":{"type":"object","properties":{"path":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["file","dir"]}},"required":["path","name","type"],"description":"One file or directory at a level of the repository"},"LedgerFile":{"type":"object","properties":{"path":{"type":"string"},"content":{"type":"string"},"sha":{"type":"string"}},"required":["path","content","sha"],"description":"One ledger file and its blob SHA"},"FileCommitAck":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"path":{"type":"string"}},"required":["ok","path"],"description":"Acknowledgement that a file change was committed"},"FileWrite":{"type":"object","properties":{"content":{"type":"string","description":"The file's full new content, as UTF-8 text","example":"2026-01-01 open Assets:Bank:Checking USD\n"},"message":{"type":"string","minLength":1,"description":"Commit message; defaults to a generated one","example":"Add January transactions"},"sha":{"type":"string","description":"Blob SHA the edit is based on. Send the SHA from a prior GET to update an existing file; omit it to create a new one."}},"required":["content"],"description":"New content for one ledger file"},"FileDelete":{"type":"object","properties":{"message":{"type":"string","minLength":1},"sha":{"type":"string","description":"Blob SHA of the file being deleted, from a prior GET"}},"description":"Delete one ledger file"},"EntriesRequest":{"type":"object","properties":{"entries":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["transaction"]},"entry":{"type":"object","properties":{"date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-08-23"},"flag":{"type":"string","description":"`*` for cleared, `!` for pending","example":"*"},"payee":{"type":"string"},"narration":{"type":"string"},"postings":{"type":"array","items":{"type":"object","properties":{"account":{"type":"string","example":"Assets:Bank:Checking"},"units":{"type":"object","properties":{"number":{"type":"string","description":"Decimal amount","example":"42.50"},"currency":{"type":"string","example":"USD"}},"required":["number","currency"]},"price":{"type":"object","properties":{"number":{"type":"string","description":"Decimal amount","example":"42.50"},"currency":{"type":"string","example":"USD"}},"required":["number","currency"]},"flag":{"type":"string"}},"required":["account","units"]},"minItems":1},"tags":{"type":"array","items":{"type":"string"}},"links":{"type":"array","items":{"type":"string"}},"meta":{"type":"object","additionalProperties":{"type":"string"}}},"required":["date","flag","postings"]}},"required":["type","entry"]},{"type":"object","properties":{"type":{"type":"string","enum":["open"]},"entry":{"type":"object","properties":{"date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-08-23"},"account":{"type":"string"},"currencies":{"type":"array","items":{"type":"string"}}},"required":["date","account","currencies"]}},"required":["type","entry"]},{"type":"object","properties":{"type":{"type":"string","enum":["close"]},"entry":{"type":"object","properties":{"date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-08-23"},"account":{"type":"string"}},"required":["date","account"]}},"required":["type","entry"]},{"type":"object","properties":{"type":{"type":"string","enum":["balance"]},"entry":{"type":"object","properties":{"date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-08-23"},"account":{"type":"string"},"amount":{"type":"object","properties":{"number":{"type":"string","description":"Decimal amount","example":"42.50"},"currency":{"type":"string","example":"USD"}},"required":["number","currency"]}},"required":["date","account","amount"]}},"required":["type","entry"]},{"type":"object","properties":{"type":{"type":"string","enum":["price"]},"entry":{"type":"object","properties":{"date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-08-23"},"currency":{"type":"string"},"amount":{"type":"object","properties":{"number":{"type":"string","description":"Decimal amount","example":"42.50"},"currency":{"type":"string","example":"USD"}},"required":["number","currency"]}},"required":["date","currency","amount"]}},"required":["type","entry"]},{"type":"object","properties":{"type":{"type":"string","enum":["commodity"]},"entry":{"type":"object","properties":{"date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-08-23"},"currency":{"type":"string"}},"required":["date","currency"]}},"required":["type","entry"]},{"type":"object","properties":{"type":{"type":"string","enum":["note"]},"entry":{"type":"object","properties":{"date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-08-23"},"account":{"type":"string"},"content":{"type":"string"}},"required":["date","account","content"]}},"required":["type","entry"]},{"type":"object","properties":{"type":{"type":"string","enum":["event"]},"entry":{"type":"object","properties":{"date":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-08-23"},"type":{"type":"string"},"description":{"type":"string"}},"required":["date","type","description"]}},"required":["type","entry"]}]},"minItems":1,"maxItems":100,"description":"Directives to append, committed all-or-nothing"}},"required":["entries"],"description":"One or more directives to add to the ledger"},"ArchiveTicket":{"type":"object","properties":{"url":{"type":"string","description":"The download URL, ticket included. Valid once, for 60 seconds.","example":"/api-gateway/v1/ledgers/alice/main-ledger/archive/gitea-main.zip?ticket=v1.eyJ1c2VySWQi..."},"expiresAt":{"type":"string","description":"When the ticket stops being redeemable (ISO 8601)","example":"2026-08-23T12:00:60.000Z"}},"required":["url","expiresAt"],"description":"A single-use archive download ticket"},"ArchiveTicketRequest":{"type":"object","properties":{"archive":{"type":"string","minLength":1,"description":"Archive to download. Git archives are `gitea-<branch>.zip`; `tar.gz` and `zip` are also accepted.","example":"gitea-main.zip"}},"required":["archive"],"description":"Which archive the ticket should authorize"},"ApiKey":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"keyPrefix":{"type":"string","description":"The first characters of the key, for telling keys apart","example":"bcio_7wXzK9mN"},"scopes":{"type":"array","items":{"type":"string"}},"ledgerScope":{"type":"string"},"lastUsedAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"},"revokedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","name","keyPrefix","scopes","createdAt"],"description":"An API key as it can be shown — never the key itself"},"MintedApiKey":{"type":"object","properties":{"key":{"$ref":"#/components/schemas/ApiKey"},"plaintext":{"type":"string","description":"The key. Returned exactly once, by this response, and never recoverable afterwards — store it now.","example":"bcio_7wXzK9mNpQrSt2VxYaBcDeF3gH4jK5mN"}},"required":["key","plaintext"],"description":"A newly minted key, including its one and only plaintext"},"CreateApiKey":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":200,"description":"What this key is for — shown in the key list","example":"CI: nightly ledger export"},"scopes":{"type":"array","items":{"type":"string","enum":["ledger.read","ledger.write","ledger.admin"],"description":"One of the three ledger scopes","example":"ledger.read"},"minItems":1,"description":"What the key may do. A key can never hold more than its creator did.","example":["ledger.read"]},"ledgerScope":{"type":"string","description":"Confine the key to one ledger, as `owner/name`. Omit for all the caller's ledgers.","example":"alice/main-ledger"},"expiresAt":{"type":"string","nullable":true,"format":"date-time","description":"When the key stops working (ISO 8601). Omit for no expiry."}},"required":["name","scopes"],"description":"A new API key to mint"}},"parameters":{}},"paths":{"/api-gateway/v1/ledgers":{"get":{"summary":"List the caller's ledgers","description":"Every ledger the caller can reach — owned, shared, and starred — newest first. Backed by the same source as the GraphQL `listLedgers` query.","tags":["Ledger v1"],"security":[{"bearerAuth":[]},{"apiKey":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"description":"1-based page number","example":1},"required":false,"description":"1-based page number","name":"page","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"description":"Page size, at most 100","example":20},"required":false,"description":"Page size, at most 100","name":"limit","in":"query"}],"responses":{"200":{"description":"The caller's ledgers","content":{"application/json":{"schema":{"type":"array","items":{"nullable":true}}}}},"400":{"description":"Request failed validation against the documented schema","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"401":{"description":"No credential, or a credential that no longer resolves","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"403":{"description":"The credential lacks the scope this operation's class requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"404":{"description":"No such ledger, or no access to it","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}}}}},"/api-gateway/v1/ledgers/{owner}/{name}":{"get":{"summary":"Get one ledger","description":"Metadata for a single ledger: description, visibility, default branch, and the caller's permissions on it.","tags":["Ledger v1"],"security":[{"bearerAuth":[]},{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"description":"Ledger owner's username","example":"alice"},"required":true,"description":"Ledger owner's username","name":"owner","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Ledger (repository) name","example":"main-ledger"},"required":true,"description":"Ledger (repository) name","name":"name","in":"path"}],"responses":{"200":{"description":"The ledger","content":{"application/json":{"schema":{"nullable":true}}}},"400":{"description":"Request failed validation against the documented schema","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"401":{"description":"No credential, or a credential that no longer resolves","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"403":{"description":"The credential lacks the scope this operation's class requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"404":{"description":"No such ledger, or no access to it","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}}}}},"/api-gateway/v1/ledgers/{owner}/{name}/query":{"post":{"summary":"Run a BQL query","description":"Runs a Beancount Query Language statement against the ledger. `Accept: application/json` returns a typed table; `Accept: text/plain` returns the shell's own text rendering.","tags":["Ledger v1"],"security":[{"bearerAuth":[]},{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"description":"Ledger owner's username","example":"alice"},"required":true,"description":"Ledger owner's username","name":"owner","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Ledger (repository) name","example":"main-ledger"},"required":true,"description":"Ledger (repository) name","name":"name","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BqlQuery"}}}},"responses":{"200":{"description":"Query result, as a typed table or as shell text","content":{"application/json":{"schema":{"nullable":true}},"text/plain":{"schema":{"type":"string"}}}},"400":{"description":"Request failed validation against the documented schema","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"401":{"description":"No credential, or a credential that no longer resolves","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"403":{"description":"The credential lacks the scope this operation's class requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"404":{"description":"No such ledger, or no access to it","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}}}}},"/api-gateway/v1/ledgers/{owner}/{name}/journal":{"get":{"summary":"List journal entries","description":"The ledger's journal, optionally narrowed by account, Fava filter, or time expression, and paged with `limit`/`offset`.","tags":["Ledger v1"],"security":[{"bearerAuth":[]},{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"description":"Ledger owner's username","example":"alice"},"required":true,"description":"Ledger owner's username","name":"owner","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Ledger (repository) name","example":"main-ledger"},"required":true,"description":"Ledger (repository) name","name":"name","in":"path"},{"schema":{"type":"string","description":"Restrict to one account and its children","example":"Assets:Bank:Checking"},"required":false,"description":"Restrict to one account and its children","name":"account","in":"query"},{"schema":{"type":"string","description":"Fava filter expression","example":"#travel"},"required":false,"description":"Fava filter expression","name":"filter","in":"query"},{"schema":{"type":"string","description":"Fava time expression","example":"2026"},"required":false,"description":"Fava time expression","name":"time","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":1000},"required":false,"name":"limit","in":"query"},{"schema":{"type":"integer","nullable":true,"minimum":0},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"Journal entries","content":{"application/json":{"schema":{"nullable":true}}}},"400":{"description":"Request failed validation against the documented schema","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"401":{"description":"No credential, or a credential that no longer resolves","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"403":{"description":"The credential lacks the scope this operation's class requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"404":{"description":"No such ledger, or no access to it","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}}}}},"/api-gateway/v1/ledgers/{owner}/{name}/accounts":{"get":{"summary":"List accounts","description":"Every account name in the ledger. `status=open` or `status=closed` narrows it to accounts with or without a close directive.","tags":["Ledger v1"],"security":[{"bearerAuth":[]},{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"description":"Ledger owner's username","example":"alice"},"required":true,"description":"Ledger owner's username","name":"owner","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Ledger (repository) name","example":"main-ledger"},"required":true,"description":"Ledger (repository) name","name":"name","in":"path"},{"schema":{"type":"string","enum":["open","closed"],"description":"Only accounts that are currently open, or only closed ones"},"required":false,"description":"Only accounts that are currently open, or only closed ones","name":"status","in":"query"}],"responses":{"200":{"description":"Account names","content":{"application/json":{"schema":{"type":"array","items":{"type":"string"}}}}},"400":{"description":"Request failed validation against the documented schema","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"401":{"description":"No credential, or a credential that no longer resolves","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"403":{"description":"The credential lacks the scope this operation's class requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"404":{"description":"No such ledger, or no access to it","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}}}}},"/api-gateway/v1/ledgers/{owner}/{name}/statements/{statement}":{"get":{"summary":"Get a financial statement","description":"Renders the balance sheet or the income statement for the period, with optional currency conversion and interval bucketing.","tags":["Ledger v1"],"security":[{"bearerAuth":[]},{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"description":"Ledger owner's username","example":"alice"},"required":true,"description":"Ledger owner's username","name":"owner","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Ledger (repository) name","example":"main-ledger"},"required":true,"description":"Ledger (repository) name","name":"name","in":"path"},{"schema":{"type":"string","enum":["balance-sheet","income-statement"],"description":"Which statement to render","example":"balance-sheet"},"required":true,"description":"Which statement to render","name":"statement","in":"path"},{"schema":{"type":"string"},"required":false,"name":"filter","in":"query"},{"schema":{"type":"string","description":"Reporting period as a Fava time expression","example":"2026-01-01 - 2026-12-31"},"required":false,"description":"Reporting period as a Fava time expression","name":"time","in":"query"},{"schema":{"type":"string","description":"Convert amounts to this currency","example":"USD"},"required":false,"description":"Convert amounts to this currency","name":"conversion","in":"query"},{"schema":{"type":"string","description":"Bucket the period: day, week, month, quarter, year","example":"month"},"required":false,"description":"Bucket the period: day, week, month, quarter, year","name":"interval","in":"query"}],"responses":{"200":{"description":"The rendered statement","content":{"application/json":{"schema":{"nullable":true}}}},"400":{"description":"Request failed validation against the documented schema","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"401":{"description":"No credential, or a credential that no longer resolves","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"403":{"description":"The credential lacks the scope this operation's class requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"404":{"description":"No such ledger, or no access to it","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}}}}},"/api-gateway/v1/ledgers/{owner}/{name}/files":{"get":{"summary":"List files and directories","description":"One directory level, directories first then files by name. Pass `dir` to descend; omit it for the repository root.","tags":["Ledger v1"],"security":[{"bearerAuth":[]},{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"description":"Ledger owner's username","example":"alice"},"required":true,"description":"Ledger owner's username","name":"owner","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Ledger (repository) name","example":"main-ledger"},"required":true,"description":"Ledger (repository) name","name":"name","in":"path"},{"schema":{"type":"string","description":"Directory to list, relative to the repository root","example":"2026"},"required":false,"description":"Directory to list, relative to the repository root","name":"dir","in":"query"}],"responses":{"200":{"description":"Directory contents","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LedgerDirEntry"}}}}},"400":{"description":"Request failed validation against the documented schema","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"401":{"description":"No credential, or a credential that no longer resolves","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"403":{"description":"The credential lacks the scope this operation's class requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"404":{"description":"No such ledger, or no access to it","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}}}}},"/api-gateway/v1/ledgers/{owner}/{name}/files/{path}":{"get":{"summary":"Read a file","description":"The file's content as UTF-8 text, with the blob SHA to pass back when updating it.","tags":["Ledger v1"],"security":[{"bearerAuth":[]},{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"description":"Ledger owner's username","example":"alice"},"required":true,"description":"Ledger owner's username","name":"owner","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Ledger (repository) name","example":"main-ledger"},"required":true,"description":"Ledger (repository) name","name":"name","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Path of the file within the ledger repository. May contain slashes.","example":"2026/january.bean"},"required":true,"description":"Path of the file within the ledger repository. May contain slashes.","name":"path","in":"path"}],"responses":{"200":{"description":"The file","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LedgerFile"}}}},"400":{"description":"Request failed validation against the documented schema","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"401":{"description":"No credential, or a credential that no longer resolves","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"403":{"description":"The credential lacks the scope this operation's class requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"404":{"description":"No such ledger, or no access to it","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}}}},"put":{"summary":"Create or replace a file","description":"Writes the file and commits it. Include the `sha` from a prior GET to replace an existing file; omit it to create a new one.","tags":["Ledger v1"],"security":[{"bearerAuth":[]},{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"description":"Ledger owner's username","example":"alice"},"required":true,"description":"Ledger owner's username","name":"owner","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Ledger (repository) name","example":"main-ledger"},"required":true,"description":"Ledger (repository) name","name":"name","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Path of the file within the ledger repository. May contain slashes.","example":"2026/january.bean"},"required":true,"description":"Path of the file within the ledger repository. May contain slashes.","name":"path","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileWrite"}}}},"responses":{"200":{"description":"The commit succeeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileCommitAck"}}}},"400":{"description":"Request failed validation against the documented schema","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"401":{"description":"No credential, or a credential that no longer resolves","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"403":{"description":"The credential lacks the scope this operation's class requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"404":{"description":"No such ledger, or no access to it","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}}}},"delete":{"summary":"Delete a file","description":"Removes the file and commits the deletion.","tags":["Ledger v1"],"security":[{"bearerAuth":[]},{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"description":"Ledger owner's username","example":"alice"},"required":true,"description":"Ledger owner's username","name":"owner","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Ledger (repository) name","example":"main-ledger"},"required":true,"description":"Ledger (repository) name","name":"name","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Path of the file within the ledger repository. May contain slashes.","example":"2026/january.bean"},"required":true,"description":"Path of the file within the ledger repository. May contain slashes.","name":"path","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileDelete"}}}},"responses":{"200":{"description":"The deletion was committed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileCommitAck"}}}},"400":{"description":"Request failed validation against the documented schema","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"401":{"description":"No credential, or a credential that no longer resolves","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"403":{"description":"The credential lacks the scope this operation's class requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"404":{"description":"No such ledger, or no access to it","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}}}}},"/api-gateway/v1/ledgers/{owner}/{name}/entries":{"post":{"summary":"Add directives to the ledger","description":"Appends one or more Beancount directives, routed to the right file by type and date and committed as a single commit. All-or-nothing: if any directive fails, none are written.","tags":["Ledger v1"],"security":[{"bearerAuth":[]},{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"description":"Ledger owner's username","example":"alice"},"required":true,"description":"Ledger owner's username","name":"owner","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Ledger (repository) name","example":"main-ledger"},"required":true,"description":"Ledger (repository) name","name":"name","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntriesRequest"}}}},"responses":{"200":{"description":"The directives were committed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}},"required":["success"]}}}},"400":{"description":"Request failed validation against the documented schema","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"401":{"description":"No credential, or a credential that no longer resolves","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"403":{"description":"The credential lacks the scope this operation's class requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"404":{"description":"No such ledger, or no access to it","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}}}}},"/api-gateway/v1/ledgers/{owner}/{name}/archive-tickets":{"post":{"summary":"Mint an archive download ticket","description":"Returns a URL that downloads the archive once, within 60 seconds. The ticket is bound to the caller, the ledger, and the archive name, and is refused on a second use.","tags":["Ledger v1"],"security":[{"bearerAuth":[]},{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"description":"Ledger owner's username","example":"alice"},"required":true,"description":"Ledger owner's username","name":"owner","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Ledger (repository) name","example":"main-ledger"},"required":true,"description":"Ledger (repository) name","name":"name","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArchiveTicketRequest"}}}},"responses":{"200":{"description":"A single-use download URL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArchiveTicket"}}}},"400":{"description":"Request failed validation against the documented schema","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"401":{"description":"No credential, or a credential that no longer resolves","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"403":{"description":"The credential lacks the scope this operation's class requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"404":{"description":"No such ledger, or no access to it","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}}}}},"/api-gateway/v1/api-keys":{"get":{"summary":"List your API keys","description":"Every key you have minted, newest first, including revoked and expired ones. Keys are shown by prefix — the key itself was returned once, when it was created.","tags":["Ledger v1"],"security":[{"bearerAuth":[]},{"apiKey":[]}],"responses":{"200":{"description":"Your API keys","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}}}},"400":{"description":"Request failed validation against the documented schema","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"401":{"description":"No credential, or a credential that no longer resolves","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"403":{"description":"The credential lacks the scope this operation's class requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"404":{"description":"No such ledger, or no access to it","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}}}},"post":{"summary":"Mint an API key","description":"Creates a key and returns its plaintext, which is shown here and never again. Requires a paid plan, and cannot be called with an API key — sign in, or use an OAuth grant.","tags":["Ledger v1"],"security":[{"bearerAuth":[]},{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiKey"}}}},"responses":{"200":{"description":"The new key, with its one-time plaintext","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MintedApiKey"}}}},"400":{"description":"Request failed validation against the documented schema","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"401":{"description":"No credential, or a credential that no longer resolves","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"402":{"description":"Minting API keys requires a paid plan","content":{"application/json":{"schema":{"nullable":true}}}},"403":{"description":"The credential lacks the scope this operation's class requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"404":{"description":"No such ledger, or no access to it","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}}}}},"/api-gateway/v1/api-keys/{id}":{"delete":{"summary":"Revoke an API key","description":"Stops the key working from the next request onward. Revoking twice is not an error, and a key id you do not own reads as not found.","tags":["Ledger v1"],"security":[{"bearerAuth":[]},{"apiKey":[]}],"parameters":[{"schema":{"type":"string","minLength":1,"description":"The key's id (`akey_…`), not the key itself","example":"akey_7wXzK9mNpQrSt2VxYaBc"},"required":true,"description":"The key's id (`akey_…`), not the key itself","name":"id","in":"path"}],"responses":{"200":{"description":"The revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKey"}}}},"400":{"description":"Request failed validation against the documented schema","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"401":{"description":"No credential, or a credential that no longer resolves","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"403":{"description":"The credential lacks the scope this operation's class requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"404":{"description":"No such ledger, or no access to it","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}}}}},"/api-gateway/v1/ledgers/{owner}/{name}/archive/{archive}":{"get":{"summary":"Download a ledger archive","description":"Streams the archive. Requires a ticket from the archive-tickets endpoint; no bearer token is read here, and a ticket works exactly once.","tags":["Ledger v1"],"parameters":[{"schema":{"type":"string","minLength":1,"description":"Ledger owner's username","example":"alice"},"required":true,"description":"Ledger owner's username","name":"owner","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Ledger (repository) name","example":"main-ledger"},"required":true,"description":"Ledger (repository) name","name":"name","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Archive to download. Git archives are `gitea-<branch>.zip`; `tar.gz` and `zip` are also accepted.","example":"gitea-main.zip"},"required":true,"description":"Archive to download. Git archives are `gitea-<branch>.zip`; `tar.gz` and `zip` are also accepted.","name":"archive","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Single-use ticket from POST /api-gateway/v1/ledgers/{owner}/{name}/archive-tickets"},"required":true,"description":"Single-use ticket from POST /api-gateway/v1/ledgers/{owner}/{name}/archive-tickets","name":"ticket","in":"query"}],"responses":{"200":{"description":"The archive bytes","content":{"application/zip":{"schema":{"type":"string"}},"application/gzip":{"schema":{"type":"string"}}}},"400":{"description":"Request failed validation against the documented schema","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"401":{"description":"No credential, or a credential that no longer resolves","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"403":{"description":"The credential lacks the scope this operation's class requires","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"404":{"description":"No such ledger, or no access to it","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1Error"}}}}}}}}}