Losys Customer API (1.0.0)

Download OpenAPI specification:

The Losys Customer API lets you read your company's construction project references (photos, location, description, services rendered) and generate PDF documents from them — directly from your own website or backend.

A runnable, public reference implementation is available in the losys-demo repository. When in doubt about a concrete request, that demo is the canonical example.

Base URL

All endpoints are relative to a single fixed base URL that already includes the /api/customer path prefix:

https://api.referenz-verwaltung.ch/api/customer/

So the project list, for example, is GET https://api.referenz-verwaltung.ch/api/customer/project. The same base URL is shown under Servers above and is used for the interactive examples.

Authentication

The Customer API uses OAuth 2.0 with the client_credentials grant. You receive a client_id and a client_secret from Losys. Each client is bound to exactly one company — that company is pinned into the issued token. As a result, none of the endpoints below take a company id in the path: every call automatically operates within your company's scope.

If you are new to OAuth 2.0, these are good starting points:

Obtain an access token:

POST /oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
&client_id=<your-client-id>
&client_secret=<your-client-secret>

The response contains an access_token. Send it as a Bearer token with every request:

Authorization: Bearer <access_token>
Accept: application/json
Accept-Language: en

Localization

Almost all responses can be localized via the Accept-Language request header. Supported languages: de, fr, it, en.

Compression (Accept-Encoding)

The API can return gzip-compressed responses. Send

Accept-Encoding: gzip

and responses that are large enough to benefit (currently from ~4 KB of payload) are returned compressed, indicated by a Content-Encoding: gzip response header (smaller responses are sent uncompressed). Any standard HTTP client handles the decompression transparently. Using compression is recommended for the (potentially large) project list responses.

Pagination

List endpoints are paginated via limit and start (offset). When paging through a result set you must send exactly the same filter parameters on every request (only start and limit may change) — otherwise the results are inconsistent. To enforce this, every response returns an X-Paginator-Hash header; send it back on the next request and the API verifies your filter parameters did not change. This is strongly recommended.

Pagination response headers

Every paginated response carries a set of X-Paginator-* headers describing the current page and the full result set:

Header Meaning
X-Paginator-Start Offset of the first returned record (echoes your start).
X-Paginator-Limit Page size in effect (echoes your limit).
X-Paginator-Count Number of records actually returned in this response.
X-Paginator-Total Total number of records matching your filter across all pages.
X-Paginator-Has-Previous-Page 1 if a previous page exists, otherwise 0.
X-Paginator-Has-Next-Page 1 if a next page exists, otherwise 0.
X-Paginator-Hash Filter fingerprint — send it back as a request header on the next page (see above and below).

Caching & the X-Paginator-Hash header

Project lists are served through a cache. This has two practical consequences when paging:

  1. The first page may take a moment longer when its cache is still cold — the result has to be computed (and, in the background, the following pages are pre-warmed).

  2. Subsequent pages are then served much faster from the warm cache — but only if you send the X-Paginator-Hash header you received with the previous page back on the next request. The hash both guards filter consistency and lets the API hit the pre-warmed cache entry for the next page. Omitting it forfeits the speed-up.

    So the recommended loop is: read X-Paginator-Hash from each response and send it back (unchanged) on the request for the next page, changing only start (and keeping all filter parameters identical).

Support

Every response carries an X-Request-Id header. Please include it when contacting support about a specific request.

Projects

Read project references.

These are the very same projects you can browse and edit interactively in the web GUI under https://referenz-verwaltung.ch/company/<your-company-id>/dashboard.

Two rules govern which projects the API returns:

  • Only "API-visible" projects are returned. A project is included only if the "Show this project on website" option ("Dieses Projekt in Webseite anzeigen") is enabled in the project editor of the web GUI. Projects with that option turned off are never returned.
  • Company groups return the whole group. If your company is a member of a company group, the Projects endpoints return the projects of all companies in that group, not only your own company's.

List projects

Returns a paginated list of your company's project references. Use the query parameters to filter, sort and page the result, and expand to include related entities.

Only "API-visible" projects are returned, and — for companies that belong to a company group — projects of all companies in the group (see the Projects section intro above).

