Aller au contenu

Invoicing (sales)

Resources for customer-facing documents: invoices, credit notes, quotes, recurring subscriptions, customers and the product catalog.

Async twins

Every resource documented here has an Async twin with the exact same methods as coroutines (AsyncCustomerInvoices, AsyncQuotes, ...), reached through AsyncPennylane.

Bases: SyncAPIResource

Manage customer invoices (French: factures de vente).

list

list(
    *,
    cursor: str | None = None,
    limit: int | None = None,
    filter: FiltersInput | None = None,
    sort: str | None = None,
    include: str | None = None,
) -> SyncCursorPage[CustomerInvoice]

List customer invoices.

Scope: customer_invoices:readonly. Reference: https://pennylane.readme.io/reference/getcustomerinvoices

Parameters:

Name Type Description Default
cursor str | None

Pagination cursor from a previous page.

None
limit int | None

Results per page (1-100, API default 20).

None
filter FiltersInput | None

Conditions built with :mod:pennylane_sdk.filters.

None
sort str | None

Sort field, prefixed with - for descending (default -id).

None
include str | None

Comma-separated list of resources to embed (e.g. invoice_lines).

None

create

create(
    *,
    date: date | str,
    deadline: date | str,
    customer_id: int,
    invoice_lines: list[dict[str, Any]],
    draft: bool = True,
    customer_invoice_template_id: int | None = None,
    pdf_invoice_free_text: str | None = None,
    pdf_invoice_subject: str | None = None,
    pdf_description: str | None = None,
    currency: str | None = None,
    special_mention: str | None = None,
    language: str | None = None,
    discount: dict[str, Any] | None = None,
    invoice_line_sections: list[dict[str, Any]]
    | None = None,
    label: str | None = None,
    external_reference: str | None = None,
    transaction_reference: dict[str, Any] | None = None,
) -> CustomerInvoice

Create a customer invoice, as a draft or already finalized.

Scope: customer_invoices:all. Reference: https://pennylane.readme.io/reference/postcustomerinvoices

The request body is an anyOf of two variants:

  • Draft invoice (draft=True, the default): accepts discount and label; transaction_reference is not allowed.
  • Finalized invoice (draft=False): accepts transaction_reference to auto-reconcile the invoice with a bank transaction; discount and label are not allowed.

Parameters:

Name Type Description Default
date date | str

Invoice date (ISO 8601).

required
deadline date | str

Invoice payment deadline (ISO 8601).

required
customer_id int

Customer identifier.

required
invoice_lines list[dict[str, Any]]

Invoice lines, each a dict of invoice line fields (label, quantity, raw_currency_unit_price, unit, vat_rate, product_id, ledger_account_id, discount, imputation_dates, section_rank...).

required
draft bool

Whether the invoice is created as a draft (default) or finalized.

True
customer_invoice_template_id int | None

The customer invoice template ID.

None
pdf_invoice_free_text str | None

Free text shown on the PDF (e.g. contact details).

None
pdf_invoice_subject str | None

Invoice title.

None
pdf_description str | None

Invoice description (max 5,000 characters).

None
currency str | None

ISO currency code (default EUR).

None
special_mention str | None

Additional details (max 20,000 characters).

None
language str | None

Invoice language (fr_FR, en_GB or de_DE).

None
discount dict[str, Any] | None

{"type": "absolute" | "relative", "value": "..."}: draft only.

None
invoice_line_sections list[dict[str, Any]] | None

List of {"title", "description", "rank"} dicts.

None
label str | None

Custom label used on accounting (ledger) entries: draft only.

None
external_reference str | None

Your own unique reference for this invoice.

None
transaction_reference dict[str, Any] | None

{"banking_provider", "provider_field_name", "provider_field_value"} to auto-reconcile: finalized only.

None

get

get(customer_invoice_id: int) -> CustomerInvoice

Retrieve a customer invoice by its Pennylane identifier.

Scope: customer_invoices:readonly. Reference: https://pennylane.readme.io/reference/getcustomerinvoice

update

update(
    customer_invoice_id: int,
    *,
    date: date | str | None = None,
    deadline: date | str | None = None,
    customer_id: int | None = None,
    customer_invoice_template_id: int | None = None,
    pdf_invoice_free_text: str | None = None,
    pdf_invoice_subject: str | None = None,
    pdf_description: str | None = None,
    currency: str | None = None,
    special_mention: str | None = None,
    discount: dict[str, Any] | None = None,
    language: str | None = None,
    invoice_lines: dict[str, Any] | None = None,
    label: str | None = None,
    external_reference: str | None = None,
    transaction_reference: dict[str, Any] | None = None,
) -> CustomerInvoice

Update a customer invoice. Only the provided fields are modified.

Scope: customer_invoices:all. Reference: https://pennylane.readme.io/reference/putcustomerinvoice

