fepli
Use cases

Upgrading from the offers API

Earlier versions of the fepli API knew one resource, offers. The API now covers the whole admin, and the offers endpoint was rebuilt along the way. If you used it before, this page lists what to change.

Checklist

  1. Use the endpoint shown under Einstellungen → Integrationen → API as your base URL (see the Quickstart).
  2. Store offers by uuid, not by the numeric id, and fetch single offers with /offers/{uuid}.
  3. Rename your filters (see below).
  4. Read status as a list, and edition and hosts as references.
  5. Treat missing fields as null.
  6. Page by page and itemsPerPage until a page is short; don't rely on a Link header.
  7. If you use a personal token, it keeps working for offers. Create a new token (ideally for a service account) to use anything else.

Base URL

The API answers under /api on the administration's host, or at the root of the municipality's own API domain if it has one. The exact address is shown under Einstellungen → Integrationen → API → Endpunkt. The paths in this documentation are relative to it: GET /offers means GET https://ferienpass-musterstadt.de/api/offers.

Identifiers

Offers are identified by a UUID, returned to every caller as uuid. The numeric id is gone, and so is /api/offers/{id}:

BeforeNow
GET /api/offers/42GET /offers/0192a4f1-6e3b-7c85-b1d2-8f4e6a9c3b03
id (authenticated callers only)uuid (everyone)

If you stored numeric IDs, match your records once by alias or url, then switch to uuid.

Fields

FieldBeforeNow
statusan object of place → timestamp, authenticated onlya list of places, e.g. ["published"], for everyone
editionan object with name, authenticated onlya reference with uuid, name, alias, for everyone
hostsobjects with namereferences with uuid, name, alias
publishpublic or private_link, for everyonepublic or private_link, authenticated only
createdAt, modifiedAtauthenticated onlyeveryone
minParticipants, maxParticipantsauthenticated onlyeveryone
dates[]begin, endalso uuid and, for recurring dates, recurrence
newteaser, vacancies, fullyBooked, categories for everyone; comment, contact, attendances, applicationQuestions, transitions and more with a token

Fields without a value are now left out instead of being returned as null. "applyText": null becomes no applyText key at all.

Filters

The filters were simplified. Editions and organisers are named by UUID or alias in a single parameter:

BeforeNow
edition.id, edition.alias, edition.nameedition (UUID or alias)
hosts.alias, hosts.namehost (UUID or alias)
dates.begin[after]from
dates.begin[before]until
dates.begin[strictly_after], dates.begin[strictly_before]from, until (both include the given day)
fee[lte], fee[gte], fee[lt], fee[gt], fee[between]removed. Filter by fee on your side.
meetingPointremoved. Use q to search the name, or filter on your side.
new: q, status, category, modifiedSince, sort, order

See List all offers for every filter.

Pagination

page works as before, and itemsPerPage now actually changes the page size, up to 200. The response is a plain JSON array. The earlier documentation described a Link header with first, next and last; the API doesn't send one. Keep requesting pages until one holds fewer records than you asked for. See Pagination.

Tokens and rate limits

  • Personal tokens created before the change carry the scope api:offer:read. They still work for GET /offers and GET /offers/{uuid}, and nothing else.
  • New tokens are read-only or read-write, and can belong to a service account instead of a person.
  • With a token, the rate limit rose from 50 requests per hour to a burst of 300, refilled at 100 per minute. Anonymous requests stay at 5 per hour per IP address. See Rate limits.

Errors

Errors are still problem details, with type, title, status and detail. The type is now a short path such as /errors/404 instead of a link to the HTTP specification. The detail messages are more specific, for example No offer with this identifier, or none you may see.

Was this page helpful?