The API's main entities allow media files to be added to them. For now media capabilities are limited to images. ## Upload an image To add an image to any of [`Organizer`](./Organizer.md), [`Location`](./Location.md) or [`Offer`](./Offer.md) issue a **multipart request** to their `POST` or `PATCH` endpoints with the `media` field of the request body being an image file. You can send multiple files per request. Each file gets validated to be a JPG, PNG, GIF or WEBP. Other formats are not supported and will be rejected. Corrupt images will be uploaded but rejected afterwards without notice if they can not be processed. Uploading an image this way will attach it directly to the parent entity. The response will contain a relations key `media` with all existing images. For `GET` requests media objects can be requested using the `media` include. ## Image renditions After an image has been uploaded and saved to the database image renditions will be automatically created. Renditions will be created according to the following ruleset: - If the original image is bigger than 2048px in any direction it will be contained to a 2048px square. - If the file extension doesn't match the actual image codec the file extension will be updated accordingly - If the image is bigger than either 1500px, 1000px or 500px a version of the image matching this size in width will be created in the same format Those image renditions are then saved to the database and are automatically available on every media object on its `renditions` relations key. ## Metadata For legal reasons uploaded images need further metadata which needs to be added to a media object after upload using the `v1/media` routes. Media files that don't get assigned the required metadata in a certain timeframe are automatically purged from the database. # `/v1/media` Media files attached to any of Organizer, Location and Offer. ## Resource ```ts interface Media { id: number; type: "media"; attributes: { url: string; width: number; height: number; filesize: number | null; format: string; copyright: string; license: string; createdAt: string; updatedAt: string; }; relations: { translations: [ { id: number; type: "mediatranslation"; attributes: { language: "de" | "en"; alternativeText: string; }; } ]; renditions?: [ { id: number; type: "rendition"; attributes: { width: number; height: number; filesize: number | null; format: string; }; } ]; }; } ``` ## Routes | Parameters | Values | | ---------- | ------ | | - | - | ### **GET** `/v1/media/{id}` #### Response ```json { "data": { "id": 3, "type": "media", "attributes": { "url": "http://beta.api.kulturdaten-berlin.anyvent.cloud/media/images/original/DEMO-ckst4acq7000d1vgle8iw2938-1200x800.webp", "width": 1200, "height": 800, "filesize": null, "format": "webp", "copyright": "Theresa Fricke", "license": "CC-BY", "expiresAt": "2021-08-29T22:45:07.000+02:00" }, "relations": { "translations": [ { "id": 3, "type": "mediatranslation", "attributes": { "language": "de", "alternativeText": "Possimus sit aut ex earum vero qui id voluptatem." } } ], "renditions": [ { "id": 1, "type": "rendition", "attributes": { "url": "http://beta.api.kulturdaten-berlin.anyvent.cloud/media/images/renditions/DEMO-ckst4acq7000d1vgle8iw2938-1200x800-1000w.webp", "width": 1200, "height": 800, "filesize": null, "format": "webp" } }, { "id": 2, "type": "rendition", "attributes": { "url": "http://beta.api.kulturdaten-berlin.anyvent.cloud/media/images/renditions/DEMO-ckst4acq7000d1vgle8iw2938-1200x800-500w.webp", "width": 1200, "height": 800, "filesize": null, "format": "webp" } } ] } }, "meta": { "language": "de" } } ``` ### **PATCH** `/v1/media/{id}` #### Request ```json { "attributes": { "copyright": "Amazing photographer", "license": "Apache 2.0" } } ``` #### Response ```json { "data": { "id": 1, "type": "media", "attributes": { "url": "http://beta.api.kulturdaten-berlin.anyvent.cloud/media/images/original/DEMO-C-ckst4ac4t00051vglgozl7kec-800x1200.webp", "width": 800, "height": 1200, "filesize": null, "format": "webp", "copyright": "Amazing Photographer", "license": "Apache 2.0", "expiresAt": "2021-05-14T16:28:02.000+02:00" }, "relations": { "translations": [ { "id": 1, "type": "mediatranslation", "attributes": { "language": "de", "alternativeText": "Dolore numquam aut tempora exercitationem libero et quidem molestias praesentium." } }, { "id": 232, "type": "mediatranslation", "attributes": { "language": "en", "alternativeText": "Also available in english" } } ], "renditions": [] } }, "meta": { "language": "de" } } ```