The request body is an anyOf of two variants:

  • Draft invoice: accepts date, deadline, customer_id, customer_invoice_template_id, discount, language and invoice_lines as {"create": [...], "update": [...], "delete": [...]}.
  • Finalized invoice: only accepts label, transaction_reference, external_reference and invoice_lines as {"update": [...]}.

Parameters:

Name Type Description Default
invoice_lines dict[str, Any] | None

{"create": [...], "update": [...], "delete": [...]} (finalized invoices only support update).

None
transaction_reference dict[str, Any] | None

{"banking_provider", "provider_field_name", "provider_field_value"}: finalized invoices only.

None

delete

delete(customer_invoice_id: int) -> None

Delete a draft customer invoice.

Scope: customer_invoices:all. Reference: https://pennylane.readme.io/reference/deletecustomerinvoices

finalize

finalize(customer_invoice_id: int) -> CustomerInvoice

Turn a draft invoice into a finalized invoice.

Scope: customer_invoices:all. Reference: https://pennylane.readme.io/reference/finalizecustomerinvoice

mark_as_paid

mark_as_paid(customer_invoice_id: int) -> None

Mark a customer invoice as paid.

Scope: customer_invoices:all. Reference: https://pennylane.readme.io/reference/markaspaidcustomerinvoice

send_by_email

send_by_email(
    customer_invoice_id: int,
    *,
    recipients: list[str] | None = None,
) -> None

Send a customer invoice by email.

Scope: customer_invoices:all. Reference: https://pennylane.readme.io/reference/sendbyemailcustomerinvoice

Parameters:

Name Type Description Default
recipients list[str] | None

Email recipients. If empty, defaults to the recipient addresses configured on the customer.

None

send_to_pa

send_to_pa(customer_invoice_id: int) -> None

Send a customer e-invoice to the Partner Platform (PA).

Scope: customer_invoices:all. Reference: https://pennylane.readme.io/reference/sendtopacustomerinvoice

link_credit_note(
    customer_invoice_id: int, *, credit_note_id: int
) -> CustomerInvoice

Link a credit note to a customer invoice.

Scope: customer_invoices:all. Reference: https://pennylane.readme.io/reference/linkcreditnote

Parameters:

Name Type Description Default
credit_note_id int

The credit note (customer invoice) ID.

required

update_imported

update_imported(
    customer_invoice_id: int,
    *,
    date: date | str | None = None,
    deadline: date | str | None = None,
    customer_id: int | None = None,
    invoice_number: str | None = None,
    currency: str | None = None,
    currency_amount_before_tax: MoneyInput | None = None,
    currency_amount: MoneyInput | None = None,
    amount: MoneyInput | None = None,
    currency_tax: MoneyInput | None = None,
    tax: MoneyInput | None = None,
    transaction_reference: dict[str, Any] | None = None,
    invoice_lines: dict[str, Any] | None = None,
    external_reference: str | None = None,
) -> CustomerInvoice

Update an imported customer invoice (whose amounts are set manually).

Scope: customer_invoices:all. Reference: https://pennylane.readme.io/reference/updateimportedcustomerinvoice

Parameters:

Name Type Description Default
invoice_lines dict[str, Any] | None

{"create": [...], "update": [...], "delete": [...]}.

None

import_from_file

import_from_file(
    *,
    file_attachment_id: int,
    date: date | str,
    deadline: date | str,
    customer_id: int,
    currency_amount_before_tax: MoneyInput,
    currency_amount: MoneyInput,
    currency_tax: MoneyInput,
    invoice_lines: list[dict[str, Any]],
    import_as_incomplete: bool | None = None,
    invoice_number: str | None = None,
    currency: str | None = None,
    amount: MoneyInput | None = None,
    tax: MoneyInput | None = None,
    label: str | None = None,
    transaction_reference: dict[str, Any] | None = None,
) -> CustomerInvoice

Import a customer invoice from a previously uploaded file attachment.

Scope: customer_invoices:all. Reference: https://pennylane.readme.io/reference/importcustomerinvoices

Parameters:

Name Type Description Default
file_attachment_id int

ID of a file uploaded through /file_attachments.

required
import_as_incomplete bool | None

Set the invoice to Incomplete status.

None
invoice_lines list[dict[str, Any]]

Invoice lines, each a dict of invoice line fields (currency_amount, currency_tax, quantity, raw_currency_unit_price, unit, vat_rate...).

required

import_e_invoice

import_e_invoice(
    *,
    file: FileInput,
    filename: str | None = None,
    invoice_options: dict[str, Any] | None = None,
) -> CustomerInvoiceImportResult

Import a customer e-invoice file (Factur-X PDF, UBL XML or CII XML).

Scope: customer_invoices:all. Reference: https://pennylane.readme.io/reference/createcustomerinvoiceeinvoiceimport

Parameters:

Name Type Description Default
file FileInput

