← Back

Use your own AI with Throughway

Let Claude, ChatGPT or an AI running on your own computer read your sessions, notes and clients, so it can write reports, brief you before a call and log notes for you.

Is an AI reading this for you?
Give it the plain-text version: the same page, written for it.
/docs/ai.md openapi.json
Quickstart

Connected in three steps

  1. 1
    Connect your AI
    1. In Claude (claude.ai, the desktop app or the phone app), open Settings › Connectors and choose Add custom connector.
    2. Name it “Throughway”, paste this address and choose Connect:
      https://staging.throughway.app/api/v1/mcp
    3. Throughway opens. Sign in and choose Read only or Read and log notes.

    Once added it works in Claude on the web, on your desktop and on your phone.

    1. In ChatGPT, open Settings › Plugins, choose Add, then Add custom MCP server.
    2. Name it “Throughway”, paste this address as the Server URL and choose OAuth:
      https://staging.throughway.app/api/v1/mcp
    3. Accept the warning, choose Create as a plugin, then Install.
    4. Sign in to Throughway and choose Read only or Read and log notes.

    Until Throughway is listed in ChatGPT's plugin directory, you add it yourself. Custom plugins need a paid plan, and some workplaces turn them off.

    1. Ollama, LM Studio and other AIs on your own computer can't do a browser sign-in, so they use a key. Mint a Read only key in Settings › Your AI.
    2. Then run the script in the weekly report recipe below.

    Your transcripts never leave your machine.

    1. In a terminal, run:
      claude mcp add --transport http throughway https://staging.throughway.app/api/v1/mcp
    2. In Claude Code, run /mcp, choose throughway, then Authenticate and sign in to Throughway.
  2. 2
    Sign in and choose what it may do

    Read only for reports and briefings. Read and log notes if you want it to add notes for you. You can disconnect it at any time.

  3. 3
    Ask it something

    “Summarise my sessions with Priya Raman this month and what she committed to.”

Recipes

Things to ask your AI

A weekly report from a local LLM

In Claude or ChatGPT, paste this:

Using Throughway, read my sessions from the last 7 days, with summaries. Write my weekly coaching report: one paragraph per client, the themes across clients, and anything I promised to follow up on.

With an AI on your own computer (Ollama, LM Studio), where transcripts never leave your machine, you or a technical friend can run this script:

import requests, ollama
from datetime import datetime, timedelta, timezone
API = "https://staging.throughway.app/api/v1"
H = {"Authorization": "Bearer trw_…"}
since = (datetime.now(timezone.utc) - timedelta(days=7)).strftime("%Y-%m-%dT%H:%M:%SZ")
rows, cursor = [], None
while True:
    page = requests.get(f"{API}/sessions", headers=H, params={
        "started_since": since, "include": "transcript", "cursor": cursor}).json()
    rows += page["data"]
    if not (cursor := page["next_cursor"]): break
report = ollama.generate(model="llama3.1",
    prompt="Write my weekly coaching report:\n" + str(rows))
print(report["response"])

Transcripts are long. If summaries are enough, leave include out and the run is much faster.

Prep for tomorrow's calls

In Claude or ChatGPT, paste this:

Look at my calendar for tomorrow. For each client I'm meeting, use Throughway to read our last two sessions and my recent notes, then give me a one-page briefing: where we left off, what they committed to, and what to ask.

