openapi: 3.1.0
info:
description: '
## Introduction
The **CAPEX API** enables you to integrate your application with the CAPEX system. The CAPEX API is REST-based and follows JSON:API principles for structuring responses.
Starting from version 1.0, the API is stable. We are continuously improving our API, and new endpoints will be added. Any updates or changes within this major version will be backward-compatible and can be found in this documentation.
For getting access to the CAPEX API, please reach out to us at: `kontakt@alasco.de`.
The base URL for all endpoints is:
`https://api.alasco.de/capex/v1`
The CAPEX API supports compressed payloads. If you would like to make use of this, you have to specify the `Accept-Encoding` header. Supported encodings are `gzip` and `br`.
### Domain model
Objects relate as follows (each `→` is a navigable sub-resource):
- **Assets** and **Measures** are the CapEx-specific top-level objects; a **Measure** → **Contracts**, and invoices are submitted against an **Asset**.
- **Contractor** and **Contracting Entity** → **Contracts**.
- **Contract** → **Change Orders**, **Invoices**, contract terms, **Documents** and **Custom Fields**.
- **Invoice** → **Documents** and **Tags** (Change Orders also carry **Documents**).
### CAPEX API Overview
The CAPEX API provides endpoints to:
- Retrieve and manage invoices, invoice tags, and invoice documents
- Retrieve assets, contracts, contractors, and measures
The CAPEX API uses pagination. The page size is 100, and additional pages can be accessed using a `next` link.
'
title: CAPEX Annual Consumption Invoice API
version: '1.0'
x-logo:
url: https://assets-global.website-files.com/656ef2eb27ad41897248f866/659eebec190ae7aaf4162f09_Logotype_Alasco_white_RGB%202.png
servers:
- url: https://api.alasco.de/capex/v1
tags:
- description: An **Invoice** is a contractor's request for payment that moves through states from `NEW` to `PAID`. Submitting an invoice against an **Asset** creates it in `NEW`, linked only to the asset's project; to process it you must link it to a **Contract** (which, in CapEx, belongs to a **Measure**). Invoices carry audited and approved amounts, **Documents** and **Tags**, and you can register their payment.
name: Invoice
paths:
/assets/{id}/submit-invoice/:
post:
description: This endpoint supports submitting new invoices. Before using this endpoint, please reach out the the support team to make sure, everything is properly set up.
operationId: submit_invoice_assets__id__submit_invoice__post
parameters:
- in: path
name: id
required: true
schema:
format: uuid
title: Id
type: string
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/Body_submit_invoice_assets__id__submit_invoice__post'
required: true
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/InvoiceResponse'
description: Successful Response
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
security:
- API Key: []
- API Token: []
summary: Submit Invoice
tags:
- Invoice
/contracts/{contract_id}/invoices/:
get:
operationId: get_invoices_by_contract_contracts__contract_id__invoices__get
parameters:
- in: path
name: contract_id
required: true
schema:
format: uuid
title: Contract Id
type: string
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/InvoiceListResponse'
description: Successful Response
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
security:
- API Key: []
- API Token: []
summary: Get Invoices By Contract
tags:
- Invoice
/invoices/:
get:
operationId: get_invoices_invoices__get
parameters:
- description: '
List endpoint responses are paginated in the Alasco API. By calling the endpoint without the
pagination parameter you will receive the first page. If not all elements fit on one page there will
be a `next` link provided in the response''s `links` object. By calling this link you will receive
the next page.
'
in: query
name: cursor[position]
required: false
schema:
anyOf:
- type: string
- type: 'null'
description: '
List endpoint responses are paginated in the Alasco API. By calling the endpoint without the
pagination parameter you will receive the first page. If not all elements fit on one page there will
be a `next` link provided in the response''s `links` object. By calling this link you will receive
the next page.
'
title: Cursor[Position]
- description: '
You can filter on certain attributes by specifying them as a GET parameter along
with an operation, e.g. `filter[internal_identifier.exact]=invoice_123`.
Those filters can be combined and multiple values are separated using commas,
for example `filter[internal_identifier.exact]=invoice123&filter[external_identifier.exact]=internal_invoice`.
Currently supported operations are
* `contains`: Expects one value
* `exact`: Expects one value
* `greater_than_equal`: Expects one value
* `in`: Expects one or multiple values
* `less_than_equal`: Expects one value
* `range`: Expects two values
* `not_in`: Expects one or multiple values
The following attributes support filtering:
| **Attribute** | `exact` | `contains` | `less_than_equal` | `greater_than_equal` | `range` | `in` | `not_in` |
| :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
| `id` | | | | | | x | x |
| `external_identifier` | x | x | | | | | |
| `internal_identifier` | x | x | | | | | |
| `date_posted` | x | | x | x | x | | |
| `date_due` | x | | x | x | x | | |
| `date_received` | x | | x | x | x | | |
| `date_approved` | | | x | x | x | | |
| `payment_created` | | | x | x | x | | |
| `date_created` | | | x | x | x | | |
| `invoice_type` | | | | | | x | x |
| `invoice_process_state` | | | | | | x | x |
| `payment_date` | x | | x | x | x | | |
| `unaudited_amount` | | | x | x | x | | |
| `discounted_approved_amount` | | | x | x | x | | |
| `undiscounted_approved_amount` | | | x | x | x | | |
| `cash_discount` | | | x | x | x | | |
| `audited_amount` | | | x | x | x | | |
| `tags` | | | | | | x | x |
| `contract` | | | | | | x | x |
Money attributes can be filtered on both, net and tax values. An example to filter for the net amount of
`unaudited_amount` would be `filter[unaudited_amount.net.greater_than_equal]=1000.00`.
Datetime attributes should be filtered by proper datetime arguments, e.g. `filter[date_created.gte]=2022-08-05T15:04:07`
'
in: query
name: filter[attribute.operation]
required: false
schema:
anyOf:
- type: string
- type: 'null'
description: '
You can filter on certain attributes by specifying them as a GET parameter along
with an operation, e.g. `filter[internal_identifier.exact]=invoice_123`.
Those filters can be combined and multiple values are separated using commas,
for example `filter[internal_identifier.exact]=invoice123&filter[external_identifier.exact]=internal_invoice`.
Currently supported operations are
* `contains`: Expects one value
* `exact`: Expects one value
* `greater_than_equal`: Expects one value
* `in`: Expects one or multiple values
* `less_than_equal`: Expects one value
* `range`: Expects two values
* `not_in`: Expects one or multiple values
The following attributes support filtering:
| **Attribute** | `exact` | `contains` | `less_than_equal` | `greater_than_equal` | `range` | `in` | `not_in` |
| :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
| `id` | | | | | | x | x |
| `external_identifier` | x | x | | | | | |
| `internal_identifier` | x | x | | | | | |
| `date_posted` | x | | x | x | x | | |
| `date_due` | x | | x | x | x | | |
| `date_received` | x | | x | x | x | | |
| `date_approved` | | | x | x | x | | |
| `payment_created` | | | x | x | x | | |
| `date_created` | | | x | x | x | | |
| `invoice_type` | | | | | | x | x |
| `invoice_process_state` | | | | | | x | x |
| `payment_date` | x | | x | x | x | | |
| `unaudited_amount` | | | x | x | x | | |
| `discounted_approved_amount` | | | x | x | x | | |
| `undiscounted_approved_amount` | | | x | x | x | | |
| `cash_discount` | | | x | x | x | | |
| `audited_amount` | | | x | x | x | | |
| `tags` | | | | | | x | x |
| `contract` | | | | | | x | x |
Money attributes can be filtered on both, net and tax values. An example to filter for the net amount of
`unaudited_amount` would be `filter[unaudited_amount.net.greater_than_equal]=1000.00`.
Datetime attributes should be filtered by proper datetime arguments, e.g. `filter[date_created.gte]=2022-08-05T15:04:07`
'
title: Filter[Attribute.Operation]
- description: '
You can get related objects by specifying them separated by comma as a GET `include` parameter.
In case of non-direct relation include parameter should be a relationship path - a dot-separated list of
relationship names.
Currently available objects are:
* contract
* contract.contractor
* contract.contract_unit
* contract.contract_unit.project
* contract.contract_unit.project.property
e.g. `include=contract,contract.contractor,contract.contract_unit,contract.contract_unit.project,contract.contract_unit.project.property`
'
in: query
name: include
required: false
schema:
anyOf:
- type: string
- type: 'null'
description: '
You can get related objects by specifying them separated by comma as a GET `include` parameter.
In case of non-direct relation include parameter should be a relationship path - a dot-separated list of
relationship names.
Currently available objects are:
* contract
* contract.contractor
* contract.contract_unit
* contract.contract_unit.project
* contract.contract_unit.project.property
e.g. `include=contract,contract.contractor,contract.contract_unit,contract.contract_unit.project,contract.contract_unit.project.property`
'
title: Include
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/InvoiceListResponse'
description: Successful Response
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
security:
- API Key: []
- API Token: []
summary: Get Invoices
tags:
- Invoice
/invoices/add-paid-invoice/:
post:
operationId: add_paid_invoice_invoices_add_paid_invoice__post
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AddPaidInvoiceRequest'
required: true
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/InvoiceResponse'
description: Successful Response
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
security:
- API Key: []
- API Token: []
summary: Add Paid Invoice
tags:
- Invoice
/invoices/{id}/:
delete:
operationId: delete_paid_invoice_invoices__id___delete
parameters:
- in: path
name: id
required: true
schema:
format: uuid
title: Id
type: string
responses:
'204':
description: Successful Response
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
security:
- API Key: []
- API Token: []
summary: Delete Paid Invoice
tags:
- Invoice
get:
operationId: get_invoice_details_invoices__id___get
parameters:
- in: path
name: id
required: true
schema:
format: uuid
title: Id
type: string
- description: '
You can get related objects by specifying them separated by comma as a GET `include` parameter.
In case of non-direct relation include parameter should be a relationship path - a dot-separated list of
relationship names.
Currently available objects are:
* contract
* contract.contractor
* contract.contract_unit
* contract.contract_unit.project
* contract.contract_unit.project.property
e.g. `include=contract,contract.contractor,contract.contract_unit,contract.contract_unit.project,contract.contract_unit.project.property`
'
in: query
name: include
required: false
schema:
anyOf:
- type: string
- type: 'null'
description: '
You can get related objects by specifying them separated by comma as a GET `include` parameter.
In case of non-direct relation include parameter should be a relationship path - a dot-separated list of
relationship names.
Currently available objects are:
* contract
* contract.contractor
* contract.contract_unit
* contract.contract_unit.project
* contract.contract_unit.project.property
e.g. `include=contract,contract.contractor,contract.contract_unit,contract.contract_unit.project,contract.contract_unit.project.property`
'
title: Include
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/InvoiceResponse'
description: Successful Response
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
security:
- API Key: []
- API Token: []
summary: Get Invoice Details
tags:
- Invoice
/invoices/{id}/register-payment/:
post:
operationId: register_payment_invoices__id__register_payment__post
parameters:
- in: path
name: id
required: true
schema:
format: uuid
title: Id
type: string
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/InvoicePayment'
required: true
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/InvoiceResponse'
description: Successful Response
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
security:
- API Key: []
- API Token: []
summary: Register Payment
tags:
- Invoice
/invoices/{id}/update-new/:
post:
description: 'This endpoint supports updating a selection of fields of invoices.
To avoid inconsistencies, this is only possible for invoices in status New.
Furthermore, when using two workflows steps for complete details, the invoice has to be in the first step (Optional Complete Details).'
operationId: update_new_invoices__id__update_new__post
parameters:
- in: path
name: id
required: true
schema:
format: uuid
title: Id
type: string
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateNewInvoiceDetailsRequest'
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/InvoiceResponse'
description: Successful Response
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
security:
- API Key: []
- API Token: []
summary: Update New
tags:
- Invoice
/invoices/{id}/update-paid-invoice/:
post:
operationId: update_paid_invoice_invoices__id__update_paid_invoice__post
parameters:
- in: path
name: id
required: true
schema:
format: uuid
title: Id
type: string
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UpdatePaidInvoiceRequest'
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/InvoiceResponse'
description: Successful Response
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
security:
- API Key: []
- API Token: []
summary: Update Paid Invoice
tags:
- Invoice
/projects/{id}/submit-invoice/:
post:
description: This endpoint supports submitting new invoices. Before using this endpoint, please reach out the the support team to make sure, everything is properly set up.
operationId: submit_invoice_projects__id__submit_invoice__post
parameters:
- in: path
name: id
required: true
schema:
format: uuid
title: Id
type: string
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/Body_submit_invoice_projects__id__submit_invoice__post'
required: true
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/InvoiceResponse'
description: Successful Response
'422':
content:
application/json:
schema:
$ref: '#/components/schemas/HTTPValidationError'
description: Validation Error
security:
- API Key: []
API Token: []
summary: Submit Invoice
tags:
- Invoice
components:
schemas:
UpdateContractRelationshipData:
properties:
data:
$ref: '#/components/schemas/UpdateContractRelationshipAttributes'
required:
- data
title: UpdateContractRelationshipData
type: object
Body_submit_invoice_projects__id__submit_invoice__post:
properties:
file:
contentMediaType: application/octet-stream
description: '
The file to submit. The file must be a valid PDF.
'
title: File
type: string
required:
- file
title: Body_submit_invoice_projects__id__submit_invoice__post
type: object
UpdateNewInvoiceDetailsData:
properties:
attributes:
anyOf:
- $ref: '#/components/schemas/UpdateNewInvoiceAttributes'
- type: 'null'
id:
format: uuid
title: Id
type: string
relationships:
anyOf:
- $ref: '#/components/schemas/UpdateInvoiceRelationships'
- type: 'null'
type:
default: INVOICE
title: Type
type: string
required:
- id
title: UpdateNewInvoiceDetailsData
type: object
InvoiceProcessState:
description: 'The invoice process state represents the state of the invoice in its workflow.
A `NEW` invoice has not been processed by any user.
An invoice in state `DETAILS_ENTERED` means that all the required details
have been entered.
After the formal verification step has been completed, the invoice is in state `FORMALLY_CHECKED`.
As soon as the first manual approval step has been completed, the invoice enters state `CHECKED`.
An invoice is `APPROVED` when all required approvals have been given.
Finally, when the payment for an invoice is registered, it enters state `PAID`.'
enum:
- NEW
- DETAILS_ENTERED
- CHECKED
- APPROVED
- PAID
title: InvoiceProcessState
type: string
InvoiceListResponse:
properties:
data:
items:
$ref: '#/components/schemas/InvoiceData'
title: Data
type: array
errors:
anyOf:
- items:
$ref: '#/components/schemas/Error'
type: array
- type: 'null'
title: Errors
included:
anyOf:
- items:
$ref: '#/components/schemas/BaseDataSchema'
type: array
- type: 'null'
title: Included
links:
anyOf:
- additionalProperties:
anyOf:
- type: string
- type: 'null'
type: object
- type: 'null'
description: '
Contains the pagination''s next link if results don''t fit on one page.
'
title: Links
required:
- data
title: InvoiceListResponse
type: object
UpdatePaidInvoiceData:
properties:
attributes:
anyOf:
- $ref: '#/components/schemas/PaidInvoiceAttributes'
- type: 'null'
id:
format: uuid
title: Id
type: string
relationships:
anyOf:
- $ref: '#/components/schemas/UpdateInvoiceRelationships'
- type: 'null'
type:
default: INVOICE
title: Type
type: string
required:
- id
title: UpdatePaidInvoiceData
type: object
AddPaidInvoiceRelationships:
properties:
contract:
$ref: '#/components/schemas/UpdateContractRelationshipData'
description: '**Contract ID** · **Auftrags-ID**'
required:
- contract
title: AddPaidInvoiceRelationships
type: object
InvoiceAttributes:
properties:
audited_amount:
anyOf:
- properties:
currency:
description: '**Currency code** · **Währungscode**'
example: EUR
title: Currency code
type: string
net:
description: '**Net amount** · **Nettobetrag**'
example: '123.123456789012'
title: Net amount
type: string
tax:
description: '**Tax amount** · **Steuerbetrag**'
example: '123.123456789012'
title: Tax amount
type: string
type: object
- type: 'null'
description: '**Audited amount** · **Geprüfter Rechnungsbetrag**'
title: Audited Amount
cash_discount:
anyOf:
- properties:
currency:
description: '**Currency code** · **Währungscode**'
example: EUR
title: Currency code
type: string
net:
description: '**Net amount** · **Nettobetrag**'
example: '123.123456789012'
title: Net amount
type: string
tax:
description: '**Tax amount** · **Steuerbetrag**'
example: '123.123456789012'
title: Tax amount
type: string
type: object
- type: 'null'
description: '**Cash discount** · **Skonto**'
title: Cash Discount
contract:
anyOf:
- format: uuid
type: string
- type: 'null'
description: '**Contract ID** · **Auftrags-ID**'
title: Contract
date_approved:
anyOf:
- format: date-time
type: string
- type: 'null'
description: '**Date approved** · **Freigabedatum**'
title: Date Approved
date_created:
description: '**Date created** · **Datum hinzugefügt**'
format: date-time
title: Date Created
type: string
date_discount:
anyOf:
- format: date
type: string
- type: 'null'
description: '**Cash discount date** · **Skontofrist**'
title: Date Discount
date_due:
anyOf:
- format: date
type: string
- type: 'null'
description: '**Due date** · **Fälligkeitsdatum**'
title: Date Due
date_posted:
anyOf:
- format: date
type: string
- type: 'null'
description: '**Posting date** · **Rechnungsdatum**'
title: Date Posted
date_received:
anyOf:
- format: date
type: string
- type: 'null'
description: '**Date received** · **Eingangsdatum**'
title: Date Received
discounted_approved_amount:
anyOf:
- properties:
currency:
description: '**Currency code** · **Währungscode**'
example: EUR
title: Currency code
type: string
net:
description: '**Net amount** · **Nettobetrag**'
example: '123.123456789012'
title: Net amount
type: string
tax:
description: '**Tax amount** · **Steuerbetrag**'
example: '123.123456789012'
title: Tax amount
type: string
type: object
- type: 'null'
description: '**Approved amount after cash discount** · **Freigegebener Betrag nach Skonto**'
title: Discounted Approved Amount
external_identifier:
anyOf:
- type: string
- type: 'null'
description: '**Invoice number (external)** · **Rechnungsnummer (extern)**'
title: External Identifier
installment_number:
anyOf:
- type: integer
- type: 'null'
description: '**Installment number** · **Abschlagsrechnungsnummer**
Consecutive number of the installment when the invoice type is `INSTALLMENT`.
Fortlaufende Nummer der Abschlagsrechnung, wenn der Rechnungstyp `INSTALLMENT` ist.'
examples:
- 1
title: Installment Number
internal_identifier:
anyOf:
- type: string
- type: 'null'
description: '**Invoice number (internal)** · **Rechnungsnummer (intern)**'
title: Internal Identifier
invoice_process_state:
$ref: '#/components/schemas/InvoiceProcessState'
description: '**Invoice status** · **Rechnungsstatus**
Available values / Verfügbare Werte:
| Value | English | Deutsch |
| --- | --- | --- |
| `NEW` | New | Neu |
| `DETAILS_ENTERED` | Details entered | Erfasst |
| `CHECKED` | Checked | Geprüft |
| `APPROVED` | Approved | Freigegeben |
| `PAID` | Paid | Bezahlt |'
examples:
- NEW
invoice_type:
anyOf:
- $ref: '#/components/schemas/InvoiceType'
- type: 'null'
description: '**Invoice type** · **Rechnungs-Typ**
Available values / Verfügbare Werte:
| Value | English | Deutsch |
| --- | --- | --- |
| `SINGLE` | Single | Einzelrechnung |
| `ADVANCE` | Advance | Vorauszahlung |
| `INSTALLMENT` | Installment | Abschlagsrechnung |
| `PARTIAL_FINAL` | Partial final | Teilschlussrechnung |
| `FINAL` | Final | Schlussrechnung |
| `RETAINAGE_PAYOUT` | Retention release | Auszahlung Einbehalt |
| `RECURRING` | Recurring | Dauerrechnung |'
examples:
- SINGLE
is_reverse_charge:
description: '**Is reverse charge?** · **Reverse Charge?**'
title: Is Reverse Charge
type: boolean
payment_amount_gross:
anyOf:
- properties:
amount:
description: '**Amount** · **Betrag**'
example: '123.123456789012'
title: Amount
type: string
currency:
description: '**Currency code** · **Währungscode**'
example: EUR
title: Currency code
type: string
type: object
- type: 'null'
description: '**Paid amount (gross)** · **Ausgezahlter Betrag (brutto)**'
title: Payment Amount Gross
payment_comment:
anyOf:
- type: string
- type: 'null'
description: '**Payment comment** · **Zahlungskommentar**'
title: Payment Comment
payment_created:
anyOf:
- format: date-time
type: string
- type: 'null'
description: '**Payment information created** · **Erstellungsdatum Zahlungsinformation**'
title: Payment Created
payment_date:
anyOf:
- format: date
type: string
- type: 'null'
description: '**Payment date** · **Zahlungsdatum**'
title: Payment Date
unaudited_amount:
anyOf:
- properties:
currency:
description: '**Currency code** · **Währungscode**'
example: EUR
title: Currency code
type: string
net:
description: '**Net amount** · **Nettobetrag**'
example: '123.123456789012'
title: Net amount
type: string
# --- truncated at 32 KB (49 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/alasco/refs/heads/main/openapi/alasco-invoice-api-openapi.yml