Event calendar QR code generator
100% Private & Local — Your data never leaves your browser. These QR codes are permanent and will never expire.
Event calendar settings
Design
Add a centre logo
The image is read in this page and embedded in the code as a data: URL. It is not uploaded, and it stays inside the file you download.
More design options
The dark half of the code. Keep it well below the background in lightness.
Covers the quiet zone as well as the gaps between modules. A transparent background leaves it out of the file, so nothing is drawn with it.
Contrast 11.5:1 between the modules and the background.
PNG and WebP keep an alpha channel; the SVG simply omits the background rectangle. Whatever the code is placed on becomes the light half of the contrast.
A gradient fills the dark modules only. Its lighter end sets the contrast a scanner actually gets, so both ends have to stay dark.
The second colour, used only while a gradient is selected. It is measured for contrast alongside the first.
Degrees clockwise from a left-to-right sweep. A radial gradient spreads from the centre outwards, so the angle applies to a linear one only.
Rounded shapes cover less of each cell. The centre stays covered, which is where a decoder samples, but a small print of a dense code reads more reliably as squares.
The ring of the three finder patterns.
The eye inside each finder pattern.
The blank margin around the code, measured in modules. 4 is the specified minimum.
Higher recovery survives more damage and costs capacity, so the same content produces a denser symbol.
A logo sits at the centre and holds the level at H. Its width limit follows the symbol: 14% on the smallest code, 30% on a dense one.
Live preview & export
Enter the event name. It becomes the title of the calendar entry.
Export
Raster, for screens
Complete the form to enable the downloads.
Export size and encoded text
- Payload
- Nothing encoded yet
- Symbol
- Not built yet
- Recovery
- M
Waiting for input
Build a complete iCalendar event and print it. The payload is the .ics content itself, so the phone can create the entry without downloading a file from anywhere.
When someone scans it
Most current camera and scanner apps recognise the BEGIN:VCALENDAR header and offer to add the event to the default calendar. Some older or minimal scanners display the text as-is instead.
The iCalendar payload, exactly
The code carries a complete RFC 5545 object, not a link to one. It opens with BEGIN:VCALENDAR, carries VERSION:2.0 and a PRODID identifying this generator, wraps a single VEVENT, and closes with END:VCALENDAR. Inside the event sit UID and DTSTAMP, which the specification requires, alongside DTSTART, DTEND, SUMMARY and whichever of LOCATION, DESCRIPTION and URL you filled in.
Every content line ends with a carriage return and a line feed, in that order. Parsers are strict about this: an object using bare line feeds is what makes an otherwise correct event fail to import. Lines longer than 75 octets are folded by inserting CRLF followed by a single space, and readers rejoin them before parsing, which is why a long description does not break the object.
Because the whole event lives in the pattern, the phone needs no network to create the entry. It also means the event is frozen: changing the venue later means generating and printing a new code, since there is nothing to update.
Floating local time against UTC
In floating mode DTSTART is written as YYYYMMDDTHHMMSS with no trailing Z and no TZID parameter. RFC 5545 calls this a floating time, and it means exactly what it says: 19:00 is 19:00 on whichever device opens it, regardless of where that device is. For a concert, a market stall or a school open evening this is almost always what you want, because everyone reading the poster is standing in the same time zone as the venue.
In UTC mode the same property is written as YYYYMMDDTHHMMSSZ and the trailing Z fixes the instant. Each device converts it into local time on import, so an event set for 14:00 UTC shows as 15:00 in Berlin and 09:00 in New York. That is the right choice for a webinar and the wrong one for a village fête.
A named zone — DTSTART;TZID=Europe/London — is the third possibility in the specification, and this tool does not offer it. Doing it properly requires embedding a VTIMEZONE component with the full set of daylight-saving transition rules, which adds several hundred bytes to a payload that must fit in one symbol, and an object referencing a TZID it does not define is invalid. Floating and UTC cover the printed-poster cases without that cost.
Escaping, all-day events and size
Text values are escaped as the specification requires before they go into the payload. Backslashes are escaped first, then semicolons and commas, then line breaks; escaping in any other order double-escapes the backslashes you just introduced. A colon inside a text value is left alone — RFC 5545 explicitly forbids escaping it, though the older RFC 2445 required it, which is why some hand-written generators still get this wrong.
An all-day event uses the date form: DTSTART;VALUE=DATE:20260904. Its DTEND is exclusive, so a single day on 4 September is written with DTEND;VALUE=DATE:20260905. Getting that wrong is what produces an event that spans one day too few or one too many.
Size is the practical limit here. A QR symbol holds at most 2,953 bytes at the lowest recovery level, and the calendar wrapper alone spends roughly two hundred before your text starts. A long description pushes the symbol to a higher version with smaller modules, which needs either a larger print or a closer scan. The preview shows the version as you type, so watch it move.
- Backslash becomes \\, semicolon becomes \;, comma becomes \,
- A line break becomes the two characters \n
- Colons are never escaped in RFC 5545 text values
Questions and answers
Why does my phone show a wall of text instead of an add-to-calendar prompt?
The scanner recognised no URL and fell back to displaying the payload. Most current camera apps detect the BEGIN:VCALENDAR header and offer to create the event, but a minimal scanner may only handle links. A dedicated QR scanner app, or the phone's own camera rather than a third-party one, usually resolves it.
Can one code hold a recurring event?
Not with this tool. RFC 5545 expresses repetition with an RRULE property, and while the syntax is compact, the combinations of interval, weekday, count and exception dates need a form of their own to be entered without mistakes. This tool builds one event with one start and one end.
Will the event carry a reminder or an alarm?
No. A VALARM component would add bytes to every code to serve a preference the person scanning usually wants to set themselves, and default reminder behaviour differs sharply between calendar apps. The entry lands in the calendar and inherits whatever default that calendar applies.
What happens if two people scan the same printed code?
Each gets an entry in their own calendar. The UID is derived from the event details, so it is the same string in both copies — which is correct, since it is the same event — but the copies are independent. There is no invitation, no attendee list and no way for one person's change to reach anyone else.
How a static QR code works
Every code on this site is static: the payload is written into the black and white modules themselves. Nothing is looked up when the code is read, no server of ours takes part, and no subscription holds the printed code up. The same property is the limit — once it is printed, what it contains cannot be changed.
Three things then decide whether a printed code reads: how many bytes the payload came to, which recovery level absorbs the damage, and how wide a single module ends up on paper. These guides work through each of them with the numbers.