The e-invoice file (path, bytes or file-like object).

required
filename str | None

Overrides the filename sent to the API.

None
invoice_options dict[str, Any] | None

Optional payload to enrich the imported invoice: {"customer_id": ..., "invoice_lines": [{"e_invoice_line_id", "ledger_account_id", "product_id"}, ...]}.

None

create_from_quote

create_from_quote(
    *,
    quote_id: int,
    draft: bool,
    external_reference: str | None = None,
    customer_invoice_template_id: int | None = None,
) -> CustomerInvoice

Create a customer invoice from an accepted quote.

Scope: customer_invoices:all. Reference: https://pennylane.readme.io/reference/createcustomerinvoicefromquote

Parameters:

Name Type Description Default
quote_id int

Quote identifier to create the invoice from.

required
draft bool

Whether the invoice should be created as a draft.

required
external_reference str | None

Your own unique reference for this invoice.

None
customer_invoice_template_id int | None

The customer invoice template ID.

None

list_invoice_lines

list_invoice_lines(
    customer_invoice_id: int,
    *,
    cursor: str | None = None,
    limit: int | None = None,
    sort: str | None = None,
) -> SyncCursorPage[InvoiceLine]

List the invoice lines of a customer invoice.

Scope: customer_invoices:readonly. Reference: https://pennylane.readme.io/reference/getcustomerinvoiceinvoicelines

list_invoice_line_sections

list_invoice_line_sections(
    customer_invoice_id: int,
    *,
    cursor: str | None = None,
    limit: int | None = None,
    sort: str | None = None,
) -> SyncCursorPage[InvoiceLineSection]

List the invoice line sections of a customer invoice.

Scope: customer_invoices:readonly. Reference: https://pennylane.readme.io/reference/getcustomerinvoiceinvoicelinesections

list_payments

list_payments(
    customer_invoice_id: int,
    *,
    cursor: str | None = None,
    limit: int | None = None,
    sort: str | None = None,
) -> SyncCursorPage[Payment]

List the payments of a customer invoice.

Scope: customer_invoices:readonly. Reference: https://pennylane.readme.io/reference/getcustomerinvoicepayments

list_matched_transactions

list_matched_transactions(
    customer_invoice_id: int,
    *,
    cursor: str | None = None,
    limit: int | None = None,
    sort: str | None = None,
) -> SyncCursorPage[MatchedTransaction]

List the bank transactions matched to a customer invoice.

Scope: customer_invoices:readonly. Reference: https://pennylane.readme.io/reference/getcustomerinvoicematchedtransactions

match_transaction

match_transaction(
    customer_invoice_id: int, *, transaction_id: int
) -> None

Match a bank transaction to a customer invoice.

Scope: customer_invoices:all. Reference: https://pennylane.readme.io/reference/postcustomerinvoicematchedtransactions

Parameters:

Name Type Description Default
transaction_id int

ID of the transaction to match.

required

unmatch_transaction

unmatch_transaction(
    customer_invoice_id: int, transaction_id: int
) -> None

Unmatch a bank transaction from a customer invoice.

Scope: customer_invoices:all. Reference: https://pennylane.readme.io/reference/deletecustomerinvoicematchedtransactions

list_appendices

list_appendices(
    customer_invoice_id: int,
    *,
    cursor: str | None = None,
    limit: int | None = None,
) -> SyncCursorPage[Appendix]

List the appendices attached to a customer invoice.

Scope: customer_invoices:readonly. Reference: https://pennylane.readme.io/reference/getcustomerinvoiceappendices

add_appendix

add_appendix(
    customer_invoice_id: int,
    *,
    file: FileInput,
    filename: str | None = None,
) -> Appendix

Upload an appendix file for a customer invoice.

Scope: customer_invoices:all. Reference: https://pennylane.readme.io/reference/postcustomerinvoiceappendices

Parameters:

Name Type Description Default
file FileInput

The appendix file (path, bytes or file-like object). Allowed content types: PNG, JPEG, PDF (see the API reference for the full list).

required
filename str | None

Overrides the filename sent to the API.

None

list_categories

list_categories(
    customer_invoice_id: int,
    *,
    cursor: str | None = None,
    limit: int | None = None,
) -> SyncCursorPage[CustomerInvoiceCategory]

List the analytic categories assigned to a customer invoice.

Scope: customer_invoices:readonly. Reference: https://pennylane.readme.io/reference/getcustomerinvoicecategories

categorize

categorize(
    customer_invoice_id: int,
    *,
    categories: list[dict[str, Any]],
) -> None

Assign analytic categories to a customer invoice.

Scope: customer_invoices:all. Reference: https://pennylane.readme.io/reference/putcustomerinvoicecategories

Parameters:

Name Type Description Default
categories list[dict[str, Any]]

List of {"id": <category_id>, "weight": "<0..1>"} dicts. The weights across all categories of the same category group must sum to 1.

