A poster is not an event. Something has to cross the gap.
On one side, the scrap somebody sent you. On the other, the fields a listing needs: a date, a duration, a venue, a price, a currency. Paste the text or drop the image, and the AI fills the form. You still get the last word on every field.
What you were sent
Sarah Johnson Trio
Blue Note, Sat Aug 22, doors 8pm
$25 on the door
tickets: bluenote.example/tix
What the form receives
Every one of those is an editable input in the preview. Nothing is saved to your schedule until you save the row.
The gap is narrow on purpose
Two inputs cross it. A link does not.
Most tools are vague about this and you find out the hard way. So here it is plainly: the parser reads what you hand it, and it does not go browsing.
Text you paste or type
A forwarded email, a message thread, a line off a listings page, a setlist. Any language: fields come back in the language they were written in, and the translated twins get filled alongside them.
One image, however you have it
Drag it onto the box, paste it out of your clipboard, or pick a file. JPEG, PNG, GIF and WebP, which covers a phone photo of a poster and a screenshot of a group chat. The image can become the event image too.
A URL for it to read
The parser never reads a web page for event details, so a bare link on its own gives it nothing to work with. Open the page, copy the text, paste that. A ticket link inside your text is kept as the registration link and followed once for its preview image, which becomes the event image, but the page behind it is never mined for the date, the venue or the price.
A selfhosted install is the one exception: a schedule there can be given a list of source pages and cities and swept once a day by the import command. That runs on your own server with your own keys, so it is not part of the hosted service.
The far terminal
The record it has to land in.
Not a blob of text with a date somewhere in it. These are the fields the extraction actually asks for, and the ones you will be editing in the preview.
| Field | What lands in it |
|---|---|
| The event itself | |
| event_name | Kept in the language it was written in. |
| event_short_name | A two to five word version, used to build the URL. |
| short_description | A one line summary, capped at 200 characters. |
| event_details | The long description, as markdown. |
| category_name | Matched against your own category list: exact first, then partial, then a similarity match above 70 percent. |
| When | |
| event_date_time | YYYY-MM-DD HH:MM. With no time given at all it defaults to 20:00. |
| event_duration | In hours. There is no separate end column: the end is the start plus the duration. |
| Where | |
| venue_name | The name the venue lookup starts from. See the ladder below. |
| event_address | The street line only, without the city or the state. Falls back to your own street when the source names none. |
| event_city | The city, which is what narrows the venue lookup to the right one. |
| event_state | Region or state, when the source names one. |
| event_postal_code | When the source names one. |
| event_country_code | Normalised to a lowercase two letter ISO code, so "ISR" arrives as "il". |
| venue_email | Only if the source actually printed one. |
| venue_website | Only if the source actually printed one. |
| Who | |
| performer_name | One per performer. Several distinct performers become several events, not one crowded event. |
| performer_email | Only if the source printed one. |
| performer_website | Only if the source printed one. |
| Money and links | |
| ticket_price | The number only, with no currency symbol. |
| ticket_currency | A currency code, when a price was mentioned. |
| registration_url | Kept as the registration link, and its preview image becomes the event image. |
Translated twins, filled in the same pass
Name, short name, short description, address, city, state, venue name and performer name each have a translated twin, and the twin is asked for only when the main field is not already English. If your schedule language is not English the AI is told outright: keep the original wording in the main field, put the translation in the twin, rather than quietly overwriting one with the other.
Your own custom fields, too
ProCustom fields you have added to events are appended to the extraction list with their type, their options and any hint you wrote for them, so a dropdown comes back as one of your options and a switch comes back as yes or no.
One document, several events
The parser returns a list, not a single record, and it is told to split distinct performers into separate events. A month grid, a festival line-up or a weekend of three sets comes back as one row per event, each with its own date, venue and performer.
Save them one at a time as you check them, or work down the list. A row that turns out to be nonsense is simply not saved.
Before it creates anything
Five rungs down, then and only then, a new venue.
The expensive failure in event import is not a wrong date, it is nine copies of the same room. So the lookup climbs down a ladder, and each rung only runs because the one above it missed.
-
A venue you already own with this name
Owning it is the strongest possible signal, so no city and no country are needed. Matched on the normalised name or the normalised translated name.
-
Same city, and the same name or the same street
Plus the country when there is one. Both sides are normalised first, so curly quotes, long dashes, stray spaces and capitals cannot break a match that should have worked.
-
A venue already connected to this schedule
Anywhere this schedule already shares an event with, including venues another admin or a calendar sync added. Name or street, no city required.
-
One more look when you press save
The normalised name, plus the city and country when they are there, is looked up again at save time. That check does not care which screen the event came from: AI import, the ordinary event form or a guest submission all get it.
-
Nothing matched
Only now is a venue created, from the address you just checked in the preview. Nothing is quietly merged into the wrong room.
Performers, two rungs of their own
The parsed name as written, plus your schedule's country, preferring a record that already has an email. Then the talent this schedule has worked with before, on name alone. A match links the event to the performer who exists instead of making a second one.
Your own schedule is assumed
Importing into a venue schedule pins every event to that venue and uses its address. Importing into a talent schedule pins every event to that performer. There is nothing to match, because you already told us.
Already on the schedule
If an upcoming event here already shares the registration link, or the start time plus the venue address or the performer, the row links to the event that exists rather than making a near duplicate of it.
Matching is normalisation, not guesswork. Curly quotes, long dashes, non-breaking spaces and capitals are folded on both sides first, so "The Blue Note" and "the blue note" are the same room and neither becomes a new one.
Inside one event
The same gap, one level down.
A conference day, a festival stage or a two hour set is not one thing, it is a running order. Point your camera at the printed agenda or upload the image, and each line becomes a part of the event with its own name, note and times.
- Four things per line: a name, an optional note or speaker, a start time and an end time, in 24 hour form.
- A setlist with no times comes back in its printed order with the times left empty, rather than invented.
- Keep the photo of the agenda on the event if you want it, or throw it away after the scan.
- Agenda scanning is an Enterprise feature. Event parts themselves are free to build by hand on any plan.
The printed sheet
Enterprise
09:00 Opening keynote, R. Adeyemi
10:30 Panel: touring on a budget
12:00 Lunch
13:30 Workshop A, studio 2
Event parts
Prompt: ignore the breaksWrite the instructions once and save them as the schedule default, then override them on the one event that is laid out differently.
Enterprise generation
Six more places it strikes.
Reading is on every plan. Writing and drawing sit on the Enterprise plan, each one a separate button you press deliberately rather than something running in the background.
Schedule descriptions
EnterpriseA short description and a full markdown description for the schedule itself, from its name, type and categories.
RoleController::generateScheduleDetails
Event descriptions
EnterpriseA category, a short description and a full description for one event, from its name and the context around it.
EventController::generateEventDetails
A flyer image
EnterpriseA poster generated from the event details you already typed, with optional style instructions, regenerated until it is right.
EventController::generateFlyer
A whole schedule style
EnterpriseProfile image, header image, background image, accent colour and font. Ask for all five or regenerate just one.
RoleController::generateStyle
Graphic email text
EnterpriseA pass over the event list text that goes out with your graphic emails, driven by a prompt you save on the schedule.
GraphicController::processGraphicAIText
Event parts from an agenda
EnterpriseName, description, start time and end time for each line of a printed agenda or a setlist.
EventController::parseEventParts
Text generation goes to Google Gemini and image generation to OpenAI, and both are configurable. Generated images arrive as ordinary uploads on your schedule, so you can regenerate, replace or delete them like any image you had uploaded yourself.
Free on every plan
Write it once. Publish it twice.
Pick one target language for the schedule and the whole thing is translated in the background: the schedule name and descriptions, every event, event parts, sub-schedule names, your request terms. Visitors get a switch between your language and the target.
- Translations are stored, not fetched per visit, so a guest page never waits on a model.
- Change the target language and the stored translations are cleared and rebuilt in the new one, including sub-schedule names.
- You can edit any translated value by hand and keep your wording instead of the model's.
12 languages
Parsing is not limited to this list. It reads whatever the source is written in and keeps it that way. The list is what the schedule can be published in.
The gap, with no screen
Photograph the poster. Send it. Done.
The one place the AI does save without you. It is meant for the moment you are standing in front of a wall of flyers, so it goes all the way and then reports back.
How it actually works
Enterprise-
Verify your phone number once, in your account settings. That number is how the message is matched to you, so it is your phone that is authorised, not a number of ours that you share around.
-
Message the Event Schedule number on WhatsApp. Type the details, or just send the photo of the flyer.
-
The event is created on your default schedule, or on your only schedule if you have one. The photo you sent becomes the event image.
-
You get a reply with the name, the date and a link, so the first thing you can do is open it and fix whatever the poster got wrong.
The message only ever makes the event. Tickets, visibility, recurrence and everything else are still set the ordinary way afterwards, on the edit screen.
Auto-curation still applies
If the schedule is set to curate into others automatically, the new event goes out to them as well, the same as one you had typed in yourself, and waits for approval wherever that curator reviews submissions.
Already have it? It says so.
A message that resolves to an event already on your schedule gets a link back to that event instead of a duplicate.
Needs Twilio
WhatsApp runs through Twilio, so a selfhosted install has to configure that first before the feature exists at all.
Plans and allowances
What is free, what is not, and where it stops.
Model calls cost real money, so the ones on the free plan are metered rather than pretended to be infinite. Here are the actual limits.
| Feature | Plan | Daily allowance |
|---|---|---|
| Parse an event from text or an image | Every plan | 10 to 100 a day, by plan |
| Translate the whole schedule | Every plan | Scheduled background job |
| Scan an agenda into event parts | Enterprise | 10 a day |
| Write a schedule or event description | Enterprise | 50 a day |
| Pass graphic email text through AI | Enterprise | 50 a day |
| Generate a flyer or a style image | Enterprise | 3 a day on trial, 10 once paid |
| Create an event over WhatsApp | Enterprise | Counts against the parse allowance |
Selfhost and the caps disappear
Every one of those allowances only exists on the hosted service. A selfhosted install supplies its own Gemini and OpenAI keys, pays the model provider directly and is not metered by us at all.
Agents can drive all of this
There is a REST API with an OpenAPI 3.0 spec, plus llms.txt and agents.json so an agent can discover it and work without a human reading the docs first. API access is on the Pro plan.
Where this usually leads.
Creating events
Everything the import screen hands off to: dates, recurrence, parts, visibility and tickets.
Read moreEvent graphics
Turn the events you just imported into shareable images for Instagram, WhatsApp and email.
Read moreNewsletters
Mail the line-up to your followers and ticket buyers. Free on every plan, at ten recipients a month.
Read moreCalendar sync
Two-way sync with Google, Outlook and CalDAV, so an imported event lands in your own calendar too.
Read moreRecurring events
A weekly night is one event with a day-of-week pattern, not fifty rows to import.
Read moreCustom fields
Add your own fields and the parser will extract them alongside the built-in ones.
Read moreFrequently asked questions
The ones worth answering precisely, because the vague answers are what waste your afternoon.
What can the AI parser read?
Text you paste or type, and one image you drop, paste from the clipboard, or pick from a file dialog. Images can be JPEG, PNG, GIF or WebP, so a photo of a poster, a screenshot of a message and an exported flyer all work. What it cannot do is read a web page for you. A registration link is followed once for its preview image, but nothing on that page is mined for the details, so paste the text off the page rather than the link to it.
Can one image become several events?
Yes. The parser returns a list, not a single record, and it is told to split distinct performers into separate events. A month grid or a festival line-up comes back as one row per event, each with its own date, venue and performer, and you save them one at a time or all together.
Which AI features are free and which are Enterprise?
Event parsing and whole-schedule translation are on every plan, including the free one. Agenda scanning into event parts, description writing, flyer generation, schedule style generation, the AI pass over graphic email text and event creation over WhatsApp are Enterprise. Parsing is metered by a daily allowance rather than a plan gate, and a selfhosted install has no cap at all.
Does the AI ever save anything without me?
Not from the import screen. Parsed events land in a preview where every field is an editable input, and nothing reaches your schedule until you save that row. The one exception is WhatsApp on Enterprise, which is designed to be hands free: it parses the message and creates the event, then messages you back a link so you can go and correct it.
Will it create a duplicate venue?
It tries hard not to. Before making anything, it looks for a venue you already own with that name, then for a venue in the same city with the same name or street, then among the venues this schedule already shares an event with. When you press save the normalised name, city and country are looked up one more time, whatever screen the event came from. Only when all of that misses is a venue created, from the address you checked in the preview. Performers get a shorter version of the same treatment: the parsed name plus your country first, then the talent this schedule already works with.
What if the event is already on my schedule?
The preview tells you. If an upcoming event on this schedule already has the same registration link, or the same start time plus the same venue address or the same performer, the row links to the event that exists instead of quietly making a second copy of it.
Can I teach it my agenda format?
Yes, for agenda scanning. You can write instructions like "each line is a session, format is time then speaker then topic, ignore the lunch breaks" and either use them once or save them as the default for the whole schedule, with a per event override. Agenda scanning is an Enterprise feature.
Which languages does it work in?
Parsing is not restricted to a list: fields are kept in the language they were written in, and where a translated twin exists the AI fills that too. The separate translation feature covers 12 languages: Arabic, Dutch, English, Estonian, French, German, Hebrew, Italian, Portuguese, Romanian, Russian and Spanish. Pick one target language for the schedule and visitors can switch between your language and it.
Which models are behind this, and what if I selfhost?
Text parsing, writing and translation go to Google Gemini, and image generation to OpenAI, both configurable. A selfhosted install brings its own API keys, which is why the daily allowances do not apply there: you are paying the model provider directly rather than us.
Free to start
Paste the mess. Keep the listing.
Parsing and translation are included on the free plan, and Event Schedule takes zero platform fees on ticket sales.
No credit card required
Related
Keep exploring
Ticketing
Sell tickets with QR check-in and zero platform fees.
Read moreCalendar Sync
Two-way Google Calendar and CalDAV sync.
Read moreEvent Graphics
Auto-generate flyers and share graphics from your events.
Read moreFor AI Agents
Expose your schedule as structured data for AI agents.
Read more