diff --git a/setra_client/client.py b/setra_client/client.py
index 53595a207a817416bea5bbd2824089177216c3e1..43a5197f45dbe3d181c853c6f718b40f98d7e466 100644
--- a/setra_client/client.py
+++ b/setra_client/client.py
@@ -13,6 +13,10 @@ from setra_client.models import (
     InputBatch,
     OutputBatch,
     Parameter,
+    Order,
+    Detail,
+    AbwOrder,
+    AbwOrderErrors,
 )
 
 logger = logging.getLogger(__name__)
@@ -49,7 +53,17 @@ class SetraEndpoints:
                  batch_complete_url='api/batch_complete/',
                  batch_error_url="api/batch_error/",
                  parameters_url="api/parameters/",
+
+                 # Order urls (sotra):
+                 order_url="api/order/",
+                 order_complete_url="api/order_complete/",
+                 detail_url="api/detail/",
+                 details_in_order_url="api/details_in_order/",
+                 abw_order_complete_url="api/abw_order_complete/",
+                 post_add_abw_order_url="api/add_abw_order/",
+                 abw_order_errors_url="api/abw_order_errors/",
                  ):
+
         self.baseurl = url
         self.batch_url = batch_url
         self.transaction_url = transaction_url
@@ -59,6 +73,14 @@ class SetraEndpoints:
         self.batch_complete_url = batch_complete_url
         self.batch_error_url = batch_error_url
         self.parameters_url = parameters_url
+        # order urls:
+        self.order_url = order_url
+        self.order_complete_url = order_complete_url
+        self.detail_url = detail_url
+        self.details_in_order_url = details_in_order_url
+        self.abw_order_complete_url = abw_order_complete_url
+        self.post_add_abw_order_url = post_add_abw_order_url
+        self.abw_order_errors_url = abw_order_errors_url
 
     """ Get endpoints relative to the SETRA API URL. """
 
@@ -123,6 +145,57 @@ class SetraEndpoints:
         """Get url for parameters endpoint"""
         return urllib.parse.urljoin(self.baseurl, self.parameters_url)
 