required

list_custom_header_fields

list_custom_header_fields(
    customer_invoice_id: int,
    *,
    cursor: str | None = None,
    limit: int | None = None,
    sort: str | None = None,
) -> SyncCursorPage[CustomHeaderField]

List the custom header fields of a customer invoice.

Scope: customer_invoices:readonly. Reference: https://pennylane.readme.io/reference/getcustomerinvoicecustomheaderfields

Bases: SyncAPIResource

Read customer invoice templates.

list

list(
    *,
    cursor: str | None = None,
    limit: int | None = None,
    sort: str | None = None,
) -> SyncCursorPage[CustomerInvoiceTemplate]

List customer invoice templates.

Scope: customer_invoice_templates:readonly. Reference: https://pennylane.readme.io/reference/getcustomerinvoicetemplates

Parameters:

Name Type Description Default
cursor str | None

Pagination cursor from a previous page.

None
limit int | None

Results per page (1-100, API default 20).

None
sort str | None

Sort field, prefixed with - for descending (default -id).

None

Bases: SyncAPIResource

Manage quotes.

list

list(
    *,
    cursor: str | None = None,
    limit: int | None = None,
    filter: FiltersInput | None = None,
    sort: str | None = None,
) -> SyncCursorPage[Quote]

List quotes.

Scope: quotes:readonly. Reference: https://pennylane.readme.io/reference/listquotes

Parameters:

Name Type Description Default
cursor str | None

Pagination cursor from a previous page.

None
limit int | None

Results per page (1-100, API default 20).

None
filter FiltersInput | None

Conditions built with :mod:pennylane_sdk.filters.

None
sort str | None

Sort field, prefixed with - for descending (default -id).

None

get

get(quote_id: int) -> Quote

Retrieve a quote by its Pennylane identifier.

Scope: quotes:readonly. Reference: https://pennylane.readme.io/reference/getquote

create

create(
    *,
    date: date | str,
    deadline: date | str,
    customer_id: int,
    invoice_lines: list[dict[str, Any]],
    quote_template_id: int | None = None,
    pdf_invoice_free_text: str | None = None,
    pdf_invoice_subject: str | None = None,
    pdf_description: str | None = None,
    currency: str | None = None,
    special_mention: str | None = None,
    language: str | None = None,
    discount: dict[str, Any] | None = None,
    invoice_line_sections: list[dict[str, Any]]
    | None = None,
    external_reference: str | None = None,
) -> Quote

Create a quote.

Scope: quotes:all. Reference: https://pennylane.readme.io/reference/postquotes

Parameters:

Name Type Description Default
date date | str

Quote date (ISO 8601).

required
deadline date | str

Quote validity deadline (ISO 8601).

required
customer_id int

Customer identifier.

required
invoice_lines list[dict[str, Any]]

Invoice lines. Each item is either a product-based line ({"product_id": ..., "quantity": ..., ...}) or a standard line ({"label": ..., "quantity": ..., "raw_currency_unit_price": ..., "vat_rate": ..., ...}).

required
quote_template_id int | None

The quote template ID.

None
pdf_invoice_free_text str | None

For example, the contact details of the person to contact.

None
pdf_invoice_subject str | None

Quote title.

None
pdf_description str | None

Quote description.

None
currency str | None

ISO currency code (default EUR).

None
special_mention str | None

Additional details.

None
language str | None

Document language (fr_FR, en_GB or de_DE).

None
discount dict[str, Any] | None

{"type": "absolute" | "relative", "value": "..."}.

None
invoice_line_sections list[dict[str, Any]] | None

Sections used to group invoice lines, each with a rank and optional title / description.

None
external_reference str | None

A unique external reference you can provide to track this quote. If not provided, Pennylane generates one.

None

update

update(
    quote_id: int,
    *,
    date: date | str | None = None,
    deadline: date | str | None = None,
    customer_id: int | None = None,
    quote_template_id: int | None = None,
    pdf_invoice_free_text: str | None = None,
    pdf_invoice_subject: str | None = None,
    pdf_description: str | None = None,
    currency: str | None = None,
    special_mention: str | None = None,
    discount: dict[str, Any] | None = None,
    language: str | None = None,
    invoice_lines: dict[str, Any] | None = None,
    external_reference: str | None = None,
) -> Quote

Update a quote. Only the provided fields are modified.

Scope: quotes:all. Reference: https://pennylane.readme.io/reference/updatequote

See :meth:create for the other arguments.

Parameters:

Name Type Description Default
invoice_lines dict[str, Any] | None

{"create": [...], "update": [...], "delete": [...]} add, update or delete invoice lines. update/delete entries require an id; create entries follow the same shape as in :meth:create.

None

update_status

update_status(quote_id: int, *, status: str) -> Quote

Update the status of a quote.