Discovering valid filter values: the concrete values you may pass to the filter parameters (type-of-work / type-of-building / type-of-construction ids, category ids, cantons, languages, years, project-attribute ids …) can be retrieved from the Available filter values endpoint (GET /project/filter_multiple_choice_values). That endpoint only ever returns values that actually occur in projects you have access to, so it is the canonical source for populating a filter UI.

Authorizations:
customerOAuth
query Parameters
projectId
integer

Restrict to a single project id.

projectIds
Array of integers <= 4000 items

Restrict to these project ids.

companyId
integer

Restrict to a single company id (subject to access checks).

companyIds
Array of integers <= 400 items

Restrict to these company ids (subject to access checks).

groupId
integer

Restrict to projects of the member companies of a single group.

groupIds
Array of integers <= 100 items

Restrict to projects of the member companies of these groups.

yearFrom
integer

Earliest year of completion (inclusive).

yearTo
integer

Latest year of completion (inclusive).

language
string

Single language short name, e.g. de, fr, it, en.

A language can only be used to retrieve projects if your company has actually configured that language — projects only exist in the languages the company maintains. The languages available to you are listed under languages in the Available filter values response.

languages
Array of strings <= 10 items

Language short names, e.g. de, fr, it, en.

Only languages your company has configured can be requested (see the single language parameter and the languages list returned by Available filter values).

categoryId
integer

Restrict to a single category id.

categoryIds
Array of integers <= 400 items
canton
string

Single Swiss canton short name, e.g. zh, be.

cantons
Array of strings <= 75 items

Swiss canton short names, e.g. zh, be.

typeOfWorkId
integer

Restrict to a single "type of work" id.

typeOfWorkIds
Array of integers <= 400 items

Restrict to these "type of work" ids.

typeOfConstructionId
integer

Restrict to a single "type of construction" id.

typeOfConstructionIds
Array of integers <= 400 items

Restrict to these "type of construction" ids.

typeOfBuildingId
integer

Restrict to a single "type of building" id.

typeOfBuildingIds
Array of integers <= 400 items

Restrict to these "type of building" ids.

withImage
boolean

Only projects that have at least one image.

searchText
string <= 400 characters

Full-text search phrase. Multiple words are combined per concatenation.

searchTextIn
Array of strings <= 4 items
Items Enum: "project" "companies" "typeOfWork"

Where to search. Defaults to all of them when omitted.

Ignored when concatenation=fuzzy: the fuzzy (trigram) search has a fixed set of fields it matches against (project title, location, …) and does not honour searchTextIn.

concatenation
string
Default: "and"
Enum: "and" "or" "fuzzy"

How multiple search words are combined. and (default) and or are exact matches; fuzzy performs an approximate (trigram) match that also finds slight misspellings.

