Inspiration

We've all been there — a great idea strikes mid-commute, during a workout, or while staring at a whiteboard. By the time you open a note-taking app and navigate to the right document, the thought is gone or diluted. We wanted to remove that friction entirely: capture anything (voice, image, or text) and have it automatically land in exactly the right place — your Notion page, Google Doc, or Slack channel — without you having to decide where it goes.

What it does

NoteRoute lets you say it, snap it, or type it — and routes the content to the right destination automatically.

  • Record a voice note → transcribed via AWS Transcribe, embedded, semantically matched to your best-fit slot (a Notion page, Google Doc, Slack channel, etc.), then delivered there
  • Snap a photo → Claude Vision extracts text or describes the image, then the same routing pipeline runs
  • Type a note → same pipeline, no transcription step

Supported integrations: Notion, Google Docs/Drive, Slack, Todoist, Trello. Available on ***web* (Next.js). Coming soon to iOS/Android (Expo)

How we built it

Four services, each with a clear responsibility:

Service Stack
Backend FastAPI + MongoDB (Beanie) + Firebase Auth
LangGraph microservice Python, LangGraph pipeline (transcribe → embed → search → rank → confirm → deliver)
Mobile Expo / React Native, Zustand
Web Next.js 15, Tailwind, shadcn/ui

The pipeline runs as a LangGraph state machine. Input arrives (audio, image, or text), branches to the correct entry node, gets embedded with AWS Bedrock, then vector-searched against the user's pinned slots stored in Pinecone Vectors. The top match is confirmed and the note is delivered via the provider's API. The entire pipeline streams status updates to the client over SSE.

OAuth for Google, Slack, Todoist, and Trello is handled with a unified callback pattern — web vs. mobile is distinguished by a ?platform=web flag so callbacks redirect to the right place (deep link vs. /oauth/callback page).

Both services are deployed on Railway via Dockerfile.

Challenges we ran into

  • Railway inter-service networking: containers can't resolve their own project's public .up.railway.app domains from within Railway. We had to switch all intra-project calls to .railway.internal private hostnames, which wasn't obvious from the docs.
  • PORT binding: Railway injects $PORT dynamically. Using exec-form CMD in Dockerfile prevents shell variable expansion, causing Railway's proxy to 502. Switching to shell-form CMD and pinning PORT explicitly in Railway Variables fixed it.
  • Todoist API deprecations: REST v2 and Sync v9 both returned 410 Gone. We had to discover and migrate to their undocumented v1 API during the hackathon.
  • Image OCR routing: integrating a new entry node into the LangGraph graph without breaking existing audio/text routing required careful conditional edge design.
  • OAuth state across platforms: keeping web and mobile OAuth flows using the same backend callback endpoint without separate routes required encoding platform context into the OAuth state parameter.

Accomplishments that we're proud of

  • A single LangGraph pipeline handles audio, image, and text inputs with branching at the graph level — no duplicate logic
  • Five OAuth integrations with a unified pattern that required adding just one file and a handful of elif branches per new provider
  • Streaming SSE status updates from deep inside a LangGraph node all the way to a React Native screen and a Next.js page, with identical UX on both
  • The web app is fully feature-parity with mobile (record, image capture, source management, OAuth) built with the same backend

What we learned

  • LangGraph is well-suited to pipelines with conditional branching and shared state, but graph topology needs to be planned upfront — retrofitting new entry points is painful
  • Railway's networking model (public vs. private domains) is not well-documented; internal service communication must use private networking explicitly
  • Building two frontends (mobile + web) in parallel against one backend forces cleaner API design — every ambiguity in the contract surfaces immediately
  • Claude Vision is remarkably capable as a first-pass OCR and content extraction layer without any fine-tuning

What's next for NoteRoute: Say it. Snap it. Route it.

  • Smart routing confidence scores — show the user why a slot was chosen and let them correct it to improve future routing
  • More integrations — Linear, GitHub Issues, Obsidian, email (via SMTP)
  • Scheduled digests — batch voice notes captured throughout the day and deliver a summarized digest to a chosen slot at a set time
  • On-device processing — run a lightweight embedding model locally so routing works offline and notes sync when connectivity returns
  • Team workspaces — shared slot libraries so a team can collectively route notes into a shared Notion workspace or Slack channel

Built With

Share this project:

Updates