Scope: quotes:all. Reference: https://pennylane.readme.io/reference/updatestatusquote

Parameters:

Name Type Description Default
status str

One of pending, accepted, denied, invoiced, expired.

required

send_by_email

send_by_email(
    quote_id: int, *, recipients: list[str] | None = None
) -> None

Send a quote by email.

Scope: quotes:all. Reference: https://pennylane.readme.io/reference/sendbyemailquote

Parameters:

Name Type Description Default
recipients list[str] | None

Email recipients. If empty, the email is sent to the recipient email addresses specified on the customer.

None

list_appendices

list_appendices(
    quote_id: int,
    *,
    cursor: str | None = None,
    limit: int | None = None,
) -> SyncCursorPage[QuoteAppendix]

List the appendices attached to a quote.

Scope: quotes:readonly. Reference: https://pennylane.readme.io/reference/getquoteappendices

add_appendix

add_appendix(
    quote_id: int,
    *,
    file: FileInput,
    filename: str | None = None,
) -> QuoteAppendix

Upload an appendix for a quote.

Scope: quotes:all. Reference: https://pennylane.readme.io/reference/postquoteappendices

Parameters:

Name Type Description Default
file FileInput

The appendix file (path, bytes, file-like object or (filename, content) tuple).

required
filename str | None

Overrides the filename sent to the API.

None

list_invoice_lines

list_invoice_lines(
    quote_id: int,
    *,
    cursor: str | None = None,
    limit: int | None = None,
    sort: str | None = None,
) -> SyncCursorPage[QuoteInvoiceLine]

List the invoice lines of a quote.

Scope: quotes:readonly. Reference: https://pennylane.readme.io/reference/getquoteinvoicelines

list_invoice_line_sections

list_invoice_line_sections(
    quote_id: int,
    *,
    cursor: str | None = None,
    limit: int | None = None,
    sort: str | None = None,
) -> SyncCursorPage[QuoteInvoiceLineSection]

List the invoice line sections of a quote.

Scope: quotes:readonly. Reference: https://pennylane.readme.io/reference/getquoteinvoicelinesections

Bases: SyncAPIResource

Read commercial documents (proforma, shipping orders, purchasing orders).

list

list(
    *,
    cursor: str | None = None,
    limit: int | None = None,
    filter: FiltersInput | None = None,
    sort: str | None = None,
) -> SyncCursorPage[CommercialDocument]

List commercial documents.

Scope: commercial_documents:readonly. Reference: https://pennylane.readme.io/reference/listcommercialdocuments

Parameters:

Name Type Description Default
cursor str | None

Pagination cursor from a previous page.

None
limit int | None

Results per page (1-100, API default 20).

None
filter FiltersInput | None

Conditions built with :mod:pennylane_sdk.filters.

None
sort str | None

Sort field, prefixed with - for descending (default -id).

None

get

get(commercial_document_id: int) -> CommercialDocument

Retrieve a commercial document by its Pennylane identifier.

Scope: commercial_documents:readonly. Reference: https://pennylane.readme.io/reference/getcommercialdocument

list_appendices

list_appendices(
    commercial_document_id: int,
    *,
    cursor: str | None = None,
    limit: int | None = None,
) -> SyncCursorPage[CommercialDocumentAppendix]

List the appendices attached to a commercial document.

Scope: commercial_documents:readonly. Reference: https://pennylane.readme.io/reference/getcommercialdocumentappendices

add_appendix

add_appendix(
    commercial_document_id: int,
    *,
    file: FileInput,
    filename: str | None = None,
) -> CommercialDocumentAppendix

Upload an appendix for a commercial document.

Scope: commercial_documents:all. Reference: https://pennylane.readme.io/reference/postcommercialdocumentappendices

Parameters:

Name Type Description Default
file FileInput

The appendix file (path, bytes, file-like object or (filename, content) tuple).

required
filename str | None

Overrides the filename sent to the API.

None

list_invoice_lines

list_invoice_lines(
    commercial_document_id: int,
    *,
    cursor: str | None = None,
    limit: int | None = None,
    sort: str | None = None,
) -> SyncCursorPage[CommercialDocumentInvoiceLine]

List the invoice lines of a commercial document.

Scope: commercial_documents:readonly. Reference: https://pennylane.readme.io/reference/getcommercialdocumentinvoicelines

list_invoice_line_sections

list_invoice_line_sections(
    commercial_document_id: int,
    *,
    cursor: str | None = None,
    limit: int | None = None,
    sort: str | None = None,
) -> SyncCursorPage[CommercialDocumentInvoiceLineSection]

List the invoice line sections of a commercial document.

Scope: commercial_documents:readonly. Reference: https://pennylane.readme.io/reference/getcommercialdocumentinvoicelinesections

Bases: SyncAPIResource

Manage recurring customer invoice subscriptions.

list

