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.
<a href="https://www.chorilo.com" target="_blank" rel="noopener">
Powered by Chorilo
</a>Preview
Powered by ChoriloEndpoint
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.
https://backend.chorilo.com/api/public-websites/{slug}/embed-eventsControlling 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.
| Setting | Affects type |
|---|---|
| show_events | Master toggle (disables everything) |
| show_rehearsals | rehearsal |
| show_concerts | concert |
| show_other_events | event |
| show_event_descriptions | Controls 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.
| Name | Type | Default | Description |
|---|---|---|---|
| limit | integer | 5 | Number of events returned. Minimum 1, maximum 100. |
| from | ISO 8601 | now | Start of the date range. Past events are not returned by default. |
| to | ISO 8601 | — | End of the date range. |
| types[] | array | all allowed | One or more of: rehearsal, concert, event. Disabled types are silently filtered. |
| lang | string (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.
{
"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
| Code | Meaning |
|---|---|
| 200 | Success, events in the events array. |
| 404 | No website found with this slug. |
| 422 | Invalid query parameters (for example unknown type or to before from). |
| 429 | Rate 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.
| Method | Path | Description | Limit |
|---|---|---|---|
| GET | /api/tickets/events | List public concert events | 90/min |
| GET | /api/tickets/events/{eventId} | Single event detail | 90/min |
| GET | /api/public-websites/{slug} | Public ensemble website by slug | 90/min |
| GET | /api/public-websites/{slug}/embed-events | Embeddable concert calendar | 60/min |
| GET | /api/choir-associations/public | Public association directory | 90/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 quotaX-RateLimit-Remaining— remaining requestsRetry-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