Your AI also needs to see your calendar (for example Claude's Google Calendar connector). Throughway gives it the history, not the schedule.

Log notes from your inbox

In Claude or ChatGPT, paste this:

Find the email from Priya Raman about her promotion and log a note on her Throughway client with the gist and any dates.

Your AI needs Read and log notes access, plus its own email connector.

For a voice memo, paste the transcript and ask it to log a note on the right client. Throughway never reads your email for your AI.

Sync your pipeline to a sheet

In Claude or ChatGPT, paste this:

Using Throughway, list my clients with their stage and last contact, and put them in a Google Sheet called Pipeline. Update the sheet if it already exists.

Your AI also needs its Google Drive or Sheets connector.

For developers

API reference

Sign in with OAuth (chat AIs) or send an API key as a bearer token (scripts) · JSON · lists page with cursor · errors as {"error": {"code", "message"}}.

Clients 5 endpoints · read & write

A person you coach, or might. Everything in the pipeline is a client.

  • get /api/v1/clients — List clients, filtered and paginated.
  • post /api/v1/clients — Create a client.
  • get /api/v1/clients/{id} — Fetch one client.
  • patch /api/v1/clients/{id} — Update a client. Only the fields you send change.
  • get /api/v1/clients/{id}/timeline — Everything that has happened with a client, newest first — notes, sessions, stage changes, emails, files.
Field Type Description
id integer Throughway's identifier for this client.
name string The client's full name, as you'd write it on a card. Writable.
stage string Where the client sits in the pipeline. Changing it records a stage transition. Null means the person is in the book only, off the board. Writable. One of: nurturing, in_conversation, chemistry_scheduled, deciding, onboarding, active, complete.
email string The client's email address. Writable.
organization string The organization the client works for. Writable.
source string How this client came to you. Writable.
red_flags string Anything to watch out for. Writable.
running_notes string Your rolling notes on this client. Writable.
outcome_note string How the engagement ended. Writable.
timezone string IANA time zone, e.g. `America/New_York`. Writable.
entered_stage_at datetime When the client entered its current stage.
last_contact_at datetime When you last had contact.
inserted_at datetime When the client was created.
updated_at datetime When the client last changed.
Filters
  • stage — One stage, or several comma-separated. Only clients in those stages are returned.
  • q — Case-insensitive substring over name, email and organization.
  • updated_since — ISO 8601 timestamp — only clients changed since then.
  • limit — Page size. Defaults to 50, capped at 200.
  • cursor — The next_cursor from the previous page.
Notes 5 endpoints · read & write · delete

A logged contact with a client — a note, a call, a meeting, a message. This is what a client's timeline calls a note.

  • get /api/v1/interactions — List logged notes, filtered and paginated. Newest logged first.
  • post /api/v1/interactions — Log a note, call, meeting or message against a client.
  • get /api/v1/interactions/{id} — Fetch one logged note.
  • patch /api/v1/interactions/{id} — Update a logged note. Only the fields you send change; it cannot be moved to another client.
  • delete /api/v1/interactions/{id} — Delete a logged note.
Field Type Description
id integer Throughway's identifier for this note.
client_id integer Which client this note is about. Set when you log it; an update cannot move it. Set on create.
type string What kind of contact this was. Writable. One of: call, email, meeting, message, note.
note string The note itself, plain text, stored and returned exactly as you send it. Writable.
occurred_at datetime When it happened, ISO 8601. Omit it and you get now. Writable.
source string Who logged this note: `coach` when the coach logged it in Throughway, `agent` when an AI logged it through this API. Set by Throughway; a value you send is ignored. One of: coach, agent.
inserted_at datetime When the note was logged.
updated_at datetime When the note last changed.
Filters
  • client_id — Only this client's notes.
  • type — One type, or several comma-separated: call, email, meeting, message, note.
  • occurred_since — ISO 8601 — only notes that occurred at or after this.
  • limit — Page size. Defaults to 50, capped at 200.
  • cursor — The next_cursor from the previous page.
Sessions 2 endpoints · read-only

A coaching session, call or meeting with a client — its notes, saved summary and transcript. Read-only.

  • get /api/v1/sessions — List sessions, filtered and paginated. Newest created first. Transcripts and your auto supervision are left out unless you ask for them.
  • get /api/v1/sessions/{id} — Fetch one session, transcript and your auto supervision included.
Field Type Description
id integer Throughway's identifier for this session.
client_id integer Which client the session was with.
kind string What kind of session this was. One of: session, chemistry_call, imported, stakeholder_interview, meeting.
status string Whether the session is still in progress or has ended. One of: in_progress, ended.
started_at datetime When the session started.
ended_at datetime When the session ended. Null while it is in progress.
length_minutes integer How long the session was, in minutes. Null when no length is known yet.
body string Your notes from the session.
summary string The session's saved summary.
transcript string The transcript as plain text, or null. Omitted from list rows unless you pass include=transcript.
transcript_entries array The transcript as speaker-labelled turns, or null. Omitted from list rows unless you pass include=transcript.
supervision string Your auto supervision of this session, as Markdown: the write-up's summary, what worked and what is worth sitting with, with quotes. Null when you have no auto supervision of this session or it has no write-up yet. Omitted from list rows unless you pass include=supervision.
inserted_at datetime When the session was created.
updated_at datetime When the session last changed.
Filters
  • client_id — Only this client's sessions.
  • kind — One kind, or several comma-separated: session, chemistry_call, imported, stakeholder_interview, meeting.
  • started_since — ISO 8601 — only sessions that started at or after this.
  • started_before — ISO 8601 — only sessions that started strictly before this.
  • include — transcript adds transcript and transcript_entries to each row; supervision adds supervision.
  • limit — Page size. Defaults to 50, capped at 200.
  • cursor — The next_cursor from the previous page.
Documents 5 endpoints · read & write · delete

A client's Throughway page or Google Doc, which you can write, or a file or link, which you can only read. Anything you create is private.

  • get /api/v1/documents — A client's documents, newest first. Metadata only, no bodies.
  • get /api/v1/documents/{id} — One document, with its body as Markdown.
  • post /api/v1/documents — A new page, or a new Google Doc in the client's Drive folder.
  • patch /api/v1/documents/{id} — Rename it, replace its body, or both.
  • delete /api/v1/documents/{id} — Remove it from the client. A Google Doc goes to the coach's Drive trash.
Field Type Description
id integer Throughway's identifier.
client_id integer Which client it belongs to. An update can't move it. Set on create.
kind string page and google_doc are writable. A list also shows file and link, read-only. Set on create. One of: page, google_doc, file, link.
title string For a Google Doc, also its name in Drive. Writable.
body string Markdown. Converted to HTML for a page and to Google Docs formatting for a Google Doc. An update replaces the whole body; there is no append. Null for a file, a link, or a Google Doc Throughway can't reach. Never in list rows. Writable.
visibility string Always private on create. Only the coach shares, in the app. One of: private, shared.
url string The Google Doc's link, or the page's link in Throughway.
hidden string Hidden from the coach's Files and Timeline: coach (they hid it) or auto (a signature image or calendar attachment). Null when visible. One of: coach, auto.
inserted_at datetime When the document was created.
updated_at datetime When the document last changed.
Filters
  • client_id — Required. Only this client's documents.
  • kind — One kind, or several comma-separated: page, google_doc, file, link.
  • limit — Page size. Defaults to 50, capped at 200.
  • cursor — The next_cursor from the previous page.
People 30 endpoints · read & write · delete

Someone in the coach's people book, as the iPhone app shows them: how to reach them, when they are next due, their open next steps and last notes. REST only; not an MCP tool.

  • get /api/v1/people — The people book, A–Z by name. With `updated_since`, also `deleted_ids`: the people deleted or archived since then.
  • get /api/v1/people/{id} — One person, with their open next steps, last 3 notes and how many notes they have.
  • post /api/v1/people — Add someone to the people book. They are not put on the board.
  • patch /api/v1/people/{id} — Change a person's details. Only the fields you send change.
  • put /api/v1/people/{id}/tier — Set how often to keep in touch, or clear it with null.
  • put /api/v1/people/{id}/photo — Give a person a photo when they have none. The body is the JPEG itself (`Content-Type: image/jpeg`, at most 5 MB); a person who already has one answers 409 `photo_exists`.
  • post /api/v1/people/{id}/snooze — Hold a person back until a later day, or skip them till next time.
  • post /api/v1/people/{id}/done — Log that you reached out: a "Reached out" note, so they are next due one interval from today.
  • post /api/v1/people/{id}/archive — Archive a person: out of the book and off Today until unarchived. Already archived answers them unchanged.
  • post /api/v1/people/{id}/unarchive — Bring an archived person back into the book.
  • post /api/v1/people/{id}/take_off_board — Take a potential client off the pipeline board, keeping them in the book. Someone not on the board, or an active or past client, is 422 on `stage`.
  • delete /api/v1/people/{id} — Delete a person and everything about them. A delta sync then lists them in `deleted_ids`.
  • post /api/v1/people/{id}/follow_ups — Schedule a text to a person, due at a later time. They need a phone on file.
  • post /api/v1/people/{id}/check_ins — Start AI-drafted check-in texts at 9:00, until their next session or two weeks out. One open series per person; they need a phone on file.
  • get /api/v1/people/{id}/notes — A person's notes, newest logged first.
  • get /api/v1/people/{id}/timeline — What has happened with a person, newest first — notes, sessions, emails, failed follow-ups. Nothing still ahead: that is the person's `coming_up`.
  • post /api/v1/people/{id}/notes — Log a note about a person.
  • post /api/v1/people/{id}/next_steps — Add a next step for a person.
  • patch /api/v1/next_steps/{id} — Mark a next step done, or reopen it.
  • patch /api/v1/notes/{id} — Change a note's text.
  • delete /api/v1/notes/{id} — Delete a note.
  • get /api/v1/reach_out — The day's three people to reach out to — the same three as Today, so either spends the day's slots — with today's meetings, the next steps due and the follow-up due texts.
  • get /api/v1/loose_ends — The people you met or wrote to who aren't in the book yet, waiting to be added or ignored.
  • post /api/v1/loose_ends/{id}/add — Add a suggested person to the people book, off the board, with a tier or none.
  • post /api/v1/loose_ends/{id}/ignore — Never suggest this address again.
  • post /api/v1/follow_ups/{id}/texted — Mark a due follow-up text as sent: a "Texted" note, which counts as reaching out. Already texted, skipped or cancelled answers its status as it stands.
  • post /api/v1/follow_ups/{id}/skip — Skip a due follow-up text, logging nothing. Already texted, skipped or cancelled answers its status as it stands.
  • post /api/v1/captures/propose — Read a note's transcript and propose the person it is about — matched against the book or new — with a tier, a next step and the tidied note. Nothing is saved. Audio is never accepted.
  • get /api/v1/groups — Your groups, A–Z by name.
  • post /api/v1/groups — Add a group. A blank name, or one you already have in any case, is 422 on `name`.
Field Type Description
id integer Throughway's identifier for this person.
name string The person's full name. Writable.
organization string Where they work. Writable.
title string Their role, e.g. `COO`. Writable.
email string Their primary email address. Writable.
phone string Their phone number, as written. Writable.
phone_apps array The apps their phone is also on, from `whatsapp` and `signal`; `[]` when none. Cleared with the phone. Writable. One of: whatsapp, signal.
facebook_username string Their Facebook username. A profile link is accepted and stored as the username. Writable.
linkedin_url string Their LinkedIn profile, stored as `linkedin.com/in/…`. A profile link, `@name` or bare name is accepted; a company page or any other link is refused. Writable.
tier string How often to keep in touch: every_2_weeks, monthly, quarterly, twice_a_year or yearly. Null is untiered. Writable. One of: every_2_weeks, monthly, quarterly, twice_a_year, yearly.
due_on date The day they are next due, in the coach's time zone. Null when untiered.
snooze_until date Held back until this day, or null.
last_touch object The latest contact as `{kind, at}`, or null.
preferred_method string The coach's preferred way to reach them, or null. Writable. One of: text, call, email, whatsapp, signal, linkedin, messenger.
ways_to_reach object `{available, primary, preferred, preferred_available}`: the ways their details allow, the one to use first, the stored preference and whether it is available.
photo_url string Their photo, an absolute URL, or null when they have none.
updated_at datetime When the person last changed.
stage string Their pipeline stage, or null when they are in the book only. One person only. One of: nurturing, in_conversation, chemistry_scheduled, deciding, onboarding, active, complete, not_a_fit.
days_in_stage integer Whole days since they entered their stage, in the coach's time zone. Null with no stage.
timezone string Their own time zone, e.g. `Europe/Lisbon`, or null. One person only. Writable.
groups array The names of the groups they are in, A–Z. One person only.
group_ids array The ids of the groups they are in, in `groups`' order. Sent, it is their exact membership; an id that is not one of your groups is refused and nothing is written. Writable.
archived_at datetime When they were archived, or null. One person only.
background string What the coach keeps in mind about them, or null. One person only. An empty string or null clears it. Writable.
source string Where this person came from, e.g. `iPhone Contacts`, or null. One person only. Writable.
bill_to string Who their invoices are made out to, or null. One person only. Writable.
billing_email string Where their invoices are sent, or null. One person only. Writable.
look_for_transcripts boolean Whether their meetings' transcripts are looked for. One person only. Writable.
next_steps array Their open next steps, soonest due first. One person only, never in list rows.
notes array Their last 3 notes, newest first. One person only, never in list rows.
notes_count integer How many notes they have in all. One person only.
coming_up array What is still ahead, soonest first: `meeting`, `follow_up`, `check_in_series` or `next_step`. `at` is an ISO datetime (a next step's a date) or null; `title` the meeting's session label or event title, a follow-up's text or subject, a step's body, null for a series; `detail` per kind. One person only.
Filters
  • q — Case-insensitive substring over name, organization, title and every email address.
  • tier — One tier: every_2_weeks, monthly, quarterly, twice_a_year, yearly, or none for the untiered.
  • updated_since — ISO 8601 — only people changed at or after this. Adds deleted_ids : the people deleted or archived since.
  • cursor — The next_cursor from the previous page.
  • limit — Page size. Defaults to 50, capped at 200.
A client's timeline 1 endpoint · read-only
  • get /api/v1/clients/{id}/timeline — Everything that has happened with a client, newest first — notes, sessions, stage changes, emails, files.

Everything that has happened with a client, newest first — notes, sessions, stage changes, contracts, invoices, email threads, files, pages and shares — merged into one list. Every event carries the same six keys: at, kind, id, title, body and detail. id is null for an event that is not a row you can fetch, and body is non-null for interaction events only — every other kind's content belongs to a resource of its own. Email bodies and snippets are never included.

before is an exclusive filter on at, not a cursor: the merged feed has no unique monotonic key, so exhaustive cursor paging over it cannot be made correct. The response says has_more rather than next_cursor for exactly that reason. If you need every row of one kind, page that kind's own endpoint, which does have a correct cursor.

limit is how many events come back — 50 by default, 200 at most. A truncated page says has_more: true; walk backwards by passing the at of the last event you got as the next before.

MCP tools 17 tools

The same operations are available as MCP tools at https://staging.throughway.app/api/v1/mcp — JSON-RPC 2.0 over streamable HTTP, JSON responses, stateless. A chat AI signs in with OAuth; a script sends a key as Authorization: Bearer trw_…. A read-only connection is only ever offered the read tools.

  • list_clients — List clients, filtered and paginated.
  • create_client — Create a client.
  • get_client — Fetch one client.
  • update_client — Update a client. Only the fields you send change.
  • get_client_timeline — Everything that has happened with a client, newest first — notes, sessions, stage changes, emails, files.
  • list_interactions — List logged notes, filtered and paginated. Newest logged first.
  • create_interaction — Log a note, call, meeting or message against a client.
  • get_interaction — Fetch one logged note.
  • update_interaction — Update a logged note. Only the fields you send change; it cannot be moved to another client.
  • delete_interaction — Delete a logged note.
  • list_sessions — List sessions, filtered and paginated. Newest created first. Transcripts and your auto supervision are left out unless you ask for them.
  • get_session — Fetch one session, transcript and your auto supervision included.
  • list_documents — A client's documents, newest first. Metadata only, no bodies.
  • get_document — One document, with its body as Markdown.
  • create_document — A new page, or a new Google Doc in the client's Drive folder.
  • update_document — Rename it, replace its body, or both.
  • delete_document — Remove it from the client. A Google Doc goes to the coach's Drive trash.
Errors, paging & limits

A list answers {"data": [...], "next_cursor": "1042"}. Pass next_cursor back as cursor to get the next page; it is null on the last one, and a page that comes back empty means you are done. limit is the page size — 50 by default, 200 at most. Each resource's own filters are listed with its fields above.

{"error": {"code": "validation_failed",
       "message": "The record could not be saved.",
       "fields": {"name": ["can't be blank"]}}}

Codes and statuses: bad_request 400, unauthorized 401, forbidden 403, not_found 404, validation_failed 422. fields appears only for validation_failed. A record belonging to another practice answers 404, never 403.

Authentication

There are two ways in. A chat AI — Claude, ChatGPT, Claude Code — signs in with OAuth: it discovers Throughway's authorization server at https://staging.throughway.app/.well-known/oauth-protected-resource, and the coach signs in and approves Read only or Read and log notes.

A script or an AI on your own computer sends an API key as a bearer token on every request, from a key minted in Settings › Your AI:

curl -H "Authorization: Bearer trw_…" https://staging.throughway.app/api/v1/clients

No credential, an unknown one or a revoked one all answer 401 with the same body. Read only access answers 403 on any write.

What your AI can't do

Your AI can't delete a client or send email for you. It never sees email bodies or a client's portal link.