list(
    *,
    cursor: str | None = None,
    limit: int | None = None,
    filter: FiltersInput | None = None,
    sort: str | None = None,
) -> SyncCursorPage[BillingSubscription]

List billing subscriptions.

Scope: billing_subscriptions:readonly. Reference: https://pennylane.readme.io/reference/getbillingsubscriptions

Parameters:

Name Type Description Default
cursor str | None

Pagination cursor from a previous page.

None
limit int | None

Results per page (1-100, API default 20).

None
filter FiltersInput | None

Conditions built with :mod:pennylane_sdk.filters. Supported fields: id, start, customer_id (lt, lteq, gt, gteq, eq, not_eq, in, not_in) and status (eq, not_eq, in, not_in).

None
sort str | None

Sort field, prefixed with - for descending (default -id).

None

get

get(billing_subscription_id: int) -> BillingSubscription

Retrieve a billing subscription by its Pennylane identifier.

Scope: billing_subscriptions:readonly. Reference: https://pennylane.readme.io/reference/getbillingsubscription

create

create(
    *,
    start: str,
    mode: dict[str, Any],
    payment_conditions: str,
    payment_method: str,
    recurring_rule: dict[str, Any],
    customer_id: int,
    customer_invoice_data: dict[str, Any],
    label: str | None = None,
) -> BillingSubscription

Create a billing subscription.

Pennylane generates a customer invoice at each occurrence of the subscription. It can also be linked to a GoCardless mandate.

Scope: billing_subscriptions:all. Reference: https://pennylane.readme.io/reference/postbillingsubscriptions

Parameters:

Name Type Description Default
start str

Subscription start date (YYYY-MM-DD).

required
mode dict[str, Any]

Invoice generation mode, {"type": "awaiting_validation" | "finalized"} or {"type": "email", "email_settings": {"recipients": [...]}}.

required
payment_conditions str

One of upon_receipt, 7_days, 15_days, 30_days, 30_days_end_of_month, 45_days, 45_days_end_of_month, 60_days.

required
payment_method str

One of offline, gocardless_direct_debit, pro_account_sepa_core.

required
recurring_rule dict[str, Any]

Recurrence rule, e.g. {"type": "monthly", "interval": 1, "day_of_month": 1} (type is one of yearly, monthly, weekly, each with its own optional interval/count and, respectively, day_of_month or day_of_week).

required
customer_id int

Customer identifier.

required
customer_invoice_data dict[str, Any]

Data used to generate each invoice, with keys such as currency, customer_invoice_template_id, pdf_invoice_free_text, pdf_invoice_subject, pdf_description, special_mention, language, discount, invoice_line_sections and the required invoice_lines (list of line dicts with label, quantity, unit, raw_currency_unit_price, vat_rate).

required
label str | None

Subscription label.

None

update

update(
    billing_subscription_id: int,
    *,
    stop: bool | None = None,
    mode: dict[str, Any] | None = None,
    payment_conditions: str | None = None,
    payment_method: str | None = None,
    recurring_rule: dict[str, Any] | None = None,
    customer_id: int | None = None,
    customer_invoice_data: dict[str, Any] | None = None,
    label: str | None = None,
) -> BillingSubscription

Update a billing subscription. Only the provided fields are modified.

Scope: billing_subscriptions:all. Reference: https://pennylane.readme.io/reference/putbillingsubscriptions

Parameters:

Name Type Description Default
stop bool | None

Use True to stop an in_progress subscription, False to resume a stopped one.

None
mode dict[str, Any] | None

See :meth:create.

None
payment_conditions str | None

See :meth:create.

None
payment_method str | None

See :meth:create.

None
recurring_rule dict[str, Any] | None

See :meth:create.

None
customer_id int | None

Customer identifier.

None
customer_invoice_data dict[str, Any] | None

See :meth:create.

None
label str | None

Subscription label.

None

list_invoice_lines

list_invoice_lines(
    billing_subscription_id: int,
    *,
    cursor: str | None = None,
    limit: int | None = None,
    sort: str | None = None,
) -> SyncCursorPage[BillingSubscriptionInvoiceLine]

List the invoice lines generated by a billing subscription.

Scope: billing_subscriptions:readonly. Reference: https://pennylane.readme.io/reference/getbillingsubscriptioninvoicelines

Parameters:

Name Type Description Default
billing_subscription_id int

Parent billing subscription identifier.

required
cursor str | None

Pagination cursor from a previous page.

None
limit int | None

Results per page (1-100, API default 20).

None
sort str | None

Sort field, prefixed with - for descending (default -id).

None

list_invoice_line_sections

list_invoice_line_sections(
    billing_subscription_id: int,
    *,
    cursor: str | None = None,
    limit: int | None = None,
    sort: str | None = None,
) -> SyncCursorPage[BillingSubscriptionInvoiceLineSection]

List the invoice line sections generated by a billing subscription.

