Browse the docs

Agent setup guide

Course Completion Upsell

Every day: students who just finished a Teachable course (found in code) get a congratulations and your next-course offer, after your approval.

Available About 15 min to set up

What it does

Every day: students who just finished a Teachable course (found in code) get a congratulations and your next-course offer, after your approval.

  • Every morning, reads your Students sheet and picks, in code, students who enrolled in the last 180 days and haven't had an offer.
  • Reads each one's courses from Teachable and finds, in code, the courses completed today or yesterday (Teachable has no completion event, so it checks daily).
  • AI writes a short congratulations with the next course from your offers list, with a discount code only if you give one.
  • Dates are worked out in code, never by the AI: days until or since each date, the window and business days are computed in your workflow's time zone, and records outside the window are skipped before the AI sees them.
  • The day's offers wait for one approval; each is checked in code, emailed and recorded in the sheet, so a student is offered once. Quiet days need no review.
  • The summary is counted in code from what each step really did (sent, held, skipped, failed), so it never reports a held message as sent.

What it needs

  • A paid plan (agents run live on paid plans).
  • An AI provider key (Settings → AI Providers).
  • Teachable (Growth plan or higher) and Google Sheets, connected in Settings → Integrations.
  • A Students tab (Enrolled | Name | Email | UserID | CourseID | Course | Upsell sent) with each student's Teachable user id.

What it doesn't do

  • It isn't instant: completions are found once a day.
  • It doesn't issue certificates, enroll students or create coupons in Teachable.
  • Up to 50 students checked per run; nothing is sent without your approval.

Availability and plans

Available

Its workflow is built and tested, and every app it needs is live. You can get it and set it up now.

Included free on the Enterprise plan; on other paid plans it's a one-time purchase per workspace (the price is on the Agents page). The Agents page in the app always shows its current status.

Before you start

  • A paid plan: agents run live, and the Free plan only runs Dry Runs.
  • An AI provider key (OpenAI, Anthropic, Google and more) in Settings → AI Providers. AI usage is billed by your provider.
  • These apps, connected in Settings → Integrations: Google Sheets and Teachable.
  • Nothing to send: the agent runs on a schedule.
  • About 15 minutes.

Set it up step by step

