Privacy Policy
Version privacy-2.0.0-draft · in force from Not yet effective. This version is unpublished and no user has been asked to agree to it. An effective date is set on publication.
Draft — not in force. This document has not been reviewed by an attorney and is published here only so the pipeline that publishes it can be tested. Nothing on this page is an offer, a representation, or a term of any agreement.
- The source still carries the "NOT REVIEWED BY COUNSEL" banner.
- The version string is "privacy-2.0.0-draft".
- 6 unresolved placeholder(s): [LIKE THIS] [COMMERCIAL MAIL ADDRESS] [REGISTERED AGENT NAME AND UTAH STREET ADDRESS] [NOT BUILT] [FUTURE] [CONFIRM WITH COUNSEL].
Course++ — a product of CoursePlusPlus LLC
| Document version | privacy-2.0.0-draft — recorded with each user's agreement |
| Effective date | Not yet effective. This version is unpublished and no user has been asked to agree to it. An effective date is set on publication. |
| Company | CoursePlusPlus LLC, a Utah limited liability company, entity number 14736627-0160, formed 10 September 2026 |
| Mailing address | [COMMERCIAL MAIL ADDRESS] |
| Registered agent | [REGISTERED AGENT NAME AND UTAH STREET ADDRESS] |
| Privacy contact | [email protected] |
| Support contact | [email protected] |
| Security contact | [email protected] (see security.txt) |
Drafting note — do not publish this note. Sections tagged
[NOT BUILT]describe a design that is not in the product. They are kept, rather than deleted, because they are where this is headed and because an institution reading this page deserves to know the difference between a protection that exists and one that is planned. A privacy policy that describes behaviour the product does not have is the same mismatch risk as one that omits behaviour it does have, which is why every such block says plainly that it is not built. Convert each one to present tense in the same change that ships the feature, and update the Chrome Web Store data disclosures in the same release.The previous draft used a
[FUTURE]tag that read, to a casual eye, as a roadmap note. It has been replaced throughout with[NOT BUILT], which cannot be misread.
01
1. The short version
Course++ is a browser extension that helps an instructor build course material inside Canvas.
- Course++ works through the Canvas login you already have. There is nothing to install on your school's systems and no Canvas API token to create.
- Your course material is read and written directly between your browser and Canvas. That traffic does not pass through us.
- What you ask Course++ to write does pass through our server on its way to the AI model that drafts it. We use it to complete your request and to count what it cost. We do not store it, we do not log it, and we keep no copy of the conversation — with one narrow, deliberate exception: when something genuinely goes wrong (a write Canvas refused, a step that could not be verified, a build that ran out of credits), we keep the last few messages of that conversation for 90 days so we can actually help. See section 4.8.
- By default Course++ cannot read student work, grades, rosters or enrolments at all. Those addresses are refused in your browser before a request is built. There is one setting, off by default, that lifts that refusal — section 5.3 describes exactly what it does, including what it does not protect.
- We store an account, a balance, and one accounting row per request. Not what you wrote, not what the model wrote back — except the narrow error-report exception described above.
- Anything you attach to a message goes to the AI model, the same as anything you type. We cannot inspect a file the way we can refuse a Canvas address. See section 5.6.
- We run no analytics and no advertising, in the extension or on our website. There is no third-party tracking code anywhere in either.
- Course++ writes two small housekeeping files into your own Canvas course, so your build history survives a new computer. See section 8.2.
Everything below is the long version. If a sentence in the short version and a sentence in the long version disagree, the long version governs — but tell us, because that means we wrote it badly: [email protected].
02
2. Words we use in a specific way
These terms mean the same thing in this policy, in the Terms of Service, in the FERPA posture page and in the DPA rider.
| Term | What it means here |
|---|---|
| Course++ | The browser extension and the service that supports it. |
| We, us, our | CoursePlusPlus LLC. |
| You | The person who holds a Course++ account — an instructor or other instructional staff member. |
| Canvas | The Canvas LMS instance your institution operates. Canvas is a product of Instructure, Inc. We are not affiliated with Instructure, Inc. |
| Institution | The school, district, college or university whose Canvas you use. |
| Course Content | Pages, assignments, quizzes, syllabi, modules, files, calendar events and similar material that is not about an identifiable student. |
| Student Data | Student work and records: submissions, grades, rosters, enrolments, discussion replies, per-student analytics, and anything else identifying an individual student. |
| Class Statistics | Class-level totals only — for example "18 of 24 submitted", or which quiz items were missed most. No per-student rows, no names, no student work. [NOT BUILT] — this is a defined term because other documents use it; Course++ has no such feature today, and the Canvas addresses that would serve it are on the refusal list. |
| Diagnostic Event | The fixed, allow-listed record described in section 6. |
| Metering Record | One accounting row per request: what it cost, which balance paid, no content. |
| Credits | The unit Course++ uses to account for what a request cost. |
| Pseudonymised | Identity metadata replaced with a stable label such as Student 1. This is not the same as anonymous, and we do not use that word. [NOT BUILT] — the mechanism exists in our source code and nothing in Course++ currently supplies it with the roster it would need, so it never runs. See section 5.4 for what actually happens today. |
| Writing engine | The AI model that drafts text. In technical terms, a large language model reached through a model router. |
03
3. Where your data actually goes
There are two separate paths, and the difference matters.
YOUR BROWSER ─────────────────────────────────► CANVAS
(Course++) your existing Canvas login
Course Content is read and written here.
This traffic never touches our servers.
YOUR BROWSER ──► api.courseplusplus.com ──► OpenRouter ──► the model provider
(Course++) CoursePlusPlus LLC model router Anthropic or
Cloudflare Workers Google
· holds the API key
· checks your balance
· counts the cost
· does NOT store the request
Path 1 — Course++ and Canvas. Reading and writing your course happens directly between your browser and your institution's Canvas, using the session you are already signed in with. We hold no Canvas API token, we never see your Canvas password, and we are not in the middle of that traffic.
Path 2 — Course++ and the writing engine. When you ask Course++ to write something, the request goes to our server, which adds our API key and passes it to OpenRouter, which passes it to the model provider. Our server is in that path because that is how we can hold the key for you — so you never have to get one — and how we can count what each request cost.
So your request does transit infrastructure we control. We are being explicit about that rather than leaving it to be discovered. What that transit does and does not involve:
| Passes through our server | Yes — in transit, in memory, for the duration of the request. |
| Written to our database | No, with one exception. If your request is part of a genuine failure — Canvas refused a write, a step could not be verified, you ran out of credits mid-build — the last few messages of that conversation are kept for 90 days so we can help. See 4.8. Everything else: no. |
| Written to our logs | No. Our server logs the shape of a request — an id, a route, a status, a duration, a cost, a model name — and the code that writes those logs can only ever emit a fixed list of fields, each of which must match a narrow character pattern that prose and HTML structurally cannot satisfy. A request or response body cannot get into a log line even by mistake. (The error-report exception above is a separate, explicit write, not our request logs.) |
| Used to train a model | No. We send an explicit no-training-and-no-data-collection instruction with every single request, and we pin which providers may serve it. See section 7. |
| Retained after the request | Not by us, with the same exception as above. For OpenRouter and the model provider, see section 7 — the answer is different at each hop and we set them out separately rather than making one blanket claim. |
| Readable by us afterwards | Only the error-report exception above. Everything else: no, there is nowhere for it to be read from. |
3.1 The five things that travel on path 2
Course++ makes five different kinds of call to our server that reach a model. They are listed separately because they carry different things, and a single "we send your request to a model" sentence would hide that.
| What you did | What is sent | What comes back into the conversation |
|---|---|---|
| Asked Course++ to build or change something | Your messages, the Course Content the tool has read in this conversation, the id and name of the course you have open, and your chosen model | The model's reply |
| Attached a file | The file itself, once | A text transcription of it. The file's own bytes are held in memory for that one call and are never stored or sent again. See 5.6 |
| Asked for an image | The image description | The generated image, which goes to your Canvas directly. The image itself never re-enters the conversation |
| Asked Course++ to look something up on the web | One search query | A short list of sources — title, link, quoted snippet. See 7.2 |
| Asked Course++ to check the links in a course | The list of links found in your course pages | Which ones are broken. No model is involved in this one at all, and it costs no credits |
The course id and the course name do reach our server, in transit, on the first of these — they are how the model knows which course it is working in. They are not written to our database and not written to a log.
[NOT BUILT]— bring your own key. An earlier draft of this policy described a path where you supply your own OpenRouter key, so that path 2 becomes browser → OpenRouter directly and your requests do not transit our servers at all. That does not exist. There is no field to enter a key, no setting, and no route that would accept one; the only key in the system is a server-side secret that never reaches your browser. If it is ever built, this policy will be updated in the same release.
04
4. What we collect and store
Everything in this section lives on our side. Everything in section 8 lives only in your browser or in your own Canvas course, and never reaches us.
4.1 Account
| Data | Why | Where it comes from |
|---|---|---|
| Email address | Sign-in, receipts, service notices | You, or Google if you sign in with Google |
A normalised form of your email address (lower-cased, +tag removed, and for Google-hosted domains, dots removed) | Making "one account per person" and "one free grant per person" mean what they say | Derived from your email |
Your email's registrable domain — for example slcc.edu | Noticing an unusual burst of sign-ups from one place, and honouring an institutional request | Derived from your email |
| A one-way salted hash of your normalised email address | Enforcing "one free credit grant per person, ever". Kept separately from your account so it survives deletion — see 11.3 | Derived from your email |
| The identity-provider user id for your sign-in | Signing you back in | Google, or our sign-in service for an email code |
| The version string of each policy you agreed to, with the date, time and IP address | Proving what you agreed to and when, and knowing who owes a fresh agreement after a material change | Recorded at the moment you agree |
How you sign in: Google, or a one-time code sent to your email. Those are the only two. An earlier draft of this policy also named Microsoft; Microsoft sign-in was removed from the product deliberately, because institutional Microsoft tenants increasingly block third-party applications until an administrator approves them, which locked out exactly the teachers it was meant to serve.
We do not ask for your Canvas password and we never see it. We do not create or hold a Canvas API token.
**What we do not collect that you might expect us to: we do not store the Canvas hostname you use, we do not store any course id or course name, and we do not store your institution's name. The extension does tell our server which Canvas host you are on when it checks whether you qualify for free credits, and that value is not read and not recorded** — the free grant is decided from your hashed email and email domain alone.
[NOT BUILT]— institution name. Other documents in this set describe recording the institution you name when enabling student-data access. There is no such screen and no such record today.
4.2 Billing
Payment is handled by Stripe. We never see or store your card number, and no card detail of any kind is stored in our database. From Stripe we keep:
| Data | Why |
|---|---|
| Stripe customer and subscription ids | Linking your payments to your account |
| Plan, billing interval, renewal date, cancellation state | Showing it to you, and billing correctly |
| For each sale: the amount, the tax, the product, and the billing state, country and postal code | Sales-tax calculation and filing, and enforcing our US-only scope |
| A record that a payment, refund or dispute happened | Accounting, tax, and dispute handling |
Your payment history in full, your card, and your billing name live with Stripe, not with us. When you manage or cancel a subscription you do it on Stripe's own pages.
[NOT BUILT]— the auto-renewal consent record. Course++ shows you a separate, unticked auto-renewal checkbox at checkout, and the Start button does not work until you tick it — that part is real, and Terms §15.1 describes exactly what it says. Our database has the columns to record that consent with its date and document version, and nothing currently writes them. California's Automatic Renewal Law expects that record to be kept. It is a build task, not a drafting one, and it is listed as a publication blocker inCHANGELOG.md.
4.3 Usage and metering
One Metering Record per request. It contains:
- your account id and a timestamp
- which model served it, and which provider served that model
- input, output and cached token counts
- the cost in US dollars, and the credits debited
- how long it took, whether it succeeded, and an error code if not
- an OpenRouter generation id, so a billing dispute can be answered later
A Metering Record contains no course content, no student data, no prompt text, no model output, and no Canvas address of any kind. Our own source code says so on the table itself: "metering only — no conversation content, ever."
We also keep a credit reservation row per request, which holds the model name, the token ceiling, and a one-way hash of the request body. The hash exists so that a request retried after a network failure is charged once rather than twice. It cannot be turned back into your request.
The credit ledger is an append-only record of every grant, purchase, debit, refund and manual adjustment on your account, each with a reason and, for a manual adjustment, the name of the person who made it. It exists so your balance is always explainable and so a mistake can be corrected rather than argued about. Neither we nor our own software can edit or delete a ledger row — corrections are new rows.
4.4 The website waitlist
Our marketing site has a form that asks for your email address so we can tell you when Course++ is available. If you fill it in, we store that email address, a normalised form of it, and which page it came from. Nothing else. It is a list of people to email once; it is not linked to a Course++ account, it is not used for any other purpose, and you can have it removed at any time by writing to [email protected].
The form carries a hidden field that a person never sees and an automated scraper usually fills in. If that field arrives filled, we store nothing at all.
4.5 Support
If you email us, we keep your message and our reply.
[NOT BUILT]— the "what were you trying to do?" box. Other documents describe a free-text box on an error message, whose contents would be your own disclosure rather than something we collected. There is no such box in the product. If it is built, we will ask you plainly not to include student names or course content, and you will be able to read and edit it before it is sent.
4.6 What we deliberately do not store
Stated as a list because the absences are the point:
- Your prompts and Course++'s replies, as a rule. Conversations live in your browser, and our own code notes that this means we usually cannot replay a response even when it would be convenient for us. The one deliberate exception: the last few messages of a conversation where something genuinely went wrong, kept 90 days so we can help — see 4.8, which is the only place a claim like "we do not store it" carries an asterisk in this document.
- Course Content. No page bodies, no assignment descriptions, no quiz questions, no files.
- Student Data. See section 5.
- Any Canvas address — not a hostname, not a path, not a course id, not a course name.
- Request and response bodies, anywhere in our logs. Including error bodies, which are the sneaky case: an error message that quotes the failing request would put course content in a log. Our server reads the error body returned by the model router only to close the connection, and never surfaces or records it, for exactly this reason.
- Your Canvas credentials, in any form.
One thing that used to be here, and is not any more. Until 15 September 2026 our database had a table that stored the literal text of what users typed, written by a default-on setting labelled as a prototype. It was built as a deliberate, temporary, pre-launch exception, and it contradicted this section. It was found during Chrome Web Store submission preparation, and the table, the server route, the client setting and all of its wiring were removed, in a migration that records why. It was also never included in our backups. We mention it because a policy that quietly acquired a true claim is less trustworthy than one that says when it became true.
4.8 Error reports — the one place we keep real conversation text
This section describes a real, deliberate exception to "we do not store your conversation," not an accident and not the same thing as the removed prototype above. The difference is what triggers it, how much it keeps, and how long.
What triggers it. Only a genuine failure — Canvas actually refused a write, a step could not be verified, a tool call was malformed, the model errored, or you ran out of credits mid-build. It is not triggered by pressing Stop, by hitting the safety pause on a long build (nothing was lost there), or by Course++ catching and correcting its own mistake mid-turn — all of those are routine, not failures, and none of them writes anything here.
What it keeps. The type of failure, a short description of what went wrong (the same thing you already saw on screen), and the last few messages of that conversation, verbatim — what you typed, what Course++ replied. Not a course page, not a Canvas address, not a tool call — only your own words and Course++'s own replies immediately around the failure, capped in length.
Why we do this at all. A fixed-shape technical event (see section 6) tells us that something broke. It cannot tell us what you were trying to do, which is usually the thing that actually explains it. This is a deliberate trade, made once, in the open, rather than the alternative of support asking you to retype what you asked and hope it reproduces.
Retention: 90 days, then deleted automatically. This is the one table in our database that holds real conversation content, and it is the only one on a content-driven retention clock for exactly that reason.
Who can see it. Only through our administrative tools, by the same restricted credential that can suspend an account or issue a refund — never through the ordinary customer-facing systems, and never shown alongside or confused with the content-free events in section 6.
4.7 Inviting a colleague by email
If you use Course++'s "invite a colleague" feature, we send a real email on your behalf, and this is the one place in the product where we hold someone else's personal information before they have ever signed up.
- What you give us: the colleague's email address, typed into the extension.
- What we send them: one email, from us, naming you as the person who invited them, with your referral code and a link to learn about and install Course++. We do not send more than one email per invitation, and we do not add the address to any list beyond what is described below.
- What we keep: a row recording that an invite was sent — your account, the address, and when — so we can enforce a daily sending limit and stop abuse. We do not keep a copy of the email itself.
- Opting out: every invite email carries a working, one-click unsubscribe link that needs no Course++ account. Clicking it adds the address to a suppression list, and no Course++ account may ever invite that address again. This is permanent and is not tied to who sent the original invite.
- Why this is legally a "commercial email" and what that requires: because we, the company, send it, US law (the CAN-SPAM Act) treats it as commercial email regardless of who asked us to send it. The email carries a truthful subject and sender, our business mailing address, and the unsubscribe link described above, exactly as that law requires.
- We do not use this address for anything else. It is not added to marketing email, it is not matched against other data we hold, and if that person never signs up we retain only the send-log row above, kept as long as the account that sent the invite exists.
05
5. Student Data
This section is the short form. The full explanation, including the limits of what we can promise, is the FERPA posture page, and it is worth reading before you turn anything on.
5.1 Default: Course++ cannot read Student Data at all
By default, Course++ refuses every Canvas address that returns student work or student records — submissions, grades, enrolments, rosters, per-student analytics, gradebook history, discussion replies, quiz submissions, quiz and score statistics, peer reviews, your Canvas inbox, and the rest of the list published on the FERPA posture page.
Three details that are the actual substance of this claim:
- The refusal happens in your browser, before a request is built, not after a response comes back. There is no moment at which student work exists inside Course++ and is then filtered out. It never arrives.
- It applies to every kind of request, not just writes — reading is refused as well.
- It applies to the query string too, not only the path, and to both the names and the values in it. Asking Canvas to include student data in an otherwise-permitted request is refused the same way.
We publish the list, and we publish a runnable bundle that proves the list is enforced. It needs no Canvas instance, no account, no credentials and no network — the part of Course++ that enforces the boundary is a self-contained function, so it can be exercised offline:
git clone [VERIFICATION BUNDLE URL — pending publication]
npm install
npm run verify
The bundle is not a hand-maintained copy. It compiles the boundary out of the same source file the extension actually ships, and extracts the published list from it, on every run. If someone weakened the list, the bundle would start failing. The published list and the enforced list cannot drift apart.
It also checks the opposite direction, which is the part worth noticing: that ordinary authoring — pages, assignments, quizzes, modules, discussion topics — still works. A guard that refused everything would pass a one-sided test while being useless.
One narrow exception, because it is a real one. Course++ can send a message to your class through Canvas's own inbox — to everyone, or to the students, teachers, TAs or observers of the course you have open. That works without reading a roster: the recipient is the course itself, so the message structurally cannot reach anyone outside it. Reading your inbox is still refused, and messaging a named individual requires the setting in 5.3.
5.2 [NOT BUILT] Class Statistics
Other documents in this set describe an optional, one-click setting that would let Course++ read class-level totals only — how many students submitted, how the class scored overall, which quiz items were missed most, with no per-student rows, no names and no student work.
It does not exist. The Canvas addresses that would serve it are on the refusal list in 5.1 like everything else, and nothing in the product distinguishes a class total from a student record. There is no middle setting today: there is the default, and there is 5.3.
5.3 Full data access — a real, live setting, off by default
This is a shipped setting. One checkbox on Course++'s own settings page — "Give the assistant full access to student data" — controls it, and it is off by default for every account.
We would rather you read the same words the product shows you than a summary of them. This is the exact, current text next to that checkbox:
"Off by default: rosters, submissions, grades, discussion replies and your Canvas inbox stay invisible to the assistant, and it can message the whole class but never a specific student by name. Turn this on and all of that opens up — nothing is held back, and everything it reads gets sent to our AI provider like any other course content. Turn it on only if you understand and accept that."
Concretely, turning it on does three things, immediately, for every course on your account:
- It lifts the refusal described in 5.1 entirely. Course++ can then read rosters, submissions, grades, discussion replies, quiz submissions, gradebook history, per-student analytics and your Canvas inbox — and, once Course++ has independently confirmed with Canvas that the person is an active member of the course you are working in, message that person by name.
- It turns off the redaction described in 5.4 for everything it reads — not only for student data, but for all content, including ordinary course pages. Names, email addresses and similar fields pass through exactly as Canvas returns them.
- It changes the instructions our server gives the model, so the model stops refusing to look at student data.
Four limits on this setting that we would rather state than have you discover.
- It is not pseudonymised. Nothing replaces a student's name with a label. See 5.4.
- It is account-wide, not per course. One checkbox covers every course you teach.
- It does not expire. It stays on until you turn it off.
- The setting lives in your browser, not on our servers. We do not record that you turned it on, and we cannot tell from our side whether it is on. That is good for your privacy and it is also the reason for the honest limit in 5.5.
[NOT BUILT]— the narrower version. The design is for this to be enabled per course, gated on an explicit representation that you are authorised (recorded with the date, time, course, institution and policy version), preceded by a screen showing you the actual text that would leave your browser, expiring after 120 days and requiring re-affirmation, and overridable by your institution. Our database already has the table and the rules for all of that, including the 120-day window and a requirement that both the representation and the payload preview have happened before full access can be recorded. No code writes to it, so no such record can exist. Until that is wired up, the paragraphs above are the whole of it.
5.4 What is, and is not, redacted today
Two different things are easy to conflate here, so we describe them separately.
Ordinary redaction — on by default, and it runs on everything Course++ reads. A page, assignment, or discussion topic you wrote yourself can still legitimately contain someone's name or email address — an instructor pastes a TA's contact details into a syllabus page, say. Before anything Course++ has read reaches the writing engine, it strips known personal-data fields (email addresses, login ids, SIS ids, unique ids, avatars, pronouns, sortable and short names, phone numbers, biographies), replaces a name field with [name], replaces a whole person-shaped object with a placeholder, and text-scrubs email addresses, US phone-number shapes and long bare digit strings out of free text.
Two honest limits on it:
- This is a structural filter, not a lookup against your actual roster. It removes fields that are shaped like identity. It cannot recognise a name written in a sentence.
- Object identifiers pass through unchanged, by design — a page id, an assignment id, a module id. The tool needs them to chain one step to the next. A Canvas user id is a stable per-student identifier, which is exactly why every address that returns one is on the refusal list.
- It is turned off completely when full data access is on — see 5.3, point 2.
[NOT BUILT] — roster-based pseudonymisation. The design is to replace each student's name with a stable label such as Student 1, drawn from your actual course roster, so the same student reads the same way throughout one job, while a map from label back to real name stays on your machine and is never transmitted. That capability does not run in Course++ today. The mechanism is present in our source code and nothing supplies it with a roster, because reading a roster is behind a setting that, when on, switches redaction off rather than on. Our own source file says so in as many words.
So, plainly: if you turn full data access on now, names and other identifying fields in student work are sent to the writing engine exactly as Canvas returns them. We are describing the design because it is where this is headed and because we would rather say plainly that a protection is unfinished than let its absence go unmentioned.
When roster-based pseudonymisation ships, both of the following will be true, and we will say both, because saying only the first would be misleading:
- Removed reliably: each roster name from that course, stripped by exact match from the text of the work itself, plus names, email addresses, login ids, SIS ids and avatars as data fields.
- Not removed, and we will not pretend otherwise: the work can still identify its author — an essay about "my summer at my dad's shop in Cedar City" identifies a student to anyone who knows the class; a name run together with no separator (
DanaWhitfield.pdf) is a known, documented gap; and a name inside a PDF's metadata, handwriting in a photograph, a face in a video, or a name in a document's sharing metadata is not caught by a text-matching rule at all.
We do not describe any of this as anonymous, today or once it ships. That word would be wrong, and the distinction is legal, not cosmetic. "Pseudonymised" does not appear in this policy as a description of anything Course++ currently does — only of what it is built toward.
5.5 Institutional opt-out
A school may ask us to disable student-data features for its Canvas domain, and we will act on it on receipt. Email [email protected] from an address at the institution, name the Canvas hostname, and we will confirm in writing. No contract, no negotiation, no form. An institutional request overrides every individual instructor's choice at that domain.
What we can actually do today, stated precisely, because this promise is only worth what it can be made to do. The setting in 5.3 is enforced in the instructor's browser and its state is not recorded on our servers, so we cannot reach in and switch it off remotely. What we can do, by hand and quickly, is suspend the affected accounts, which stops Course++ working at all for them; and stop the service entirely, which we have a tested control for. Our database has a per-domain block table for a narrower answer than suspension, and nothing consults it yet.
So the commitment we are prepared to make is the one we can keep: we will honour the request, and where we cannot yet disable the feature selectively we will suspend service at that domain rather than leave it running. Building the selective version is on our list, and this paragraph changes the day it works.
5.6 Files you attach yourself
Course++ lets you attach a file to a message — a chapter PDF, a syllabus, a photograph of a handout — so it can build from your own material.
Whatever you attach goes to the AI model, the same as anything you type. This is the one place where the structural protection in 5.1 does not help you, and we would rather be blunt about why: that protection works by refusing Canvas addresses. It cannot inspect the contents of a file. A gradebook export, a stack of graded essays or a screenshot of SpeedGrader would go to the model like any other attachment, whatever the rest of this page says about student records.
So:
- Please do not attach student work, grades, or rosters. Course++ says this at the attach control itself, not only here.
- Course++ notices some obviously risky filenames and asks "are you sure?" That is a speed bump, not a protection, and it will miss a file called
Book1.csv. We will not describe it as anything more. - What happens to the file: it is sent once to our server, read once by a model into a text transcription, and the text — not the file — is what enters the conversation. The file's bytes are held in memory for that one call, are never written to our database or our logs, and are never sent again. A second attachment of the same bytes reuses the earlier transcription from your own browser's memory rather than being sent again at all.
- A file you attach is your own disclosure. Student records cannot reach Course++ through Canvas; a file you choose to attach is a different thing, and it is yours.
06
6. Diagnostics
When something breaks, Course++ builds a small record describing what. This is the section we would most like you to read, because the design is unusual, and because as the product ships today it does not send us anything at all.
6.1 Where this actually stands — read this before the table
No Diagnostic Event is transmitted to us, to courseplusplus.com, or to any third party. The record is built in your browser and handed to a receiver that, in a released build, does not exist — it is a local development address on your own machine, so the attempt fails silently and nothing leaves your computer. There is no endpoint on our server to receive one. We are describing a design, not a current collection.
We publish it anyway, in full, for two reasons: it is the design we intend to ship, and the field list below is the complete set of what the code is capable of sending, which is a stronger disclosure than a promise. The day a receiving endpoint goes live, this section loses this paragraph and nothing else about it changes — and the Chrome Web Store disclosures will be updated in the same release.
6.2 It is an allow-list, not a scrub
We do not collect a log and then remove what looks sensitive. The code that builds a Diagnostic Event can only ever populate the fields in the table below. Course content is not filtered out of the payload — it is never available to that code path in the first place.
6.3 The complete list of fields. Nothing else exists in the payload.
| Field | Example |
|---|---|
| Event type, from a fixed list | model_timeout · model_error · auth_failed · token_refresh_failed · payment_failed · canvas_denied · canvas_busy · tool_malformed · verification_failed · out_of_credits · restore_skipped · history_write_failed · sweep_failed · page_error |
| Timestamp | ISO 8601 |
| Canvas hostname only | slcc.instructure.com |
| HTTP status | 403 |
| How long it took | 181,204 ms |
| Which writing engine | anthropic/claude-sonnet-5 |
| Step number and total | 4 / 12 |
| Retry count | 3 |
| Extension build version | a4f19c2 |
| A short reason string, from a fixed vocabulary | student data segment refused · object changed since the build |
On that last field. It carries reasons our own code generated about what it did or refused to do — never a page title, an assignment name, or anything an instructor typed. There is one case where the text comes from outside our code: when the Canvas page itself crashes, the record carries the browser's own error message and the first line of its stack trace, capped short, at most ten times per page load. That is a description of a code fault, not page content, and it was added after a real incident where the only way to see Canvas's own editor crashing was for an instructor to copy their browser console into chat by hand.
6.4 Never collected — absent by construction, not filtered
- Course id or course name
- Page, assignment, quiz or module titles or ids
- Any Canvas address beyond the hostname
- Any request body or any response body
- Your prompt, your message, or anything else from the conversation
- Any student's name, work, grade or identifier
- Your account id, your email address, or your plan
- Your browser version or your operating system
Why the Canvas hostname stays: if an entire institution's Canvas breaks, that is exactly the thing we need to see, and it discloses nothing we do not already hold, because your account already carries an email domain.
Two of these event types currently record the hostname as a full origin — https://slcc.instructure.com rather than slcc.instructure.com. Still no path and no course id; noted because it is a difference from the sentence above and we would rather name it than have it found.
6.5 Automatic, if it is ever sent — and there is no way to turn it off yet
Because the payload is a fixed list with no content available to it, the design is to send it automatically, without asking each time. That is a deliberate trade and we would rather explain it than bury it: the users least likely to file a report are exactly the ones about to give up on the product, and a model that has started timing out is something we need to know about within minutes, not whenever someone gets around to emailing.
There is no diagnostics setting in the product today. Course++'s settings page has exactly three preferences — which model to use, full data access, and whether to notice changes made outside Course++ — and none of them is this. Since nothing is transmitted (see 6.1) there is nothing to switch off yet; a working opt-out will ship in the same release as the receiving endpoint, or the endpoint will not ship. We are writing that down here so it is a commitment rather than an intention.
6.6 What we would use them for, and how long we would keep them
Used only to find and fix problems, and to notice that a problem is happening at all. We would not use Diagnostic Events for advertising, for scoring you, or for anything to do with your course.
Retained for 30 days, then deleted.
07
7. The writing engine, and what we instruct it
Course++ drafts text using an AI model. We reach it through OpenRouter, a model router, which passes the request to the provider that serves that model.
What we send with every single request, without exception:
- A no-data-collection instruction, asserted per request rather than relied on as an account setting. The reason for doing it that way is that this policy says your course content is not used to train anyone's model, and the honest way to be able to say that is to assert it on every call.
- A pinned list of which providers may serve the request, rather than letting the router choose one. That is what makes the subprocessor list a real list instead of a guess — we cannot name our subprocessors if a router picks them for us.
- A requirement that the provider actually honour those settings. If a pinned provider cannot, the request fails rather than quietly routing somewhere that does not. This is not theoretical: one model was dropped from Course++ entirely because no endpoint for it would accept the no-data-collection instruction, and we would rather lose a model than lose the claim.
7.1 No training, and retention — three hops, answered separately
This is the one place where a single reassuring sentence would be dishonest, so we set out each hop. Do not read a blanket "nothing is retained" into this page; it is not what we are able to say.
| Hop | Training | Retention |
|---|---|---|
| 1. Our server | Not applicable — we have no model | Never stored. In memory for one request, not in our database, not in our logs |
| 2. OpenRouter, the model router | Committed. OpenRouter's own terms state it does not use inputs or outputs for model training | ⚠ Not established. OpenRouter publishes no retention period for inference data and defers it to its own data-processing agreement. We have not executed that agreement. Until we do, we cannot tell you how long OpenRouter holds a request, and we will not claim a number we do not have |
| 3. The model provider — Anthropic or Google | Excluded by the no-data-collection instruction, enforced per request | Excluded by the same instruction, on the pinned providers only |
Hop 2 is an open item and an institution reading this page will find it. It is on our pre-publication list, and the fix is a signature rather than an engineering change. We are naming it here rather than waiting to be asked.
Which providers, today. Anthropic and Google. Our pinned list also names OpenAI, and no model Course++ offers can currently be served by OpenAI — the one we tried was dropped because it would not accept the no-data-collection instruction. subprocessors.md lists OpenAI for that reason, and the honest reading is "permitted by configuration, unreachable in practice."
7.2 Web search
If you ask Course++ to look something up, one search query goes to our server and on to OpenRouter's web-search facility, under the same no-data-collection instruction and the same pinned providers as everything else. What comes back is a short list of sources — a title, a link and a quoted snippet — and Course++ is instructed to cite and link rather than copy.
Two consequences worth knowing: the query is a request to a live web search, so treat it as you would a search you typed into a search engine; and material fetched from the open web is not trustworthy input. Course++ treats it as untrusted text, and you should treat what it produces from it as a draft to check, the same as everything else.
7.3 AI output can be wrong
That is a product limitation rather than a privacy matter, so it lives in the Terms of Service, but it belongs in your head while reading this page: everything Course++ writes is a draft for you to check.
08
8. What stays out of our hands
8.1 What stays in your browser
These never reach us. They are listed so the picture is complete, and because they are yours to delete at any time.
| What | Where | How long |
|---|---|---|
| Your conversation with Course++ in the course you have open | Your browser's extension storage | Until you clear it or start a new one |
| Finished conversations, archived so a new one does not lose what was built | Your browser's extension storage | The most recent 20 per course, then the oldest is dropped |
| The offer to resume a conversation you were in the middle of | Your browser's extension storage | 6 hours, then it is deleted and no longer offered |
| A detailed session log of a build, for troubleshooting your own run | Your browser's memory only | The tab's lifetime. It is capped, and it never leaves your machine |
| Your sign-in tokens | Your browser's extension storage, held by the extension's background worker. The part of Course++ that runs on the Canvas page never holds your refresh token | Refresh token: 30 days of inactivity, 90 days maximum. Short-lived request tokens: 10 minutes |
| Your settings — model, full data access, whether to notice outside changes, window size, the email you last signed in with | Your browser's extension storage | Until you change or clear them |
| A running total of what you have spent, for display | Your browser's extension storage | Until you clear it |
[NOT BUILT] The map from a pseudonym back to a real name | Your browser only, never transmitted | For the duration of the task |
Never sent to our servers, as a rule and not as a default: the session log. It can contain raw Canvas responses, so sending it would collect exactly the data the rest of this policy says we do not collect. If we ever need diagnostic detail beyond section 6, we will ask for the shape of a session — counts and types, no content.
Signing out clears all of it. There is also a "This is a shared computer — don't stay signed in" option on the sign-in screen, which keeps your session in memory only, so closing Chrome ends it. It exists because the real risk for this product is not malware, it is the classroom podium machine. One honest detail about it: it is read at the moment you sign in, so if you click "Continue with Google" before you reach that checkbox, you get an ordinary session. It sits below the sign-in buttons deliberately, to keep the first screen short, and that is the cost of that choice.
8.2 What Course++ writes into your Canvas course
This is not us storing your data — it is Course++ storing it in your own institution's Canvas, where you and your Canvas administrators control it, and where it survives you changing computers. We describe it because it is a real thing that appears in your course, and nobody should find an unexplained folder.
| Where | What | Why |
|---|---|---|
A hidden, locked folder in the course's Files called course++ (do not delete) | course++-history.json — one entry per build: the words you typed, the date, the model, the credits spent, and what was created or changed, with the previous values of anything it edited. Capped at the most recent 300 entries | This is your build history and your undo. The prompt is stored because "undo the Week 3 module I asked for" is the only index into your own history that is legible |
| The same folder | course++-fingerprint.json and course++-baseline-<type>.json — only if you turn on "Notice changes made outside Course++," which is off by default | So Course++ can tell you what changed in the course when it was not looking, and offer to put it back |
A visible folder called course++ (delete me) | Files Course++ generated and later replaced — an old version of a slide deck or an image | Course++ cannot delete a file in Canvas at all, so rather than leaving clutter scattered through your course it moves superseded files into one obviously-named folder you can empty by hand |
None of these files is ever sent to us. They are in your Canvas, reachable with your own Canvas login, subject to your institution's own retention and access rules. They are not a complete backup of your course, and Course++'s undo is described, with its limits, in Terms §12.
One thing worth knowing if you generate quizzes: a history entry for a quiz edit can contain the question and its answer key, because that is what it needs in order to put a wrong edit back. That answer key is already sitting in the same course inside the quiz itself, so this is not a new secret — but it is the reason the folder is created hidden and locked rather than visible.
09
9. Security
Not a complete description of our security programme — a description of the parts that decide what happens to your data.
- Our API keys live in encrypted secrets on Cloudflare, not in the database, not in the code repository, and not inside the extension. The key that pays for the writing engine never reaches your browser; an earlier version of Course++ called the model provider directly from the browser and that path was deliberately removed.
- Your account's data is stored in per-account rows in a database schema that is not exposed to any public API. A table in an unexposed schema is unreachable from the internet regardless of what any access rule says. Row-level security is on for every table and denies by default, with no client-facing policy at all. No account can read another account's rows. Your balance, plan and history are served by our own server, never by the database talking to your browser.
- The credit ledger cannot be edited or deleted, including by us and including by our own software's bugs — that is enforced by the database itself, against the table's owner as well as against everything else. Corrections are new rows with a required written reason.
- The identity that can create credits is a different credential from the one exposed to the internet.
- Your sign-in token never enters the part of Course++ that runs on the Canvas page. That part gets a short-lived capability, not a credential. The Canvas page cannot read Course++'s storage, and Course++'s window cannot be read by scripts on the Canvas page.
- Credentials are only ever entered on a
chrome-extension://page or oncourseplusplus.com— never in a box drawn on top of a Canvas page. That is deliberate, and it is how you can tell a real Course++ sign-in from a fake one. - Administrative access is on a separate domain behind separate authentication, with an append-only audit log and a required written reason for every manual credit adjustment.
- We keep a nightly backup of the financial records — the ledger, the metering rows and the audit log — in storage where the copies cannot be altered or deleted for 30 days. Course content and conversations are not in it, because we do not have them.
- We have a tested emergency stop that can refuse every request, or every paid request, within seconds. It exists so that a billing or metering fault is something we halt rather than something we debug while it runs.
- We publish a security contact and we read it. See
security.txt.
No system is perfectly secure, and we do not claim ours is. If there is a breach affecting your information, we will notify you as required by law and tell you what we know, including what we do not yet know.
Drafting note. No claim of any certification, audit, penetration test, insurance policy or third-party assessment appears anywhere in this document, because none has happened. If one happens, it can be added then — and not before.
10
10. How long we keep things
One table, so the numbers are in one place. These figures also appear in the Terms of Service and the DPA rider, and they must always match.
| Data | Retention |
|---|---|
| Diagnostic Events | 30 days — and see 6.1: none is collected today |
| Server request logs (shape only — no bodies) | Held by Cloudflare under its own observability retention, which we do not extend. [VERIFY: the configured period, and state it as a number here before publication — the plan's own rule is to say the number and honour it] |
| Account record | Life of the account. On deletion, see section 11 |
| Credit reservations, including the one-way hash of a request | Kept with the account. [TO BUILD: there is no automatic deletion of these rows today. A short retention — 90 days is proposed — needs a job that does not exist, and this row must state whichever is true at publication] |
| Metering Records and the credit ledger | Kept after account deletion, with no name or email attached, for 7 years, for tax and accounting. [CONFIRM WITH CPA — 7 years is the conservative figure and matches our own record-retention practice] |
| Sales records used for sales-tax filing (amount, tax, state, country, postal code) | 7 years, same basis |
| Your agreement to the automatic-renewal terms | 3 years, or 1 year after your subscription ends, whichever is longer (required by California's Automatic Renewal Law). See 4.2 — the record is not yet being written |
| Your agreement to these policies (version, date, time, IP) | Life of the account, then 3 years. [CONFIRM WITH COUNSEL] |
[NOT BUILT] Student-data enablement record (who, when, which course, which institution, which policy version) | Life of the account, then 3 years. [CONFIRM WITH COUNSEL] |
| Hashed email used for the "one free grant per person" check | Indefinitely. See 11.3 |
| Waitlist email address | Until Course++ is generally available and we have written to you, or until you ask us to remove it — whichever is first. [CONFIRM: proposed as 24 months maximum] |
| Support email and its attachments | 24 months. [CONFIRM WITH COUNSEL] |
| Nightly backups of financial records | 30 days, in unalterable storage, then expired |
| Your prompts, Course++'s output, Course Content, Student Data | Not retained by us, as a rule. Your own copies are in your browser and in your Canvas course — see section 8. The one exception: the error-report row below |
| Error reports — the last few messages of a conversation around a genuine failure | 90 days, then deleted automatically. See 4.8 |
| A record that a referral-invite email was sent (the address, your account, the date — not the email itself) | Kept as long as the sending account exists. See 4.7 |
| The referral-invite unsubscribe (suppression) list | Indefinitely — the entire purpose is "never again," for as long as we send this kind of email at all |
11
11. Your choices
11.1 See and export your data
Email [email protected] and we will send you your account data — profile, plan, balance, credit ledger and Metering Records — within 30 days, and in practice much sooner.
[NOT BUILT]— self-serve export. A button in settings that does this without emailing anyone is planned and does not exist. Until it does, the email route above is the whole of it, and it is a commitment, not a courtesy.
Your conversations are already on your own machine, and your build history is in your own Canvas course (section 8). Both are yours to copy.
11.2 Delete your account
Email [email protected].
[NOT BUILT]— a delete button in settings. Planned, does not exist. The email route above is how deletion happens today.
Cancelling is not deleting. Cancelling a subscription stops it renewing. Deleting removes the account, and you need an account to spend credits you have already paid for — so:
Before we delete anything, we will tell you your unused purchased-credit balance and offer to refund it. We will not quietly keep money you paid for something you did not receive. Our own administration tools will not complete a deletion until that balance has been read and acknowledged in writing, precisely so that it cannot be skipped. If you would rather keep the balance, keep the account; cancelling costs nothing to leave dormant.
On deletion: your email address is removed from your account record, your profile is removed, and your financial records stay as required by tax law — with no name or email attached to them. The account row itself is retained in a deleted state rather than destroyed, because the credit ledger points at it and destroying it would take your own purchase history with it.
11.3 What survives deletion, and why
One thing survives: a one-way salted hash of your email address, kept so that the free credit grant stays one-per-person rather than one-per-account. Without it, deleting and re-registering would restart the free tier indefinitely, and the cost of that is real money we would have to recover from paying customers.
It cannot be turned back into your address, it is not used for anything except answering "has this person already had a free grant?", and no other personal information is kept with it.
11.4 Turn diagnostics off
There is no diagnostics setting yet, and nothing is being collected. See 6.5 — a working opt-out ships in the same release as the collection, or the collection does not ship.
11.5 Correct something
[email protected]. If we have something wrong about you, tell us and we will fix it.
11.6 Marketing email
We send service email — receipts, renewal notices, security notices, and notice of a material change to these policies. You cannot opt out of service email while you have an account, because some of it is legally required. Any marketing email has an unsubscribe link that works.
If you joined the waitlist on our website and never created an account, you can be removed from that list at any time — 4.4.
11.7 Do Not Track, and "sale" of personal information
Some browsers send a "Do Not Track" signal. We do not respond to it differently, because there is nothing for it to change: we do not track you across other websites, we run no advertising, and there is no third-party analytics or advertising code anywhere in the extension or on our website — no Google Analytics, no tag manager, no session recorder, not even an external font or script.
We do not sell personal information, and we do not share it for cross-context behavioural advertising. We have never done either and there is no mechanism in the product by which we could.
12
12. Who else touches your data
Named individually, with what each one does, in subprocessors.md. Summary:
| Who | What they do |
|---|---|
| Cloudflare | Runs our API, our website, our admin site, our inbound email, and our backup storage |
| Supabase | Stores accounts and balances; handles sign-in — including sending you a sign-in code by email if you choose that option |
| Stripe | Payments, the checkout page, and the portal where you manage or cancel. Card details go to Stripe, never to us |
| OpenRouter | Routes each request to the writing engine, and provides the web-search facility |
| Anthropic, Google | Provide the writing engines, pinned per request. See 7.1 |
| Signs you in, if you choose Google | |
| Resend | Sends our own operational alerts to us — for example a sales-tax threshold warning — and, since 15 September 2026, a colleague's invite email when you use "invite a colleague" (see 4.7). Operational alerts still carry no account id, no email address and no course content. An invite email carries the invited address, your own sign-in email, and your referral code — nothing else |
One correction to an earlier draft of this table, because it matters. It named Microsoft as a sign-in provider: Microsoft sign-in was removed from the product and Microsoft receives nothing.
A second thing that was true when this policy was first written and is not any more. An earlier version said Resend sends us only our own operational alerts and receives no customer data at all, and that we have no customer-facing email system of our own. That was accurate until the "invite a colleague" feature shipped. Receipts and renewal notices still come from Stripe, and sign-in codes still come from Supabase — those have not changed — but a referral-invite email is now real customer-facing mail this company sends, described in full at 4.7.
We do not sell personal information, and we do not share it for advertising. We disclose it only to the providers above to run the service, to our accountant and lawyer where they need it, when the law requires it, or to a buyer if the business is sold — in which case this policy travels with your data and we will tell you before anything changes.
If a subprocessor changes, the list is updated and the change is noted in CHANGELOG.md.
13
13. Children
Course++ is for adults. You must be 18 or older to hold an account, and Course++ is for instructors and instructional staff — not for students.
We do not knowingly collect personal information from anyone under 13. COPPA governs collecting personal information from children, and Course++'s users are teachers. Students do not have Course++ accounts, do not sign in to Course++, and Course++ collects nothing from them.
We do not describe Course++ as "COPPA compliant," because that is not a thing a vendor in our position holds. What we can say is structural: in its default state Course++ cannot read a student record at all, and no student is ever a user of it.
Where an instructor turns on full data access (5.3) in a course that includes students under 13, the institution's own obligations flow through to us as a provider acting at its direction — which is one more reason that setting is the instructor's institution's decision to make and not the instructor's alone. This is discussed on the FERPA posture page and covered in the DPA rider.
14
14. Where we operate
Course++ is offered in the United States only. We do not offer it in the European Union, the United Kingdom, or elsewhere outside the United States; we do not market it there; our marketing is in English only; and we restrict billing to United States addresses. If you are outside the United States, please do not use Course++.
Where your data is, precisely. Our database, our backups and our administrative systems are configured in the United States [VERIFY: confirm the database project region and the backup bucket region are both US before publication]. Our API runs on Cloudflare's network, which by design executes code close to the person making the request — so for a US user it runs in the United States. Since a request is processed in memory and never stored there, the durable copy of anything is in the United States either way. Per-provider detail is in subprocessors.md.
15
15. FERPA
We do not describe Course++ as "FERPA compliant" or "FERPA certified," and you should be sceptical of any vendor who does. FERPA places obligations on educational institutions, not on vendors, and there is no such thing as a vendor FERPA certification to hold.
What we do instead is describe exactly what Course++ can and cannot reach, publish the list, publish a bundle that proves it, name what is not protected, and sign your institution's data protection agreement. That is the FERPA posture page, and the agreement is the DPA rider.
One thing on that page that belongs here too, because it is the crux: an individual instructor cannot designate a vendor a "school official" under 34 CFR 99.31(a)(1). That takes institutional action. Ticking a box in Course++ documents that you were careful; it does not confer authority that only your institution can give.
16
16. Changes to this policy
We will update this policy when the product changes. When we do:
- The version string and effective date at the top change, and the change is described in
CHANGELOG.md. - For a material change we will email you at least 30 days in advance, and where the change materially affects how we handle your data we will ask you to agree again before it takes effect. (The same 30 days appears in Terms §2; the two must always match. The figure itself is a proposal for counsel — see
README.md, U7.) - We keep a record of which version you agreed to and when, which is how we know who still owes a fresh agreement.
We will not make a material change quietly and rely on you re-reading this page.
17
17. Contact
| For | Write to |
|---|---|
| Privacy, data requests, institutional opt-out | [email protected] |
| Security reports | [email protected] — see security.txt |
| Institutional or district contracts | [email protected] |
| Everything else | [email protected] |
| Post | CoursePlusPlus LLC, [COMMERCIAL MAIL ADDRESS] |
Drafting note.
support@andprivacy@are in use and monitored.security@andsales@are asserted by this document and bysecurity.txtand must exist, route somewhere a person reads, and be tested before publication.
18
Appendix A — Chrome Web Store data disclosures
Drafting note. The store's privacy form and this policy must match word for word. A mismatch between the two is the commonest cause of a listing being taken down, and under-declaring is worse than over-declaring. The categories and wording below are a draft mapping and must be checked against the store's current form at submission time, because the form's wording changes. Re-check it in the same change that converts any
[NOT BUILT]block to present tense.
| Store category | Declare? | What, exactly |
|---|---|---|
| Personally identifiable information | Yes | Email address, and a hashed form of it |
| Authentication information | Yes | Sign-in tokens, held in extension storage |
| Financial and payment information | Yes | Handled by Stripe. We receive the amount, the tax, and the billing state, country and postal code — never a card number and no card detail at all |
| Personal communications | Yes | Two things. (a) Course++ can send a message to your class through Canvas's own inbox, which requires no roster and reaches nobody outside the course. (b) With the "full data access" setting turned on — off by default, see 5.3 — Course++ can read a student's discussion replies and your Canvas inbox, and message a specific student by name. All of that reaches our AI provider like any other Course Content |
| Health information | No | — |
| Location | No | We do not collect location. Billing state, country and postal code come from Stripe for sales tax |
| Web history | No | We do not collect browsing history |
| User activity | Yes | Metering Records — one accounting row per request, with no content. Diagnostic Events are designed and not currently transmitted (6.1); they will be declared here in the same release that starts sending them |
| Website content | Yes | Course Content read from Canvas, the id and name of the course you have open, files you attach, and web-search queries you ask for are transmitted to a third-party AI provider to fulfil your request. Not stored by us, except the error-report exception named below |
| Personal communications, continued — error reports | Yes | When a build genuinely fails, the last few messages of that conversation are stored on our servers for 90 days so we can help — see 4.8. This is the one case where "not stored by us" above does not apply |
Also required on the listing and in the store's fields:
- The single purpose statement, and a justification for every permission requested. The extension requests exactly
storage,activeTabandidentity, and host access to*.instructure.com, our own API, and our sign-in service. - "Not affiliated with Instructure, Inc."
- We do not sell or transfer user data to third parties outside the approved use cases; we do not use or transfer user data for purposes unrelated to Course++'s single purpose; and we do not use or transfer user data to determine creditworthiness or for lending purposes.
- The Limited Use disclosure for Google user data — see
limited-use.md.