Developers

Events API for your website

Embed your ensemble's public events on any website — with a simple HTTP request, no account and no API key required.

The essentials

  • Publicly accessible, no authentication required.
  • CORS is enabled, the endpoint works directly from the browser.
  • Responses are cached for 5 minutes, rate limit 60 requests per minute.
  • Only data you have enabled for public display in your website settings is returned.
  • For public use, a 'Powered by Chorilo' notice with a link to our website is required.

Powered by Chorilo — Attribution on your site

If you use the API on a public page, please add a visible 'Powered by Chorilo' notice with a link to https://www.chorilo.com. A discreet line in the footer is perfectly enough.

It's a fair trade: you embed your events automatically into other systems and don't have to maintain them twice. Each API request also puts load on our servers and costs infrastructure — the more traffic your page gets, the more resources it consumes on our side. In return, the small attribution gives Chorilo a bit of visibility that helps us reach new choirs.

HTML
<a href="https://www.chorilo.com" target="_blank" rel="noopener">
  Powered by Chorilo
</a>

Endpoint

A single GET endpoint returns your ensemble's upcoming events. Replace with the URL slug of your public Chorilo website.

Where do I find my slug?

Open your public website settings in the Chorilo backend. The slug is the unique part of the URL, for example 'my-choir' in https://chorilo.com/w/my-choir.

GET
https://backend.chorilo.com/api/public-websites/{slug}/embed-events

Controlling visibility

The API respects your public website's visibility settings. Anything hidden on the website is also blocked by the API — even when explicitly requested.

Master toggle: If show_events is disabled, the API returns an empty list.

Event types: Only enabled types are returned. A request for disabled types (for example types[]=concert while the concert toggle is off) is silently filtered out.

SettingAffects type
show_eventsMaster toggle (disables everything)
show_rehearsalsrehearsal
show_concertsconcert
show_other_eventsevent
show_event_descriptionsControls the description field in the response

Query parameters

All parameters are optional. Without parameters the endpoint returns the next events according to your website's default settings.

NameTypeDefaultDescription
limitinteger5Number of events returned. Minimum 1, maximum 100.
fromISO 8601nowStart of the date range. Past events are not returned by default.
toISO 8601End of the date range.
types[]arrayall allowedOne or more of: rehearsal, concert, event. Disabled types are silently filtered.
langstring (2)Two-letter language code (de, en, fr, nl, es, sv, it, sl). Currently echoed back in the response meta.

Rate limit & caching

The endpoint is limited to 60 requests per minute per IP address. If the limit is exceeded, the server responds with HTTP 429.

Responses are cached server-side for 5 minutes (per parameter combination). New events may therefore appear with a short delay.

Rate limit

60 / min

per IP address

Server cache

5 min

per parameter combination

Response format

The response is a JSON object. Each event only contains public fields — internal descriptions, participant data and other sensitive information are never returned.

  • events[] — List of events with id, title, type, location, start_time, end_time, has_ticket_sale, optionally ticket_sale_url (when ticket sales are active) and optionally description.
  • ensemble_name — Display name of your ensemble.
  • theme_color — Hex color code from website settings.
  • language — Language code of your website.

The description field only ever contains the public description. An event's internal description is never part of the response.

JSON
{
  "events": [
    {
      "id": 42,
      "title": "Sommerkonzert",
      "type": "concert",
      "location": "Stadthalle Musterstadt",
      "start_time": "2026-06-14T19:30:00+02:00",
      "end_time": "2026-06-14T21:30:00+02:00",
      "description": "Annual summer concert in the garden of the community hall.",
      "has_ticket_sale": true,
      "ticket_sale_url": "https://www.chorilo.com/shop/tickets/42"
    }
  ],
  "ensemble_name": "Musterchor",
  "theme_color": "#6366f1",
  "language": "de"
}

Examples

How to call the API from different languages. The example loads up to 10 upcoming concerts and other events.

curl "https://backend.chorilo.com/api/public-websites/mein-chor/embed-events?limit=10&types[]=concert&types[]=event"

Status codes

CodeMeaning
200Success, events in the events array.
404No website found with this slug.
422Invalid query parameters (for example unknown type or to before from).
429Rate limit exceeded, try again in a minute.

All public endpoints

These are the read-only public endpoints currently exposed. No authentication required. JSON responses only.

MethodPathDescriptionLimit
GET/api/tickets/eventsList public concert events90/min
GET/api/tickets/events/{eventId}Single event detail90/min
GET/api/public-websites/{slug}Public ensemble website by slug90/min
GET/api/public-websites/{slug}/embed-eventsEmbeddable concert calendar60/min
GET/api/choir-associations/publicPublic association directory90/min

Rate-limit response headers

Every /api/* response carries rate-limit headers. They are exposed via Access-Control-Expose-Headers for cross-origin agents.

  • X-RateLimit-Limit — per-window quota
  • X-RateLimit-Remaining — remaining requests
  • Retry-After — seconds to wait (HTTP 429 only)

JSON error format (RFC 9457)

All /api/* errors return application/problem+json regardless of Accept header.

{
  "type":     "https://www.chorilo.com/api/errors/not-found",
  "title":    "Resource not found",
  "status":   404,
  "detail":   "...",
  "instance": "/api/tickets/events/99999999"
}

Validation errors (422) include an errors object mapping fields to messages.

Questions?

For technical questions about the API please contact: support@chorilo.com