Making requests

How to target an organization, choose a format, read identifiers and dates, and get content in the right language.

Target an organization

Loupe hosts many libraries. Most requests say which one they are about, in one of three ways depending on the endpoint.

Collections take an organization.slug (or organization.id) query parameter. Without it, the API answers 400 Missing organization filter.

Shell
curl "https://api.loupe.ch/api/public/cms-events?organization.slug=riveville"

Single items are fetched by slug with the /item endpoint of the collection:

Shell
curl "https://api.loupe.ch/api/public/cms-events/item?organization.slug=riveville&slug=story-time"

Some endpoints take the organization in the path or in the request body instead, for example /api/public/organizations/{slug} or the organization field of a catalogue search. Each guide shows the exact form.

When a manager endpoint takes no organization parameter, it works on the organization of the key's owner.

Choose a format

The API speaks JSON in two flavours, selected with the Accept header:

AcceptResponse
application/ld+jsonJSON-LD: objects carry @id and @type, and collections are wrapped with member, totalItems and pagination links in view
application/jsonPlain JSON: objects only, and collections are plain arrays

Use JSON-LD when you need totals and pagination links; use plain JSON when you just want the data. Send bodies as application/json. For PATCH, use application/merge-patch+json: only the fields you send are changed.

A JSON-LD collection looks like this:

JSON
{  "@context": "/api/contexts/CmsEvent",  "@id": "/api/public/cms-events",  "@type": "Collection",  "totalItems": 124,  "member": [    { "@id": "/api/public/cms-events/0199…", "@type": "CmsEvent", "id": "0199…", "title": "Story time" }  ],  "view": {    "@id": "/api/public/cms-events?organization.slug=riveville&page=1",    "next": "/api/public/cms-events?organization.slug=riveville&page=2"  }}

Identifiers

Resources are identified by UUIDs (id). In JSON-LD, related resources may appear as IRIs, the path of the resource, such as /api/files/0199…. Slugs are stable, human-readable identifiers you can use in URLs; they are unique within an organization.

Fields with no value are returned as null rather than omitted, so your code can rely on the shape of an object.

Dates and times

Timestamps such as createdAt are ISO 8601 with a time zone offset. A few fields use simpler, local formats because they describe the library's calendar rather than an instant:

FieldFormatExample
Most timestampsISO 86012026-10-12T09:30:00+02:00
Event startAt, endAtY-m-d H:i2026-10-17 14:00
Reservation startAt, endAtY-m-d H:i:s2026-10-17 14:00:00
publishedAtY-m-d2026-10-01

Local times are in the library's time zone.

Languages

Content that a library translates (titles, descriptions, pages) comes back in one language per request. Choose it with the locale query parameter, using a two-letter code:

Shell
curl "https://api.loupe.ch/api/public/cms-events?organization.slug=riveville&locale=de"

Without locale, you get the organization's default language. A language the organization does not publish falls back to that default, and an unknown code returns 400. The response tells you which language you received in its Content-Language header. The Accept-Language header is not used.

Conditional requests

Map definitions carry an ETag. Send it back in If-None-Match and the API answers 304 Not Modified when nothing changed, which saves you from downloading a large document again.