Pennylane is a financial management and accounting platform built for SMEs and accounting firms in France. It handles everything from invoice creation to VAT declarations, and its API lets you programmatically connect your own software to that accounting backbone. As one of the top accounting APIs gaining traction in the European market, it's worth understanding how it works under the hood.
If you're building a product that touches invoicing, payments, or financial data for the French market, connecting to Pennylane is increasingly a requirement. Here's what you need to know to get started.
What the API covers
Pennylane exposes two separate APIs depending on your use case:
The Company API is designed for businesses that want to automate their own accounting workflows. Think: pushing invoices from your billing system into Pennylane, syncing supplier invoices, or creating ledger entries automatically. This falls squarely into the open accounting trend, where financial data flows freely between systems via APIs rather than manual exports.
The Firm API is for accounting firms managing multiple client companies. It provides access to client accounting data like trial balances, FEC exports, general ledgers, fiscal years, and client records.
Both APIs are now on v2, which is the official stable version. The v1 API has been deprecated, and Pennylane originally targeted end of 2025 for full removal. If you're starting a new integration, go straight to v2 as v1 will not receive any new features.
In terms of what you can actually build, the v2 API supports:
- Creating and importing customer invoices (both from structured data and from PDF)
- Importing supplier invoices
- Managing quotes, billing subscriptions, and commercial documents (purchase orders, proformas)
- Creating and reading ledger entries with analytical tags
- Creating and retrieving banking transactions
- Uploading file attachments (required for PDF-based invoice imports)
- Payment matching and reconciliation
- Tracking data changes via changelog endpoints for near real-time sync
- Managing customers, suppliers, products, and ledger accounts
- Importing Factur-X e-invoices (relevant for the upcoming French e-invoicing reform)
A few things are not natively supported yet. Downpayment invoices can be created as a workaround by importing an invoice line with ledger account 4191, though they won't display as a downpayment in the Pennylane UI. Delivery notes are not available through the API.
Authentication
There are three authentication paths depending on who you are:
Company API tokens can be generated directly in Pennylane account settings. You need admin access (Executive, Internal Accountant, or External Accountant role). You can create multiple tokens per company, each with their own scopes and expiration settings. Tokens are not stored by Pennylane and can't be retrieved after creation, so store them securely on your side.
Firm API tokens are generated from Firm account settings and give access to client data across the firm's portfolio.
OAuth 2.0 is required for any integration that will be published on the Pennylane Marketplace or used across multiple companies. You'll need to contact integrations@pennylane.com to get registered. Access tokens expire after 24 hours by default, and refresh tokens are valid for 90 days. Once a refresh token is used, it's revoked and replaced with a new one, so make sure your token rotation logic handles this properly. (This is one of the areas where building vs buying accounting integrations becomes a real trade-off, since a unified API can handle token management for you.)
All requests use Bearer token authentication in the Authorization header:
Authorization: Bearer <YOUR_API_KEY_OR_OAUTH_TOKEN>
The base URL for v2 endpoints is:
https://app.pennylane.com/api/external/v2/
Setting up a sandbox
Before hitting production, you'll want a sandbox environment. For companies, you can create one directly from your Pennylane account by navigating to your profile and selecting "Test environment." For firms, you use your existing Firm account (no sandbox needed). Integrators need to email integrations@pennylane.com with their name and email for sandbox creation.
The sandbox mirrors the production environment so you can test your full integration flow without affecting real data. If you plan to test invoicing, you'll also need to configure your invoice settings (company address, bank details, logo, and sequential numbering).
Making your first request
Start by verifying your credentials work:
curl https://app.pennylane.com/api/external/v2/me \
-H "Authorization: Bearer <YOUR_TOKEN>"
A successful response returns your user and company context, confirming authentication is working and you're hitting the right environment.
Working with invoices
Invoicing is the most common accounting integration use case, and Pennylane distinguishes between two approaches:
Creating an invoice means Pennylane generates the invoice document from structured data you provide (customer ID, line items, VAT rates, amounts). This is the right path when your system is the source of truth for what should be on the invoice.
Importing an invoice means you're pushing a pre-existing PDF into Pennylane. This requires a two-step process in v2: first upload the PDF via the /file_attachments endpoint to get an attachment ID, then use that ID when calling the import endpoint. Only PDF files are accepted, up to 100 MB.
Here's the general flow for creating a customer invoice:
- Look up or create the customer via
/customersor/company_customers - Optionally look up products via
/productsfor consistent pricing and VAT handling - Optionally look up ledger accounts via
/ledger_accountsif you need specific account mappings - POST to
/customer_invoiceswith the customer ID, line items, dates, and VAT rates
You can create invoices in draft mode by passing "draft": true, which is useful for review workflows before finalization. You can also convert a quote into an invoice directly via /customer_invoices/create_from_quote.
One important detail: customer, product, and ledger account IDs are unique per company. If your integration serves multiple Pennylane companies, you need to store these mappings per tenant.
Pagination and filtering
The v2 API uses cursor-based pagination instead of the offset-based pagination from v1. This is a meaningful change if you're migrating. Pennylane has a dedicated guide on implementing cursor-based pagination correctly.
For filtering, the API uses a structured filter parameter in query strings. Filters follow a JSON format specifying the field, operator, and value:
?filter=[{"field":"external_reference","operator":"eq","value":"ACME_001"}]
Filtering is available on most list endpoints, including customer invoices, supplier invoices, draft invoices, credit notes, customers, suppliers, ledger accounts, ledger entries, ledger entry lines, products, and categories.
Tracking changes
The changelog endpoints are particularly useful for keeping your system in sync with Pennylane. They let you poll for creation, update, and deletion events on specific resources in near real-time. Currently supported for customer invoices and supplier invoices.
When you receive change events, you'll need to make a follow-up request to fetch the complete resource data, since the changelog only tells you what changed, not the full payload.
Rate limits
The v2 API allows up to 5 requests per second. Rate limiting applies on both production and sandbox environments across all endpoints. If you exceed the limit, you'll receive a 429 HTTP error.
If you're processing high volumes (nightly invoice syncs, historical imports), you'll need proper queuing and retry logic with exponential backoff to handle 429 responses gracefully. This is a common challenge across accounting API integrations for fintech products. Also worth noting: Pennylane does not enforce idempotency on creation endpoints like /customer_invoices or /ledger_entries, so duplicate requests will create duplicate records. Build deduplication logic on your side.
Key differences from v1
If you're migrating from v1, a few structural changes to be aware of:
Internal IDs only. V2 uses Pennylane's internal IDs exclusively. You can no longer retrieve resources by source_id. To help with migration, v1 responses include a v2_id attribute so you can map old IDs to new ones.
Granular scopes. V2 introduces more specific OAuth scopes, each with a readonly counterpart. You'll need to update your OAuth app configuration and re-authenticate to use v2 endpoints.
Single-resource creation. V1 allowed creating multiple object types in a single call. V2 requires separate calls through dedicated endpoints, which simplifies error handling and debugging.
File attachments as resources. In v1, you could inline base64 file content or a URL directly in an invoice import call. In v2, file attachments are a separate resource that you create first and then reference by ID.
Linked collections. Where v1 returned nested arrays (like invoice lines inside an invoice), v2 returns a URL pointing to the collection endpoint instead.
Standardized response bodies. In v2, a data model like customer_invoice always returns the same response attributes regardless of whether you're hitting the show or list endpoint.
Practical tips
Store IDs per tenant. If your integration serves multiple companies, maintain a mapping of Pennylane IDs (customers, products, ledger accounts) for each company.
Use external references. When creating customers or other entities, populate the external_reference field with your own system's ID. This makes lookups much easier later.
Default VAT and ledger mappings. If you omit the ledger_account_id when creating invoices, Pennylane applies the company's default chart of accounts and VAT settings. This can simplify your integration if you don't need fine-grained control over accounting mappings.
Monitor the changelog. Pennylane's API evolves frequently with new endpoints and deprecations. Subscribe to their API changelog RSS feed to stay ahead of breaking changes.
Plan for role and plan requirements. End users need at least a "gestionnaire" (manager) role and an Essential plan or higher to activate API integrations. Surface clear error messages if users lack the required permissions.
Validate before you send. Check totals and VAT consistency on your side before making API calls. Pennylane returns detailed error payloads with a details object that tells you exactly which field caused the failure, but catching issues client-side saves round trips.
Using a unified API instead
If you're building integrations across multiple accounting platforms and not just Pennylane, building and maintaining direct integrations with each one adds up quickly. Each platform has its own authentication flows, data models, rate limits, and breaking changes to track. For a deeper look at this trade-off, see our guide on how fintech startups can integrate with 20+ accounting platforms using a single API.
Apideck's Unified Accounting API lets you connect to QuickBooks, Xero, Sage, NetSuite, and 20+ other accounting platforms through a single integration. Authentication, data normalization, and ongoing connector maintenance are handled for you.
Disclaimer: Apideck does not currently support Pennylane as a connector on the Accounting API yet. If Pennylane coverage is a requirement, you'll need to build and maintain the direct integration as described in this guide.
This is especially relevant if your product needs to support both French and international accounting systems. Instead of managing Pennylane's OAuth token rotation, Xero's partner certification process, and QuickBooks' different API versions separately, a unified API platform gives you one integration point, one data schema, and one set of SDKs across all of them. Check the full list of accounting connectors to see what's available.
Resources
Ready to get started?
Scale your integration strategy and deliver the integrations your customers need in record time.