+    def abw_order_complete(self, abw_order_id: str = None):
+        """
+        URL for getting an abw order including a list of its orders, and each order contains a list of its detail objects
+        """
+        return urllib.parse.urljoin(self.baseurl,
+                                    '/'.join((self.abw_order_complete_url, abw_order_id)))
+
+    def add_abw_order(self):
+        """
+        URL for posting a new complete abw order containing order and detail objects
+        """
+        return urllib.parse.urljoin(self.baseurl, self.post_add_abw_order_url)
+
+    def order(self, order_id: str = None):
+        """
+        URL for order endpoint
+        """
+        if order_id is None:
+            return urllib.parse.urljoin(self.baseurl, self.order_url)
+        else:
+            return urllib.parse.urljoin(self.baseurl,
+                                        '/'.join((self.order_url, order_id)))
+
+    def order_complete(self, order_id: str):
+        """
+        URL for getting an order object including a list of its detail objects
+        """
+        return urllib.parse.urljoin(self.baseurl,
+                                    '/'.join((self.order_complete_url, order_id)))
+
+    def detail(self, detail_id: str):
+        """
+        URL for detail endpoint
+        """
+        return urllib.parse.urljoin(self.baseurl,
+                                        '/'.join((self.detail_url, detail_id)))
+
+    def details_in_order(self, order_id: str):
+        """
+        URL for getting a list of detail objects in an order
+        """
+        return urllib.parse.urljoin(self.baseurl,
+                                    '/'.join((self.details_in_order_url, order_id)))
+
+    def abw_order_errors(self, abw_order_id: str):
+        """
+        URL for getting an object containing lists of all errors for AbwOrder, Orders and Details
+        """
+        return urllib.parse.urljoin(self.baseurl,
+                                    '/'.join((self.abw_order_errors_url, abw_order_id)))
+
 
 class SetraClient(object):
     default_headers = {
@@ -344,6 +417,123 @@ class SetraClient(object):
         response = self.get(url, params=queryparams)
         return self.object_or_data(Parameter, response.json())
 
+    # Order ("Sotra") functions:
+
+    def get_order(self, order_id: str) -> Union[Order, dict]:
+        """
+        GETs one order object
+        """
+        url = self.urls.order(str(order_id))
+        response = self.get(url)
+        data = response.json()
+        response.raise_for_status()
+        if self.return_objects:
+            return Order(**data)
+        else:
+            return data
+
+    def get_detail(self, detail_id: str) -> Union[Detail, dict]:
+        """
+        GETs one detail object
+        """
+        url = self.urls.detail(str(detail_id))
+        response = self.get(url)
+        data = response.json()
+        response.raise_for_status()
+        if self.return_objects:
+            return Detail(**data)
+        else:
+            return data
+
+    def get_order_list(self):
+        """
+        GETs a list of all orders, without detail objects
+        """
+        url = self.urls.order()
+        response = self.get(url)
+        data = response.json()
+        response.raise_for_status()
+        return self.object_or_data(Order, response.json())
+
+    def get_details_in_order(self, order_id: str) -> Union[List[Detail], dict]:
+        """
+        GETs list of all detail objects belonging to an order
+        """
+        url = self.urls.details_in_order(str(order_id))
+        response = self.get(url)
+        data = response.json()
+        response.raise_for_status()
+        if self.return_objects:
+            if isinstance(data, list):
+                return [Detail(**item) for item in data]
+            elif isinstance(data, dict):
+                return [Detail(**data)]
+        else:
+            return data
+
+    def get_order_complete(self, order_id: str) -> Union[Order, dict]:
+        """
+        GETs one order, with all detail objects
+        """
+        url = self.urls.order_complete(str(order_id))
+        response = self.get(url)
+        data = response.json()
+        response.raise_for_status()
+        if self.return_objects:
+            return Order(**data)
+        else:
+            return data
+
+    def get_abw_order_complete(self, abw_order_id: str) -> Union[AbwOrder, dict]:
+        """
+        GETs one abworder, with all order and detail objects
+        """
+        url = self.urls.abw_order_complete(str(abw_order_id))
+        response = self.get(url)
+        data = response.json()
+        response.raise_for_status()
+        if self.return_objects:
+            return AbwOrder(**data)
+        else:
+            return data
+
+    def post_add_abw_order(self, abworder: AbwOrder):
+        """
+        POST one AbwOrder, with its orders and its details.
+
+        Note: There are some fields that cannot be sent in when creating a new AbwOrder:
+        AbwOrder.id
+        AbwOrder.progress
+        AbwOrder.abworder_validated_ok_date
+        Order.id
+        Order.abw_order_id
+        Detail.id
+        Detail.order_id
+
+        Returns tuple, with (data, status)
+        """
+        url = self.urls.add_abw_order()
+        headers = {'Content-Type': 'application/json'}
+        response = self.post(url,
+                             data=abworder.json(),
+                             headers=headers,
+                             return_response=True)
+        if response.status_code == 202:
+            return response.content, 'Accepted'
+        elif response.status_code == 409:
+            return response.content, "Conflict"
+        else:
+            response.raise_for_status()
+            return response
+
+    def get_abw_order_errors(self, abw_order_id: str):
+        """
+        Gets an object containing three lists of all errors, for each of AbwOrder, Orders and Details
+        """
+        url = self.urls.abw_order_errors(abw_order_id)
+        response = self.get(url)
+        return self.object_or_data(AbwOrderErrors, response.json())
+
 
 def get_client(config_dict):
     """
diff --git a/setra_client/models.py b/setra_client/models.py
index 19474776a31c07b777ce77f523f88c43d2838069..f1d62c19d80ad38ec611231c0e8f85f85fad8ae9 100644
--- a/setra_client/models.py
+++ b/setra_client/models.py
@@ -217,3 +217,91 @@ class Parameter(BaseModel):
     valid_from: Optional[datetime.date]
     valid_to: Optional[datetime.date]
     description: Optional[str]
+
+
+class Detail(BaseModel):
+    id: Optional[int]  # Cannot be sent in
+    order_id: Optional[int]  # Cannot be sent in
+    account: str
+    buyer_product_descr: Optional[str]
+    buyer_product_code: str
+    line_total: Optional[float]
+    koststed: str
+    prosjekt: Optional[str]
+    t1: Optional[str]
+    r00: Optional[str]
+    delprosjekt: str
+    anlegg: Optional[str]
+    aktivitet: Optional[str]
+    line_no: int
+    product_specification: int
+    price: Optional[float]
+    quantity: Optional[float]
+
+
+class Order(BaseModel):
+    id: Optional[int]  # Cannot be sent in
+    abw_order_id: Optional[int]  # Cannot be sent in
+    accountable: Optional[str]
+    buyer_no: str
+    currency: str
+    ext_order_ref: Optional[str]
+    order_date: Optional[datetime.date]
+    order_type: str
+    sales_man: str
+    trans_type: str
+    ext_order_id: Optional[str]
+    order_no: Optional[int]
+    deliv_date: Optional[datetime.date]
+    text3: Optional[str]
+    text4: Optional[str]
+    header_text: Optional[str]
+    footer_text: Optional[str]
+    details: Optional[List[Detail]]
+
+
+class AbwOrder(BaseModel):
+    """
+    Model representing an AbwOrder, with a list of orders (and each order has a list of details.)
+    """
+    id: Optional[int]  # Cannot be sent in
+    progress: Optional[str]  # Cannot be sent in
+    abworder_validated_ok_date: Optional[datetime.date]  # Cannot be sent in
+    responsible: str
+    interface: str
+    client: str
+    abworderid: str
+    orders: List[Order]
+
+
+class ErrorDetail(BaseModel):
+    id: int
+    detail_id: int
+    validation_date: datetime.datetime
+    validation_error: str
+    validation_error_type_code: str
+
+
+class ErrorOrder(BaseModel):
+    id: int
+    order_id: int
+    validation_date: datetime.datetime
+    validation_error: str
+    validation_error_type_code: str
+
+
+class ErrorAbwOrder(BaseModel):
+    id: int
+    abworder_id: int
+    date: datetime.datetime
+    error: str
+    error_type_code: str
+    error_level: str
+    error_source: str
+
+
+class AbwOrderErrors(BaseModel):
+    """Model for the /abw_order_errors/<id> endpoint"""
+    abw_order_errors: List[ErrorAbwOrder]
+    order_errors: List[ErrorOrder]
+    detail_errors: List[ErrorDetail]
diff --git a/tests/conftest.py b/tests/conftest.py
index 7b8e99b02371fb6c6c15cb0b8fc226fe67a7a1e9..11bc09593d2f1e424522ad09bb953b290cab05a8 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -110,3 +110,38 @@ def complete_batch():
 @pytest.fixture
 def param_list():
     return load_json_file("params.json")
+
+
+@pytest.fixture
+def abw_order_fixture():
+    return load_json_file("abw_order_fixture.json")
+
+
+@pytest.fixture
+def order_fixture():
+    return load_json_file("order_fixture.json")
+
+
+@pytest.fixture
+def detail_fixture():
+    return load_json_file("detail_fixture.json")
+
+
+@pytest.fixture
+def order_with_detail_fixture():
+    return load_json_file("order_with_detail_fixture.json")
+
+
+@pytest.fixture
+def order_list_fixture():
+    return load_json_file("order_list_fixture.json")
+
+
+@pytest.fixture
+def detail_list_fixture():
+    return load_json_file("detail_list_fixture.json")
+
+
+@pytest.fixture
+def complete_abw_order_fixture():
+    return load_json_file("complete_abw_order_fixture.json")
diff --git a/tests/fixtures/abw_order_fixture.json b/tests/fixtures/abw_order_fixture.json
new file mode 100644
index 0000000000000000000000000000000000000000..393ca558e479836339e0593c13eeb8f3979eea3a
--- /dev/null
+++ b/tests/fixtures/abw_order_fixture.json
@@ -0,0 +1,8 @@
+{
+  "id": 2,
+  "responsible": "responsible2",
+  "client": "testclient",
+  "interface": "testinterface",
+  "abworderid": "some-external-order-id",
+  "orders": []
+}
diff --git a/tests/fixtures/complete_abw_order_fixture.json b/tests/fixtures/complete_abw_order_fixture.json
new file mode 100644
index 0000000000000000000000000000000000000000..dfd8da084d502d720eaad455637e750aac93ea0b
--- /dev/null
+++ b/tests/fixtures/complete_abw_order_fixture.json
@@ -0,0 +1,89 @@
+{
+    "id": 2,
+    "responsible": "responsible2",
+    "client": "testclient",
+    "interface": "testinterface",
+    "abworderid": "some-external-order-id",
+    "orders": [
+        {
+            "id": 3,
+            "abw_order_id": 2,
+            "accountable": "accountable3",
+            "buyer_no": "buyerno",
+            "currency": "currency",
+            "ext_order_ref": "extorderref",
+            "order_date": "2021-07-20",
+            "order_type": "ab",
+            "sales_man": "sales man",
+            "trans_type": "tr",
+            "ext_order_id": "extorderid",
+            "order_no": 1,
+            "deliv_date": "2021-07-20",
+            "text3": "txt3",
+            "text4": "txt4",
+            "header_text": "headertext",
+            "footer_text": "footertext",
+            "details": [
+                {
+                    "id": 2,
+                    "order_id": 3,
+                    "account": "account4",
+                    "buyer_product_descr": "buyer prod decrs",
+                    "buyer_product_code": "product code",
+                    "line_total": 4444.0,
+                    "koststed": "123123",
+                    "prosjekt": "prosjekt",
+                    "t1": "t1",
+                    "r00": "r00",
+                    "delprosjekt": "prosjekt",
+                    "anlegg": "anlegg",
+                    "aktivitet": "aktivitet",
+                    "line_no": 1,
+                    "product_specification": 213,
+                    "price": 444.0,
+                    "quantity": 2.0
+                }
+            ]
+        },
+        {
+            "id": 4,
+            "abw_order_id": 2,
+            "accountable": "accc4",
+            "buyer_no": "buyerno2",
+            "currency": "curr",
+            "ext_order_ref": "ext order ref",
+            "order_date": "2021-07-20",
+            "order_type": "ty",
+            "sales_man": "sales man",
+            "trans_type": "tr",
+            "ext_order_id": "ext order id",
+            "order_no": 2,
+            "deliv_date": "2021-07-20",
+            "text3": "222222",
+            "text4": "txt444",
+            "header_text": "headertext",
+            "footer_text": "footertext",
+            "details": [
+                {
+                    "id": 3,
+                    "order_id": 4,
+                    "account": "account5",
+                    "buyer_product_descr": "buyer prod decrs",
+                    "buyer_product_code": "product code",
+                    "line_total": 555.0,
+                    "koststed": "123123",
+                    "prosjekt": "prosjekt",
+                    "t1": "t1",
+                    "r00": "r00",
+                    "delprosjekt": "prosjekt",
+                    "anlegg": "anlegg",
+                    "aktivitet": "aktivitet",
+                    "line_no": 1,
+                    "product_specification": 213,
+                    "price": 555.0,
+                    "quantity": 2.0
+                }
+            ]
+        }
+    ]
+}
diff --git a/tests/fixtures/detail_fixture.json b/tests/fixtures/detail_fixture.json
new file mode 100644
index 0000000000000000000000000000000000000000..e766f33b59ec7cffd12528b072dd98eb44125af3
--- /dev/null
+++ b/tests/fixtures/detail_fixture.json
@@ -0,0 +1,19 @@
+{
+    "id": 1,
+    "order": 1,
+    "account": "account",
+    "buyer_product_descr": "buyer prod decrs",
+    "buyer_product_code": "product code",
+    "line_total": "123.00",
+    "koststed": "123123",
+    "prosjekt": "prosjekt",
+    "t1": "t1",
+    "r00": "r00",
+    "delprosjekt": "prosjekt",
+    "anlegg": "anlegg",
+    "aktivitet": "aktivitet",
+    "line_no": 1,
+    "product_specification": 213,
+    "price": "1234.00",
+    "quantity": 2.0
+}
diff --git a/tests/fixtures/detail_list_fixture.json b/tests/fixtures/detail_list_fixture.json
new file mode 100644
index 0000000000000000000000000000000000000000..5116b0dd3d076cef1615544a891a93acca7d1060
--- /dev/null
+++ b/tests/fixtures/detail_list_fixture.json
@@ -0,0 +1,40 @@
+[
+  {
+    "id": 1,
+    "order": 1,
+    "account": "account",
+    "buyer_product_descr": "buyer prod decrs",
+    "buyer_product_code": "product code",
+    "line_total": "123.00",
+    "koststed": "123123",
+    "prosjekt": "prosjekt",
+    "t1": "t1",
+    "r00": "r00",
+    "delprosjekt": "prosjekt",
+    "anlegg": "anlegg",
+    "aktivitet": "aktivitet",
+    "line_no": 1,
+    "product_specification": 213,
+    "price": "1234.00",
+    "quantity": 2.0
+  },
+  {
+    "id": 2,
+    "order": 1,
+    "account": "account",
+    "buyer_product_descr": "buyer prod decrs",
+    "buyer_product_code": "product code",
+    "line_total": "123.00",
+    "koststed": "123123",
+    "prosjekt": "prosjekt",
+    "t1": "t1",
+    "r00": "r00",
+    "delprosjekt": "prosjekt",
+    "anlegg": "anlegg",
+    "aktivitet": "aktivitet",
+    "line_no": 1,
+    "product_specification": 213,
+    "price": "1234.00",
+    "quantity": 2.0
+  }
+]
diff --git a/tests/fixtures/order_fixture.json b/tests/fixtures/order_fixture.json
new file mode 100644
index 0000000000000000000000000000000000000000..ecd44bf39d5a63a1ee95c35cec0c30e55431e015
--- /dev/null
+++ b/tests/fixtures/order_fixture.json
@@ -0,0 +1,20 @@
+{
+    "id": 1,
+    "abw_order_id": 1,
+    "accountable": "accountable",
+    "buyer_no": "buyerno",
+    "currency": "currency",
+    "ext_order_ref": "extorderref",
+    "order_date": "2021-07-20",
+    "order_type": "ab",
+    "sales_man": "sales man",
+    "trans_type": "tr",
+    "ext_order_id": "extorderid",
+    "order_no": 1,
+    "deliv_date": "2021-07-20",
+    "text3": "txt3",
+    "text4": "txt4",
+    "header_text": "headertext",
+    "footer_text": "footertext",
+    "details": []
+}
diff --git a/tests/fixtures/order_list_fixture.json b/tests/fixtures/order_list_fixture.json
new file mode 100644
index 0000000000000000000000000000000000000000..f24eb229185d068fd8cf57f3d673211f5c389359
--- /dev/null
+++ b/tests/fixtures/order_list_fixture.json
@@ -0,0 +1,82 @@
+[
+    {
+        "id": 1,
+        "abw_order_id": 1,
+        "accountable": "accountable",
+        "buyer_no": "buyerno",
+        "currency": "currency",
+        "ext_order_ref": "extorderref",
+        "order_date": "2021-07-20",
+        "order_type": "ab",
+        "sales_man": "sales man",
+        "trans_type": "tr",
+        "ext_order_id": "extorderid",
+        "order_no": 1,
+        "deliv_date": "2021-07-20",
+        "text3": "txt3",
+        "text4": "txt4",
+        "header_text": "headertext",
+        "footer_text": "footertext",
+        "details": []
+    },
+    {
+        "id": 2,
+        "abw_order_id": 1,
+        "accountable": "accc2",
+        "buyer_no": "buyerno2",
+        "currency": "curr",
+        "ext_order_ref": "ext order ref",
+        "order_date": "2021-07-20",
+        "order_type": "ty",
+        "sales_man": "sales man",
+        "trans_type": "tr",
+        "ext_order_id": "ext order id",
+        "order_no": 2,
+        "deliv_date": "2021-07-20",
+        "text3": "222222",
+        "text4": "txt444",
+        "header_text": "headertext",
+        "footer_text": "footertext",
+        "details": []
+    },
+    {
+        "id": 3,
+        "abw_order_id": 2,
+        "accountable": "accountable3",
+        "buyer_no": "buyerno",
+        "currency": "currency",
+        "ext_order_ref": "extorderref",
+        "order_date": "2021-07-20",
+        "order_type": "ab",
+        "sales_man": "sales man",
+        "trans_type": "tr",
+        "ext_order_id": "extorderid",
+        "order_no": 1,
+        "deliv_date": "2021-07-20",
+        "text3": "txt3",
+        "text4": "txt4",
+        "header_text": "headertext",
+        "footer_text": "footertext",
+        "details": []
+    },
+    {
+        "id": 4,
+        "abw_order_id": 2,
+        "accountable": "accc4",
+        "buyer_no": "buyerno2",
+        "currency": "curr",
+        "ext_order_ref": "ext order ref",
+        "order_date": "2021-07-20",
+        "order_type": "ty",
+        "sales_man": "sales man",
+        "trans_type": "tr",
+        "ext_order_id": "ext order id",
+        "order_no": 2,
+        "deliv_date": "2021-07-20",
+        "text3": "222222",
+        "text4": "txt444",
+        "header_text": "headertext",
+        "footer_text": "footertext",
+        "details": []
+    }
+]
diff --git a/tests/fixtures/order_with_detail_fixture.json b/tests/fixtures/order_with_detail_fixture.json
new file mode 100644
index 0000000000000000000000000000000000000000..474ee1127677eb49b585f7978b20cf1d721c34f5
--- /dev/null
+++ b/tests/fixtures/order_with_detail_fixture.json
@@ -0,0 +1,59 @@
+{
+    "id": 1,
+    "abw_order_id": 1,
+    "accountable": "accountable",
+    "buyer_no": "buyerno",
+    "currency": "currency",
+    "ext_order_ref": "extorderref",
+    "order_date": "2021-07-20",
+    "order_type": "ab",
+    "sales_man": "sales man",
+    "trans_type": "tr",
+    "ext_order_id": "extorderid",
+    "order_no": 1,
+    "deliv_date": "2021-07-20",
+    "text3": "txt3",
+    "text4": "txt4",
+    "header_text": "headertext",
+    "footer_text": "footertext",
+    "details": [
+        {
+            "id": 1,
+            "order_id": 1,
+            "account": "account",
+            "buyer_product_descr": "buyer prod decrs",
+            "buyer_product_code": "product code",
+            "line_total": 123.0,
+            "koststed": "123123",
+            "prosjekt": "prosjekt",
+            "t1": "t1",
+            "r00": "r00",
+            "delprosjekt": "prosjekt",
+            "anlegg": "anlegg",
+            "aktivitet": "aktivitet",
+            "line_no": 1,
+            "product_specification": 213,
+            "price": 1234.0,
+            "quantity": 2.0
+        },
+        {
+            "id": 2,
+            "order_id": 1,
+            "account": "account2",
+            "buyer_product_descr": "buyer prod decrs2",
+            "buyer_product_code": "product code2",
+            "line_total": 124.0,
+            "koststed": "444",
+            "prosjekt": "prosjekt2",
+            "t1": "t2",
+            "r00": "r00",
+            "delprosjekt": "prosjekt2",
+            "anlegg": "anlegg2",
+            "aktivitet": "aktivitet2",
+            "line_no": 2,
+            "product_specification": 213,
+            "price": 1234.0,
+            "quantity": 2.0
+        }
+    ]
+}
diff --git a/tests/test_client.py b/tests/test_client.py
index 45d4355cb891ebf6463d14f0da41d9d38ec2bdc1..b339596c08294ca2d0adddb82a1a0f9a5a103c26 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -1,4 +1,5 @@
 import datetime
+import json
 from json.decoder import JSONDecodeError
 
 import pytest
@@ -7,20 +8,28 @@ from requests import HTTPError
 
 from setra_client.client import SetraClient
 from setra_client.client import SetraEndpoints
-from setra_client.models import CompleteBatch, BatchErrors, Parameter, InputBatch, \
-    OutputBatch
+from setra_client.models import (
+    CompleteBatch,
+    BatchErrors,
+    Parameter,
+    InputBatch,
+    OutputBatch,
+    AbwOrder,
+    Order,
+    Detail,
+)
 
 
 @pytest.fixture
 def header_name():
-    return 'X-Test'
+    return "X-Test"
 
 
 @pytest.fixture
 def client_cls(header_name):
     class TestClient(SetraClient):
         default_headers = {
-            header_name: '6a9a32f0-7322-4ef3-bbce-6685a3388e67',
+            header_name: "6a9a32f0-7322-4ef3-bbce-6685a3388e67",
         }
 
     return TestClient
@@ -41,7 +50,7 @@ def test_init_applies_default_headers(client_cls, baseurl, header_name):
 
 
 def test_init_modify_defaults(client_cls, baseurl, header_name):
-    headers = {header_name: 'ede37fdd-a2ae-4a96-9d80-110528425ea6'}
+    headers = {header_name: "ede37fdd-a2ae-4a96-9d80-110528425ea6"}
     client = client_cls(baseurl, headers=headers)
     # Check that we respect the headers arg, and don't use default_headers
     assert client.headers[header_name] == headers[header_name]
@@ -51,24 +60,25 @@ def test_init_modify_defaults(client_cls, baseurl, header_name):
 
 # Test call method
 
+
 def test_get_successful_batch_with_json_content(client, requests_mock, baseurl):
     """A working GET call should return HTTP 200, with json content"""
 
-    url = SetraEndpoints(baseurl).batch(batch_id='3')  # https://localhost/api/batch/3
-    requests_mock.get(url, json={'foo': 'bar'}, status_code=200)
+    url = SetraEndpoints(baseurl).batch(batch_id="3")  # https://localhost/api/batch/3
+    requests_mock.get(url, json={"foo": "bar"}, status_code=200)
 
-    response = client.call(method_name='GET', url=url)
+    response = client.call(method_name="GET", url=url)
     assert response.status_code == 200
-    assert response.json() == {'foo': 'bar'}
+    assert response.json() == {"foo": "bar"}
 
 
 def test_get_successful_batch_with_text_content(client, requests_mock, baseurl):
     """A working GET call should return HTTP 200, with json content"""
 
-    url = SetraEndpoints(baseurl).batch(batch_id='3')  # https://localhost/api/batch/3
+    url = SetraEndpoints(baseurl).batch(batch_id="3")  # https://localhost/api/batch/3
     requests_mock.get(url, text="some content", status_code=200)
 
-    response = client.call(method_name='GET', url=url)
+    response = client.call(method_name="GET", url=url)
     assert response.status_code == 200
     assert response.text == "some content"
 
@@ -76,11 +86,11 @@ def test_get_successful_batch_with_text_content(client, requests_mock, baseurl):
 def test_get_failing_batch_with_json_content(client, batch_url, requests_mock, baseurl):
     """A failing GET call with 404 should pass through the same response from the client, and return HTTP 404,
     and the request with json content"""
-    requests_mock.get(batch_url, json={'a': 'b'}, status_code=404)
+    requests_mock.get(batch_url, json={"a": "b"}, status_code=404)
 
-    resp = client.call(method_name='GET', url=batch_url)
+    resp = client.call(method_name="GET", url=batch_url)
     assert resp.status_code == 404
-    assert resp.json() == {'a': 'b'}
+    assert resp.json() == {"a": "b"}
 
 
 def test_get_failing_batch_with_text_content(client, batch_url, requests_mock, baseurl):
@@ -88,83 +98,99 @@ def test_get_failing_batch_with_text_content(client, batch_url, requests_mock, b
     and the request with json content"""
     requests_mock.get(batch_url, text="some content", status_code=404)
 
-    resp = client.call(method_name='GET', url=batch_url)
+    resp = client.call(method_name="GET", url=batch_url)
     assert resp.status_code == 404
     assert resp.text == "some content"
 
 
-def test_get_failing_batch_without_return_response_text(client, batch_url, requests_mock, baseurl):
+def test_get_failing_batch_without_return_response_text(
+    client, batch_url, requests_mock, baseurl
+):
     """A failing GET call with 404 should raise HTTPError from the client,
     and return HTTP 404, and the request with text content"""
     requests_mock.get(batch_url, text="some content", status_code=404)
 
     with pytest.raises(HTTPError) as err:
-        client.call(method_name='GET', url=batch_url, return_response=False)
+        client.call(method_name="GET", url=batch_url, return_response=False)
 
     assert err.type == requests.exceptions.HTTPError
     assert err.value.response.status_code == 404
     assert err.value.response.text == "some content"
 
 
-def test_get_failing_batch_without_return_response_json(client, batch_url, requests_mock, baseurl):
+def test_get_failing_batch_without_return_response_json(
+    client, batch_url, requests_mock, baseurl
+):
     """A failing GET call with 404 should raise HTTPError from the client,
     and return HTTP 404, and the request with json content"""
-    requests_mock.get(batch_url, json={'a': 'b'}, status_code=404)
+    requests_mock.get(batch_url, json={"a": "b"}, status_code=404)
 
     with pytest.raises(HTTPError) as err:
-        client.call(method_name='GET', url=batch_url, return_response=False)
+        client.call(method_name="GET", url=batch_url, return_response=False)
 
     assert err.type == requests.exceptions.HTTPError
     assert err.value.response.status_code == 404
-    assert err.value.response.json() == {'a': 'b'}
+    assert err.value.response.json() == {"a": "b"}
 
 
-def test_get_failing_batch_without_return_response2(client, batch_url, requests_mock, baseurl):
+def test_get_failing_batch_without_return_response2(
+    client, batch_url, requests_mock, baseurl
+):
     """A failing GET call with 404 returning text content, with return_response=False
     should raise for HTTPError from the client
-    (because we expect json from setra, and it will give error with text content) """
+    (because we expect json from setra, and it will give error with text content)"""
     requests_mock.get(batch_url, text="some content", status_code=200)
 
     with pytest.raises(JSONDecodeError) as err:
-        client.call(method_name='GET', url=batch_url, return_response=False)
+        client.call(method_name="GET", url=batch_url, return_response=False)
 
     assert err.type == JSONDecodeError
 
+
 # Test post method
 
+
 def test_get_failing_batch_with_http500(client, batch_url, requests_mock, baseurl):
     """A failing POST call with return_response=False and http 500,
     should raise HTTPError from the client,
     and return HTTP 500, and the request with json content"""
-    requests_mock.post(batch_url, json={'a': 'b'}, status_code=500)
+    requests_mock.post(batch_url, json={"a": "b"}, status_code=500)
 
     with pytest.raises(HTTPError) as err:
         client.post(url=batch_url, return_response=False)
 
     assert err.type == requests.exceptions.HTTPError
     assert err.value.response.status_code == 500
-    assert err.value.response.json() == {'a': 'b'}
+    assert err.value.response.json() == {"a": "b"}
 
 
 def test_get_failing_batch_with_http5002(client, batch_url, requests_mock, baseurl):
     """A failing POST call with 500 with return_response=True,
     should just return the response, with 500"""
-    requests_mock.post(batch_url, json={'a': 'b'}, status_code=500)
+    requests_mock.post(batch_url, json={"a": "b"}, status_code=500)
 
     response = client.post(url=batch_url)
     assert response.status_code == 500
-    assert response.json() == {'a': 'b'}
+    assert response.json() == {"a": "b"}
 
 
 # Test setting headers
 
+
 def test_header_replacement(client_with_a_header, batch_url, requests_mock, baseurl):
     """Given a SetraClient created with a "global" header,
     making a request with the same header key,
     should replace the "global" header value"""
-    requests_mock.get(batch_url, text="some content", status_code=200, headers={"content-type": "replaced"})
+    requests_mock.get(
+        batch_url,
+        text="some content",
+        status_code=200,
+        headers={"content-type": "replaced"},
+    )
 
-    response = client_with_a_header.call(method_name='GET', url=batch_url, headers={"content-type": "replaced"})
+    response = client_with_a_header.call(
+        method_name="GET", url=batch_url, headers={"content-type": "replaced"}
+    )
     assert response.status_code == 200
     assert response.text == "some content"
     assert response.headers == {"content-type": "replaced"}
@@ -175,9 +201,16 @@ def test_header_replacement2(client_with_a_header, batch_url, requests_mock, bas
     making a request with the same header key,
     should replace the "global" header value,
     while new headers should be added to the request"""
-    requests_mock.get(batch_url, text="some content", status_code=200, headers={"content-type": "replaced", "key": "val"})
+    requests_mock.get(
+        batch_url,
+        text="some content",
+        status_code=200,
+        headers={"content-type": "replaced", "key": "val"},
+    )
 
-    response = client_with_a_header.call(method_name='GET', url=batch_url, headers={"content-type": "replaced"})
+    response = client_with_a_header.call(
+        method_name="GET", url=batch_url, headers={"content-type": "replaced"}
+    )
     assert response.status_code == 200
     assert response.text == "some content"
     assert response.headers == {"content-type": "replaced", "key": "val"}
@@ -185,6 +218,7 @@ def test_header_replacement2(client_with_a_header, batch_url, requests_mock, bas
 
 # Test get_batches method
 
+
 def test_successful_get_all_batches(client, requests_mock, baseurl, batch_fixture):
     """A working GET call should return HTTP 200, with json content"""
     url = SetraEndpoints(baseurl).batch()
@@ -195,7 +229,7 @@ def test_successful_get_all_batches(client, requests_mock, baseurl, batch_fixtur
 
 
 def test_successful_get_batches_filtered_by_status(
-        client, requests_mock, baseurl, batch_fixture
+    client, requests_mock, baseurl, batch_fixture
 ):
     """A working GET call should return HTTP 200, with json content"""
     url = SetraEndpoints(baseurl).batch()
@@ -206,10 +240,10 @@ def test_successful_get_batches_filtered_by_status(
 
 
 def test_successfully_getting_single_batch(
-        client, requests_mock, baseurl, batch_fixture
+    client, requests_mock, baseurl, batch_fixture
 ):
     """A working GET call should return HTTP 200, with json content"""
-    url = SetraEndpoints(baseurl).batch(batch_id='3')
+    url = SetraEndpoints(baseurl).batch(batch_id="3")
     requests_mock.get(url, json=batch_fixture, status_code=200)
 
     response = client.get_batch(3)
@@ -226,64 +260,70 @@ def test_failing_to_get_all_batches(client, batch_url, requests_mock, baseurl):
 
 # Test get_voucher method
 
+
 def test_successfully_getting_single_voucher(client, requests_mock, baseurl):
     """A working GET call should return HTTP 200, with json content"""
-    url = SetraEndpoints(baseurl).voucher(vouch_id='5')
-    requests_mock.get(url, json={'foo': 'bar'}, status_code=200)
+    url = SetraEndpoints(baseurl).voucher(vouch_id="5")
+    requests_mock.get(url, json={"foo": "bar"}, status_code=200)
 
     response = client.get_voucher(5)
-    assert response == {'foo': 'bar'}
+    assert response == {"foo": "bar"}
 
 
-def test_requesting_single_voucher_with_invalid_voucherid(client, requests_mock, baseurl):
+def test_requesting_single_voucher_with_invalid_voucherid(
+    client, requests_mock, baseurl
+):
     """Requesting a voucher, with None as voucherid, will request get all vouchers instead """
     url = SetraEndpoints(baseurl).voucher()
-    requests_mock.get(url, json={'foo': 'bar'}, status_code=200)
+    requests_mock.get(url, json={"foo": "bar"}, status_code=200)
 
-    response = client.get_voucher(None) #using None as voucherid
-    assert response == {'foo': 'bar'}
+    response = client.get_voucher(None)  # using None as voucherid
+    assert response == {"foo": "bar"}
 
 
-def test_successfully_getting_single_voucher_with_alphanumeric_voucherid(client, requests_mock, baseurl):
+def test_successfully_getting_single_voucher_with_alphanumeric_voucherid(
+    client, requests_mock, baseurl
+):
     """Requesting a voucher, with alphanumeric voucherid, will work, and not crash
 
     TODO: investigate if this is intentional behaviour (need spec on voucher id format)
 
     """
     url = SetraEndpoints(baseurl).voucher("abcd123efg")
-    requests_mock.get(url, json={'foo': 'bar'}, status_code=200)
+    requests_mock.get(url, json={"foo": "bar"}, status_code=200)
 
-    response = client.get_voucher("abcd123efg") #using alphanum string as voucherid
-    assert response == {'foo': 'bar'}
+    response = client.get_voucher("abcd123efg")  # using alphanum string as voucherid
+    assert response == {"foo": "bar"}
 
 
 def test_failing_to_get_all_vouchers(client, requests_mock, baseurl):
     """A failing GET all vouchers call should still return json"""
     url = SetraEndpoints(baseurl).voucher()
-    requests_mock.get(url, json={'error': 'some json error message'}, status_code=404)
+    requests_mock.get(url, json={"error": "some json error message"}, status_code=404)
 
     response = client.get_voucher()
-    assert response == {'error': 'some json error message'}
+    assert response == {"error": "some json error message"}
 
 
 # Test get_transaction method
 
+
 def test_successfully_getting_single_transaction(client, requests_mock, baseurl):
     """A working GET call should return HTTP 200, with json content"""
-    url = SetraEndpoints(baseurl).transaction(trans_id='9')
-    requests_mock.get(url, json={'foo': 'bar'}, status_code=200)
+    url = SetraEndpoints(baseurl).transaction(trans_id="9")
+    requests_mock.get(url, json={"foo": "bar"}, status_code=200)
 
     response = client.get_transaction(9)
-    assert response == {'foo': 'bar'}
+    assert response == {"foo": "bar"}
 
 
 def test_failing_to_get_all_transactions(client, requests_mock, baseurl):
     """A failing GET all vouchers call should still return json"""
     url = SetraEndpoints(baseurl).transaction()
-    requests_mock.get(url, json={'error': 'some json error message'}, status_code=404)
+    requests_mock.get(url, json={"error": "some json error message"}, status_code=404)
 
     response = client.get_transaction()
-    assert response == {'error': 'some json error message'}
+    assert response == {"error": "some json error message"}
 
 
 # Test post_new_batch method
@@ -299,7 +339,9 @@ def test_successfully_post_batch_with_voucher(client, batch_with_voucher_fixture
     assert data == {}
 
 
-def test_successfully_post_batch_with_voucher_and_response(client, batch_with_voucher_fixture, requests_mock, baseurl):
+def test_successfully_post_batch_with_voucher_and_response(
+    client, batch_with_voucher_fixture, requests_mock, baseurl
+):
     """A working POST new batch call with return_response=True,
     should return the response with HTTP 202, with json content"""
     url = SetraEndpoints(baseurl).post_new_batch()
@@ -330,13 +372,13 @@ def test_unknown_post_new_batch_state(client, batch_with_voucher_fixture, reques
 
 
 def test_successfully_getting_batch_complete(
-        client, requests_mock, baseurl, complete_batch
+    client, requests_mock, baseurl, complete_batch
 ):
     """A working GET call should return HTTP 200, with json content"""
-    url = SetraEndpoints(baseurl).batch_complete(batch_id='1')
+    url = SetraEndpoints(baseurl).batch_complete(batch_id="1")
     requests_mock.get(url, json=complete_batch, status_code=200)
 
-    response = client.get_batch_complete('1')
+    response = client.get_batch_complete("1")
     assert response == CompleteBatch(**complete_batch)
 
 
@@ -348,18 +390,18 @@ def test_get_batch_error(baseurl, requests_mock, client, batch_errors):
 
 
 def test_successfully_getting_batch_complete_objectless(
-        client_no_objects, requests_mock, baseurl, complete_batch
+    client_no_objects, requests_mock, baseurl, complete_batch
 ):
     """A working GET call should return HTTP 200, with json content"""
-    url = SetraEndpoints(baseurl).batch_complete(batch_id='1')
+    url = SetraEndpoints(baseurl).batch_complete(batch_id="1")
     requests_mock.get(url, json=complete_batch, status_code=200)
 
-    response = client_no_objects.get_batch_complete('1')
+    response = client_no_objects.get_batch_complete("1")
     assert isinstance(response, dict)
 
 
 def test_get_batch_error_objectless(
-        client_no_objects, requests_mock, baseurl, batch_errors
+    client_no_objects, requests_mock, baseurl, batch_errors
 ):
     url = SetraEndpoints(baseurl).batch_error("5")
     requests_mock.get(url, json=batch_errors, status_code=200)
@@ -384,7 +426,7 @@ def test_get_params_interface(client_no_objects, requests_mock, param_list):
     requests_mock.get(
         "https://localhost/api/parameters/?interface=HB",
         json=param_list[2:],
-        status_code=200
+        status_code=200,
     )
     response = client_no_objects.get_parameters(interface="HB")
     assert isinstance(response, list)
@@ -412,9 +454,114 @@ def test_get_params_interface_object(client, requests_mock, param_list):
     requests_mock.get(
         "https://localhost/api/parameters/?interface=HB",
         json=param_list[2:],
-        status_code=200
+        status_code=200,
     )
     response = client.get_parameters(interface="HB")
     assert isinstance(response, list)
     assert isinstance(response[0], Parameter)
     assert len(response) == 4
+
+
+# Sotra tests:
+
+
+def test_get_abworder(client, requests_mock, baseurl, complete_abw_order_fixture):
+    """Should return HTTP 200, with a complete abw order, with orders and detail objects"""
+    url = SetraEndpoints(baseurl).abw_order_complete(abw_order_id="2")
+    requests_mock.get(url, json=complete_abw_order_fixture, status_code=200)
+
+    response = client.get_abw_order_complete(2)
+    assert response == AbwOrder(**complete_abw_order_fixture)
+    assert len(response.orders) == 2
+    assert len(response.orders[0].details) == 1
+    assert len(response.orders[1].details) == 1
+
+
+def test_get_order(client, requests_mock, baseurl, order_with_detail_fixture):
+    """Should return HTTP 200, with a complete order with detail objects"""
+    url = SetraEndpoints(baseurl).order_complete(order_id="2")
+    requests_mock.get(url, json=order_with_detail_fixture, status_code=200)
+
+    response = client.get_order_complete(2)
+    assert response == Order(**order_with_detail_fixture)
+
+
+def test_get_detail(client, requests_mock, baseurl, detail_fixture):
+    """Should return HTTP 200, with one detail"""
+    url = SetraEndpoints(baseurl).detail(detail_id="1")
+    requests_mock.get(url, json=detail_fixture, status_code=200)
+
+    response = client.get_detail(1)
+    assert response == Detail(**detail_fixture)
+
+
+def test_get_order_list(client, requests_mock, baseurl, order_list_fixture):
+    """Should return HTTP 200, with a list of orders"""
+    url = SetraEndpoints(baseurl).order()
+    requests_mock.get(url, json=order_list_fixture, status_code=200)
+
+    response = client.get_order_list()
+    assert isinstance(response, list)
+    assert len(response) == 4
+
+
+def test_get_order_details_list(client, requests_mock, baseurl, detail_list_fixture):
+    """Should return HTTP 200, with a list of details for an order"""
+    url = SetraEndpoints(baseurl).details_in_order("1")
+    requests_mock.get(url, json=detail_list_fixture, status_code=200)
+
+    response = client.get_details_in_order(order_id="1")
+    assert isinstance(response, list)
+    assert len(response) == 2
+
+
+def test_send_in_abworder(client, requests_mock, baseurl, complete_abw_order_fixture):
+    """Setra client should give us a tuple, with the data, and a status"""
+    url = SetraEndpoints(baseurl).add_abw_order()
+    resp = {
+        "responsible": "responsible2",
+        "interface": "testinterface",
+        "client": "testclient",
+    }
+    requests_mock.post(url, json=resp, status_code=202)
+    abworder = AbwOrder(**complete_abw_order_fixture)
+
+    response = client.post_add_abw_order(abworder)
+    if isinstance(response, tuple):
+        assert response[0].decode("utf-8") == json.dumps(resp)
+        assert response[1] == "Accepted"
+
+
+def test_send_in_abworder_failure_conflict(
+    client, requests_mock, baseurl, complete_abw_order_fixture
+):
+    """Setra client should give us a tuple, with the data, and a status"""
+    url = SetraEndpoints(baseurl).add_abw_order()
+    resp = {
+        "responsible": "responsible2",
+        "interface": "testinterface",
+        "client": "testclient",
+    }
+    requests_mock.post(url, json=resp, status_code=409)
+    abworder = AbwOrder(**complete_abw_order_fixture)
+
+    response = client.post_add_abw_order(abworder)
+    assert isinstance(response, tuple)
+    assert response[0].decode("utf-8") == json.dumps(resp)
+    assert response[1] == "Conflict"
+
+
+def test_send_in_abworder_failure(
+    client, requests_mock, baseurl, complete_abw_order_fixture
+):
+    """Setra client should get HTTPError if Setra returns 404"""
+    url = SetraEndpoints(baseurl).add_abw_order()
+    requests_mock.post(url, status_code=404)
+    abworder = AbwOrder(**complete_abw_order_fixture)
+
+    with pytest.raises(HTTPError) as err:
+        client.post_add_abw_order(abworder)
+
+    assert err.type == requests.exceptions.HTTPError
+    assert err.value.response.status_code == 404
+    assert err.value.response.text == ""
diff --git a/tests/test_endpoints.py b/tests/test_endpoints.py
index 5d0cde877ef71fcb0a489e0efe5dabce3872eda7..df614389c63c9934aef8e25491c5ac5ed582b2dc 100644
--- a/tests/test_endpoints.py
+++ b/tests/test_endpoints.py
@@ -45,3 +45,43 @@ def test_init_batch_complete_with_value(baseurl):
 def test_init_batch_error(baseurl):
     endpoints = SetraEndpoints(baseurl)
     assert endpoints.batch_error("123") == baseurl + "/api/batch_error/123"
+
+
+def test_init_order_complete_with_value(baseurl):
+    endpoints = SetraEndpoints(baseurl)
+    assert endpoints.order_complete(order_id="7") == baseurl + "/api/order_complete/7"
+
+
+def test_init_abw_order_complete_with_value(baseurl):
+    endpoints = SetraEndpoints(baseurl)
+    assert (
+        endpoints.abw_order_complete(abw_order_id="4")
+        == baseurl + "/api/abw_order_complete/4"
+    )
+
+
+def test_init_order(baseurl):
+    endpoints = SetraEndpoints(baseurl)
+    assert endpoints.order() == baseurl + "/api/order/"
+
+
+def test_init_order_with_value(baseurl):
+    endpoints = SetraEndpoints(baseurl)
+    assert endpoints.order(order_id="4") == baseurl + "/api/order/4"
+
+
+def test_init_detail_with_value(baseurl):
+    endpoints = SetraEndpoints(baseurl)
+    assert endpoints.detail(detail_id="3") == baseurl + "/api/detail/3"
+
+
+def test_init_details_in_order(baseurl):
+    endpoints = SetraEndpoints(baseurl)
+    assert (
+        endpoints.details_in_order(order_id="9") == baseurl + "/api/details_in_order/9"
+    )
+
+
+def test_init_add_abw_order(baseurl):
+    endpoints = SetraEndpoints(baseurl)
+    assert endpoints.add_abw_order() == baseurl + "/api/add_abw_order/"
diff --git a/tests/test_models.py b/tests/test_models.py
index a845e4bdef54a8c15071d9904568bf9d8f20c4d2..4bef489aacda1a6e96264f7b61e12123e62bf370 100644
--- a/tests/test_models.py
+++ b/tests/test_models.py
@@ -9,7 +9,12 @@ from setra_client.models import (
     ErrorBatch,
     Parameter,
     Transaction,
-    Voucher, InputBatch, OutputBatch,
+    Voucher,
+    InputBatch,
+    OutputBatch,
+    AbwOrder,
+    Order,
+    Detail,
 )
 
 
@@ -28,8 +33,8 @@ def test_voucher(voucher_fixture):
 def test_voucher_has_transactions(voucher_fixture):
     voucher = Voucher(**voucher_fixture)
     assert len(voucher.transactions) == 2
-    assert voucher.transactions.__getitem__(0).amount == 1
-    assert voucher.transactions.__getitem__(1).amount == 2
+    assert voucher.transactions[0].amount == 1
+    assert voucher.transactions[1].amount == 2
 
 
 def test_transaction(trans_fixture):
@@ -77,3 +82,33 @@ def test_params(param_list):
     assert param[0].created == datetime.datetime(
         2020, 1, 1, 2, 0, 0, tzinfo=datetime.timezone.utc
     )
+
+
+def test_abw_order(abw_order_fixture):
+    assert AbwOrder(**abw_order_fixture)
+
+
+def test_order(order_fixture):
+    assert Order(**order_fixture)
+
+
+def test_detail(detail_fixture):
+    assert Detail(**detail_fixture)
+
+
+def test_order_with_detail(order_with_detail_fixture):
+    order = Order(**order_with_detail_fixture)
+    assert len(order.details) == 2
+    assert order.details[0].koststed == "123123"
+    assert order.details[1].koststed == "444"
+
+
+def test_complete_abw_order(complete_abw_order_fixture):
+    abworder = AbwOrder(**complete_abw_order_fixture)
+    assert len(abworder.orders) == 2
+    assert len(abworder.orders[0].details) == 1
+    assert len(abworder.orders[1].details) == 1
+    assert abworder.orders[0].id == 3
+    assert abworder.orders[0].details[0].id == 2
+    assert abworder.orders[1].id == 4
+    assert abworder.orders[1].details[0].id == 3