Get the agent first (buy it, or it's already yours when your plan includes it), then in Agents → My agents press “Set up this agent”. That creates the agent's workflow in your workspace (it counts towards your plan's workflow limit) and opens the canvas with a setup checklist above it. Each item links to the exact place to go and ticks itself off when it's done.

1. Connect your AI provider

The AI steps run on your own key (OpenAI, Anthropic, Google and more). Add one in Settings → AI Providers.

2. Connect Google Sheets

Connect the Google account that can open your Students sheet.

3. Connect Teachable

Connect Teachable with a school API key (Growth plan or higher).

4. Pick the Students sheet

Open “Read your Students sheet” and pick the account, spreadsheet and tab, then pick your school on “Read their courses”.

SettingWhat to enterIn step
Google account (Students)The Google account that can open the spreadsheet. Pick your connected Google Sheets account.“Read your Students sheet”
Students spreadsheetPaste the link of the spreadsheet.“Read your Students sheet”
Students tabThe tab with one row per student (Enrolled | Name | Email | UserID | CourseID | Course | Upsell sent).“Read your Students sheet”
Teachable schoolThe Teachable school your students are in. Pick your connected Teachable account.“Read their courses”

5. List your offers

Open “Write the congratulations and offers” and replace the placeholder, then enter the Reply-to on “Email the offer”.

SettingWhat to enterIn step
Your next-course offersReplace the placeholder with the next course (and link, and any discount code with its exact terms) for each course, your school name, tone and sign-off. It starts as “[FOR EACH COURSE: THE NEXT COURSE TO OFFER WHEN A STUDENT FINISHES IT, ITS LINK, ANY DISCOUNT CODE AND ITS EXACT TERMS (OR NONE); ALSO YOUR SCHOOL NAME, YOUR TONE AND YOUR SIGN-OFF]” until you replace it.“Write the congratulations and offers”
Your inbox (replies)Students' replies come back to this address.“Email the offer”

6. Where to record offers

Open “Record it in the sheet”: the same account, spreadsheet and tab, and the Upsell sent column letter.

SettingWhat to enterIn step
Google account (recording, same one)The same Google account. Pick your connected Google Sheets account.“Record it in the sheet”
Students spreadsheet (same one)The same spreadsheet.“Record it in the sheet”
Students tab (same one)The same tab.“Record it in the sheet”
Upsell sent column letterThe letter of the Upsell sent column, e.g. G.“Record it in the sheet”

7. Your summary

Open “Email your summary” and enter your email and Reply-to.

SettingWhat to enterIn step
Your email (summary)Who gets the daily summary when offers were sent. Replace the example address. It starts as “you@your-business.example” until you replace it.“Email your summary”
Reply-to on the summaryUsually your own address.“Email your summary”

8. Test it with Dry Run

Press Dry Run: the agent runs on sample data with no messages sent and nothing written to your apps.

9. Switch the trigger on

Open the trigger, set your time zone and switch the schedule on. It runs every day at 10:00.

How it works

The agent is a normal workflow with 24 steps (1 AI step, with a person approving in Reviews). You can open, edit and monitor it like any other workflow.

  • Every day at 10:00 — Runs on a schedule (cron 0 10 * * *, UTC — change it in the trigger's settings). Runs every morning. Set your time zone on the trigger: completion dates are judged in that zone.
  • Read your Students sheet — Google Sheets: Read rows. Reads your Students tab (Enrolled | Name | Email | UserID | CourseID | Course | Upsell sent), e.g. the one Course Student Onboarding fills.
  • Pick students to check — Step. In code, not AI: students who enrolled in the last 180 days and haven't been sent an offer (blank Upsell sent cell). Change the 180 days here (within.min).
  • Each student — Repeats the steps below for each item (up to 50 per run). Checks each student's courses in Teachable (up to 50 per run).
  • [For each item — “Each student”] Read their courses — Teachable: Get a user. Reads the student's courses from Teachable, with each course's completion date.
  • [For each item — “Each student”] Finished recently? — Step. In code: the courses this student completed today or yesterday (your time zone).
  • Write the congratulations and offers — AI step (runs on your AI provider key). AI writes a short congratulations and the next-course offer from your offers list for each student who just finished a course.
  • Anyone finished? — Step. In code: is there at least one offer to approve? Quiet days end here with no review.
  • Offers to approve? — Decision: picks the branch to follow. No one finished: nothing to approve today.
  • No one finished — Kept in the run history. Branch: No one finished. No completions today: nothing to send.
  • Approve the offers — A person approves or rejects it in Reviews (the run waits). Branch: Offers. Today's congratulations and offers wait in Reviews together: edit any, set send to false on any that shouldn't go, and approve.
  • Each approved offer — Repeats the steps below for each item (up to 50 per run). Branch: Approved. Checks, sends and records every approved offer.
  • [For each item — “Each approved offer”] Check before sending — Step. In code: still marked to send, one valid email, a link and no placeholders.
  • [For each item — “Each approved offer”] Send it? — Decision: picks the branch to follow. Passes: emailed and recorded in the sheet. Otherwise held.
  • [For each item — “Each approved offer”] Held — Kept in the run history. Branch: Held. Set to not send, no valid email or no link; listed in the summary.
  • [For each item — “Each approved offer”] Already offered? — Recalls what it remembered earlier (memory “course-completion-upsell”). Branch: Passes. Remembers every student who was sent an offer (kept a year), so an older batch approved late never emails them twice.
  • [For each item — “Each approved offer”] New? — Decision: picks the branch to follow. Already offered: skipped.
  • [For each item — “Each approved offer”] Already offered — Kept in the run history. Branch: Already offered. This student was already sent an offer; nothing was sent.
  • [For each item — “Each approved offer”] Email the offer — Sends an email from your workspace's sender. Branch: New. Sends the congratulations and offer, with replies to your inbox.
  • [For each item — “Each approved offer”] Record it in the sheet — Google Sheets: Update a row. Writes today's date into the student's Upsell sent cell, so they're offered once.
  • [For each item — “Each approved offer”] Remember the offer — Remembers it for later runs (memory “course-completion-upsell”, kept 365 days). Marks this student as offered for a year.
  • Count what happened — Step. In code, not AI: offers sent, held or already sent, with the reason.
  • Email your summary — Sends an email from your workspace's sender. Emails you today's sent and held offers, counted in code.
  • Done — Kept in the run history. The run history keeps every offer and the summary.

Test it with Dry Run

Press Dry Run in the canvas. The agent runs on the sample data stored on its trigger (the “Sample data for Dry Run” box), so you can check every step's output before anything is live.

  • Nothing is sent or written: app actions, emails and Slack posts are simulated, and AI steps don't call your AI provider.
  • Approval steps use the Dry Run decision you pick in the step's settings (approved, rejected or timeout), so you can try each branch.
  • For-each loops repeat only the first 3 items.
  • Memory steps don't read or write stored memory: a recall finds nothing, and a save only shows what it would store.

Go live

  • Open the trigger, set your time zone and switch the schedule on. It runs every day at 10:00.
  • Scheduled runs start only once the schedule is activated, and can't repeat faster than your plan's minimum interval.
  • The setup checklist adds a “paid plan” item before activation: live runs need a paid plan (the Free plan only runs Dry Runs).
  • When every checklist item is done and the trigger is on, the checklist says “Live — this agent is running”. Follow its runs in the workflow's History tab and in Analytics → Agents.

Questions

How does it know someone finished?

Teachable's API has no completion event, so once a day it reads each recent student's courses with Teachable's “Get a user” and code checks each course's completion date. A completion is picked up the same day or the next morning.

Which students does it check?

Students in your Students tab who enrolled in the last 180 days and haven't been sent an offer yet, up to 50 per run. Change the 180 days on “Pick students to check”.

Does it issue certificates?

No. Pair it with Completion Certificate Sender if you issue certificates.

Troubleshooting

  • “No AI provider connected” or a rejected key: connect or fix the key in Settings → AI Providers, then press Test there.
  • A checklist item stays unticked: the setting is still empty or still contains its placeholder text. Open the step from the checklist and fill it in.
  • An app step fails with “Needs reconnect”: the account's access was revoked or expired. Reconnect it in Settings → Integrations.
  • It didn't run at the expected time: the schedule must be activated, and its time is in the trigger's timezone.
  • A run shows as paused: it's waiting for someone in Reviews to approve or reject it.
  • A step failed: open the run in History and check that step in the Trace tab for the error and what it received.

Generated from the agent's own workflow, so it always matches what the agent does. Last updated .