This page documents how to use the endpoint for optician providers.

The API is essentially the same, only that a different endpoint must be used and the structure of the treatments array in the invoice object is different.


{info} Requires authentication

The optician invoice endpoint /invoice_opticians must be used. It supports the same sub-endpoints as /invoices:

  • GET /invoice_opticians/{uuid}
  • POST /invoice_opticians
  • POST /invoice_opticians/validate
  • POST /invoice_opticians/check-permission

These work the same as for normal invoices; Refer to Invoices for details.

Authentication is done through the common /auth endpoint.

The optician invoice object

  "treatments": [
      (...) See below
  "cpr": "string|required",
  "provider_id": "string|required",
  "payment_date": "string|date(YYYY-MM-DD)|required",
  "invoice_number": "integer|required",
  "fi_code": "string|optional",
  "override_invoice": "boolean|optional"


"treatments": [
    "is_subscription": "required|bool",
    "start_date": "required_if:is_subscription,true|date_format:Y-m-d",
    "end_date": "required_if:is_subscription,true|date_format:Y-m-d",
    "user_expense": "required|integer|between:0,2147483647",
    "product": "required|string",
    "product_type": "required|integer",

    "sphere_component_right": "numeric|between:-100,100|dioptre",
    "cylinder_component_right": "numeric|between:-100,100|dioptre",
    "axis_right": "required|integer|between:0,180",
    "addition_component_right": "numeric|between:-100,100|dioptre",
    "prism_right": "required|integer|between:0,360",
    "basis_right": "required|integer|between:0,9999",
    "radius1_right": "numeric|between:-100,100|dioptre",
    "radius2_right": "numeric|between:-100,100|dioptre",

    "sphere_component_left": "numeric|between:-100,100|dioptre",
    "cylinder_component_left": "numeric|between:-100,100|dioptre",
    "axis_left": "required|integer|between:0,180",
    "addition_component_left": "numeric|between:-100,100|dioptre",
    "prism_left": "required|integer|between:0,360",
    "basis_left": "required|integer|between:0,9999",
    "radius1_left": "numeric|between:-100,100|dioptre",
    "radius2_left": "numeric|between:-100,100|dioptre",

    "color_percentage": "required|integer|between:0,100",
    "eye_examination_date": "date_format:Y-m-d",
    "correction_code_optician": "required|integer",
    "service_code": "required|integer",
    "number_of_lenses": "required|integer|between:0,65535"


treatments array can be left out entirely, just like for normal invoices, if it is not needed.

is_subscription must be true/false. If true, the line is a subscription, otherwise it is a purchase.
If the treatment line is a purchase, the start_date and end_date is not required. If they are provided regardless, they will be silently ignored.

user_expense The amount of user expense in øre.

product must be one of the following values (single-character string):

  • B = Glasses ("Briller")
  • L = Contact Lenses ("Kontaktlinser)

product_type must be one of the following values: Glasses:

  • 01 = Far (Single vision "Enkeltstyrke")
  • 02 = Near (Single vision "Enkeltstyrke")
  • 03 = Bifocal (Multifocal "Flerstyrke")
  • 04 = Progressive (Multifocal "Flerstyrke")
  • 05 = Trifocal (Multifocal "Flerstyrke")
  • 06 = Low vision (No "d" coverage)
  • 07 = Lenticular (No "d" coverage)
  • 08 = Special add. (No "d" coverage)
  • 09 = Bifocal (Multifocal w/o addition "Flerstyrke uden addition") Lenses:
  • 31 = One-time-use lenses ("Engangslinser", 30 x 2 / month)
  • 32 = 2-week lenses ("14 dages linser", 2 x 2 / month)
  • 33 = Monthly lenses ("Månedslinser", 1 x 2 / month)
  • 34 = Long-term lenses ("Langtidslenser", lasts multiple months)

Each of the following fields are optional, but if present must be a Quarter Dioptre:

  • sphere_component_right ("Sfærisk styrke, højre")
  • cylinder_component_right ("Cylinder, højre")
  • addition_component_right ("Addition, højre")
  • radius1_right ("Radie1, højre")
  • radius2_right ("Radie2, højre")
  • sphere_component_left ("Sfærisk styrke, venstre")
  • cylinder_component_left ("Cylinder, venstre")
  • addition_component_left ("Addition, venstre")
  • radius1_left ("Radie1, venstre")
  • radius2_left ("Radie2, venstre")

axis_right must be an integer between (both inclusive) 0 and 180 prism_right must be an integer between (both inclusive) 0 and 360 basis_right must be an integer between (both inclusive) 0 and 9999

axis_left must be an integer between (both inclusive) 0 and 180 prism_left must be an integer between (both inclusive) 0 and 360 basis_left must be an integer between (both inclusive) 0 and 9999

color_percentage must be an integer between (both inclusive) 0 and 100

correction_code_optician must be one of the following values:

  • 0 = Positive transaction (Invoice)
  • 1 = Negative Transaction (credit note)
  • 2 = Paid by insurance company
  • 3 = Paid by municipality
  • 8 = Product returned in exchange for a new one

service_code must be one of the following values:

  • 0 = Customer was served in a store and had an eye examination performed at the store or by a doctor ahead of time
  • 1 = Internet- or mailorder. The customer had their eye examination performed independently, e.g. at a doctor

eye_examination_date must be a valid date "YYYY-MM-DD" date, e.g. 2018-05-22

  • If service_code is 1, this field is automatically internally set to 0.

number_of_lenses must be an integer between 0 and 65535

  • Represents number of purchased lenses.
  • For glasses, this is typically 2, but can have other values, e.g. 1 in case of repairs
  • For lenses, this is the bought amount, e.g. for a months supply, 30 days times 2 lenses = 60

The rest of the invoice uses the same fields as regular invoices, see the Invoice Object for details.


Some of the fields in the treatments array take in a 'Dioptre', specifically in quarters.

All the fields that take a dioptre are optional. If a value is provided, it must be a multiple of 0.25, i.e. a quarter.

The value for these fields should be provided as a decimal with 2 digits of precision, i.e. it should end in .00, .25, .50 or .75.

Examples of valid values: 0.00, 0, 1, 1.25, 3.5, -2.25 etc.

Examples of invalid values: 0.2, 0.99, -1.24 etc.

{info} Values beyond floating point precision will be rounded, e.g. "1.2499999999999" will be interpreted as 1.25, however, no other roundind takes place