Last updated: February 12, 2026
https://api.altaporta.com/apiAltaporta is a mobile-first goal and travel planning platform. The iOS app orchestrates user flows for Trips, Goals, Wishes, Tasks, and Social Circles. The backend is a Bun + Hono API that exposes OpenAPI-documented endpoints, handles AI generation, manages subscriptions, and provides real-time SSE updates.
/api.These are key production dependencies used by the API service and feature stack.
hono@hono/zod-openapibetter-authdrizzle-ormhono-rate-limiteropenaireplicate@aws-sdk/client-s3@aws-sdk/s3-request-presignerresendsharpzodqrcodeapi.altaporta.com and can proxy traffic in front of the VPS.altaporta-app serves Bun/Hono API on internal port 3000../data) with Redis sidecar for cache-oriented workloads.Traffic Flow
Client (iOS/Web) → Cloudflare (DNS/Proxy) → Hetzner VPS → Nginx (optional) → Bun/Hono API → SQLite/Redis + external services (R2/S3, OpenAI, Replicate, RevenueCat, Resend).
Authorization: Bearer <token>.sessionUser context for route handlers. x-session-token and x-session-expires-at.All routes below are relative to https://api.altaporta.com/api.
GET /healthPOST /auth/sign-upPOST /auth/sign-inPOST /auth/google-signinPOST /auth/apple-signinPOST /verify-otpPOST /resend-otpGET /verification-status/{email}POST /auth/forgot-passwordPOST /auth/verify-reset-codePOST /auth/reset-passwordPOST /auth/* (Better Auth passthrough)POST /v1/generate-tripGET /v1/tripsGET /v1/trips/{tripId}POST /v1/trips/{tripId}/select-tierDELETE /v1/trips/{tripId}POST /v1/goalsGET /v1/goalsGET /v1/goals/{goalId}PATCH /v1/goals/{goalId}DELETE /v1/goals/{goalId}GET /v1/goals/daily-statusPOST /v1/goals/{goalId}/checkinPOST /v1/goals/{goalId}/progressGET /v1/goals/{goalId}/actionsPOST /v1/goals/{goalId}/actions/{actionId}/completePOST /v1/goals/{goalId}/streak/freezeDELETE /v1/goals/{goalId}/streak/freezePOST /v1/trips/{tripId}/create-goalGET /v1/tasksGET /v1/tasks/by-datePOST /v1/tasksGET /v1/tasks/{taskId}PATCH /v1/tasks/{taskId}DELETE /v1/tasks/{taskId}POST /v1/tasks/classifyPOST /v1/wishesGET /v1/wishesGET /v1/wishes/{wishId}PATCH /v1/wishes/{wishId}DELETE /v1/wishes/{wishId}PATCH /v1/wishes/{wishId}/milestones/{milestoneId}POST /v1/wishes/{wishId}/milestones/{milestoneId}/tips/{tipIndex}/toggleGET /v1/circlesPOST /v1/circlesGET /v1/circles/{circleId}PATCH /v1/circles/{circleId}DELETE /v1/circles/{circleId}GET /v1/circles/invitationsPOST /v1/circles/{circleId}/invitePOST /v1/circles/{circleId}/acceptPOST /v1/circles/{circleId}/declinePOST /v1/circles/{circleId}/leaveDELETE /v1/circles/{circleId}/members/{memberId}GET /v1/circles/{circleId}/goalsPOST /v1/circles/{circleId}/goalsDELETE /v1/circles/{circleId}/goals/{goalId}POST /v1/circles/{circleId}/invite-linksGET /v1/circles/{circleId}/invite-linksDELETE /v1/circles/{circleId}/invite-links/{linkId}GET /v1/circles/{circleId}/invite-links/{linkId}/qrGET /v1/circle-invite/{token}POST /v1/circle-invite/{token}/acceptPOST /v1/circle-invite/{token}/declineGET /v1/circle-invite/{token}/qrPOST /v1/circles/{circleId}/checkinGET /v1/circles/{circleId}/checkins/todayGET /v1/circles/{circleId}/checkins/historyGET /v1/circles/{circleId}/streakGET /v1/circles/{circleId}/winsPATCH /v1/circles/{circleId}/settings/checkinGET /v1/circles/{circleId}/commentsPOST /v1/circles/{circleId}/commentsPOST /v1/circles/{circleId}/comments/{commentId}/likeGET /v1/circles/{circleId}/comments/{commentId}/repliesDELETE /v1/circles/{circleId}/comments/{commentId}POST /v1/goals/{goalId}/invite-linkGET /v1/invite/{token}POST /v1/invite/{token}/acceptPOST /v1/invite/{token}/declineGET /v1/invite/{token}/qrGET /v1/goals/{goalId}/invite-linksDELETE /v1/goals/{goalId}/invite-links/{linkId}GET /v1/goals/{goalId}/invite-links/{linkId}/qrGET /v1/goals/{goalId}/participantsPOST /v1/goals/{goalId}/leaveDELETE /v1/goals/{goalId}/participants/{participantId}PATCH /v1/goals/{goalId}/participants/me/private-modeGET /v1/goals/{goalId}/participants/me/settingsPATCH /v1/goals/{goalId}/participants/me/settingsGET /v1/goals/{goalId}/commentsPOST /v1/goals/{goalId}/commentsDELETE /v1/goals/{goalId}/comments/{commentId}GET /v1/goals/{goalId}/reactionsPOST /v1/goals/{goalId}/reactionsDELETE /v1/goals/{goalId}/reactions/{reactionId}POST /v1/goals/{goalId}/reactions/toggleGET /v1/sse/eventsGET /v1/sse/goals/{goalId}GET /v1/sse/circles/{circleId}GET /v1/sse/healthGET /v1/sse/missed-updatesPOST /v1/uploads/presigned-urlPOST /v1/devices/registerPOST /v1/devices/unregisterGET /v1/subscription/statusPOST /v1/subscription/activatePATCH /v1/user/timezoneGET /v1/user/timezonePATCH /v1/user/profileGET /v1/user/profilePATCH /v1/user/profile-picturePOST /v1/user/profile-picture/uploadDELETE /v1/user/profile-pictureGET /v1/user/sessionsDELETE /v1/user/sessions/{sessionId}DELETE /v1/user/sessionsPOST /v1/user/change-passwordDELETE /v1/user/accountPOST /webhooks/revenuecatPOST /webhooks/replicatetext/event-stream with heartbeat pings.400; auth failures return 401; permission issues return 403; missing resources return 404.Typical authenticated request
curl -X GET "https://api.altaporta.com/api/v1/goals" \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json"
/docs is backed by a custom OpenAPI document at /doc-custom with bearer security preconfigured.