This project provides serverless endpoints for various Notion integrations:
/api/calendar— Reads a Notion database and returns a subscribable .ics calendar feed (usesical-generator).
/api/spanish-tips— Generates Spanish language learning tips using OpenAI and saves them to a Notion database./api/recipes— Generates detailed cooking recipes with AI-generated images and saves them to a Notion database.
- Create a Notion internal integration and copy its secret.
- Share your target Notion database(s) with that integration.
- Set environment variables in Vercel Project Settings (or in
.envfor local development):NOTION_TOKEN— Required for all endpointsOPENAI_API_KEY— Required for/api/spanish-tipsand/api/recipes
- Deploy:
npm i vercel vercel --prod
- Calendar subscribe (Apple Calendar / Google Calendar):
You can create a pretty URL
https://<your-app>.vercel.app/api/calendar?db=<DATABASE_ID>/calendar.ics?db=...thanks tovercel.json.
Generates Spanish language learning tips using OpenAI and creates structured pages in your Notion database.
Required Query Parameters:
db— Notion database ID (e.g.,22028e1a435d807cb1a3fca3e2675d1f)prompt— Your Spanish tip request (e.g., "What are different ways to greet someone in the evening?")
Example:
GET /api/spanish-tips?db=22028e1a435d807cb1a3fca3e2675d1f&prompt=What%20are%20different%20ways%20to%20greet%20someone%20in%20the%20evening%3F
Response:
{
"message": "Spanish tip created successfully",
"title": "Evening Greetings in Spanish"
}Required Notion Database Properties:
Name(title) — The tip titleCategory(select) — One of: Core Grammar & Verb Use, Vocabulary & Word Use, Conversation & Usage, Pronunciation & Listening, Cultural / Regional VariationSubcategory(select) — Various subcategories like Verb Conjugation, Vocabulary, Idiomatic Expressions, etc.CEFR Level(select) — A1 through C2 proficiency levelsLast Reviewed(date) — Automatically set to the current date
Generated Content:
- Practice link to ChatGPT
- Detailed explanation in markdown
- Example sentences/phrases
- Practice prompts
Generates detailed cooking recipes with AI-generated food photography and comprehensive nutritional information.
Required Query Parameters:
db— Notion database ID for recipesprompt— Your recipe request (e.g., "Give me a recipe for chicken tacos")
Example:
GET /api/recipes?db=YOUR_RECIPE_DB_ID&prompt=Give%20me%20a%20recipe%20for%20chicken%20tacos
Response:
{
"message": "Recipe created successfully",
"title": "Authentic Chicken Tacos"
}Required Notion Database Properties:
Name(title) — Recipe nameDescription(rich_text) — Recipe descriptionCountry of Origin(select) — Origin country/regionDifficulty(select) — Easy, Medium, or HardPrep Time (min)(number) — Preparation timeCook Time (min)(number) — Cooking timeServing Size(rich_text) — Number of servingsIngredients(rich_text) — Formatted ingredient listMeal Type(multi_select) — Breakfast, Lunch, Dinner, Snack, DessertDiet(multi_select) — Diet types (Keto, Vegan, Vegetarian, etc.)Allergies(multi_select) — Common allergensProtein Type(multi_select) — None, Chicken, Beef, Pork, Tofu, Fish, Seafood, OtherCalories (cal)(number) — Total caloriesProtein (g)(number) — Protein in gramsCarbs (g)(number) — Carbohydrates in gramsFat (g)(number) — Fat in gramsFiber (g)(number) — Fiber in gramsNutrition Facts(rich_text) — Additional nutrition information
Generated Content:
- AI-generated food photography (set as page cover)
- Step-by-step preparation instructions
- Step-by-step cooking instructions
- Complete nutritional breakdown
In addition to NOTION_TOKEN, the content generation APIs require:
OPENAI_API_KEY— Your OpenAI API key for GPT and image generation
The endpoints try to work with sensible defaults, but you can override via query params.
Expected fields in your Notion database:
- Event name (title) → default: first Title property found or
namePropparam - Start date (date) → default: property named
Startor viastartProp - End date (date) → default: property named
Endor viaendProp(fallback to Start.end) - All Day (checkbox) → default: property named
AllDayorallDayPropparam - Location name (rich_text/text) → default:
LocationorlocationProp - URL (url) → default:
URLorurlProp
Examples:
GET /api/calendar?db=xxxxx&startProp=Begin&endProp=Finish
- Timed events: a
VALARM1 hour before start. - All-day events: a
VALARM1 day before (00:00 of the event’s day minus 1 day).
- Anyone with the URL can view the ICS/API responses. For private use, add a
key=...query param check in the API handlers and pass it in your URLs.