Skip to main content

Import existing invoices from a CSV file

Bulk-import your existing invoices into Cybooks via a CSV template. Required fields, default tax rules, and the income chart of accounts.

Written by Christopher Dosin

You can move all your existing invoices into Cybooks in one go. Upload a CSV file and Cybooks creates the invoices, customers (if they don't exist yet), and the matching journal entries — exactly as if you had typed each invoice by hand.

Invoice import is a Premium feature. You can import up to 1,000 rows per file.

Before you start

Get a few things ready so the import runs cleanly:

  • The currency of every invoice must match your tenant's default currency. Foreign currency rows are rejected in this version.

  • The tax rule code on every line must be a sales tax rule (codes L, M, N, O, P, Q, R, S, OSS, or T).

  • The chart of account code on every line must be a postable income account (depth-2 account in the 4xxx range).

  • You can only import invoices with status draft or awaiting_payment. paid is not supported in this version — record the payment in the UI after import.

Step 1: Download the template

  1. Go to Imports → Invoices.

  2. Click Download CSV template.

  3. Open the file in Excel, Numbers, or Google Sheets.

Screenshot needed: The Imports → Invoices landing page with the "Download CSV template" button highlighted.

Step 2: Fill in the CSV

The template has columns for the invoice header, the customer, and one line per row. Multi-line invoices share the same invoice_number across rows — Cybooks groups them automatically.

Required columns

Every row must have these filled in:

Column

What to enter

invoice_number

Your existing invoice number, e.g. INV-1001. Cybooks preserves it and advances the sequence.

customer_name

Name of the customer. If no match is found, Cybooks creates the customer.

invoice_date

The invoice date. Accepted formats: YYYY-MM-DD, DD/MM/YYYY, DD.MM.YYYY.

currency

ISO currency code, e.g. EUR. Must match your tenant currency.

status

draft or awaiting_payment.

line_description

The description shown on the invoice line.

line_quantity

Quantity. Decimals supported (locale-aware).

line_unit_price

Unit price excluding VAT.

line_tax_rule_code

One of the sales tax rule codes — see the table below.

Optional invoice columns

Column

What to enter

due_date

The payment due date. Same date formats as invoice_date.

reference

Free-text reference (PO number, etc.).

line_discount

Per-line discount as a percentage (0–100).

line_account_code

Chart of account code — see the table below. Falls back to the import's default income account when blank.

oss_supply_type

OSS classification — see the OSS (One Stop Shop) imports section below for the full rules.

Customer columns

These columns are used to match an existing customer (by VAT ID, email, then name). If no match is found, Cybooks creates the customer using whatever fields you've filled in.

Column

What to enter

customer_type

person, individual, organisation, organization, business, or company. Leave blank to auto-detect: a row with a customer_vat_id is treated as a business, otherwise as a person.

customer_legal_name

Registered legal name (companies).

customer_account_number

Your internal account/customer number.

customer_first_name, customer_last_name

Used for individual customers and as the display name when no customer_name is supplied.

customer_email

Primary email address. Also used for matching existing customers (second priority after VAT ID).

customer_vat_id

VAT registration number, e.g. CY12345678. Top priority for matching existing customers.

customer_phone, customer_website, customer_note

Contact details and free-text notes saved on the customer record.

customer_business_registration_number

Company registration number (e.g. HE123456).

customer_bank_account_name, customer_iban, customer_swift_code

Bank details saved on the customer record.

customer_tic

Tax Identification Code (Cyprus).

customer_is_triangular

Whether the customer is part of a triangular EU transaction. Accepted values: yes/no, true/false, 1/0.

customer_contact_person_first_name, customer_contact_person_last_name, customer_contact_person_email

A contact person on the customer. If you fill in any of these, you must fill in all three.

customer_billing_street, customer_billing_street_2, customer_billing_city, customer_billing_state, customer_billing_postcode, customer_billing_country

Billing address. customer_billing_country accepts an ISO-2 code (CY), ISO-3 code (CYP), or full country name (Cyprus).

customer_shipping_street, customer_shipping_street_2, customer_shipping_city, customer_shipping_state, customer_shipping_postcode, customer_shipping_country

Shipping address. Same country format as billing. If left blank, the billing address is reused as the shipping address.

Important: If you list the same invoice_number across several rows, every row in the group must validate. If one row fails, the whole invoice is rejected — Cybooks never imports a partial invoice.

Sales tax rule codes

Use the code in the line_tax_rule_code column. Only sales codes are valid for invoices.

Code

Name

Rate

Use for

L

19% (VAT on Income)

19%

Standard-rated Cyprus sales

M

9% (VAT on Income)

9%

Reduced-rate Cyprus sales (hotels, catering, etc.)

N

5% (VAT on Income)

5%

Super-reduced Cyprus sales (food, books, etc.)

O

0% (VAT on Income)

0%

Zero-rated Cyprus sales

P

Exempt Sales

0%

VAT-exempt sales (financial services, education, etc.)

Q

EU Sales of Goods (Reverse Charge)

0%

Goods sold to a VAT-registered EU business

R

EU Sales of Services (Reverse Charge)

0%

Services sold to a VAT-registered EU business

S

Export Non EU

0%

Sales to customers outside the EU

OSS

OSS (EU B2C)

destination rate

Distance sales or digital services to EU consumers — requires oss_supply_type (see OSS (One Stop Shop) imports below)

T

No VAT

0%

Use only when your company is not VAT-registered

Income chart of accounts

Use the code in the line_account_code column. Only postable income accounts (4xxx range) are valid for invoice lines.

Code

Account name

4000

Discounts/Refunds Given

4010

Non-Profit Income

4020

Other Primary Income

4030

Revenue - General

4040

Revenue - General

4050

Sales - retail

4060

Sales - retail

4070

Sales - wholesale

4080

Sales - wholesale

4090

Sales of Product Income

4100

Billable Expense Income

4110

Sales (default postable account)

4120

Sales of Product Income

4130

Uncategorised Income

4140

Service/Fee Income

4150

Unapplied Cash Payment Income

4160

Unapplied Cash Payment Income

4170

Dividend income

4180

Dividend income

4190

Interest earned

4200

Interest income

4210

Gain/Loss on Disposal of Assets

4220

Gain/Loss on Disposal of Assets

4230

Other Investment Income

4240

Other Miscellaneous Income

4250

Other operating income

4260

Other operating income (expenses)

4270

Tax-Exempt Interest

4280

Unrealised loss on securities, net of tax

4290

Unrealised loss on securities, net of tax

If you don't know which account to use, leave line_account_code blank and pick a default account in step 3 of the wizard. 4110 — Sales is a safe choice for most businesses.

OSS (One Stop Shop) imports

Use OSS to flag invoices issued to private consumers in another EU member state. Cybooks looks up the destination country's standard VAT rate, applies it to every line, and posts the VAT to the OSS VAT control account so it lands on your OSS return rather than your domestic VAT return.

For background on how OSS works in Cybooks, see OSS Returns (One Stop Shop).

Before importing OSS rows

  • Your company must be EU VAT registered — turn on EU destination country tax in Settings → Organisation Profile → Private VAT.

  • Your company must be in an EU member state.

  • The customer must be a private consumer — set customer_type to person (or individual), and leave customer_vat_id blank. For VAT-registered EU businesses, use reverse charge codes Q or R instead.

  • The customer must have an address with a country in another EU member state — see the address rules below.

How to flag a row as OSS

Two columns work together on every OSS line:

Column

Value

What it does

line_tax_rule_code

OSS

Marks the line as an OSS supply. Cybooks ignores the rule's nominal rate and uses the destination country's standard rate instead.

oss_supply_type

distance_sales

Physical goods shipped cross-border. Destination country is read from the customer's shipping address.

electronic_services

Digital services (software, e-books, SaaS). Destination country is read from the customer's billing address.

services

Alias for electronic_services — treated identically.

One supply type per invoice. All rows that share an invoice_number must use the same oss_supply_type (or all leave it blank). Mixed values reject the whole invoice.

OSS validation rules

A row with oss_supply_type filled in is rejected if any of these are true:

  • line_tax_rule_code is not OSS.

  • oss_supply_type is not one of distance_sales, services, or electronic_services.

  • Your company is not EU VAT registered, or your company is not in an EU country.

  • The customer is a business with a VAT ID — OSS does not apply to B2B sales.

  • The customer's billing address (for services) or shipping address (for distance sales) has no country.

  • The customer is in the same country as your company (domestic sale).

  • The customer is outside the EU.

  • No standard VAT rate is published for the destination country on the invoice date.

If line_tax_rule_code is OSS but oss_supply_type is left blank, the row imports without OSS classification — it lands on the regular VAT return instead of the OSS return, and the wizard shows an amber warning so you can spot it.

What the preview shows

When a row is correctly flagged, the preview grid shows an OSS badge with the supply type — either OSS: distance sales or OSS: services — so you can verify which rows will land on the OSS return before you run the import.

Step 3: Upload and preview

  1. Go to Imports → Invoices and click Start import.

  2. Drop your CSV onto the upload zone.

  3. Pick a default income account for any rows that leave line_account_code blank.

  4. Cybooks shows a row-by-row preview with three colours:

    • Green — ready to import.

    • Amber — imports, but with a warning (e.g. duplicate invoice number — that row is skipped).

    • Red — has errors. Fix them in the CSV and re-upload, or the whole invoice group will be rejected.

Screenshot needed: Step 2 of the wizard showing the colour-coded preview rows with green/amber/red badges.

Step 4: Run the import

  1. When you're happy with the preview, click Run import.

  2. The import runs in the background. You can leave the page — Cybooks will email you when it's done.

  3. Open Imports → Invoices → History to see the result and download an error CSV for any rejected invoice groups.

Imported invoices behave exactly like hand-keyed invoices: journal entries post immediately, the audit trail is recorded, and document templates apply on download.

Common errors and fixes

Error

What to do

"line_tax_rule_code must be a sales tax rule"

You used a purchase code (A–K). Switch to a sales code (L, M, N, O, P, Q, R, S, OSS, T).

"Chart of account code must be a postable income account"

You picked a non-income account or a parent/header account. Use a 4xxx postable code from the table above.

"Currency must match the tenant default"

Foreign currency invoices are not supported in this version. Convert to your tenant currency before import.

"Paid status not supported in v1"

Set status to awaiting_payment and record the payment in the UI after import.

"Invoice number already exists — skipped"

An invoice with that number is already in Cybooks. The row is safely skipped — no duplicate is created.

"customer_type must be one of [person, organisation]"

Use one of the accepted values: person, individual, organisation, organization, business, or company.

"customer_is_triangular must be yes/no, true/false, or 1/0"

Replace any other value with one of the accepted boolean tokens.

"customer_billing_country / customer_shipping_country must be a valid country ISO code or country name"

Use ISO-2 (CY), ISO-3 (CYP), or the full country name (Cyprus).

"customer_contact_person_* is required when importing a contact person"

Contact person is all-or-nothing. Fill in first name, last name, and email — or leave all three blank.

"oss_supply_type must be one of [distance_sales, services, electronic_services]"

Replace the value with one of the three accepted strings.

"oss_supply_type requires line_tax_rule_code to be OSS"

Either change the line code to OSS, or clear oss_supply_type.

"OSS is only available for EU-registered companies" / "OSS is only available for companies in EU member states"

Enable EU destination country tax in Settings → Organisation Profile, and check that your company country is set to an EU member state.

"OSS cannot be applied to business customers with a VAT ID. Use reverse charge instead."

Switch the line to code Q (goods) or R (services), or remove the customer's VAT ID and set customer_type to person.

"OSS requires the customer to have a billing/shipping address with a country"

Fill in the relevant address country for the customer — billing for services, shipping for distance sales.

"OSS does not apply to domestic sales (same country as company)"

The customer is in your own country. Use a domestic code like L, M, or N instead.

"OSS only applies to customers in EU member states"

Customer is outside the EU. Use code S (Export Non-EU) instead.

"oss_supply_type must be the same on every line for invoice X"

All rows that share an invoice number must agree on the supply type. Pick one and apply it to every line of that invoice.

"No standard OSS VAT rate found for {country} on {date}"

The destination VAT rate isn't published for that date. Check the invoice date is correct and that the destination country is up to date in our EU VAT rate table.

What happens to customers

For each invoice, Cybooks looks up the customer in this order:

  1. VAT ID match (if customer_vat_id is filled in).

  2. Email match (if customer_email is filled in).

  3. Name match (case-insensitive).

If no match is found, Cybooks creates the customer using the details in the CSV — name, type, contact person, addresses, IBAN, VAT ID, and so on. If you re-import the same file, existing customers are reused (no duplicates) and existing invoice numbers are skipped.

Did this answer your question?