---
title: "Import an invoice with file attached"
method: POST
path: "/api/external/v2/customer_invoices/import"
tags: ["Customer Invoices"]
---

# Import an invoice with file attached

`POST /api/external/v2/customer_invoices/import`

## Request

- Base URL: `https://app.pennylane.com`
- URL: `https://app.pennylane.com/api/external/v2/customer_invoices/import`
- Auth: OAuth 2
  - Authorization code: `https://app.pennylane.com/oauth/authorize`
  - Token URL: `https://app.pennylane.com/oauth/oauth/token` scopes: `customer_invoices:all`

This endpoint allows you to import an invoice. Amounts are stored exactly as provided — Pennylane does not recalculate or round them.

ℹ️ **Amount consistency:** The amounts you send must be internally coherent:
- `currency_amount_before_tax + currency_tax` must equal `currency_amount`.
- The sum of invoice line `currency_tax` values must match the invoice-level `currency_tax`.
- The sum of invoice line `currency_amount` values must match the invoice-level `currency_amount`.

Small rounding differences are tolerated. When `convert_to_e_invoice` is `true`, stricter requirements apply — see that field's description.


> ℹ️
> This endpoint requires the following scope: `customer_invoices:all`

## Headers

- `X-Company-Id` string

## Request body

- object
  - `file_attachment_id` integer, required: ID of a previously uploaded file attachment. The attachment must already have a file. If the file is not available yet, the API returns 409; retry after a few seconds.
  - `import_as_incomplete` boolean: This will set the invoice to Incomplete status
  - `date` string, date, required: Invoice date (ISO 8601)
  - `deadline` string, date, required: Invoice payment deadline (ISO 8601)
  - `customer_id` integer, required: Customer identifier
  - `sale_type` union: Type of sale printed on the invoice (Type de vente). `goods` is a supply of goods, `services` is a supply of services, and `goods_and_services` is both. `null` means the type has not been chosen. This is not invoice line `substance`. Omit this field to keep the invoice template default. Send `null` to clear it.
    - 'goods' | 'services' | 'goods_and_services': Type of sale printed on a customer invoice. This is not invoice line substance.
    - unknown
  - `invoice_number` string: Invoice number. When `convert_to_e_invoice` is `true`, must be at most 35 characters and only contain alphanumeric characters and `-+_/`.
  - `currency` 'EUR' | 'USD' | 'GBP' | 'AED' | 'AFN' | 'ALL' | 'AMD' | 'ANG' | 'AOA' | 'ARS' | 'AUD' | 'AWG' | 'AZN' | 'BAM' | 'BBD' | 'BDT' | 'BGN' | 'BHD' | 'BIF' | 'BMD' | 'BND' | 'BOB' | 'BRL' | 'BSD' | 'BTN' | 'BWP' | 'BYN' | 'BYR' | 'BZD' | 'CAD' | 'CDF' | 'CHE' | 'CHF' | 'CLF' | 'CLP' | 'CNY' | 'COP' | 'CRC' | 'CUC' | 'CUP' | 'CVE' | 'CZK' | 'DJF' | 'DKK' | 'DOP' | 'DZD' | 'EGP' | 'ERN' | 'ETB' | 'FJD' | 'FKP' | 'GEL' | 'GGP' | 'GHS' | 'GIP' | 'GMD' | 'GNF' | 'GTQ' | 'GYD' | 'HKD' | 'HNL' | 'HRK' | 'HTG' | 'HUF' | 'IDR' | 'ILS' | 'IMP' | 'INR' | 'IQD' | 'IRR' | 'ISK' | 'JEP' | 'JMD' | 'JOD' | 'JPY' | 'KES' | 'KGS' | 'KHR' | 'KMF' | 'KPW' | 'KRW' | 'KWD' | 'KYD' | 'KZT' | 'LAK' | 'LBP' | 'LKR' | 'LRD' | 'LSL' | 'LTL' | 'LVL' | 'LYD' | 'MAD' | 'MDL' | 'MGA' | 'MKD' | 'MMK' | 'MNT' | 'MOP' | 'MRO' | 'MRU' | 'MUR' | 'MVR' | 'MWK' | 'MXN' | 'MYR' | 'MZN' | 'NAD' | 'NGN' | 'NIO' | 'NOK' | 'NPR' | 'NZD' | 'OMR' | 'PAB' | 'PEN' | 'PGK' | 'PHP' | 'PKR' | 'PLN' | 'PYG' | 'QAR' | 'RON' | 'RSD' | 'RUB' | 'RWF' | 'SAR' | 'SBD' | 'SCR' | 'SDG' | 'SEK' | 'SGD' | 'SHP' | 'SLL' | 'SLE' | 'SOS' | 'SRD' | 'STD' | 'SVC' | 'SYP' | 'SZL' | 'THB' | 'TJS' | 'TMT' | 'TND' | 'TOP' | 'TRY' | 'TTD' | 'TWD' | 'TZS' | 'UAH' | 'UGX' | 'UYU' | 'UZS' | 'VEF' | 'VES' | 'VND' | 'VUV' | 'WST' | 'XAF' | 'XCD' | 'XDR' | 'XOF' | 'XPF' | 'YER' | 'ZAR' | 'ZMK' | 'ZMW' | 'ZWL'
  - `currency_amount_before_tax` string, required: Invoice currency amount before tax (total value before tax of the invoice in the currency of the invoice)
  - `currency_amount` string, required: Invoice currency amount (total value of the invoice in the currency of the invoice)
  - `amount` string: Invoice amount in euros (total value of the invoice in euros). If the currency is euro, `currency_amount` and `amount` are identical.
  - `currency_tax` string, required: Invoice taxable amount (in invoice currency)
  - `tax` string: Invoice taxable amount (in euros). If the currency is euro, `currency_tax` and `tax` are identical.
  - `label` string, nullable: Custom label for the invoice used on accounting (ledger) entries. If not provided, Pennylane generates a label automatically.
  - `transaction_reference` object: By adding this field you can automatically reconcile the newly imported invoice with a transaction. See documentation about [automatic payment matching](https://pennylane.readme.io/v2.0/docs/automating-payment-matching).
    - `banking_provider` 'stripe' | 'gocardless' | 'bank' | 'budgetinsight' | 'helloasso', required: The banking provider for the transaction
    - `provider_field_name` 'payment_id' | 'charge_id' | 'report_id' | 'webid' | 'label' | 'order_id', required: Name of the field that you want to match
    - `provider_field_value` string, required: Value that you want to match. With `banking_provider: stripe` or `gocardless`, the value is matched exactly against the reference with the same `provider_field_name` synced from that provider, on non-archived transactions. With `banking_provider: bank` and `provider_field_name: label`, every non-archived bank transaction whose label contains this value as a whole word is matched, including transactions already matched to other documents. The match is case-sensitive, and a value that does not start and end with a letter, digit or underscore never matches. Use a value that identifies a single payment, such as a card transaction ID: a merchant name or a short generic value groups unrelated documents together. Pass the literal string `invoice_number` to match on this invoice's number instead of a fixed value. Other combinations do not match any transaction. In all cases, matching runs again on every update of this invoice.
  - `invoice_lines` object[], required
    - `currency_amount` string, required: Invoice line total amount in the currency of the invoice.
    - `amount` string: Invoice line amount in euros. If the currency is euro, `currency_amount` and `amount` are identical.
    - `currency_tax` string, required: Invoice line taxable amount (in invoice currency)
    - `tax` string: Invoice line taxable amount (in euros). If the currency is euro, currency_tax and tax are identical.
    - `label` string: Line item label. Required when `convert_to_e_invoice` is `true`.
    - `quantity` number, required: Line item quantity (number of items)
    - `ledger_account_id` integer: The ledger account ID
    - `substance` 'goods' | 'services': Resolves the line's ledger account to the company's goods or services account. Unlike customer invoice create, import does not auto-fill fields from `product_id`, and `product_id` is not checked against `substance`. When provided together with `ledger_account_id`, both must refer to the same account. If they do not match, the request returns 422.
    - `raw_currency_unit_price` string, required: The unit price excluding taxes. Can be set up to 6 decimals.
    - `unit` string, required: Line item unit (type of unit)
    - `vat_rate` 'FR_1_05' | 'FR_1_75' | 'FR_09' | 'FR_21' | 'FR_40' | 'FR_50' | 'FR_55' | 'FR_60' | 'FR_65' | 'FR_85' | 'FR_92' | 'FR_100' | 'FR_130' | 'FR_15_385' | 'FR_160' | 'FR_196' | 'FR_200' | 'AD_10' | 'AD_45' | 'AD_95' | 'AT_100' | 'AT_130' | 'AT_190' | 'AT_200' | 'BE_60' | 'BE_120' | 'BE_210' | 'BG_90' | 'BG_200' | 'CH_25' | 'CH_37' | 'CH_77' | 'CH_26' | 'CH_38' | 'CH_81' | 'CY_30' | 'CY_50' | 'CY_80' | 'CY_90' | 'CY_190' | 'CZ_100' | 'CZ_120' | 'CZ_150' | 'CZ_210' | 'DE_70' | 'DE_190' | 'DK_250' | 'EE_90' | 'EE_200' | 'EE_220' | 'EE_240' | 'ES_40' | 'ES_70' | 'ES_100' | 'ES_210' | 'FI_100' | 'FI_135' | 'FI_140' | 'FI_240' | 'FI_255' | 'GB_50' | 'GB_200' | 'GR_60' | 'GR_130' | 'GR_170' | 'GR_240' | 'GR_40' | 'HR_50' | 'HR_130' | 'HR_250' | 'HU_50' | 'HU_180' | 'HU_270' | 'IE_48' | 'IE_90' | 'IE_135' | 'IE_210' | 'IE_230' | 'IT_40' | 'IT_50' | 'IT_100' | 'IT_220' | 'LT_50' | 'LT_90' | 'LT_120' | 'LT_210' | 'LU_30' | 'LU_70' | 'LU_80' | 'LU_120' | 'LU_130' | 'LU_140' | 'LU_160' | 'LU_170' | 'LV_50' | 'LV_120' | 'LV_210' | 'MC_09' | 'MC_21' | 'MC_55' | 'MC_85' | 'MC_100' | 'MC_200' | 'MT_50' | 'MT_70' | 'MT_120' | 'MT_180' | 'MU_150' | 'NL_90' | 'NL_210' | 'PL_50' | 'PL_80' | 'PL_230' | 'PT_60' | 'PT_130' | 'PT_160' | 'PT_180' | 'PT_220' | 'PT_230' | 'RO_50' | 'RO_90' | 'RO_110' | 'RO_190' | 'RO_210' | 'SE_60' | 'SE_120' | 'SE_250' | 'SI_50' | 'SI_95' | 'SI_220' | 'SK_50' | 'SK_100' | 'SK_190' | 'SK_200' | 'SK_230' | 'NO_120' | 'NO_150' | 'NO_250' | 'DE_70_BU0002' | 'DE_190_BU0003' | 'DE_70_BU0008' | 'DE_190_BU0009' | 'DE_intracom_70_BU0012' | 'DE_intracom_190_BU0013' | 'DE_190_electronic_BU0226' | 'exempt' | 'DE_intracom_exempt_BU0011' | 'DE_intracom_exempt_BU0047' | 'DE_intracom_exempt_BU0233' | 'DE_exempt_BU0001' | 'DE_exempt_BU0181' | 'DE_exempt_BU0490' | 'intracom_21' | 'intracom_55' | 'intracom_85' | 'intracom_100' | 'crossborder' | 'ES_intracom_sales_goods' | 'ES_intracom_sales_services' | 'DE_intracom_70_BU0018' | 'DE_intracom_190_BU0019' | 'DE_intracom_190_BU0506' | 'extracom' | 'DE_extracom_BU0173' | 'DE_extracom_BU0191' | 'DE_extracom_190_BU0511' | 'ES_isp_sales' | 'ES_suplido' | 'FR_85_construction' | 'FR_100_construction' | 'FR_200_construction' | 'DE_exempt_construction_BU0046' | 'DE_70_construction_BU0091' | 'DE_190_construction_BU0094' | 'DE_190_construction_BU0526' | 'DE_190_construction_BU0546' | 'ES_isp_purchases_210' | 'ES_isp_purchases_100' | 'mixed', required: Product VAT rate. A 20% VAT in France is FR_200.
    - `description` string, nullable: The description of the invoice line > ⚠️ This attribute is deprecated and will be removed soon.
    - `product_id` integer: The product ID
    - `imputation_dates` object, nullable
      - `start_date` string, date, required: Start date of the imputation period (ISO 8601)
      - `end_date` string, date, required: End date of the imputation period (ISO 8601)
    - `performance_period` union
      - object: Date range during which the service or delivery was performed (ISO 8601). Used for German VAT accounting (Leistungsdatum). Only accepted for companies using German accounting, otherwise the request is rejected. Omit it to keep the current performance period, or set it to null to remove it.
        - `start_date` string, date, nullable: Start date of the performance period (ISO 8601). Null for single-date types (`delivery_date`, `service_date`), required otherwise.
        - `end_date` string, date, required: End date of the performance period (ISO 8601)
        - `date_type` 'delivery_date' | 'service_date' | 'delivery_period' | 'service_period', required: Whether the performance period represents a single date or a range, and whether it is a delivery or service. - delivery_date: single delivery date (end_date only) - service_date: single service date (end_date only) - delivery_period: delivery date range (start_date and end_date) - service_period: service date range (start_date and end_date)
      - unknown
    - `ledger_entry_line` object
      - `label` string, required: Ledger entry line label. Ledger entry lines with identical labels, tax, and ledger accounts will be automatically compacted into a single line.
    - `discount` object: Line-level discount. Only allowed when `convert_to_e_invoice` is `true` — sending this field without conversion enabled is an error. All amounts must be provided after discount — no recomputation is performed. Use `relative` for a percentage discount and `absolute` for a fixed amount discount.
      - `type` 'absolute' | 'relative', required: Discount type. - absolute if it is an amount - relative if it is a percentage
      - `value` string, nullable, required: Discount value on the total amount before tax of the line
  - `convert_to_e_invoice` boolean: When set to `true`, Pennylane will asynchronously convert the imported invoice into a Factur-X e-invoice (PDF/A-3) by embedding a structured XML into the provided PDF. The invoice is returned immediately in the response; the conversion happens in the background shortly after. Requires `file_attachment_id` to reference a PDF file, all invoice lines to have a `label`, and `invoice_number` to not exceed 35 characters and only contain alphanumeric characters and `-+_/`. The attached PDF must **not** already embed a Factur-X (or ZUGFeRD) XML. If it does, the request can fail with an error asking you to use the customer e-invoice import endpoint (`/customer_invoices/e_invoices/imports`) instead. Use `convert_to_e_invoice` only for plain PDFs that Pennylane should convert. **Important:** The three mandatory French legal notices ("Late payment penalties", "Fixed recovery cost for late payment", and "Early payment discount") are required. Either provide them in `legal_notices`, or configure them in the footer of the default invoice template of your Pennylane account. Without either, the request returns a 422 error. **Factur-X amount compliance (BR-CO-14/BR-CO-15):** The Factur-X XML standard requires the sum of line-level `currency_tax` values to equal the invoice-level `currency_tax` exactly, and `currency_amount_before_tax + currency_tax` to equal `currency_amount` exactly. A difference of even a few cents will produce a non-compliant XML. Ensure your amounts are fully consistent before sending.
  - `discount` object: Invoice-level discount. Only allowed when `convert_to_e_invoice` is `true` — sending this field without conversion enabled is an error. All amounts must be provided after discount — no recomputation is performed. Use `relative` for a percentage discount and `absolute` for a fixed amount discount.
    - `type` 'absolute' | 'relative', required: Discount type. - absolute if it is an amount - relative if it is a percentage
    - `value` string, nullable, required: Discount value on the total amount before tax of the invoice
  - `legal_notices` object: The three mandatory French legal notices to embed in the e-invoice. Only allowed when `convert_to_e_invoice` is `true` — sending this field without conversion enabled is an error. When provided, it takes priority over the legal notices configured in the footer of your Pennylane account.
    - `late_payment_penalties` string, required: Text of the "Late payment penalties" legal notice.
    - `fixed_recovery_cost` string, required: Text of the "Fixed recovery cost for late payment" legal notice.
    - `discount_terms` string, required: Text of the "Early payment discount" legal notice.
  - `credited_invoice_id` integer: ID of an existing customer invoice in Pennylane that this credit note credits. The imported document must have negative amounts (a credit note). The referenced invoice must exist in the same company, belong to the same customer, be finalized (not a draft), not itself be a credit note, and have enough remaining amount to absorb the credit note.
  - `external_reference` string: A unique external reference you can provide to track this customer invoice. If not provided, Pennylane will generate an identifier for you.
  - `purchase_order_reference` string, nullable: Buyer's purchase order reference (e-invoice field BT-13). Maximum 50 characters.
  - `contract_reference` string, nullable: Contract reference (e-invoice field BT-12). Maximum 50 characters.
  - `electronic_billing_address` string, nullable: The electronic billing address of the customer used for the e-invoicing routing of this invoice. Use a value returned by the GET /api/external/v2/customers/{id}/electronic_billing_addresses endpoint. Only allowed when `convert_to_e_invoice` is `true`. When it is not sent, null, or an empty string, the electronic billing address of the customer is used.

## Response `201`

The imported customer invoice

- object
  - `id` integer, required: Invoice identifier
  - `label` string, nullable, required
  - `invoice_number` string, required
  - `currency` 'EUR' | 'USD' | 'GBP' | 'AED' | 'AFN' | 'ALL' | 'AMD' | 'ANG' | 'AOA' | 'ARS' | 'AUD' | 'AWG' | 'AZN' | 'BAM' | 'BBD' | 'BDT' | 'BGN' | 'BHD' | 'BIF' | 'BMD' | 'BND' | 'BOB' | 'BRL' | 'BSD' | 'BTN' | 'BWP' | 'BYN' | 'BYR' | 'BZD' | 'CAD' | 'CDF' | 'CHE' | 'CHF' | 'CLF' | 'CLP' | 'CNY' | 'COP' | 'CRC' | 'CUC' | 'CUP' | 'CVE' | 'CZK' | 'DJF' | 'DKK' | 'DOP' | 'DZD' | 'EGP' | 'ERN' | 'ETB' | 'FJD' | 'FKP' | 'GEL' | 'GGP' | 'GHS' | 'GIP' | 'GMD' | 'GNF' | 'GTQ' | 'GYD' | 'HKD' | 'HNL' | 'HRK' | 'HTG' | 'HUF' | 'IDR' | 'ILS' | 'IMP' | 'INR' | 'IQD' | 'IRR' | 'ISK' | 'JEP' | 'JMD' | 'JOD' | 'JPY' | 'KES' | 'KGS' | 'KHR' | 'KMF' | 'KPW' | 'KRW' | 'KWD' | 'KYD' | 'KZT' | 'LAK' | 'LBP' | 'LKR' | 'LRD' | 'LSL' | 'LTL' | 'LVL' | 'LYD' | 'MAD' | 'MDL' | 'MGA' | 'MKD' | 'MMK' | 'MNT' | 'MOP' | 'MRO' | 'MRU' | 'MUR' | 'MVR' | 'MWK' | 'MXN' | 'MYR' | 'MZN' | 'NAD' | 'NGN' | 'NIO' | 'NOK' | 'NPR' | 'NZD' | 'OMR' | 'PAB' | 'PEN' | 'PGK' | 'PHP' | 'PKR' | 'PLN' | 'PYG' | 'QAR' | 'RON' | 'RSD' | 'RUB' | 'RWF' | 'SAR' | 'SBD' | 'SCR' | 'SDG' | 'SEK' | 'SGD' | 'SHP' | 'SLL' | 'SLE' | 'SOS' | 'SRD' | 'STD' | 'SVC' | 'SYP' | 'SZL' | 'THB' | 'TJS' | 'TMT' | 'TND' | 'TOP' | 'TRY' | 'TTD' | 'TWD' | 'TZS' | 'UAH' | 'UGX' | 'UYU' | 'UZS' | 'VEF' | 'VES' | 'VND' | 'VUV' | 'WST' | 'XAF' | 'XCD' | 'XDR' | 'XOF' | 'XPF' | 'YER' | 'ZAR' | 'ZMK' | 'ZMW' | 'ZWL', required
  - `amount` string, required: Invoice amount (total value of the invoice in euros. If the currency is euro, `currency_amount` and `amount` are identical)
  - `currency_amount` string, required: Invoice currency amount (total value of the invoice in the currency of the invoice)
  - `currency_amount_before_tax` string, required: Invoice currency amount before tax (total value before tax of the invoice in the currency of the invoice)
  - `exchange_rate` string, required: Invoice exchange rate (used to convert the invoice to euros. If the invoice currency is euro it will be 1.0)
  - `date` string, date, nullable, required: Invoice issue date (ISO 8601)
  - `deadline` string, date, nullable, required: Invoice payment deadline (ISO 8601)
  - `performance_date` string, date, nullable, required: End date of the performance period of the first invoice line that has one (ISO 8601). Used for German VAT accounting (Leistungsdatum). Null if the company does not use German accounting, or if no invoice line has a performance period.
  - `currency_tax` string, required: Invoice taxable amount (in invoice currency)
  - `tax` string, required: Invoice taxable amount (in euros). If the currency is euro, `currency_tax` and `tax` are identical.
  - `language` 'fr_FR' | 'en_GB' | 'de_DE' | 'es_ES', required: The local default is based on the thirdparty (customer / supplier ) billing_language . In case the customer is not present, we will default to the company locale.
  - `paid` boolean, required: Invoice paid status (set to True if the invoice is paid)
  - `status` 'archived' | 'incomplete' | 'cancelled' | 'paid' | 'partially_paid' | 'partially_cancelled' | 'upcoming' | 'late' | 'draft' | 'credit_note' | 'proforma' | 'shipping_order' | 'purchasing_order' | 'estimate_pending' | 'estimate_accepted' | 'estimate_invoiced' | 'estimate_denied', required
  - `discount` object, required
    - `type` 'absolute' | 'relative', required: Discount type. - absolute if it is an amount - relative if it is a percentage
    - `value` string, required: Discount value on the total amount before tax of the line
  - `ledger_entry` object, required
    - `id` integer, required: Ledger entry identifier
  - `public_file_url` string, nullable, required: Public URL of the invoice file. The URL will expire after 30 minutes. May be null if the PDF has not been generated yet (for example right after creation or finalization); fetch the invoice again to get the URL once it is available.
  - `filename` string, nullable, required: Name of the file attached to the invoice. May be null immediately after creation if the PDF has not been generated yet; fetch the invoice again to get the filename once it is available.
  - `remaining_amount_with_tax` string, nullable, required: The remaining amount with VAT to pay for the invoice to be considered paid
  - `remaining_amount_without_tax` string, nullable, required: The remaining amount without VAT to pay for the invoice to be considered paid
  - `draft` boolean, required: Indicates if the invoice is in draft (has not been finalized)
  - `special_mention` string, nullable, required: Additional details
  - `sale_type` union, required: Type of sale printed on the invoice (Type de vente). `goods` is a supply of goods, `services` is a supply of services, and `goods_and_services` is both. `null` means the type has not been chosen. This is not invoice line `substance`.
    - 'goods' | 'services' | 'goods_and_services': Type of sale printed on a customer invoice. This is not invoice line substance.
    - unknown
  - `customer` object, nullable, required
    - `id` integer, required
    - `url` string, required: URL to get the customer.
  - `payment_method_ledger_account` object, nullable, required: Ledger account used for reconciliation by payment method. When present, the receivable was transferred to this account.
    - `id` integer, required
    - `url` string, required: URL to get the ledger account.
  - `invoice_line_sections` object, required
    - `url` string, required: URL to get the invoice line sections of the invoice.
  - `invoice_lines` object, required
    - `url` string, required: URL to get the invoice lines of the invoice.
  - `custom_header_fields` object, required
    - `url` string, required: URL to get the custom header fields of the invoice.
  - `categories` object, required
    - `url` string, required: URL to get the categories of the invoice.
  - `pdf_invoice_free_text` string, required
  - `pdf_invoice_subject` string, required
  - `pdf_description` string, nullable, required
  - `billing_subscription` object, nullable, required
    - `id` integer, required
  - `credited_invoice` object, nullable, required: The credited invoice if the invoice is a credit note.
    - `id` integer, required
    - `url` string, required: URL to get the credited invoice.
  - `customer_invoice_template` object, nullable, required
    - `id` integer, required
  - `transaction_reference` object, nullable, required: This reconciles the invoice with a transaction. See documentation about [automatic payment matching](https://pennylane.readme.io/v2.0/docs/automating-payment-matching).
    - `banking_provider` string, required: The banking provider for the transaction
    - `provider_field_name` string, required: Name of the field that you want to match
    - `provider_field_value` string, required: Value that you want to match
  - `payments` object, required
    - `url` string, required: URL to get the payments of the invoice.
  - `matched_transactions` object, required
    - `url` string, required: URL to get the transactions of the invoice.
  - `appendices` object, required
    - `url` string, required: URL to get the appendices of the invoice.
  - `installments` object, nullable, required: > ⚠️ **Warning**: This feature is in alpha > Until further rollout, this field will be `null` for all invoices. > If you plan to rely on it, please get in touch with us first.
    - `url` string, required: URL to get the installments of the invoice.
  - `quote` object, nullable, required: The quote at the origin of the invoice
    - `id` integer, required
  - `external_reference` string, required: The unique external reference that was assigned during creation either by you or Pennylane. (Same attribute as `external_id` in the API v1)
  - `purchase_order_reference` string, nullable, required: Buyer's purchase order reference (e-invoice field BT-13). Maximum 50 characters.
  - `contract_reference` string, nullable, required: Contract reference (e-invoice field BT-12). Maximum 50 characters.
  - `sales_order_reference` string, nullable, required: Seller's sales order reference (e-invoice field BT-14). Maximum 50 characters.
  - `e_invoicing` object, nullable, required: E-invoicing lifecycle information managed by the PA. Contains the current status and associated reason when applicable. This field is only present for invoices sent through e-invoicing.
    - `status` 'accepted' | 'approved' | 'collected' | 'in_dispute' | 'partially_collected' | 'refused' | 'rejected' | 'sent' | 'submitted', required
    - `reason` string, nullable, required
    - `flow` object, nullable, required: The AFNOR flow associated with this e-invoice.
      - `id` string, uuid, required
    - `lifecycle_events` object[], nullable, required: > ⚠️ **Warning**: This feature is in beta. > Until further rollout, this field will be `null` for all invoices. > If you plan to rely on it, please get in touch with us first. Chronologically ordered e-invoicing lifecycle events received from the PA. Some events are optional and only present when the receiving platform reports them.
      - `type` 'accepted' | 'available_to_buyer' | 'emitted_by_seller_platform' | 'in_dispute' | 'partially_collected' | 'received_by_buyer_platform' | 'refused' | 'rejected' | 'sent' | 'submitted', required
      - `timestamp` string, date-time, required
  - `factur_x` boolean, required: Whether the attached invoice file is a Factur-X document (a PDF/A-3 with an embedded structured XML).
  - `schematron_validation_status` 'pending' | 'valid' | 'invalid', nullable, required: Result of Schematron structural validation for Factur-X invoices. Only relevant when `factur_x` is true, null otherwise.
  - `archived_at` string, date-time, nullable, required: The time the invoice has been archived
  - `created_at` string, date-time, required: The time the invoice has been created
  - `updated_at` string, date-time, required: The last time the invoice has been updated

## Other responses

- `400`: Bad request
- `401`: Access token is missing or invalid
- `403`: Access to this resource forbidden
- `404`: The resource was not found
- `409`: Conflict with the current state of the target resource, such as when trying to create a resource that already exists.
- `422`: Unprocessable content
- `503`: The service is temporarily unavailable

## Changes

- **2026-11-03** `871f863307e5`: 2 warning, 28 info
  - added the new `VES` enum value to the `currency` response property for the response status `201`
  - added the new `es_ES` enum value to the `language` response property for the response status `201`
  - added the new optional `header` request parameter `X-Company-Id`
  - added the new optional request property `contract_reference`
  - …26 more

[Operation history](https://skmtc.dev/pennylane/apis/company-v2/changes/api/external/v2/customer_invoices/import/post.md)

---

[API](https://skmtc.dev/pennylane/apis/company-v2.md) - [All operations](https://skmtc.dev/pennylane/apis/company-v2/llms.txt) - [OpenAPI document](https://skmtc.dev/pennylane/apis/company-v2/revisions/871f863307e5?raw)
