{"openapi":"3.1.0","info":{"title":"Pennylane Ledger (BYOK) API","version":"0.1.0","description":"Pennylane Ledger (BYOK) lets an AI assistant read your own Pennylane Ledger data through the Pennylane Ledger API with a key you supply (Pennylane company API token (read-only scopes recommended)). Read-only: 8 tools (list_ledger_entries, list_ledger_entry_lines, get_trial_balance, list_category_groups, list_group_categories, list_invoice_templates, list_billing_subscriptions,...\n\nEvery operation is read-only or compute-only. The same tools are available over MCP (streamable HTTP) at https://byok-pennylane-ledger.connectorbay.com/mcp.","contact":{"name":"Unify Dynamics LLC","email":"agent@connectorbay.com","url":"https://connectorbay.com/byok-pennylane-ledger/docs"},"termsOfService":"https://connectorbay.com/byok-pennylane-ledger/terms"},"servers":[{"url":"https://byok-pennylane-ledger.connectorbay.com"}],"externalDocs":{"url":"https://connectorbay.com/byok-pennylane-ledger/docs"},"security":[{"upstreamKey":[]}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"Optional. A Pro API key raises rate limits; no credentials are required."},"upstreamKey":{"type":"apiKey","in":"header","name":"X-Upstream-Key","description":"Your own key for the service this connector wraps (bring your own key). Used for that one call only; never stored, logged or cached."}},"schemas":{"Error":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object"}}}}},"paths":{"/v1/tools/list_ledger_entries":{"post":{"operationId":"list_ledger_entries","summary":"List accounting ledger entries with label, piece number, date, due date, invoice number, journal id and status. Needs th","description":"List accounting ledger entries with label, piece number, date, due date, invoice number, journal id and status. Needs the ledger_entries scope. Use for \"Which Pennylane ledger entries were posted in October 2026\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"limit":{"anyOf":[{"maximum":100,"minimum":1,"type":"integer"},{"type":"null"}],"default":20,"description":"How many results to return (1 to 100, default 20).","title":"Limit"},"cursor":{"anyOf":[{"maxLength":300,"type":"string"},{"type":"null"}],"default":null,"description":"Paging cursor: leave out for the first page, or pass the next_cursor value from the previous answer while has_more is true.","title":"Cursor"},"filter":{"anyOf":[{"maxLength":500,"type":"string"},{"type":"null"}],"default":null,"description":"Optional filter: a JSON array of objects with field, operator and value, for example [{\"field\":\"date\",\"operator\":\"gteq\",\"value\":\"2026-10-01\"}]. Fields: id, date, journal_id.","title":"Filter"},"sort":{"anyOf":[{"maxLength":30,"type":"string"},{"type":"null"}],"default":null,"description":"Sort field (id or date); prefix with - for descending.","title":"Sort"}},"title":"list_ledger_entriesArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_ledger_entry_lines":{"post":{"operationId":"list_ledger_entry_lines","summary":"List ledger entry lines with label, date, debit, credit and the linked ledger account, journal and entry. Needs the ledg","description":"List ledger entry lines with label, date, debit, credit and the linked ledger account, journal and entry. Needs the ledger_entries scope. Use for \"Show the ledger lines posted to a Pennylane ledger account\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"limit":{"anyOf":[{"maximum":100,"minimum":1,"type":"integer"},{"type":"null"}],"default":20,"description":"How many results to return (1 to 100, default 20).","title":"Limit"},"cursor":{"anyOf":[{"maxLength":300,"type":"string"},{"type":"null"}],"default":null,"description":"Paging cursor: leave out for the first page, or pass the next_cursor value from the previous answer while has_more is true.","title":"Cursor"},"filter":{"anyOf":[{"maxLength":500,"type":"string"},{"type":"null"}],"default":null,"description":"Optional filter: a JSON array of objects with field, operator and value, for example [{\"field\":\"ledger_account_id\",\"operator\":\"eq\",\"value\":\"123\"}]. Fields: id, journal_id, ledger_account_id, ledger_entry_id, date.","title":"Filter"},"sort":{"anyOf":[{"maxLength":30,"type":"string"},{"type":"null"}],"default":null,"description":"Sort field (id or date); prefix with - for descending.","title":"Sort"}},"title":"list_ledger_entry_linesArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_trial_balance":{"post":{"operationId":"get_trial_balance","summary":"Get the trial balance for a period: account number, label, total debits and credits. Set is_auxiliary to include auxilia","description":"Get the trial balance for a period: account number, label, total debits and credits. Set is_auxiliary to include auxiliary accounts. Needs the trial_balance scope. Use for \"What is my Pennylane trial balance for 2026\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"period_start":{"description":"First day of the period (YYYY-MM-DD).","maxLength":200,"title":"Period Start","type":"string"},"period_end":{"description":"Last day of the period (YYYY-MM-DD).","maxLength":200,"title":"Period End","type":"string"},"is_auxiliary":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":false,"description":"True to include auxiliary (customer and supplier) accounts.","title":"Is Auxiliary"},"limit":{"anyOf":[{"maximum":1000,"minimum":1,"type":"integer"},{"type":"null"}],"default":20,"description":"How many results to return (1 to 1000, default 20).","title":"Limit"},"cursor":{"anyOf":[{"maxLength":300,"type":"string"},{"type":"null"}],"default":null,"description":"Paging cursor: leave out for the first page, or pass the next_cursor value from the previous answer while has_more is true.","title":"Cursor"}},"required":["period_start","period_end"],"title":"get_trial_balanceArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_category_groups":{"post":{"operationId":"list_category_groups","summary":"List analytical category groups with label and their categories. Needs the categories scope. Use for \"What analytical ca","description":"List analytical category groups with label and their categories. Needs the categories scope. Use for \"What analytical category groups does Pennylane have\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"limit":{"anyOf":[{"maximum":100,"minimum":1,"type":"integer"},{"type":"null"}],"default":20,"description":"How many results to return (1 to 100, default 20).","title":"Limit"},"cursor":{"anyOf":[{"maxLength":300,"type":"string"},{"type":"null"}],"default":null,"description":"Paging cursor: leave out for the first page, or pass the next_cursor value from the previous answer while has_more is true.","title":"Cursor"}},"title":"list_category_groupsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_group_categories":{"post":{"operationId":"list_group_categories","summary":"List the categories inside one category group with label, direction, analytical code and linked ledger account. Needs th","description":"List the categories inside one category group with label, direction, analytical code and linked ledger account. Needs the categories scope. Use for \"Which categories are in Pennylane category group 12\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"category_group_id":{"description":"Numeric id of the category group, from list_category_groups.","title":"Category Group Id","type":"integer"},"limit":{"anyOf":[{"maximum":100,"minimum":1,"type":"integer"},{"type":"null"}],"default":20,"description":"How many results to return (1 to 100, default 20).","title":"Limit"},"cursor":{"anyOf":[{"maxLength":300,"type":"string"},{"type":"null"}],"default":null,"description":"Paging cursor: leave out for the first page, or pass the next_cursor value from the previous answer while has_more is true.","title":"Cursor"}},"required":["category_group_id"],"title":"list_group_categoriesArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_invoice_templates":{"post":{"operationId":"list_invoice_templates","summary":"List customer invoice templates with id and name. Needs the customer_invoice_templates scope. Use for \"Which customer in","description":"List customer invoice templates with id and name. Needs the customer_invoice_templates scope. Use for \"Which customer invoice templates exist in Pennylane\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"limit":{"anyOf":[{"maximum":100,"minimum":1,"type":"integer"},{"type":"null"}],"default":20,"description":"How many results to return (1 to 100, default 20).","title":"Limit"},"cursor":{"anyOf":[{"maxLength":300,"type":"string"},{"type":"null"}],"default":null,"description":"Paging cursor: leave out for the first page, or pass the next_cursor value from the previous answer while has_more is true.","title":"Cursor"},"sort":{"anyOf":[{"maxLength":30,"type":"string"},{"type":"null"}],"default":null,"description":"Sort field (id); prefix with - for descending.","title":"Sort"}},"title":"list_invoice_templatesArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_billing_subscriptions":{"post":{"operationId":"list_billing_subscriptions","summary":"List recurring billing subscriptions with label, status, mode, start and finish dates, next and previous occurrence and ","description":"List recurring billing subscriptions with label, status, mode, start and finish dates, next and previous occurrence and payment method. The customer is not returned. Needs the billing_subscriptions scope. Use for \"Which Pennylane billing subscriptions are in progress\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"limit":{"anyOf":[{"maximum":100,"minimum":1,"type":"integer"},{"type":"null"}],"default":20,"description":"How many results to return (1 to 100, default 20).","title":"Limit"},"cursor":{"anyOf":[{"maxLength":300,"type":"string"},{"type":"null"}],"default":null,"description":"Paging cursor: leave out for the first page, or pass the next_cursor value from the previous answer while has_more is true.","title":"Cursor"},"filter":{"anyOf":[{"maxLength":500,"type":"string"},{"type":"null"}],"default":null,"description":"Optional filter: a JSON array of objects with field, operator and value, for example [{\"field\":\"status\",\"operator\":\"eq\",\"value\":\"in_progress\"}]. Fields: id, start, customer_id, status.","title":"Filter"},"sort":{"anyOf":[{"maxLength":30,"type":"string"},{"type":"null"}],"default":null,"description":"Sort field (id); prefix with - for descending.","title":"Sort"}},"title":"list_billing_subscriptionsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_company_features":{"post":{"operationId":"get_company_features","summary":"Show which optional Pennylane features (installments, custom fields) are enabled for the company. Use for \"Does my Penny","description":"Show which optional Pennylane features (installments, custom fields) are enabled for the company. Use for \"Does my Pennylane company have custom fields enabled\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{},"title":"get_company_featuresArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}}}}