Developer Page Specifications
API Contracts
6 endpoints — listing, summary (landing rails), details, submit (rate-limited + CAPTCHA), .ics generation.
Complete
Six endpoints: listing (with scope), summary (landing rails), details, submit, ics-download (server-generated), and a public iCal feed per scope (planned, see roadmap).
1 · GET /api/calendar/events — listing
- Query: scope (all|country|category|audience|stage|time), scopeValue?, country (csv), category (csv), audience (csv), stage (csv), status, mode (physical|online|hybrid), sort (start-asc default|start-desc|deadline-asc|created-desc), page, pageSize, lang.
- Response items: { id, slug, title, shortDescription, status, category {slug, label, iconKey}, country {code, name}, city, mode, startDate, endDate?, applicationDeadline?, registrationDeadline?, organizer {name, logoUrl}, isFeatured, isSpotlight, audiences[], stages[], coverImageUrl }.
- Cache: 60s public + 180s s-maxage (calendar updates frequently).
2 · GET /api/calendar/summary
- Returns landing-page rails: { thisWeek[], closingSoon[], spotlight?, countryCounts (per-country event count), categoryCounts (per-category event count), totalUpcoming }.
- Cache: 60s — counts must reflect events flipping into closing-soon promptly.
3 · GET /api/calendar/events/{slug}
- Response: full CalendarEvent + relatedEntities resolved (relatedFounders[], relatedStartups[], relatedEditorial[], relatedOpportunities[], relatedFiles[]) + coverage[] (every CoverageArticle with parentEventId = this.id) + seo {metaTitle, metaDescription, jsonLd}.
- Cache: 300s + 1800s s-maxage. Invalidate on update OR coverage publish/unpublish touching this event.
4 · POST /api/calendar/events/submissions
- Body: full event-submission payload (see §13.4.2 form fields). Server validates required fields + at least one outbound URL + bilingual title/short-description present.
- Server: writes CalendarEvent row with verificationStatus=pending, writes CalendarEventSubmission audit row, queues 2 emails (submitter confirmation + admin triage alert).
- Rate limit: 3 submissions/IP/day. 429 on rate-limit hit. CAPTCHA required for IP ≥2 submissions/day.
- Response: 201 { submissionId, eventId, status: 'pending' }.
5 · GET /api/calendar/events/{slug}/ics
- Returns text/calendar VEVENT. Cache 300s. Filename: {slug}.ics. Fires calendar_ics_download analytics event when client opens or clicks.