Scope: billing_subscriptions:readonly. Reference: https://pennylane.readme.io/reference/getbillingsubscriptioninvoicelinesections

Parameters:

Name Type Description Default
billing_subscription_id int

Parent billing subscription identifier.

required
cursor str | None

Pagination cursor from a previous page.

None
limit int | None

Results per page (1-100, API default 20).

None
sort str | None

Sort field, prefixed with - for descending (default -id).

None

Bases: SyncAPIResource

Manage customers (company and individual).

.companies and .individuals expose the type-specific create/update endpoints, e.g. client.customers.companies.create(...).

list

list(
    *,
    cursor: str | None = None,
    limit: int | None = None,
    filter: FiltersInput | None = None,
    sort: str | None = None,
) -> SyncCursorPage[Customer]

List customers (company and individual).

Scope: customers:readonly. Reference: https://pennylane.readme.io/reference/getcustomers

Parameters:

Name Type Description Default
cursor str | None

Pagination cursor from a previous page.

None
limit int | None

Results per page (1-100, API default 20).

None
filter FiltersInput | None

Conditions built with :mod:pennylane_sdk.filters.

None
sort str | None

Sort field, prefixed with - for descending (default -id).

None

get

get(customer_id: int) -> Customer

Retrieve a customer by its Pennylane identifier.

Scope: customers:readonly. Reference: https://pennylane.readme.io/reference/getcustomer

list_categories

list_categories(
    customer_id: int,
    *,
    cursor: str | None = None,
    limit: int | None = None,
) -> SyncCursorPage[CustomerCategory]

List the categories assigned to a customer.

Scope: customers:readonly. Reference: https://pennylane.readme.io/reference/getcustomercategories

categorize

categorize(
    customer_id: int, *, categories: list[dict[str, Any]]
) -> None

Replace the categories assigned to a customer.

Scope: customers:all. Reference: https://pennylane.readme.io/reference/putcustomercategories

Parameters:

Name Type Description Default
categories list[dict[str, Any]]

List of {"id": <category id>, "weight": <str fraction, e.g. "0.6575">}.

required

list_contacts

list_contacts(
    customer_id: int,
    *,
    cursor: str | None = None,
    limit: int | None = None,
    sort: str | None = None,
) -> SyncCursorPage[CustomerContact]

List the contacts of a customer.

Scope: customers:readonly. Reference: https://pennylane.readme.io/reference/getcustomercontacts

Bases: SyncAPIResource

Manage company customers.

create

create(
    *,
    name: str,
    billing_address: dict[str, Any],
    vat_number: str | None = None,
    reg_no: str | None = None,
    ledger_account: dict[str, Any] | None = None,
    phone: str | None = None,
    delivery_address: dict[str, Any] | None = None,
    payment_conditions: str | None = None,
    billing_iban: str | None = None,
    recipient: str | None = None,
    reference: str | None = None,
    notes: str | None = None,
    emails: list[str] | None = None,
    external_reference: str | None = None,
    billing_language: str | None = None,
) -> Customer

Create a company customer.

Scope: customers:all. Reference: https://pennylane.readme.io/reference/postcompanycustomer

Parameters:

Name Type Description Default
name str

Company name.

required
billing_address dict[str, Any]

{"address", "postal_code", "city", "country_alpha2"}.

required
vat_number str | None

VAT number.

None
reg_no str | None

Registration number (SIREN in France).

None
ledger_account dict[str, Any] | None

{"number": <ledger account number>}.

None
phone str | None

Phone number.

None
delivery_address dict[str, Any] | None

Same shape as billing_address.

None
payment_conditions str | None

One of upon_receipt, custom, 7_days, 15_days, 30_days, 30_days_end_of_month, 45_days, 45_days_end_of_month, 60_days (default 30_days).

None
billing_iban str | None

Billing IBAN.

None
recipient str | None

Name of the person the invoice is addressed to.

None
reference str | None

Your own reference for this customer.

None
notes str | None

Free-form notes.

None
emails list[str] | None

Email addresses.

None
external_reference str | None

Your own unique reference (auto-assigned if omitted).

None
billing_language str | None

One of fr_FR, en_GB, de_DE (default fr_FR).

None

get

get(company_customer_id: int) -> Customer

Retrieve a company customer by its Pennylane identifier.

Scope: customers:readonly. Reference: https://pennylane.readme.io/reference/getcompanycustomer

update

update(
    company_customer_id: int,
    *,
    name: str | None = None,
    vat_number: str | None = None,
    reg_no: str | None = None,
    phone: str | None = None,
    billing_address: dict[str, Any] | None = None,
    delivery_address: dict[str, Any] | None = None,
    payment_conditions: str | None = None,
    billing_iban: str | None = None,
    recipient: str | None = None,
    reference: str | None = None,
    notes: str | None = None,
    emails: list[str] | None = None,
    external_reference: str | None = None,
    billing_language: str | None = None,
) -> Customer

