diff --git a/linode_api4/objects/__init__.py b/linode_api4/objects/__init__.py
index 6b408ad..63f3c9d 100644
--- a/linode_api4/objects/__init__.py
+++ b/linode_api4/objects/__init__.py
@@ -1,4 +1,4 @@
-from .base import Base, Property, MappedObject
+from .base import Base, Property, MappedObject, DATE_FORMAT
 from .dbase import DerivedBase
 from .filtering import and_, or_
 from .region import Region
diff --git a/linode_api4/objects/account.py b/linode_api4/objects/account.py
index cb5d820..eb8c910 100644
--- a/linode_api4/objects/account.py
+++ b/linode_api4/objects/account.py
@@ -1,10 +1,11 @@
 from __future__ import absolute_import
 
+from datetime import datetime
 import requests
 
 from linode_api4.errors import ApiError, UnexpectedResponseError
 from linode_api4.objects import (Base, DerivedBase, Domain, Image, Instance,
-                                 Property, StackScript, Volume)
+                                 Property, StackScript, Volume, DATE_FORMAT)
 from linode_api4.objects.longview import LongviewClient, LongviewSubscription
 from linode_api4.objects.nodebalancer import NodeBalancer
 from linode_api4.objects.support import SupportTicket
@@ -104,21 +105,11 @@ class Event(Base):
         self._client.post('{}/read'.format(Event.api_endpoint), model=self)
 
 
-class Invoice(Base):
-    api_endpoint = "/account/invoices/{id}"
-
-    properties = {
-        "id": Property(identifier=True),
-        "label": Property(),
-        "date": Property(is_datetime=True),
-        "total": Property(),
-    }
-
-
 class InvoiceItem(DerivedBase):
     api_endpoint = '/account/invoices/{invoice_id}/items'
     derived_url_path = 'items'
     parent_id_name='invoice_id'
+    id_attribute = 'label' # this has to be something
 
     # TODO - this object doesn't have its own ID .. this might need
     # special handling
@@ -128,11 +119,34 @@ class InvoiceItem(DerivedBase):
         'label': Property(),
         'amount': Property(),
         'quantity': Property(),
-        'from': Property(is_datetime=True),
+        #'from_date': Property(is_datetime=True), this is populated below from the "from" attribute
         'to': Property(is_datetime=True),
+        #'to_date': Property(is_datetime=True), this is populated below from the "to" attribute
         'type': Property(),
     }
 
+    def _populate(self, json):
+        """
+        Allows population of "from_date" from the returned "from" attribute which
+        is a reserved word in python.  Also populates "to_date" to be complete.
+        """
+        super(InvoiceItem, self)._populate(json)
+
+        self.from_date = datetime.strptime(json['from'], DATE_FORMAT)
+        self.to_date = datetime.strptime(json['to'], DATE_FORMAT)
+
+
+class Invoice(Base):
+    api_endpoint = "/account/invoices/{id}"
+
+    properties = {
+        "id": Property(identifier=True),
+        "label": Property(),
+        "date": Property(is_datetime=True),
+        "total": Property(),
+        "items": Property(derived_class=InvoiceItem),
+    }
+
 
 class OAuthClient(Base):
     api_endpoint = "/account/oauth-clients/{id}"
diff --git a/linode_api4/objects/base.py b/linode_api4/objects/base.py
index 9cc8a5f..e04e15b 100644
--- a/linode_api4/objects/base.py
+++ b/linode_api4/objects/base.py
@@ -5,6 +5,10 @@ from future.utils import with_metaclass
 
 from .filtering import FilterableMetaclass
 
+
+DATE_FORMAT = "%Y-%m-%dT%H:%M:%S"
+
+
 # The interval to reload volatile properties
 volatile_refresh_timeout = timedelta(seconds=15)
 
@@ -249,7 +253,7 @@ class Base(object, with_metaclass(FilterableMetaclass)):
                     self._set(key, mapping._list) # pylint: disable=no-member
                 elif type(self).properties[key].is_datetime:
                     try:
