Add an event

Anyone can add events. A bot checks each submission and prepares a proposal that an editor reviews before it is published – you get a reply as a comment on GitHub.

One event – or a simple weekly series

For: a single milonga, a workshop, or something that repeats the same way every week.

Fill in the form. For regular evenings choose «Gjentas: Ukentlig» (repeats weekly) and the last date; each date becomes an event of its own that can later be changed or cancelled separately.

The form is in Norwegian, but you can write the title and description in English – just choose «Tekstspråk: English». If you have the text in both languages, add the other one in the optional fields at the bottom; one language is enough.

Open the form ↗
The form fields in English
Tekstspråk
Text language: choose English if you write the title and description in English
Tittel
Title
Type
Kurs = class, Workshop, Milonga, Practica, Festival, Maraton = marathon, Utetango = open-air, Annet = other
Dato
Date (YYYY-MM-DD)
Starttid / Sluttid
Start / end time
Gjentas
Repeats: Nei = no, Ukentlig = weekly
Gjentas til / Unntatt datoer
Repeats until / except on these dates
Sted / Adresse
Venue / address
Arrangør
Organiser
Lærere
Teachers
Pris / Studentpris / Kurspris (kr)
Price / student price / class price in kroner
Musikk
Music: Tradisjonell = traditional, Alternativ / neo, Levende orkester = live orchestra
Lenke
Link to the event page
Beskrivelse
Description
Tittel / Beskrivelse (andre språk)
Optional title / description in the other language
Samtykke
Consent: the people named have agreed to be listed

Several dates with variations – from a spreadsheet

For: a series where e.g. the DJ or price varies, or many dates at once.

  1. The first row holds the column names (in Norwegian, see below), the second row everything the dates have in common (title, venue, times, price …).
  2. On the following rows, fill in only what is different – typically Dato (date) and DJ. An empty cell = same as row two. Write - to remove a value, and «Avlyst» in Status for cancelled dates.
  3. Select all the cells (including the column names), copy (Ctrl+C / ⌘C) and paste them into the form «Nytt arrangement (fra tabell)». Works from Excel, Google Sheets and Numbers.
TittelTypeDatoStarttidSluttidStedAdresseArrangørDJPris (kr)LenkeStatus
FredagsmilongaMilonga16.10.202620:0000:30SalenStorgata 1, OsloTangoklubbenDJ A150https://…–
23.10.2026DJ B
30.10.2026Avlyst
Open the spreadsheet form ↗Download the template (CSV for Excel)
Columns
Tittel
Title: the name of the event. (required)
Type
One or more, separated by commas: Class, Workshop, Milonga, Practica, Festival, Marathon, Open-air, Other (or the Norwegian Kurs, Maraton, Utetango, Annet) – e.g. “Class, Milonga”. (required)
Dato
Date, one per row: YYYY-MM-DD, DD.MM.YYYY or DD/MM/YYYY. (required)
Starttid / Sluttid
Start / end time, HH:MM. An end after midnight is fine (e.g. 01:00). Start time (required)
Sted / Adresse
Venue name and street address. (required)
Arrangør
Organiser: the club or person organising. (required)
DJ / Lærere
DJ / teachers – teachers separated by commas.
Pris (kr), Studentpris (kr), Kurspris (kr)
Price, student price, class price in whole kroner.
Musikk
Music: Traditional, Alternative / neo and/or Live orchestra, separated by commas.
Flyer / Video
Link to an image / YouTube or Vimeo.
Lenke
Link: the event's web page or Facebook event. (required)
Beskrivelse
Description: a short text.
Tekstspråk
Text language: “English” or “Norsk” (the default) – the language of Tittel and Beskrivelse.
Tittel (andre språk) / Beskrivelse (andre språk)
Optional: title and description in the other language (Norwegian if your text is English).
Status
Write “Avlyst” (or “Cancelled”) on cancelled dates.

The columns can be in any order, and you only need the ones you use.

With AI – from a Facebook page or website

For: the event is already described somewhere and you would rather not type it in yourself.

  1. Copy the prompt below.
  2. Open your AI assistant (Copilot, Gemini, ChatGPT …), paste the prompt and add the event text right after it – copy the text from the event page, or attach a screenshot. AI assistants usually cannot log in to Facebook themselves.
  3. Read through the answer. AI can get things wrong – check the date, times, venue and price in particular.
  4. Paste the whole answer into the form «Nytt arrangement (JSON fra KI)».
