Upsert an event by external id (partial)
Changed onUpserts the event carrying the (extKey, extId) pair. When it already exists, only the fields present in the body (an EventPatch) are changed - the rest is left untouched (200). If no event carries the pair it is created (201 + a Location header pointing at its canonical by-uid URL), in which case the full server-side requirements apply, so the body must be complete enough to create a valid event (else 422). The path pair is added to the event's extIds, keeping the mappings from other systems; any extIds in the body are ignored.
The acting member must be allowed to create or edit the event, otherwise 403.
Request
- Base URL: https://api.openagenda.com/v3
- URL: https://api.openagenda.com/v3/agendas/{agendaUid}/events/ext/{extKey}/{extId}
- Auth: one of:
- HTTP bearer
- OAuth 2 (authorization code, authorization URL https://openagenda.com/api/auth/oauth2/authorize, token URL https://openagenda.com/api/auth/oauth2/token, scopes: events:write)
Path parameters
Numeric uid of the agenda.
Name of the external system/source the identifier belongs to (the key of an ExtId mapping carried on the resource — an event or a location).
The resource's identifier within that external system (the value of an ExtId mapping carried in the resource's extIds). Percent-encode reserved characters.
Request body
Example request
{
"title": {
"fr": "Concert de jazz",
"en": "Jazz concert"
},
"description": {
"fr": "Concert de jazz",
"en": "Jazz concert"
},
"longDescription": {
"fr": "Concert de jazz",
"en": "Jazz concert"
},
"conditions": {
"fr": "Concert de jazz",
"en": "Jazz concert"
}
}Response
The existing event was updated.
Example response
{
"uid": 9876543,
"slug": "concert-de-jazz-au-parc",
"title": {
"fr": "Concert de jazz au parc",
"en": "Jazz concert in the park"
},
"description": {
"fr": "Une soirée jazz en plein air.",
"en": "An open-air jazz evening."
},
"status": 1,
"dateRange": {
"fr": "Le 20 juin 2025 de 18h00 à 22h00",
"en": "June 20, 2025, 6:00 PM – 10:00 PM"
},
"featured": false,
"image": {
"width": 1200,
"height": 800,
"src": "https://img.openagenda.com/u/1080x0/main/9876543.full.image.jpg",
"srcTemplate": "https://img.openagenda.com/u/{geo}/main/9876543.full.image.jpg",
"srcset": [
{
"width": 640,
"url": "https://img.openagenda.com/u/640x0/main/9876543.full.image.jpg"
},
{
"width": 1080,
"url": "https://img.openagenda.com/u/1080x0/main/9876543.full.image.jpg"
}
]
},
"imageCredits": "Ville de Lyon",
"keywords": {
"fr": [
"jazz",
"concert",
"plein air"
],
"en": [
"jazz",
"concert",
"open air"
]
},
"originAgenda": {
"uid": 12345,
"title": "Festival des Lumières",
"slug": "festival-des-lumieres",
"image": {
"src": "https://img.openagenda.com/u/400x0/main/a1b2c3d4e5f60718293a4b5c6d7e8f90.full.image.jpg",
"srcTemplate": "https://img.openagenda.com/u/{geo}/main/a1b2c3d4e5f60718293a4b5c6d7e8f90.full.image.jpg"
},
"url": "https://openagenda.com/festival-des-lumieres",
"official": true
},
"rights": {
"license": {
"id": "etalab-2.0",
"name": "Licence Ouverte 2.0",
"url": "https://www.data.gouv.fr/pages/legal/licences/etalab-2.0/"
},
"licensor": {
"name": "Ville de Lyon",
"url": "https://www.lyon.fr",
"agendaUid": 12345
},
"publisher": {
"name": "Ville de Lyon",
"url": "https://www.lyon.fr",
"agendaUid": 12345
}
},
"canonicalUrl": "https://www.lyon.fr/evenement/concert-de-jazz-au-parc",
"timings": [
{
"begin": "2025-06-20T18:00:00+02:00",
"end": "2025-06-20T22:00:00+02:00"
}
],
"location": {
"uid": 55512,
"name": "Parc de la Tête d'Or",
"address": "Place Général Leclerc",
"city": "Lyon",
"region": "Auvergne-Rhône-Alpes",
"postalCode": "69006",
"countryCode": "FR",
"latitude": 45.7772,
"longitude": 4.8558,
"district": null,
"department": "Rhône",
"adminLevel3": null,
"adminLevel5": null,
"country": {
"fr": "France",
"en": "France"
},
"timezone": "Europe/Paris"
},
"timezone": "Europe/Paris",
"attendanceMode": 1,
"onlineAccessLink": null,
"firstTiming": {
"begin": "2025-06-20T18:00:00+02:00",
"end": "2025-06-20T22:00:00+02:00"
},
"lastTiming": {
"begin": "2025-06-20T18:00:00+02:00",
"end": "2025-06-20T22:00:00+02:00"
},
"nextTiming": {
"begin": "2025-06-20T18:00:00+02:00",
"end": "2025-06-20T22:00:00+02:00"
},
"additionalFields": {},
"longDescription": {
"fr": "Un concert en plein air avec plusieurs formations de jazz…",
"en": "An open-air concert featuring several jazz ensembles…"
},
"conditions": {
"fr": "Entrée libre",
"en": "Free entry"
},
"country": {
"fr": "France",
"en": "France"
},
"registration": [
{
"type": "link",
"value": "https://openagenda.com/festival-des-lumieres/events/concert-de-jazz-au-parc"
}
],
"createdAt": "2025-03-12T11:30:00+01:00",
"updatedAt": "2025-05-28T16:45:00+02:00",
"accessibility": {
"hi": false,
"ii": false,
"vi": true,
"pi": false,
"mi": true
},
"age": {
"min": 0,
"max": null
},
"state": 2,
"links": [
{
"link": "https://example.org/jazz-au-parc",
"data": {}
}
],
"extIds": [
{
"key": "legacy",
"value": "4421007"
}
],
"sourceAgendas": []
}Changes
- info
added the optional property
///to the response with the status - info
added the optional property
///////to the response with the status
- info
- breaking
added to the response body
oneOflist for the response status - breaking
the response's body type changed from
objectto no type for status - breaking
removed the required property
from the response with the status - warning
removed the optional property
/from the response with the status - warning
removed the optional property
/from the response with the status - warning
removed the optional property
/from the response with the status - warning
removed the optional property
/from the response with the status - warning
added the new
bad_requestenum value to the/response property for the response status - warning
added the new
bad_requestenum value to the/response property for the response status - warning
added the new
bad_requestenum value to the/response property for the response status - warning
added the new
bad_requestenum value to the/response property for the response status - warning
added the new
forbiddenenum value to the/response property for the response status - warning
added the new
forbiddenenum value to the/response property for the response status - warning
added the new
forbiddenenum value to the/response property for the response status - warning
added the new
insufficient_scopeenum value to the/response property for the response status - warning
added the new
insufficient_scopeenum value to the/response property for the response status - warning
added the new
insufficient_scopeenum value to the/response property for the response status - warning
added the new
not_foundenum value to the/response property for the response status - warning
added the new
not_foundenum value to the/response property for the response status - warning
added the new
not_foundenum value to the/response property for the response status - warning
added the new
read_only_credentialenum value to the/response property for the response status - warning
added the new
read_only_credentialenum value to the/response property for the response status - warning
added the new
read_only_credentialenum value to the/response property for the response status - warning
added the new
service_unavailableenum value to the/response property for the response status - warning
added the new
service_unavailableenum value to the/response property for the response status - warning
added the new
service_unavailableenum value to the/response property for the response status - warning
added the new
unauthorizedenum value to the/response property for the response status - warning
added the new
unauthorizedenum value to the/response property for the response status - warning
added the new
unauthorizedenum value to the/response property for the response status - warning
added the new
validation_errorenum value to the/response property for the response status - info
added the required property
/to the response with the status
- breaking