-                        t = time.strptime(json[key], "%Y-%m-%dT%H:%M:%S")
+                        t = time.strptime(json[key], DATE_FORMAT)
                         self._set(key, datetime.fromtimestamp(time.mktime(t)))
                     except:
                         #TODO - handle this better (or log it?)
diff --git a/test/objects/image_tests.py b/test/objects/image_test.py
similarity index 100%
rename from test/objects/image_tests.py
rename to test/objects/image_test.py
diff --git a/tox.ini b/tox.ini
index a71b956..05a9f19 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
 [tox]
-envlist = py27,py34,py35,py36
+envlist = py27,py34,py35,py36,py37
 skip_missing_interpreters = true
 
 [testenv]

How to access a list of Invoice Items?
I do not see a way to retrieve a list of invoice line items.
diff --git a/test/fixtures/account_invoices.json b/test/fixtures/account_invoices.json
new file mode 100644
index 0000000..980ecde
--- /dev/null
+++ b/test/fixtures/account_invoices.json
@@ -0,0 +1,13 @@
+{
+  "data": [
+    {
+      "id": 123456,
+      "date": "2015-01-01T05:01:02",
+      "label": "Invoice #123456",
+      "total": 9.51
+    }
+  ],
+  "page": 1,
+  "pages": 1,
+  "results": 1
+}
diff --git a/test/fixtures/account_invoices_123456_items.json b/test/fixtures/account_invoices_123456_items.json
new file mode 100644
index 0000000..289b131
--- /dev/null
+++ b/test/fixtures/account_invoices_123456_items.json
@@ -0,0 +1,16 @@
+{
+  "data": [
+    {
+      "from": "2014-12-19T00:27:02",
+      "label": "Linode 2048 - Example",
+      "type": "hourly",
+      "amount": 9.51,
+      "to": "2015-01-01T04:59:59",
+      "quantity": 317,
+      "unit_price": "0.03"
+    }
+  ],
+  "page": 1,
+  "pages": 1,
+  "results": 1
+}
diff --git a/test/linode_client_test.py b/test/linode_client_test.py
index 739c304..bf01c82 100644
--- a/test/linode_client_test.py
+++ b/test/linode_client_test.py
@@ -205,6 +205,20 @@ class AccountGroupTest(ClientBaseCase):
         self.assertEqual(type(s.longview_subscription), LongviewSubscription)
         self.assertEqual(s.longview_subscription.id, 'longview-100')
 