You are helping to submit an event to Tangokalender, a community calendar for Argentine tango in Oslo.
Read the event information I give you below (text, screenshot or link contents) and convert it as follows.

Pages to use (open them if you can browse; if you cannot, work from what the user gives you):
- https://tango.oslo.no/schema/tango-event-submission.schema.json: the submission JSON Schema, with every field and the allowed values. Follow it exactly.
- https://tango.oslo.no/events.json: the upcoming events, as stored. Check it before you answer: whether the event is already listed, which events belong to the same series, and how venues, addresses, organisers and teachers are already spelt.
- https://github.com/Tangokalender/tangokalender.github.io/tree/main/events: every event as one JSON file, past dates too (events/YYYY/MM-month/YYYY-MM-DD-<id>.json). Use it when the series has no upcoming dates left, e.g. a new term of a course.

Rules:
- Output ONLY a JSON value that conforms to this JSON Schema, with no explanation around it: https://tango.oslo.no/schema/tango-event-submission.schema.json
- Required in every object: "title", "types", "start", "venue" (with "name" and "address"), "organizer" and "link". Everything else may be null or left out.
- "organizer" is the group or person the source names as organiser. If none is named, use the page or profile that published the event (on Facebook: the event host). Ask the user if you cannot tell.
- One JSON object per date. If the event repeats (e.g. "every Wednesday until 9 December"), output an array with one object per date and leave out dates the source says are cancelled. If no end date is given, include the next 4 dates.
- "start" and "end" are Oslo local time: "YYYY-MM-DDTHH:MM", without a time zone. Use "YYYY-MM-DD" when no time is given (e.g. festivals). If the event ends after midnight, "end" has the next day's date. If the year is not stated, use the next upcoming occurrence of that date.
- "types" is a list with one or more of: class (class or course), workshop (workshop or seminar), milonga (social dance evening), practica (practice evening), festival (festival or multi-day event with workshops), marathon (multi-day, mostly social dancing), outdoor (open-air / outdoor event (utetango); combine with e.g. milonga), other (anything else). Use several when the event combines them, e.g. ["class", "milonga"], or ["milonga", "outdoor"] for an open-air milonga.
- "music_style" (only if the source states it) is a list of: alternative (alternative or neo tango), live_orchestra (live orchestra), traditional (traditional / golden-age tango).
- Prices are whole Norwegian kroner as integers: "price_nok" (regular entry), "student_price_nok", "class_price_nok" (the class or course part). If a price covers a whole course or several dates (e.g. 910 kr for a 6-session course), put it in "class_price_nok" on each date, leave "price_nok" null, and say what it covers in "description" (e.g. "Pris for hele kurset.").
- "venue" is {"name", "address", "city"}; "city" is usually "Oslo".
- "link" is the URL of the event page (for example the Facebook event). "flyer_url" and "video_url" (YouTube or Vimeo) only if such links appear in the source.
- "description": 1–3 short, neutral sentences (level, entry, dress code). No marketing language. Write it in the language of the source if that is Norwegian or English, otherwise in English.
- "lang" is the language of "title" and "description": "nb" (Norwegian) or "en" (English).
- "translations" only if the source itself has the text in both languages: {"en": {"title": …, "description": …}} for a Norwegian event (or {"nb": …} for an English one). Never translate yourself.
- Use null (or [] for lists) for anything the source does not state. Never guess names, prices, times or addresses.
- Write people's names (DJ, teachers, organiser) only as they appear in the public event.
- If a date is already in the calendar (same title or organiser, venue and date), do not output it again. Tell the user that it is already listed and that corrections go through the «Rett opp» link on the event page.

