{"openapi":"3.1.0","info":{"title":"Pennylane (BYOK) API","version":"0.1.0","description":"Pennylane (BYOK) lets an AI assistant read your own Pennylane data through the Pennylane API with a key you supply (Pennylane company API token (read-only scopes recommended)). Read-only: 12 tools (get_me, list_customer_invoices, list_supplier_invoices, list_customers, list_suppliers, list_transactions, list_bank_accounts, list_products, list_ledger_accounts, list_categories, list_fiscal_years,...\n\nEvery operation is read-only or compute-only. The same tools are available over MCP (streamable HTTP) at https://byok-pennylane.connectorbay.com/mcp.","contact":{"name":"Unify Dynamics LLC","email":"agent@connectorbay.com","url":"https://connectorbay.com/byok-pennylane/docs"},"termsOfService":"https://connectorbay.com/byok-pennylane/terms"},"servers":[{"url":"https://byok-pennylane.connectorbay.com"}],"externalDocs":{"url":"https://connectorbay.com/byok-pennylane/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/get_me":{"post":{"operationId":"get_me","summary":"Show the Pennylane user and company the token belongs to, and the scopes the token has. Use for \"Which Pennylane company","description":"Show the Pennylane user and company the token belongs to, and the scopes the token has. Use for \"Which Pennylane company is my token for and what can it read\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{},"title":"get_meArguments","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_customer_invoices":{"post":{"operationId":"list_customer_invoices","summary":"List customer invoices and credit notes with number, dates, amounts, paid state, remaining amount and customer id. Needs","description":"List customer invoices and credit notes with number, dates, amounts, paid state, remaining amount and customer id. Needs the customer_invoices scope. Use for \"Which Pennylane customer invoices are unpaid\".","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).","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.","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\":\"draft\",\"operator\":\"eq\",\"value\":\"false\"}]. Fields: id, date, customer_id, invoice_number, draft, credit_note, external_reference, category_id.","title":"Filter"},"sort":{"anyOf":[{"maxLength":30,"type":"string"},{"type":"null"}],"default":null,"description":"Sort field (id or date); prefix with - for descending. Default -id.","title":"Sort"}},"title":"list_customer_invoicesArguments","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_supplier_invoices":{"post":{"operationId":"list_supplier_invoices","summary":"List supplier invoices with number, dates, amounts, payment and accounting status, remaining amount and supplier id. Nee","description":"List supplier invoices with number, dates, amounts, payment and accounting status, remaining amount and supplier id. Needs the supplier_invoices scope. Use for \"Which supplier invoices still need to be paid 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).","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.","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\":\"payment_status\",\"operator\":\"eq\",\"value\":\"to_be_paid\"}]. Fields: id, supplier_id, invoice_number, date, category_id, external_reference, payment_status, flow_id.","title":"Filter"},"sort":{"anyOf":[{"maxLength":30,"type":"string"},{"type":"null"}],"default":null,"description":"Sort field (id or date); prefix with - for descending. Default -id.","title":"Sort"}},"title":"list_supplier_invoicesArguments","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_customers":{"post":{"operationId":"list_customers","summary":"List customers (companies and individuals) with name, type, emails, phone, payment terms, address and registration numbe","description":"List customers (companies and individuals) with name, type, emails, phone, payment terms, address and registration numbers. Needs the customers scope. Use for \"Who are my Pennylane customers\".","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).","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.","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\":\"name\",\"operator\":\"start_with\",\"value\":\"Acme\"}]. Fields: id, customer_type, ledger_account_id, name, external_reference, reg_no, emails.","title":"Filter"},"sort":{"anyOf":[{"maxLength":30,"type":"string"},{"type":"null"}],"default":null,"description":"Sort field (id); prefix with - for descending. Default -id.","title":"Sort"}},"title":"list_customersArguments","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_suppliers":{"post":{"operationId":"list_suppliers","summary":"List suppliers with name, VAT and registration numbers, emails, IBAN, payment method and due date rules. Needs the suppl","description":"List suppliers with name, VAT and registration numbers, emails, IBAN, payment method and due date rules. Needs the suppliers scope. Use for \"Who are my Pennylane suppliers\".","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).","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.","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\":\"name\",\"operator\":\"start_with\",\"value\":\"Acme\"}]. Fields: id, ledger_account_id, name, external_reference, emails.","title":"Filter"},"sort":{"anyOf":[{"maxLength":30,"type":"string"},{"type":"null"}],"default":null,"description":"Sort field (id); prefix with - for descending. Default -id.","title":"Sort"}},"title":"list_suppliersArguments","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_transactions":{"post":{"operationId":"list_transactions","summary":"List bank transactions with date, label, amount in euros and original currency, fee, journal, bank account and linked cu","description":"List bank transactions with date, label, amount in euros and original currency, fee, journal, bank account and linked customer or supplier. Needs the transactions scope. Use for \"What bank transactions does Pennylane have for this month\".","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).","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.","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, bank_account_id, journal_id, date.","title":"Filter"},"sort":{"anyOf":[{"maxLength":30,"type":"string"},{"type":"null"}],"default":null,"description":"Sort field (id); prefix with - for descending. Default -id.","title":"Sort"}},"title":"list_transactionsArguments","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_bank_accounts":{"post":{"operationId":"list_bank_accounts","summary":"List the company's bank accounts in Pennylane with name, currency, balance and linked journal and ledger account. Needs ","description":"List the company's bank accounts in Pennylane with name, currency, balance and linked journal and ledger account. Needs the bank_accounts scope. Use for \"What are my bank balances 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).","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.","title":"Cursor"},"sort":{"anyOf":[{"maxLength":30,"type":"string"},{"type":"null"}],"default":null,"description":"Sort field (id); prefix with - for descending. Default -id.","title":"Sort"}},"title":"list_bank_accountsArguments","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_products":{"post":{"operationId":"list_products","summary":"List products and services with label, reference, price before tax and with VAT, VAT rate, unit and currency. Needs the ","description":"List products and services with label, reference, price before tax and with VAT, VAT rate, unit and currency. Needs the products scope. Use for \"What products are in my Pennylane catalogue\".","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).","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.","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\":\"label\",\"operator\":\"eq\",\"value\":\"Consulting\"}]. Fields: id, label, reference, external_reference.","title":"Filter"},"sort":{"anyOf":[{"maxLength":30,"type":"string"},{"type":"null"}],"default":null,"description":"Sort field (id); prefix with - for descending. Default -id.","title":"Sort"}},"title":"list_productsArguments","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_accounts":{"post":{"operationId":"list_ledger_accounts","summary":"List ledger (chart of accounts) entries with number, label, VAT rate, country and enabled flag. Needs the ledger_account","description":"List ledger (chart of accounts) entries with number, label, VAT rate, country and enabled flag. Needs the ledger_accounts scope. Use for \"Which ledger accounts start with 411 in Pennylane\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"limit":{"anyOf":[{"maximum":1000,"minimum":1,"type":"integer"},{"type":"null"}],"default":20,"description":"How many results to return (1 to 1000).","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.","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\":\"number\",\"operator\":\"start_with\",\"value\":\"411\"}]. Fields: id, number, enabled.","title":"Filter"},"sort":{"anyOf":[{"maxLength":30,"type":"string"},{"type":"null"}],"default":null,"description":"Sort field (id); prefix with - for descending. Default -id.","title":"Sort"}},"title":"list_ledger_accountsArguments","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_categories":{"post":{"operationId":"list_categories","summary":"List analytical categories with label, cash direction, analytical code, group and ledger account. Needs the categories s","description":"List analytical categories with label, cash direction, analytical code, group and ledger account. Needs the categories scope. Use for \"What categories are set up 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).","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.","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\":\"label\",\"operator\":\"start_with\",\"value\":\"Travel\"}]. Fields: id, label, category_group_id, analytical_code.","title":"Filter"},"sort":{"anyOf":[{"maxLength":30,"type":"string"},{"type":"null"}],"default":null,"description":"Sort field (id); prefix with - for descending. Default -id.","title":"Sort"}},"title":"list_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_fiscal_years":{"post":{"operationId":"list_fiscal_years","summary":"List the company's fiscal years with start, end and status (open, reopen, closed, frozen). Use for \"What fiscal years do","description":"List the company's fiscal years with start, end and status (open, reopen, closed, frozen). Use for \"What fiscal years does my Pennylane company 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).","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.","title":"Cursor"},"sort":{"anyOf":[{"maxLength":30,"type":"string"},{"type":"null"}],"default":null,"description":"Sort field (id or start); prefix with - for descending. Default -id.","title":"Sort"}},"title":"list_fiscal_yearsArguments","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_journals":{"post":{"operationId":"list_journals","summary":"List accounting journals with code, label and type, optionally filtered by type. Use for \"Which accounting journals exis","description":"List accounting journals with code, label and type, optionally filtered by type. Use for \"Which accounting journals 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).","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.","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\":\"type\",\"operator\":\"eq\",\"value\":\"payroll\"}]. Fields: type.","title":"Filter"},"sort":{"anyOf":[{"maxLength":30,"type":"string"},{"type":"null"}],"default":null,"description":"Sort field (id); prefix with - for descending. Default -id.","title":"Sort"}},"title":"list_journalsArguments","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}}}}