+    def test_get_invoices(self):
+        """
+        Tests that invoices can be retrieved
+        """
+        i = self.client.account.invoices()
+
+        self.assertEqual(len(i), 1)
+        invoice = i[0]
+
+        self.assertEqual(invoice.id, 123456)
+        self.assertEqual(invoice.date, datetime(2015, 1, 1, 5, 1, 2))
+        self.assertEqual(invoice.label, 'Invoice #123456')
+        self.assertEqual(invoice.total, 9.51)
+
 
 class LinodeGroupTest(ClientBaseCase):
     """
diff --git a/test/objects/account_test.py b/test/objects/account_test.py
new file mode 100644
index 0000000..f869eb7
--- /dev/null
+++ b/test/objects/account_test.py
@@ -0,0 +1,38 @@
+from datetime import datetime
+
+from test.base import ClientBaseCase
+
+from linode_api4.objects import Invoice
+
+
+class InvoiceTest(ClientBaseCase):
+    """
+    Tests methods of the Invoice
+    """
+    def test_get_invoice(self):
+        invoice = Invoice(self.client, 123456)
+        self.assertEqual(invoice._populated, False)
+
+        self.assertEqual(invoice.label, 'Invoice #123456')
+        self.assertEqual(invoice._populated, True)
+
+        self.assertEqual(invoice.date, datetime(2015, 1, 1, 5, 1, 2))
+        self.assertEqual(invoice.total, 9.51)
+
+    def test_get_invoice_items(self):
+        """
+        Tests that you can get items for an invoice
+        """
+        invoice = Invoice(self.client, 123456)
+        items = invoice.items
+
+        self.assertEqual(len(items), 1)
+        item = items[0]
+
+        self.assertEqual(item.label, "Linode 2048 - Example")
+        self.assertEqual(item.type, "hourly")
+        self.assertEqual(item.amount, 9.51)
+        self.assertEqual(item.quantity, 317)
+        self.assertEqual(item.unit_price, "0.03")
+        self.assertEqual(item.from_date, datetime(year=2014, month=12, day=19, hour=0, minute=27, second=2))
+        self.assertEqual(item.to_date, datetime(year=2015, month=1, day=1, hour=4, minute=59, second=59))

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest mock
3.6
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==22.2.0
certifi==2021.5.30
charset-normalizer==2.0.12
enum34==1.1.10
future==1.0.0
httplib2==0.22.0
idna==3.10
importlib-metadata==4.8.3
iniconfig==1.1.1
-e git+https://github.com/linode/linode_api4-python.git@ee2789013fbaa20498a812f5ec7ca5e1711d7332#egg=linode_api4
mock==5.2.0
packaging==21.3
pluggy==1.0.0
py==1.11.0
pyparsing==3.1.4
pytest==7.0.1
requests==2.27.1
tomli==1.2.3
typing_extensions==4.1.1
urllib3==1.26.20
zipp==3.6.0

name: linode_api4-python
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==22.2.0
      - charset-normalizer==2.0.12
      - enum34==1.1.10
      - future==1.0.0
      - httplib2==0.22.0
      - idna==3.10
      - importlib-metadata==4.8.3
      - iniconfig==1.1.1
      - mock==5.2.0
      - packaging==21.3
      - pluggy==1.0.0
      - py==1.11.0
      - pyparsing==3.1.4
      - pytest==7.0.1
      - requests==2.27.1
      - tomli==1.2.3
      - typing-extensions==4.1.1
      - urllib3==1.26.20
      - zipp==3.6.0
prefix: /opt/conda/envs/linode_api4-python

test/objects/account_test.py::InvoiceTest::test_get_invoice_items
test/linode_client_test.py::LinodeClientGeneralTest::test_get_account test/linode_client_test.py::LinodeClientGeneralTest::test_get_domains test/linode_client_test.py::LinodeClientGeneralTest::test_get_images test/linode_client_test.py::LinodeClientGeneralTest::test_get_no_empty_body test/linode_client_test.py::LinodeClientGeneralTest::test_get_regions test/linode_client_test.py::LinodeClientGeneralTest::test_get_tags test/linode_client_test.py::LinodeClientGeneralTest::test_get_volumes test/linode_client_test.py::LinodeClientGeneralTest::test_image_create test/linode_client_test.py::LinodeClientGeneralTest::test_tag_create test/linode_client_test.py::LinodeClientGeneralTest::test_tag_create_with_entities test/linode_client_test.py::LinodeClientGeneralTest::test_tag_create_with_ids test/linode_client_test.py::AccountGroupTest::test_get_invoices test/linode_client_test.py::AccountGroupTest::test_get_settings test/linode_client_test.py::LinodeGroupTest::test_instance_create test/linode_client_test.py::LinodeGroupTest::test_instance_create_with_image test/linode_client_test.py::LongviewGroupTest::test_client_create test/linode_client_test.py::LongviewGroupTest::test_client_create_with_label test/linode_client_test.py::LongviewGroupTest::test_get_clients test/linode_client_test.py::LongviewGroupTest::test_get_subscriptions test/linode_client_test.py::ProfileGroupTest::test_client_create test/linode_client_test.py::ProfileGroupTest::test_get_sshkeys test/linode_client_test.py::ProfileGroupTest::test_ssh_key_create test/objects/account_test.py::InvoiceTest::test_get_invoice
linode_api4/objects/__init__.py tox.ini linode_api4/objects/account.py linode_api4/objects/base.py test/objects/image_tests.py
test/objects/image_test.py linode_api4/objects/__init__.py tox.ini linode_api4/objects/account.py linode_api4/objects/base.py