Existing events as templates:
- When the event continues a series that is already in the calendar (a weekly milonga, a course, a monthly practica), or the user gives you an existing event as JSON, use the latest event of that series as a template. Find it in the pages above, by the same title, or by the same organiser and venue.
- Copy "title" exactly: a new date with the same title and the same organiser or venue is added to the existing series. Also copy "types", "venue", "organizer", "teachers", "music_style", the prices, "description", "lang" and "translations", unless the source says something different. The source always wins over the template.
- Take "start", "end", "dj", "flyer_url" and "video_url" from the source only. These change from date to date. "link" is the source's event page; use the template's only when the source has none.
- Even for a new event, if the venue or the organiser is already in the calendar, write the name and address exactly as they are there.
- Stored events are not submissions. Convert them: leave out "$schema", "id", "series", "status", "source", "source_url", "published_date", "first_seen", "last_verified", "crawl_timestamp" and "confidence". Shorten "start" and "end" to "YYYY-MM-DDTHH:MM" (no seconds, no "+01:00"/"+02:00"). Turn "video" {"platform", "id"} into "video_url" (https://www.youtube.com/watch?v=<id> or https://vimeo.com/<id>).

Example. For the input
Milonga del Fiordo 🎶 Fredag 12. mars kl. 21–01.30 på Kulturhuset Fjord, Storgata 9, Oslo.
DJ: Gjeste-DJ. Inngang 150 kr, studenter 100 kr. Tradisjonell tango hele kvelden.
Arr: Tangoforeningen Fjord. https://www.facebook.com/events/000000000000000
the output is
{
  "title": "Milonga del Fiordo",
  "types": ["milonga"],
  "start": "2027-03-12T21:00",
  "end": "2027-03-13T01:30",
  "venue": {"name": "Kulturhuset Fjord", "address": "Storgata 9, Oslo", "city": "Oslo"},
  "organizer": "Tangoforeningen Fjord",
  "dj": "Gjeste-DJ",
  "teachers": [],
  "music_style": ["traditional"],
  "price_nok": 150,
  "student_price_nok": 100,
  "class_price_nok": null,
  "description": "Milonga med tradisjonell tango hele kvelden.",
  "lang": "nb",
  "flyer_url": null,
  "video_url": null,
  "link": "https://www.facebook.com/events/000000000000000"
}

Event information:
Open the AI form ↗

Regular evenings become one entry per date – tell the assistant which dates apply, e.g. “every Wednesday from 7 October to 9 December, except 18 November”. For new dates of something already in the calendar, the assistant uses an earlier date as a template, so names, venue and price are written the same way. If your assistant cannot open links, paste an earlier date from events.json as well.

Correct or cancel

Every event has a link «Suggest a correction ↗». The form (in Norwegian) shows what is listed now; fill in only what should change, choose whether the change applies to this date only or to all later dates in the series too, and submit. Cancellations are reported with «Status: Avlyst» – the event stays in the calendar marked as cancelled.

For editors: change many events from the command line

When: you have write access to the data repository and want to change many dates at once – cancel a month, move a series to a new venue, correct a price.

tangoedit is a small program for Linux, Windows and macOS (download, nothing to install). Run it in a clone of the data repository; with Julia, julia --project=. -m TangoKalender edit … does the same.

  1. Find the events. All search words must match; key:text searches one field (series:, type:, venue:). Upcoming events only; narrow it down with --from/--until.
  2. Look before you change. --dry-run lists the changes line by line, --preview shows them as cards.
  3. Change with key=value: status=cancelled, price_nok=150, venue.name=…. Everything is checked before it is written; if anything is wrong, nothing changes.
  4. Commit and open a pull request. The site updates once it is merged.
Animation: tangoedit lists the four Wednesdays in November in the series onsdagsmilonga, shows the change status=cancelled with --dry-run, and cancels them.
Example with invented events: cancel a weekly milonga for all of November.
# which events match?
tangoedit series:onsdagsmilonga --from=2026-11-01 --until=2026-11-30
# what they will look like (nothing is written)
tangoedit series:onsdagsmilonga --from=2026-11-01 --until=2026-11-30 status=cancelled --dry-run
# cancel them
tangoedit series:onsdagsmilonga --from=2026-11-01 --until=2026-11-30 status=cancelled
tangoedit --help

Privacy

Only use information that is already public. Names of DJs and teachers should only be included if they have agreed to it – you confirm this in the form. Don't paste private messages or personal data into an AI assistant.

You need a (free) GitHub account to submit. For developers and AI agents: llms.txt · submission schema (JSON Schema) · stored format