Event CSV import — format spec
This page describes the exact CSV format Palmetto Playbook accepts for bulk event imports. It is meant to be read by both people and AI assistants. Produce a plain UTF-8 CSV with a header row using the exact column names below. One event per row. Only the first four columns are required (title, place_name, city, starts_at); leave any other column blank when the value is unknown — do not invent it.
Columns
| Column | Required | Description |
|---|---|---|
| title | required | The event's name. |
| place_name | required | Venue / business name. Matched to an existing business by name + city, or created new. |
| city | required | City or town, e.g. Summerville. |
| starts_at | required | Start, as YYYY-MM-DD or YYYY-MM-DD HH:MM (24-hour). A date with no time is treated as all-day. |
| state | optional | 2-letter state. Defaults to SC. |
| category | optional | Venue type, one of: library, park, museum, restaurant, theater, sports, play, entertainment, church, school, class, festival, market, municipality, other. Anything else becomes 'other'. |
| address | optional | Street address of the venue. |
| description | optional | 1–3 sentence description of the event. |
| ends_at | optional | End time, same format as starts_at. |
| cost | optional | 'free' or a price string like '$10'. |
| source_url | optional | Link to the event's own page / tickets / registration. |
| image_url | optional | Public URL of an event image (https://…). |
| audience | optional | Who it's for: all | kids | adults. Defaults to all. |
| age_min | optional | Minimum age (whole number). |
| age_max | optional | Maximum age (whole number). |
| tags | optional | Comma-separated, from: free, indoor, outdoor, toddler, teens, holiday, signups, storytime, class, camp, deal, halloween, thanksgiving, christmas, hanukkah, new-years, valentines, st-patricks, easter, july-4th. |
| recur_freq | optional | daily | weekly | monthly. Blank = one-off event. |
| recur_days | optional | Weekly only: weekday numbers Mon=0 … Sun=6, e.g. '5,6' for Sat+Sun. |
| recur_until | optional | ISO date (YYYY-MM-DD) the recurrence stops. |
category
Use one of these; anything else is stored as other.
libraryparkmuseumrestauranttheatersportsplayentertainmentchurchschoolclassfestivalmarketmunicipalityother
audience
Who the event is for. Defaults to all.
allkidsadults
tags
Comma-separated. Only these are kept; others are dropped.
freeindooroutdoortoddlerteensholidaysignupsstorytimeclasscampdealhalloweenthanksgivingchristmashanukkahnew-yearsvalentinesst-patrickseasterjuly-4th
Dates & recurrence
starts_at/ends_at/recur_until:YYYY-MM-DDorYYYY-MM-DD HH:MM(24-hour).- A date with no time is treated as all-day.
recur_freq:daily,weekly, ormonthly(blank = one-off).recur_days(weekly only): weekday numbers, Mon=0 … Sun=6 (e.g.5,6).
Example
A valid file with the header row and one event:
title,place_name,city,starts_at,state,category,address,description,ends_at,cost,source_url,image_url,audience,age_min,age_max,tags,recur_freq,recur_days,recur_until
"Toddler Storytime","Summerville Library",Summerville,"2026-10-15 10:30",SC,library,"76 Old Trolley Rd, Summerville","Songs, stories, and rhymes for little ones ages 0–3 and their grown-ups.","2026-10-15 11:15",free,https://example.org/storytime,,kids,0,3,"free,indoor,toddler",weekly,3,2026-12-17
Notes for accuracy
- Venues are matched to existing businesses by
place_name+city; a new one is created if there's no match. - Re-importing the same file is safe — an event with the same venue, title, and start time is skipped, not duplicated.
- Only include real events present in your source. Leave unknown fields blank rather than guessing.
- Imported events start as unverified until the community confirms them.