orderBy
Array of strings <= 25 items [ items^!?(yearOfCompletion|hasImage|id|zipcode|city... ]

Sort criteria, applied in order. Allowed values: yearOfCompletion, hasImage, id, zipcode, city, priority, canton, random, relevance. Prefix any value with ! to sort descending (e.g. !yearOfCompletion).

relevance is meant for fuzzy search: when concatenation=fuzzy, pass orderBy=relevance to sort the results by how well they match the search phrase (best matches first). In fact, for a fuzzy search with a searchText and no explicit orderBy, relevance is applied automatically. Outside of a fuzzy search relevance has no effect.

status
string
Enum: "1" "0" "true" "false" "on" "off" "active" "inactive" "null"

Filters projects by their visibility flag. By default the API already restricts results to API-visible projects (see the Projects section intro); status lets you query that flag explicitly.

Accepted values (a wide range of truthy/falsy spellings is supported):

Value Meaning
1, true, on, active only visible projects
0, false, off, inactive only non-visible projects
null or omitted do not filter on visibility

Examples: status=1 (visible only), status=0 (hidden only).

Array of objects (AttributeFilter)

Advanced filter on project attributes (the configurable project properties / custom fields a company defines). Each entry of the array selects one or more attributes — by numeric id or by name — and constrains the value the project must have for them. The available attribute ids and names are listed under attribute / attributeByName in the Available filter values response.

The value of an entry expresses the constraint. Common shapes:

Constraint value example Matches when …
equals (one of) [1] or [1, 2] attribute equals one of the given option ids
range { "from": 4000, "to": 5000 } numeric value lies in [from, to]
text contains { "contains": ["text"] } text value contains the phrase
assigned { "assigned": true } the attribute is set on the project at all
negation { "not": { "assigned": true } } wraps any of the above to invert it

Example — projects whose attribute named Realisierungszeitraum falls between 2018 and 2020:

attributes[0][name][]=Realisierungszeitraum
attributes[0][value][from]=2018
attributes[0][value][to]=2020

See filtered_listing.php in losys-demo for more worked examples.

limit
integer [ 0 .. 501 ]

Maximum number of projects to return. Keep constant while paging. The server caps this at 501; values above are clamped.

start
integer [ 0 .. 5000 ]

Offset of the first project to return (for pagination).

expand
Array of strings
Items Enum: "project_images" "project_videos" "parent" "children" "project_properties" "project_categories" "project_type_of_works" "project_type_of_constructions" "project_type_of_buildings" "project_address_contact_persons" "project_participating_companies" "company" "language" "*"

Related entities to include in the response. For every expand value you pass, the corresponding sub-entity is embedded — under a key of the same name — inside each project of the response. Pass several values comma-separated or repeated, or * to include all available expands.

Without expand a project only carries its own base fields; the relations below are added on demand. The concrete shape of each embedded sub-entity is best seen in the public reference implementation php-basic/public/json_listing.php in losys-demo.

Expand value Adds …
project_images the project's images (with their source-image data and URLs).
project_videos the project's (YouTube) videos.
parent the parent project — for a translation, the project it is a translation of.
children the child projects — translations of this project into other languages.
project_properties the project's attribute values (the configurable custom fields), each with its attribute definition.
project_categories the categories assigned to the project (localized).
project_type_of_works the "type of work" entries assigned to the project (localized).
project_type_of_constructions the "type of construction" entries assigned to the project (localized).
project_type_of_buildings the "type of building" entries assigned to the project (localized).
project_address_contact_persons the contact persons attached to the project's address.
project_participating_companies the other companies that participated in the project.
company the owning company's data.
language the project's language.
header Parameters
Accept-Language
string
Enum: "de" "fr" "it" "en"

Language to localize the response into. One of de, fr, it, en.

X-Paginator-Hash
string

Send back the X-Paginator-Hash value from the previous page's response to let the API verify that your filter parameters did not change between pages. Strongly recommended when paging.

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Get a single project

Authorizations:
customerOAuth
path Parameters
projectId
required
integer

Numeric id of the project.

query Parameters
expand
Array of strings
Items Enum: "project_images" "project_videos" "parent" "children" "project_properties" "project_categories" "project_type_of_works" "project_type_of_constructions" "project_type_of_buildings" "project_address_contact_persons" "project_participating_companies" "company" "language" "*"

Related entities to include in the response. For every expand value you pass, the corresponding sub-entity is embedded — under a key of the same name — inside each project of the response. Pass several values comma-separated or repeated, or * to include all available expands.

Without expand a project only carries its own base fields; the relations below are added on demand. The concrete shape of each embedded sub-entity is best seen in the public reference implementation php-basic/public/json_listing.php in losys-demo.

Expand value Adds …
project_images the project's images (with their source-image data and URLs).
project_videos the project's (YouTube) videos.
parent the parent project — for a translation, the project it is a translation of.
children the child projects — translations of this project into other languages.
project_properties the project's attribute values (the configurable custom fields), each with its attribute definition.
project_categories the categories assigned to the project (localized).
project_type_of_works the "type of work" entries assigned to the project (localized).
project_type_of_constructions the "type of construction" entries assigned to the project (localized).
project_type_of_buildings the "type of building" entries assigned to the project (localized).
project_address_contact_persons the contact persons attached to the project's address.
project_participating_companies the other companies that participated in the project.
company the owning company's data.
language the project's language.

Responses

Response samples

Content type
application/json
{
  • "id": 0,
  • "title": "string",
  • "description": "string",
  • "yearOfCompletion": 0,
  • "address": "string",
  • "zipcode": "string",
  • "city": "string",
  • "canton": "string",
  • "country": "string",
  • "geolocationX": "string",
  • "geolocationY": "string",
  • "projectWebsite": "string",
  • "priority": 0,
  • "companyId": 0,
  • "languageId": 0,
  • "parentId": 0,
  • "status": "0",
  • "visibility": [
    ],
  • "project_images": [
    ],
  • "project_videos": [
    ],
  • "parent": { },
  • "children": [
    ],
  • "project_properties": [
    ],
  • "project_categories": [
    ],
  • "project_type_of_works": [
    ],
  • "project_type_of_constructions": [
    ],
  • "project_type_of_buildings": [
    ],
  • "project_address_contact_persons": [
    ],
  • "project_participating_companies": [
    ],
  • "company": { },
  • "language": { }
}

Filters

Discover available filter values. The returned values are not the full set of values defined in the system — only those actually used by projects the caller has access to are returned.

Available filter values

Returns the values you can offer in a filter UI (type of work, type of building, type of construction, categories, cantons, languages, years, project attributes …), already localized. Optionally pass the same filters as on /project/ to restrict the returned options.

Only values actually in use are returned. The endpoint does not list every value defined in the system — it returns only those values that are actually used by projects the caller has access to. A type of work, category, canton, language, etc. that no accessible project uses will not appear here. This keeps the filter UI free of options that would yield no results.

Authorizations:
customerOAuth
query Parameters
displayLocale
string

Language to localize the returned values into (e.g. en).

Responses

Response samples

Content type
application/json
{
  • "languages": [
    ],
  • "canton": [
    ],
  • "category": [
    ],
  • "quickFilter": [
    ],
  • "typeOfWork": {
    },
  • "typeOfBuilding": {
    },
  • "typeOfConstruction": {
    },
  • "attribute": [
    ],
  • "attributeByName": {
    },
  • "year": {
    }
}

PDF

Generate PDF documents from project references (asynchronous).

Start PDF generation

Starts an asynchronous PDF generation job for the projects matching the given filters. Returns a job_uuid you can poll for completion via /project/pdf/{jobUuid}/status.

Filter parameters are passed with a filter_ prefix (e.g. filter_companyIds[]=1, filter_yearFrom=2020) and mirror the parameters of /project/.

Authorizations:
customerOAuth
query Parameters
printlayout
string

PDF template id, or one of datasheet / datalist (default).

mode
string
Default: "extern"
Enum: "extern" "intern"

Which data variant to render:

  • extern (default) — the external datasheet, i.e. the public-facing content, exactly as it is shown on a website.
  • intern — the internal datasheet, which may include additional internal fields.
orientation
string
Enum: "portrait" "landscape"

Page orientation. Defaults depend on the chosen layout/template.

format
string
Enum: "a4" "a3"

Paper format of the generated PDF. When omitted, the format from the chosen layout/template is used (a4 by default).

quality
string
Default: "regular"
Enum: "regular" "low"

Image rendering quality of the generated PDF:

  • regular (default) — full quality.
  • low — lower image resolution, producing a smaller file (useful for large project lists or faster downloads).
displayLocale
string

Language to render the PDF content in (e.g. de, fr, it, en). When omitted, the request's Accept-Language / default locale is used.

companycover
integer

Company id to render a cover sheet for.

usercover
integer

Employee id to render on the cover sheet.

secondusercover
integer

Optional second employee id to render on the cover sheet.

Responses

Response samples

Content type
application/json
{
  • "job_uuid": "de25c4df-6d4e-439f-9d5f-a4c55d30f26e",
  • "message": "string"
}

Poll PDF generation status

Authorizations:
customerOAuth
path Parameters
jobUuid
required
string <uuid>

The job_uuid returned when starting the job.

Responses

Response samples

Content type
application/json
{
  • "pdf_url": "string",
  • "message": "string"
}

List PDF templates

Authorizations:
customerOAuth

Responses

Response samples

Content type
application/json
[
  • {
    }
]

List PDF templates for a specific company

Authorizations:
customerOAuth
path Parameters
companyId
required
integer

Responses

Response samples

Content type
application/json
[
  • {
    }
]

HTML

Ready-to-embed HTML widgets.

Embeddable project box (HTML)

Returns a ready-to-embed, interactive HTML widget (with built-in search, map and PDF controls). Requires Accept: text/html.

Authorizations:
customerOAuth
query Parameters
hide
Array of strings
Items Enum: "search" "map" "pdf"

UI components to hide.

skip_includes
Array of strings
Items Enum: "jquery" "bootstrap" "popper" "select2" "polyfill"

External libraries the widget should not load itself.

Responses

Response samples

Content type
application/json
{
  • "type": "string",
  • "code": 0,
  • "message": "string",
  • "field_errors": {
    }
}