Update a company customer. Only the provided fields are modified.

Scope: customers:all. Reference: https://pennylane.readme.io/reference/putcompanycustomer

Bases: SyncAPIResource

Manage individual customers.

create

create(
    *,
    first_name: str,
    last_name: str,
    billing_address: dict[str, Any],
    phone: str | None = None,
    delivery_address: dict[str, Any] | None = None,
    payment_conditions: str | None = None,
    billing_iban: str | None = None,
    recipient: str | None = None,
    reference: str | None = None,
    ledger_account: dict[str, Any] | None = None,
    notes: str | None = None,
    emails: list[str] | None = None,
    external_reference: str | None = None,
    billing_language: str | None = None,
) -> Customer

Create an individual customer.

Scope: customers:all. Reference: https://pennylane.readme.io/reference/postindividualcustomer

Parameters:

Name Type Description Default
first_name str

Given name.

required
last_name str

Family name.

required
billing_address dict[str, Any]

{"address", "postal_code", "city", "country_alpha2"}.

required
phone str | None

Phone number.

None
delivery_address dict[str, Any] | None

Same shape as billing_address.

None
payment_conditions str | None

See :meth:CompanyCustomers.create.

None
billing_iban str | None

Billing IBAN.

None
recipient str | None

Name of the person the invoice is addressed to.

None
reference str | None

Your own reference for this customer.

None
ledger_account dict[str, Any] | None

{"number": <ledger account number>}.

None
notes str | None

Free-form notes.

None
emails list[str] | None

Email addresses.

None
external_reference str | None

Your own unique reference (auto-assigned if omitted).

None
billing_language str | None

One of fr_FR, en_GB, de_DE (default fr_FR).

None

get

get(individual_customer_id: int) -> Customer

Retrieve an individual customer by its Pennylane identifier.

Scope: customers:readonly. Reference: https://pennylane.readme.io/reference/getindividualcustomer

update

update(
    individual_customer_id: int,
    *,
    first_name: str | None = None,
    last_name: str | None = None,
    phone: str | None = None,
    billing_address: dict[str, Any] | None = None,
    delivery_address: dict[str, Any] | None = None,
    payment_conditions: str | None = None,
    billing_iban: str | None = None,
    recipient: str | None = None,
    reference: str | None = None,
    notes: str | None = None,
    emails: list[str] | None = None,
    external_reference: str | None = None,
    billing_language: str | None = None,
) -> Customer

Update an individual customer. Only the provided fields are modified.

Scope: customers:all. Reference: https://pennylane.readme.io/reference/putindividualcustomer

Bases: SyncAPIResource

Manage the company product catalog.

list

list(
    *,
    cursor: str | None = None,
    limit: int | None = None,
    filter: FiltersInput | None = None,
    sort: str | None = None,
) -> SyncCursorPage[Product]

List products.

Scope: products:readonly. Reference: https://pennylane.readme.io/reference/getproducts

Parameters:

Name Type Description Default
cursor str | None

Pagination cursor from a previous page.

None
limit int | None

Results per page (1-100, API default 20).

None
filter FiltersInput | None

Conditions built with :mod:pennylane_sdk.filters.

None
sort str | None

Sort field, prefixed with - for descending (default -id).

None

get

get(product_id: int) -> Product

Retrieve a product by its Pennylane identifier.

Scope: products:readonly. Reference: https://pennylane.readme.io/reference/getproduct

create

create(
    *,
    label: str,
    price_before_tax: MoneyInput,
    vat_rate: str,
    description: str | None = None,
    external_reference: str | None = None,
    unit: str | None = None,
    currency: str | None = None,
    reference: str | None = None,
    ledger_account_id: int | None = None,
) -> Product

Create a product.

Scope: products:all. Reference: https://pennylane.readme.io/reference/postproducts

Parameters:

Name Type Description Default
label str

Product label.

required
price_before_tax MoneyInput

Price without taxes (Decimal or string).

required
vat_rate str

VAT rate code: a 20% French VAT is "FR_200".

required
description str | None

Product description (max 5,000 characters).

None
external_reference str | None

Your own unique reference for this product.

None
unit str | None

Product unit.

None
currency str | None

ISO currency code (default EUR).

None
reference str | None

Product reference shown on documents.

None
ledger_account_id int | None

Ledger account to book sales on.

None

update

update(
    product_id: int,
    *,
    label: str | None = None,
    price_before_tax: MoneyInput | None = None,
    vat_rate: str | None = None,
    description: str | None = None,
    external_reference: str | None = None,
    unit: str | None = None,
    currency: str | None = None,
    reference: str | None = None,
    ledger_account_id: int | None = None,
) -> Product

Update a product. Only the provided fields are modified.

Scope: products:all. Reference: https://pennylane.readme.io/reference/putproduct