Getting Started
Welcome to Mycorr, the collaborative data platform designed to improve your productivity and bring structure to your data workflows. If you are someone who works with a lot of data, Mycorr will be a time-saver by centralizing your data and transforming your traditional spreadsheets into powerful, structured, and shareable resources.
This guide will introduce you to the core concepts and features that make Mycorr unique.
Why Choose Mycorr?
-
Real-time collaboration and synchronization
Work together with other users in real time. See data changes instantly as they happen.
-
Data versioning
Track every change, create checkpoints, and roll back to previous versions when needed. Our versioning system ensures you never lose important data and can always track your history.
-
Access Management
Control who can view, edit, or share your resources. Define granular permissions for individuals or teams, ensuring your data stays secure and only accessible to the right people.
-
Integration with external datasources
Quickly import data from external datasources and keep your data in sync with external sources.
Ready to Get Started ?
- Learn about Account Management to get access to Mycorr.
- Explore the Resources section for detailed guides on available resources and how to interact with them.
- Explore different Data Sources you can bring data from into Mycorr.
- Check out Data Management to get into the details of different ways to manage your data.
- Visit API Access to learn about accessing your data from external applications.
Account Management
Your account is who you are in Mycorr. It carries your identity, the organizations you belong to, and everything you own.
Creating an account
Two ways in:
- Continue with Google — the fastest route, and no password to keep.
- Email and password — enter your full name, email address and a password.
A password sign-up sends a verification email. Open it and follow the link before signing in; until you do, the account exists but is not yet yours to use.
If you were invited to an organization or to a resource, follow the link in the invitation. It brings you to the same sign-up, and your access is waiting when you arrive.
Signing up with Google and signing up with a password create the same kind of account. What differs is how you prove it is you.
Terms and privacy
Before you can use the app, you accept the Terms of Service and the Privacy Policy. When either is updated you are asked again, and the screen says plainly that the terms have changed rather than presenting them as new.
Signing in
Use whichever method you signed up with.
If you forgot a password, use Forgot password on the sign-in screen. A reset link is sent to your address; it lets you set a new password and sign in again.
Your personal organization
Every account gets one Personal organization at sign-up. It holds exactly one person — you — and it is where your own models and tables live.
It has its own plan and its own storage allowance, separate from any company organization you belong to. See Organizations and Billing.
Deleting your account
Account deletion is deliberate, reversible for a window, and it tells you what will happen before you confirm.
- Open settings and choose to delete your account.
- Read the summary, which is calculated for your account specifically — it names the number of tables involved.
- Confirm.
You then have 48 hours. During that window you can still sign in and cancel, and everything comes back.
What happens
- Your personal organization, every space in it and every model you own go to the Trash for 48 hours.
- After that, your models and their tables are deleted for good.
- Tables that other people imported stay copyable for a further 10 days, so their work is not destroyed without warning, and then go too.
- Models in organization spaces you manage are not affected — they belong to the space, not to you.
- If you are the only admin of a team, another member is promoted automatically.
- Teams you own with no other members are permanently deleted.
Your saved connections, personal access tokens and stored credentials are removed with the account.
Two things that stop the deletion
You are the only owner of an organization. Deletion is refused outright, because it would leave that organization with no owner and no way to recover one. Hand ownership to someone else first; the dialog lists the organizations and links to each one's settings.
You pay for an organization that stays behind. This does not block the deletion, but you are warned, because deleting your account does not cancel those subscriptions — they keep charging your card until someone replaces it. Replace the card while you are still an owner, or cancel the plan if the organization is winding down too. See when a payment fails for what the people who stay behind will see.
Signing up again afterwards
A deleted address can be used to register again. The new account is genuinely new: it does not recover the old account's data, models or access, all of which were deleted. What you get back is the address, not the history.
Resources
Mycorr's strength lies in its structured and shareable resources made available to its users. It allows them to organize and collaborate on their data with ease without worrying about conflicts or inconsistencies.
To help you get started, the following section provides an overview of what resources defined in Mycorr and how they are structured inside your workspace. Understanding the structure will make it easier for you to crunch the data.
Start by diving into our Resources Structure for a detailed breakdown.
Structure
In Mycorr, all data is organized in Models and Tables within them. Think of this as databases and tables in traditional systems.
Tables always have a parent model, from which they can be edited. In that model, they exist in their latest state. When tables are shared to other users, they can import the tables into their own models. When a table is imported into a model, it can only be visualized, but not edited.
Learn more about Sharing of Tables.
Models
Think of Models as folders that hold data together in a single common space. A Model contains one or more Tables, displayed on a shared Canvas where you can collaborate with others and see real-time data changes as they happen.
When you create a Model, you are automatically the Owner of it, which is the highest level of access to the Model.
You can create Models in your private workspace, or within Teams you are a part of.
After the Model is created, you can add Tables to it and start working on your data. You can also share the Model with others, allowing them to collaborate on the same data.
Learn all about Sharing of Models.
Tables
Our Tables are just like tables in a database, that you can create, edit and manage within a Model.
A Table is accessed and visualized through Table Views, of which a Table can have as many as you like. For example, you can create one Table Views that are filtered or sorted differently.
Within a Table View, you can:
- Remove columns
- Add Columns
- Remove Rows
- Add Rows
- Filter Data
- Update Data
Any data changes made within a Table View are persisted to the main Table to ensure data consistency between views. Learn more about Data Management.
Column Types
Every column in a table has a type, which decides what it can hold, how it sorts, how it is displayed, and which filter operators apply to it.
The types
| Type | Holds |
|---|---|
| Text | Any string |
| Number | Integers and decimals, in several widths |
| Boolean | True or false |
| Date | A calendar date, with no time |
| Date & time | A moment, stored in UTC |
| Duration | A length of time |
| JSON | A structured value |
| UUID | An identifier |
| List | Several text values in one cell |
| Categorical | One of a defined set of values |
| Attachment | Files on the row |
Numbers carry a width — Int32, Int64, Float32, Float64 and so on — shown beside the type as Number · Int32. The width decides the range a column can hold, which is why narrowing one is not always safe.
Decimal columns keep their precision and scale. A column defined as ten digits with two decimal places stays that; it is part of the type, not a display setting. Number formatting, including how many decimal places are shown, is separate and does not change what is stored.
Date & time columns carry a precision — seconds, microseconds or nanoseconds — and are stored in UTC. The display timezone is a view setting, shown as Display timezone: UTC (default).
Changing a column's type
You can cast a column to another type from the column menu. Three things can happen, and the app decides which before you commit:
| What it means | |
|---|---|
| Safe | The cast always works on well-formed data — Int32 to Int64, say |
| Lossy | It may empty rows it cannot convert, or fail outright, depending on what is actually in the column |
| Disallowed | Not offered at all |
Lossy casts are offered but flagged. Text to Number is the common one: it works for the rows that hold numbers and cannot work for the rest. Narrowing a number — Int64 down to Int32 — is lossy for the same reason: values outside the smaller range have nowhere to go.
Disallowed casts are hidden rather than refused with an error, so you never pick one. They fall into two groups: conversions with no meaning (boolean to timestamp), and ones that should go through text first rather than directly.
Two types are locked and never cast:
- Attachment, because a cast would fall through to text and silently detach every file while reporting success.
- Categorical, except to a List, which is the one conversion that preserves what the column meant.
Where types come from
When you upload a CSV or paste data, types are inferred from the values. Text is the fallback: anything that does not parse consistently as something narrower stays text, which is lossless and always castable later.
Tables read through a connection carry the types the source defines.
Categorical Columns
A categorical column restricts its cells to a set of labels you define — statuses, regions, priorities. Instead of typing Active and hoping everyone else spells it the same way, the column holds the list and people pick from it.
Single and multiple
A categorical column can be either:
- Single-select — one label per cell.
- Multi-select — several labels per cell.
Cells render as coloured chips. Where several labels do not fit the cell width, the extras collapse into a +N badge you can open.
Defining the categories
Each category has a label and optionally a colour. You can add, rename, recolour, reorder and remove them from the column.
Three things behave in a way worth knowing:
Removing a category is blocked while a filter uses it. If any view filters on that value, the removal is refused rather than silently emptying the filter. Clear the filter first.
Category edits are not undoable. Adding, renaming and removing categories sit outside undo and redo. Renaming a category affects every cell holding it at once, and an undo that silently reverted a rename across a whole table is worse than doing it again deliberately.
Concurrent edits are caught. If someone else changed the category set while you were editing it, your change is rejected rather than applied over theirs — which would empty cells pointing at categories that no longer mean what they did.
Filtering
A categorical column offers its values in a picker rather than a free-text box, so you filter on what the column can actually hold.
For a multi-select column, a filter tests membership — "the value occurs in the list" — so a cell tagged EU, Priority matches a filter for EU.
Casting
Categorical is one of the two locked types. The only conversion offered is to a List, which keeps what the cell meant: the labels become list values.
Casting to text or anything else is not offered. See column types.
Attachments
An attachment column holds files on a row — a contract beside the vendor, a scan beside the invoice.
Adding the column
Open the table's item menu and choose Add attachment column.
You will not find Attachment in the ordinary column type picker, and the menu entry greys out once the table has one. That is because a table may have exactly one attachment column. Files are heavy and their permissions are answered per table; one column keeps that answerable.
The column's type is locked once created. It cannot be cast to text or anything else — a cast would fall through to text and silently detach every file on every row while reporting success.
Working with files
A cell holds a list of files, not one.
- Add files by uploading into the cell. Several can be in flight at once.
- Enter commits the list as one value. An unchanged list commits nothing.
- Escape cancels, aborting any uploads still in flight.
- Each file offers Download, Open in a new tab, a copy-link action, and Delete.
Files are capped at 100 MB each.
Detaching is an ordinary edit. Removing a file from a cell is just committing the list without it — the row changes, and the file itself is untouched wherever else it is used.
Deleting a file
Deleting the file itself is different from detaching it, and the dialog shows you the reach before you confirm:
Contracts (3 cells) · 1 table you cannot see
The same file can sit in many cells and in tables you have no access to, so the count tells you what a delete would take with it — including, honestly, that some of it is invisible to you.
What attachments cost
Attachment bytes count against the storage of the organization that owns the table — see usage and limits.
Downloading one costs egress, charged to the organization you are working in. A file leaving Mycorr costs exactly what a CSV of the same size costs.
A file is only reclaimed once nothing references it anywhere, and only after a later sweep confirms that is still true — so restoring a table from the Trash never comes back missing its files.
Limits worth knowing
A table with attachments cannot be published to the catalog. Catalog data is unbilled, so its files would stay billed to the source organization while being reachable by everyone.
Computed tables hold no files. The attachment type is not available on that path at all.
AI assistants see file names and change nothing. Through the MCP server an agent can read the names of attached files, and that is all — it cannot upload, detach, clear a cell, delete the column, or cast it. A cleared attachment cell is a detach, and detaching every file on a row is not something to leave to an agent.
If you want an assistant to help with an attached document, ask it for the row; the canvas link it hands back opens for you and not for it.
Table Links
A link records that a column in one table refers to a column in another — an order's customer_id pointing at a customer's id.
Links are what let you expand from one table into a related one on the canvas, and they are how the shape of your data is described rather than just its contents.
Creating one
- Select a table on the canvas and open Links.
- Choose Add table link.
- Pick the column on each side. The app spots likely matches — "Looks like a match. Hit the link button to add your first pair."
- Add the pair.
Composite links — where the relationship needs more than one column on each side — are built by adding more pairs to the same link.
For a link into a list column, a single membership pair is the whole link: "A membership pair (value in list) makes the whole link — no further pairs."
The link direction can be swapped, and clicking again resets it.
Both tables must be in the model
You can only link tables that are both present in the model you are working in. If the other end lives elsewhere, the app says so: "Other endpoint lives in a different model. Import that table here to use this link."
Import the table first, then make the link.
Who may create and delete a link
Authority comes from the pair of tables, never from one of them. That is the rule to hold on to: a link is a fact about two tables, so no single table's permissions can settle it.
The floor, for every link: you must be able to see both tables. If you cannot, you cannot create the link, delete it, or even know it exists — and the refusal deliberately tells you nothing about the table you cannot see, not even what kind it is.
Above that floor:
| The pair | Who may create or delete |
|---|---|
| Two ordinary tables | Anyone who can edit either one |
| An ordinary table and a catalog table | Anyone who can edit the ordinary side |
| Two catalog tables | A catalog manager |
Importing a table gives you no link rights over it. Being able to read a published catalog table does not let you rewrite the catalog's link graph — that belongs to whoever edits the table, not to everyone who imported it.
Link health
Link health checks whether a link's values actually line up — whether the referring values are found on the other side.
It becomes available once the table is released; before that the app says "Link health is available once the table is released."
Links and ownership transfers
Moving a table to another organization can sever links, and you are told how many before you confirm.
A link is severed when the destination organization would not grant access back to the other endpoint — in other words, when the other end stays behind in an organization that can no longer see the table. Links whose other end is in the destination organization, in the catalog, or in a third organization survive, and a link from a table to itself travels with it.
The count shown in the confirmation is exactly the set that will be removed.
Deleting
Delete table link removes it, and the confirmation says it cannot be undone. The tables and their data are untouched — only the relationship between them goes.
Computed Tables
A computed table is the result of a SQL query, saved as a table in its own right.
It is how you keep a derived view — a join, an aggregate, a filtered extract — as something you can open, export and import, rather than re-running a query every time.
How one is made
Computed tables are created by asking an AI assistant through the MCP server to save a query's result. There is no SQL editor in the app.
One rule the query must satisfy: every output column needs an explicit alias. A column with no name of its own is refused rather than guessed at.
Where they live
A computed table has no parent model. It belongs to you and appears in your overview, outside any model.
To use one in a model, import it. The import is a reference rather than a copy — the data exists once, and the in-model table is a read-only view onto it.
Computed tables are owner-only. Importing one into a model is the single thing anyone else can do with it.
Refreshing
A computed table does not update itself. When its source tables move on, it shows as out of date, and Refresh from current versions re-runs the query.
Three things about refresh:
- It is owner-only, and done from the overview rather than from inside a model.
- It replaces the data in place.
- It fails if the query's output types have changed rather than migrating the table to the new shape. A refresh that quietly changed a column's type would break everything reading it downstream, so it stops and tells you instead.
No versions
Computed tables are unversioned. A refresh replaces the contents, and there is no history behind it.
That means:
- No checkpoints and no aliases.
- No going back to what the query returned last week.
- Nothing to compare against.
If you need the history, the source tables have it — a computed table is a derived view, and the versioning lives with the data it derives from.
What else they cannot do
- They cannot hold attachments.
- They cannot be edited cell by cell. The query is the definition; change the query, not the result.
Deleting
Delete computed table removes it. An import of it in someone's model stops resolving, so check what depends on it first.
In this part, we'll cover the way you can share resources in Mycorr and what permissions you can define for each resource.
Sharing Resources
What can you share?
Resources in Mycorr are private by default, meaning that only you can access them when you create them. However, you can share both models and tables with individual Users or Teams you are a part of, and define the level of access they get to the resource.
How can you share?
- Sharing to Users
In order to share a resource with a group of users, you’ll need their email addresses. By default, once the resource is shared, they will receive both a notification in their Mycorr account and an email with a link to directly access the resource. In other cases, this will depend on the notification settings of the user.
Depending on the access level you choose, the users will be able to directly access the resource as soon as it is shared with them.
- Sharing to a Team
Alternatively, you can share a resource with a team by selecting one of the teams you are a part of. By doing so, all members of the team will have access to it, as per the access level you have chosen.
Permissions
What are permissions?
Permissions are the settings defined when sharing a resource that determine what actions they can perform on the resource and what access level they have.
How can you set permissions?
When sharing a resource, you can choose from a list of permissions that are available. Each one of the resource has its own set of permissions :
- All about Sharing Models.
- All about Sharing Tables.
Sharing Models
As the Model Owner, you are the only one who can invite others to collaborate on your Models by sharing it with Users or Teams you are a part of.
When sharing a Model, you can assign one of these two roles :
- Collaborator : Allows users or teams to edit the Model and Tables within it.
- Viewer : Allows users or teams to view the Model and its Tables but not make changes.
Neither Collaborators nor Viewers can share the Model. Only you, as the Owner, have the permission to do so.
Revoking Access to a Model
As the Model Owner, you can revoke access to a Model at any given time by removing a User or Team from the shared list.
When revoking access, you can choose to allow the User or Team to keep any table (owned by the model) they imported, or you can choose to remove all those imports. When choosing the second option, you revoke access to the model entirely with all its tables.
If you decide to allow them to keep the imports of the tables owned by that model, they will retain the versions they already have of the tables, whether they are behind the original versions or up-to-date, but they will no longer receive updates made to the tables.
Sharing Models
As the Model Owner, you can share Tables owned by the Model individually with Users or Teams, you are a part of, even without sharing the entire Model.
When sharing a Table, you can grant one of these two permissions :
- Can Import : Allows users or teams to import the Table into other Models but not share it with others.
- Can Reshare : Allows both importing the Table into other Models and sharing it with others.
Only you, as the Model Owner, can share a Table and give the re-share permission. Users or Teams who can reshare a Table can only share it again without the ability to grant the re-share permission to whoever they are sharing it with.
Revoking Access to a Table
As the Model Owner, you can revoke access to a Table at any given time by removing a User or Team from the shared list.
When revoking access, if the User or Team has imported the table elsewhere, you can choose to let them keep the imported copies or remove any import of the table.
If you allow them to keep the importeds, they will retain the version they already have of the table in the model(s) they have imported it into, but they will no longer receive updates made to the table.
Ownership Transfer of a Table
As the Model Owner, you can transfer ownership of a Table to another Model, making it the new Parent Model of the Table.
You can transfer ownership to models you own or to models you are collaborator in.
If the Table is imported in the target model we are transferring ownership to and it is not up-to-date with the latest version of the table in the source model, the table's state in the target model will be fast-forwarded to the latest version at the time of the ownership transfer.
When transferring ownership of a table in a model you are Collaborator in, the model Owner will be notified and would need to accept the ownership transfer request.
Data Sources
In Mycorr, tables can originate from different sources. Tables manually created within a Model are Owned by the Model. But you can always bring in data from external sources.
You can access the Import section inside a Model where you can find different options:
- Table Import — bring tables in from other Models you have access to.
- Connections — anything backed by saved credentials: Google Sheets, PostgreSQL, Supabase, Cloud Storage Buckets. Set up a connection once and import from it across any Model.
Other options are doable on the Canvas directly, such as:
Table Import
In the Import section, you will see all the Models you have access to, whether those you own or those that were shared with you. Below each Model, you will find a list of all the tables available there. You can also find a list of Tables that have been explicitly shared with you.
You can reuse those Tables by importing them into the current Model you are working on. In order to do so, you can drag and drop any Table into the Canvas.
If you import Tables from Models where you are a Collaborator or Viewer and the Table is not explicitly shared with you, this action will trigger a request for the Model Owner to share the Table with you. You will need to wait for their approval before you can access the Table.
⚠️ Pending Import Requests
Imported Tables that are waiting for the Model Owner’s response will not appear in the Canvas until the request is approved and you create a Table View based on it.
You can find the pending tables grayed out in the Directory section.
You can choose to cancel the import request at any time.
If you are a viewer of a Model, meaning that you can not edit it, and one of the tables owned by your models have been imported there, you can still control the access to the table.
Data Consistency Across Models
After importing Tables, we make sure that the data in the source Table and the imported Table are consistent across Models.
Whenever changes are made to the original Table, they are detected in the Models where the Table has been imported, allowing you to manually trigger a sync to update the data to the latest state to ensure consistency wherever the Table is.
CSV Upload
You can ingest CSV data into your Models by dragging and dropping a CSV file onto the Canvas.
You can optionally set a specific delimiter (e.g., semicolon, comma, tab…) or header row number for more control over the data you are importing.
⚠️ Note that only .CSV files are accepted for now.
Pasted Data
You can quickly create a new Table by copying and pasting data directly into the Canvas.
A Table will be created and you can start manipulating the data right away.
⚠️ Only Pasted Data is editable. Other external Data sources mentioned are read-only.
Connections
A Connection in Mycorr is a saved set of credentials for an external data source — a PostgreSQL database, a Supabase project, a Google account, a cloud storage bucket. You create a Connection once and reuse it across as many Models as you like.
You manage Connections from Settings → Connections, or create new ones inline from the Import panel inside a Model.
How Connections work
- Saved once, reused everywhere. Connect to your Postgres once and every Model in your account can import tables from it without re-entering credentials.
- Encrypted at rest. Passwords and tokens are encrypted with AES-256-GCM. Mycorr's server cannot read them back as plaintext after storage — only decrypt them in memory at the moment a query runs.
- Owner-scoped. A Connection belongs to the user who created it. Other team members cannot see your saved credentials, even if they share a Model with you.
- Read-only in practice. Mycorr's import code only ever reads:
SELECTon Postgres / Supabase,storage.objectVieweron buckets, and Drive picker-selected files on Google. (The Googledrive.filescope is technically read-write because that's the only Google API for picker-selected files — Mycorr only reads.) - Revocable from your side. Removing access in Postgres, GCP, or Google immediately stops Mycorr from being able to read — the next refresh fails cleanly with a permission error.
Supported connection types
| Type | Use it for | Setup |
|---|---|---|
| Google account | Importing Google Sheets | Google Sheets |
| PostgreSQL | RDS, self-hosted, Heroku, anything Postgres-wire-compatible | PostgreSQL |
| Supabase | A Supabase project (same as Postgres, with helpers for pooler URLs) | Supabase |
| Cloud Storage Bucket | Importing CSV / TSV / Parquet from GCS (S3 + Azure coming) | Cloud Storage Buckets |
Editing and revoking
From Settings → Connections you can:
- Rename a connection (the identity fields — host, database, username — are immutable; rotate the password by editing it).
- Replace the password / CA certificate without recreating the connection.
- Delete a connection. Any tables previously imported through it stay in Mycorr (the data is yours) but can no longer be refreshed — re-create the connection to resume syncing.
What's next
Pick the type you want to set up:
Google Sheets
A Google connection lets Mycorr read spreadsheets from any Google account you control. Imported sheets become Tables inside a Model, and you can re-sync them later to pick up changes.
One Google connection per account per user — you can have several side by side if you work across multiple accounts (e.g. work + personal).
What you need
- A Google account.
- Pop-ups allowed for
mycorr.app(the OAuth flow opens a small Google sign-in window).
That's it. There is no admin step — Google's consent screen is the entire setup.
Connecting your Google account
- Go to Settings → Connections → New Connection (or use the Import panel inside a Model and click "Connect a Google account").
- Pick Google account.
- A Google sign-in pop-up opens.
- Pick the Google account you want to use and approve the consent screen.
- The pop-up closes and the new connection appears in your list, labeled with the email you signed in with.
What Mycorr asks for
The OAuth consent screen requests three scopes:
drive.file— "See, edit, create, and delete only the specific Google Drive files you use with this app." Mycorr can only see spreadsheets you explicitly hand it through the Drive file picker; it cannot enumerate the rest of your Drive.userinfo.email+userinfo.profile— your email address and name, used to label the saved connection in your list.
Mycorr never writes to your spreadsheets in practice — the drive.file
scope is what Google's API requires to read picker-selected files, but
the import code only ever reads.
Importing sheets into a Model
Once the connection is saved:
- Inside a Model, open the Import panel.
- Pick the Google connection.
- The Drive file picker opens — select one or multiple spreadsheets.
- Each selected sheet is imported as its own Table inside the Model.
Drag any imported Table onto the Canvas to start working with it.
Keeping data in sync
After import, each Sheets-backed Table gets a Check for updates button. Click it to pull the latest cell values from the original spreadsheet. Sync covers:
- Row additions and deletions
- Column additions and deletions
- Value updates in cells
There are limits on what sync can detect cleanly across renames / reorders — see Syncing Data from Google Sheets for the rules.
Revoking
Two ways to disconnect:
- In Mycorr: Settings → Connections → click the row → Delete. The connection is removed; any tables you imported stay in your Models but stop syncing.
- In Google: visit myaccount.google.com/permissions, find Mycorr in the list, and click Remove access. The connection in Mycorr will start failing on the next refresh — delete it from Mycorr afterward to clean up.
Either action is enough. Doing both is fine.
Troubleshooting
| Symptom | Fix |
|---|---|
| Pop-up never opens | Allow pop-ups for mycorr.app and click again |
| "Google account didn't match" when re-signing in | You're switching accounts on an existing connection — sign in with the original email, or delete and re-create the connection with the new account |
| Import picker shows "No spreadsheets found" | Either your account has no Sheets, or you skipped the file-picker — re-click Sign in with Google and select the files in the Drive picker |
| Sync fails with "permission denied" after working before | You revoked Mycorr in Google's account permissions — re-create the Mycorr connection |
See also
- Syncing Data from Google Sheets — what sync can and can't detect.
The Sign in with Google button inside the Cloud Storage
Bucket setup runs a separate OAuth flow with
different scopes (openid email profile, for Workload Identity
Federation). Mycorr keeps one Google connection per account per user — if
you already have a Sheets connection for an account and want to use the
same account for Cloud Storage Buckets, delete the existing connection
first and re-create it from the Bucket form.
Syncing Data from Google Sheets
When importing a Spreadsheet into the Canvas, there will be a button for the created Table that allows users to check for updates in the Spreadsheet. If there are any updates found, the system will automatically update the table with the latest data.
Our strategy accounts for:
- Rows Addition/Deletion
- Column Addition/Deletion
- Value Updates in Cells
But, while we offer robust synchronization system, there are some rules to keep in mind to ensure smooth operations and prevent inconsistencies.
Column Reorder
If you move a lot of columns around in your Spreadsheet, our system will treat them as new columns at new positions rather than reordered columns.
Column Renaming
If you rename a column in your Spreadsheet, our system will treat it as a new column at that position rather than a renamed column.
The synchronization doesn't affect the overall structure of the Table in the Canvas. If changes are detected in the Schema and the Table is updated, you will see the correct new order of columns as they appear in the Spreadsheet.
If you need to make significant structural changes, consider re-importing your spreadsheet or contact support for guidance.
PostgreSQL Connection
A Postgres connection lets Mycorr read tables from any Postgres-wire-compatible database — RDS, Cloud SQL, self-hosted, Heroku, Neon, Crunchy Bridge, etc.
For a managed Supabase project, use the Supabase connection type instead — it has helpers for finding the connection string and dealing with poolers.
What Mycorr needs
A user (role) on your database with SELECT on the tables you want
to import. Mycorr never issues anything beyond SELECT and a handful of
information_schema lookups.
We strongly recommend creating a dedicated read-only role rather than reusing an application or admin role:
-- Create the role
CREATE ROLE mycorr_reader WITH LOGIN PASSWORD '<strong-random-password>';
-- Allow connecting to the database
GRANT CONNECT ON DATABASE your_db TO mycorr_reader;
-- Allow seeing the schema(s) you want to expose
GRANT USAGE ON SCHEMA public TO mycorr_reader;
-- Allow reading existing tables
GRANT SELECT ON ALL TABLES IN SCHEMA public TO mycorr_reader;
-- Allow reading tables created in the future too
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO mycorr_reader;
Repeat the last three statements for every schema you want to import from.
Network access
Mycorr connects to your database over the public internet from its hosting environment. Two things follow:
- Public reachability required. The host you give Mycorr must
resolve to a public IP. Private addresses (
10.x,172.16-31.x,192.168.x,169.254.x, loopback,*.local,localhost) are rejected up front — see the SSRF note in the Security model section. - No static egress IPs published today. If your database firewall needs an allowlist, reach out to support — VPC peering / site-to-site tunnels are on the roadmap. For now the practical setup is "publicly reachable, TLS-required, read-only role".
Setting it up
- Go to Settings → Connections → New Connection.
- Pick PostgreSQL.
- Fill in:
- Name — anything human, e.g. "Prod analytics replica".
- Host —
db.example.comor an IP. Internal hostnames (e.g.localhost,*.local) are rejected. - Port — usually
5432. - Database — the database name (not the cluster name).
- Username — the read-only role you created above.
- Password — the password for that role.
- Require encrypted connection is on by default. Leave it on unless your database is on a trusted private network.
- (Optional) Under Advanced, paste a Custom CA certificate (PEM) if your database uses a private / self-signed CA that isn't in the public trust store (common for RDS proxy, internal PKI). Get the PEM from your DBA.
- Test & save. Mycorr opens one short connection, runs a trivial query, and stores the encrypted credentials.
The host, port, database, and username are immutable after creation — they define the connection's identity. To point at a different database, create a new connection. The password and CA certificate can be updated by editing the connection.
SSL modes
| Setting | Equivalent libpq mode | When to use |
|---|---|---|
| Require encrypted connection ON (default) | verify-full | Always, unless you have a specific reason not to. Encrypts traffic and validates the server's certificate against either the public trust store or your provided CA. |
| Require encrypted connection OFF | disable | Trusted private network only — traffic is unencrypted. |
There is no equivalent of prefer / require (encrypt but don't
validate). If you have a self-signed CA, paste it in the Advanced
section rather than turning off validation.
Finding the connection details
Where to look depends on your provider:
- AWS RDS / Aurora: RDS console → your instance → Connectivity & security → Endpoint is your host, Port is the port. Database / username were set at create time.
- Google Cloud SQL: Cloud SQL console → your instance → Connections → Public IP is the host. Enable "Public IP" and allowlist Mycorr's egress IPs.
- Heroku Postgres:
heroku config:get DATABASE_URL→postgres://user:pass@host:port/database. Parse out each field. - Neon / Crunchy Bridge / Render: each provider shows a connection string on the project dashboard. Parse the URL into its parts.
- Self-hosted: whatever you set in
postgresql.conf/pg_hba.conf.
For Supabase, use the Supabase page — it has provider-specific guidance.
Importing data
Once the connection is saved:
- Inside a Model, open the Import panel.
- Pick the connection.
- Browse schemas → tables → click a table to import it.
- The imported table is fully owned by your Model. You can sync it later from the same panel; sync re-fetches the table contents and overwrites the previous data.
Security model
- Read-only by IAM. The role you create only has
SELECT. Even if Mycorr's code asked for more, your database would refuse it. - Encrypted at rest. The password and (if provided) CA certificate are AES-256-GCM encrypted in Mycorr's database. Other team members cannot see them; Mycorr support cannot read them as plaintext.
- Encrypted in flight. TLS to your database (
verify-fullby default) using either the system trust store or your custom CA. - No SQL injection surface. Mycorr does not run user-supplied SQL.
Schema and table names are validated against
information_schemabefore being interpolated into queries. - No SSRF. Connections to private / metadata / loopback addresses
(
127.0.0.0/8,10.0.0.0/8,172.16-31.0.0/12,192.168.0.0/16,169.254.0.0/16,localhost,*.local) are blocked. Mycorr cannot be used as a proxy into a private network.
Revoking
Two ways:
- In Mycorr: Settings → Connections → click the row → Delete.
- In Postgres:
REVOKEthe role's privileges, drop the role, or rotate the password. Sync will start failing on the next refresh.
Either is sufficient. Both is fine.
Troubleshooting
| Error | Likely cause | Fix |
|---|---|---|
connection refused / failed to lookup address | Wrong host or port, or your database firewall is dropping us | Verify host/port; allowlist Mycorr's egress IPs |
password authentication failed | Wrong username or password | Re-check; rotate the password if needed |
SSL error: certificate verify failed | Server uses a private CA not in the trust store | Paste your CA in Advanced → Custom CA certificate |
database "..." does not exist | Typoed database name (cluster vs database confusion) | Use the database name, not the cluster name |
permission denied for schema X | The role lacks USAGE on the schema | GRANT USAGE ON SCHEMA X TO mycorr_reader; |
permission denied for table Y | The role lacks SELECT on the table | GRANT SELECT ON Y TO mycorr_reader; |
prepared statement "..." already exists | A connection pooler in transaction mode (PgBouncer / Supavisor / PGCat) | Mycorr disables named statements by default — if you still see this, you're hitting a pooler edge case; switch to session mode or the direct connection |
connections to private/internal addresses are not allowed | Your host resolves to an RFC 1918 address | Mycorr can only reach public-internet hosts today; expose the database publicly with TLS, or wait for VPC peering support |
Used by
- Table imports from your database, browseable inside any Model's Import panel.
Supabase Connection
Supabase projects are Postgres under the hood, but Supabase exposes three different endpoints for a given project, with subtly different behavior. The Supabase connection type in Mycorr is a thin wrapper over the PostgreSQL connection with guidance on which endpoint to use.
If you just want the short version: use the Session Pooler endpoint
on port 5432, with the postgres.<project-ref> username and your
project database password. Read on for why.
What you need
- A Supabase project (any plan, free tier works).
- The database password for your project. This is the one you set
during project creation — it's not your Supabase login password
and it's not your anon / service-role key.
- Forgot it? In the Supabase dashboard: Project Settings → Database → Reset database password.
You do not need to create a separate Postgres role for Mycorr —
Supabase exposes the postgres superuser by default, and the pooler
endpoints route through it. If you want stricter least-privilege,
create a dedicated read-only role as described in the Postgres
connection page.
The three Supabase endpoints
In the Supabase dashboard, Project Settings → Database → Connection string shows three options:
| Endpoint | Port | What it is | Use it for Mycorr? |
|---|---|---|---|
| Direct connection | 5432 | Talks straight to Postgres. IPv6-only on the free / Pro plan unless you have the IPv4 add-on. | Only if you have the IPv4 add-on, or if your network has IPv6. |
| Session Pooler | 5432 | Supavisor in session mode — looks like a normal Postgres connection, IPv4-reachable. | Yes — recommended. |
| Transaction Pooler | 6543 | Supavisor in transaction mode. One server connection is multiplexed across many clients per transaction. | Works, but session mode is simpler. |
Why Session Pooler is recommended
- IPv4 by default, so it works from Mycorr's network without any add-ons.
- Behaves like a regular Postgres connection — no transaction-mode pitfalls.
- Same TLS guarantees as the direct connection.
If you specifically want transaction-pooler semantics (e.g. because
that's how the rest of your stack connects), the Transaction Pooler on
port 6543 also works — Mycorr disables named prepared statements so
the typical prepared statement "sqlx_s_1" already exists collision
doesn't occur.
Finding the connection details
In the Supabase dashboard:
-
Go to Project Settings → Database → Connection string.
-
Choose the Session pooler tab.
-
Copy the URI. It looks like:
postgresql://postgres.abcdefghijklmnop:<password>@aws-0-eu-west-1.pooler.supabase.com:5432/postgres -
Parse it into the Mycorr form fields:
Mycorr field From the URI Host aws-0-eu-west-1.pooler.supabase.com(your region differs)Port 5432Database postgresUsername postgres.abcdefghijklmnop(note the dot-suffix — that's your project ref)Password your project database password
The postgres.<project-ref> username format is mandatory on the pooler
endpoints — the project ref tells Supavisor which project to route to.
Setting it up
- Go to Settings → Connections → New Connection in Mycorr.
- Pick Supabase.
- Fill in the fields you parsed from the connection string above.
- Leave Require encrypted connection on (Supabase requires TLS).
- Test & save.
The form is identical to the PostgreSQL one — pick Supabase so the connection is tagged correctly in your list and displays with the Supabase icon.
SSL / TLS
Supabase's pooler endpoints present certificates signed by a public CA,
so Mycorr's default verify-full mode works out of the box — no custom
CA certificate needed.
Permissions
Out of the box, Mycorr will connect as the postgres superuser through
the pooler. That's fine for reading, but it's broader access than
necessary. To follow least-privilege:
-- Run this in the Supabase SQL editor (Project → SQL Editor).
CREATE ROLE mycorr_reader WITH LOGIN PASSWORD '<strong-random-password>';
GRANT USAGE ON SCHEMA public TO mycorr_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO mycorr_reader;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO mycorr_reader;
Then use mycorr_reader.<project-ref> as the username in the pooler
URL (the dot-suffix is still required for pooler routing).
If you use Supabase's Row-Level Security, remember that policies
are evaluated against the connecting role — mycorr_reader will see
exactly what your policies allow that role to see.
Importing data
Same as any Postgres connection — see Postgres → Importing data.
Troubleshooting
| Error | Likely cause | Fix |
|---|---|---|
connection refused / failed to lookup address on port 5432 | You used the direct connection string and your network has no IPv6 | Switch to the Session pooler string (still port 5432) |
password authentication failed | Wrong password — most often, you used your Supabase login password instead of the database password | Project Settings → Database → Reset database password, copy the new one |
Tenant or user not found | Username is missing the .<project-ref> suffix on a pooler endpoint | Use postgres.<project-ref> (or <your-role>.<project-ref>) |
SSL error: certificate verify failed | Stale or self-managed CA bundle on your end | Leave Custom CA certificate blank — Supabase's public CA is in the standard trust store |
prepared statement "..." already exists | You're on the transaction pooler (port 6543) and Mycorr's auto-disable of named statements didn't take effect | Switch to the session pooler (port 5432), or contact support |
Revoking
Two ways:
- In Mycorr: Settings → Connections → click the row → Delete.
- In Supabase: rotate the database password (Project Settings → Database → Reset database password) or drop the dedicated role. The Mycorr connection will start failing on the next refresh.
Used by
- Table imports from your Supabase project, browseable inside any Model's Import panel.
Cloud Storage Buckets
A Cloud Storage Bucket connection lets Mycorr read files — CSV, TSV, or Parquet — directly from a cloud storage bucket and import them into a Model as Tables.
Supported providers: Google Cloud Storage (GCS). Amazon S3 and Azure Blob Storage are on the roadmap.
How it works
Once a connection is set up, you can browse your bucket from the Import panel inside a Model. Folders and files appear as a tree — click a file and Mycorr imports it as a new Table in the current Model.
- Per-file import. Each file you click becomes its own Table.
- Fully owned. After import, the Table is yours — edit it, share it, version it. There is no live link back to the bucket.
- Re-import by clicking the file again to bring in a fresh copy as a new Table.
Connecting a bucket
Connections are created from Settings → Connections → New Connection → Cloud Storage Bucket, or from the Import panel inside a Model.
When creating a GCS connection, you provide:
- Access scope — a single bucket (recommended) or your entire GCP project (browse all buckets you have access to).
- Sign in with Google to link your Google account to the
connection. (Mycorr requests only non-sensitive
openid email profilescopes — never access to your Cloud data via OAuth.) - The WIF audience your admin gives you (see below). Mycorr uses Workload Identity Federation: your Google sign-in is exchanged for a short-lived token whose bucket access comes from IAM, not the OAuth grant.
⚠️ Cloud setup is required first. Before the connection will work, someone with admin access to your GCP project needs to grant Mycorr's access. See the GCP Setup page for the commands your admin runs once, then hands you the WIF audience to paste into Mycorr.
Security model
- No long-lived secret in Mycorr. Mycorr never asks for a service account JSON key. Access is brokered by your Google sign-in, exchanged on the fly for a short-lived (1 hour) token to read the bucket.
- No sensitive OAuth scope. Sign-in requests only
openid email profile; the bucket grant lives in your GCP IAM, not the OAuth scope. - Read-only. The roles granted (
storage.objectViewer, optionallystorage.bucketViewer) only allow reading. Mycorr cannot write, modify, or delete anything in your bucket. - Revocable in GCP. Removing the federated principal from the IAM binding (or deleting the WIF provider) cuts off access at the next token refresh — independent of Mycorr.
- Audit trail. Every bucket read shows up in Cloud Audit Logs with
the human user's identity (
principalSubject) attached.
Revoking
Two ways to disconnect:
- In Mycorr: Settings → Connections → click the row → Delete.
- In GCP: remove the principalSet binding, or delete the WIF provider. Full commands in GCP Setup → Revoking access.
Either is sufficient. Both is fine.
Next
- GCP Setup (admin) — the one-time GCP configuration your admin runs to grant Mycorr access.
GCP Setup for Cloud Storage Buckets
This page is for the GCP admin setting up a bucket connection for one or more Mycorr users. Run these commands once, then hand the result (a WIF audience string) to your teammates to paste into Mycorr.
Mycorr uses Workload Identity Federation (WIF): users sign in with
Google, and Mycorr exchanges the user's Google id-token against your WIF
provider for a short-lived federated token that reads the bucket directly.
No service-account keys and no service-account impersonation. The Google
consent screen requests only non-sensitive scopes (openid email profile) — bucket access comes entirely from the IAM bindings you set
below, not from an OAuth scope.
The user's Google identity is the trust anchor; Mycorr never holds a long-lived customer secret.
What Mycorr signs as
Google is the OIDC issuer. The id-token Mycorr presents looks like:
{
"iss": "https://accounts.google.com",
"sub": "108234567890123456789",
"email": "you@yourcompany.com",
"email_verified": true,
"hd": "yourcompany.com",
"aud": "<Mycorr OAuth client_id>",
"exp": ...
}
Your WIF provider validates the signature against Google's JWKS, checks
the aud against --allowed-audiences, and evaluates your
--attribute-condition against the mapped claims.
Setup
Prerequisites
- A GCP project with Cloud Storage, IAM, and Security Token Service APIs enabled.
- A GCS bucket.
gcloudauthenticated withiam.workloadIdentityPoolAdminandstorage.admin.- Mycorr users sign in with Workspace Google accounts. Personal
@gmail.comaccounts have nohdclaim and will fail the default org-domain condition (usually what you want).
Step 1 — Set variables
export PROJECT=your-gcp-project
export BUCKET=your-bucket-name
export MYCORR_HOST=https://mycorr.app # use your Mycorr deployment's URL
gcloud config set project $PROJECT
PROJECT_NUM=$(gcloud projects describe $PROJECT --format='value(projectNumber)')
# Mycorr's allowed-audience — the bare OAuth client_id Google sets as
# the `aud` claim on user-OAuth id-tokens. Stable per Mycorr deployment.
# (Mycorr also shows this value inline on the connection form.)
MYCORR_AUDIENCE=$(curl -s $MYCORR_HOST/api/public/federation/config | jq -r .allowed_audience)
# The user (or domain) you want to authorize.
USER_EMAIL=you@yourcompany.com
USER_DOMAIN=${USER_EMAIL#*@}
Step 2 — Create the Workload Identity Pool + Provider
gcloud iam workload-identity-pools create mycorr-pool \
--location=global --project=$PROJECT
gcloud iam workload-identity-pools providers create-oidc mycorr-issuer \
--workload-identity-pool=mycorr-pool --location=global --project=$PROJECT \
--issuer-uri="https://accounts.google.com" \
--allowed-audiences="$MYCORR_AUDIENCE" \
--attribute-mapping="google.subject=assertion.sub,attribute.email=assertion.email,attribute.org=assertion.hd" \
--attribute-condition="attribute.email == '$USER_EMAIL'"
# Or trust every user in your Workspace domain — swap the last flag:
# --attribute-condition="attribute.org == '$USER_DOMAIN'"
The three flags doing real work:
--issuer-uri=https://accounts.google.com— Google is the OIDC issuer; GCP fetches Google's JWKS to verify token signatures.--allowed-audiences=$MYCORR_AUDIENCE— required. Without it, STS only accepts tokens whoseaudequals the provider resource name.--attribute-condition=...— the security gate. Email-pinned for one user, orattribute.orgfor whole-org trust.
Step 3 — Grant the federated principalSet read on your bucket
Bucket-scoped (recommended):
PREFIX="principalSet://iam.googleapis.com/projects/$PROJECT_NUM/locations/global/workloadIdentityPools/mycorr-pool"
# Anyone in your Workspace domain:
PRINCIPAL_SET="$PREFIX/attribute.org/$USER_DOMAIN"
# Or a specific user:
# PRINCIPAL_SET="$PREFIX/attribute.email/$USER_EMAIL"
gcloud storage buckets add-iam-policy-binding gs://$BUCKET \
--member="$PRINCIPAL_SET" --role=roles/storage.objectViewer
Project-scoped: grant both bucketViewer (to enable buckets.list)
and objectViewer at the project level:
gcloud projects add-iam-policy-binding $PROJECT \
--member="$PRINCIPAL_SET" --role=roles/storage.bucketViewer
gcloud projects add-iam-policy-binding $PROJECT \
--member="$PRINCIPAL_SET" --role=roles/storage.objectViewer
Step 4 — Hand the audience string to the Mycorr user
echo "//iam.googleapis.com/projects/$PROJECT_NUM/locations/global/workloadIdentityPools/mycorr-pool/providers/mycorr-issuer"
What the Mycorr user does in the app
- New Connection → Cloud Storage Bucket → Google Cloud Storage.
- Access scope: Single bucket (and the bucket name) or Entire project.
- Click Sign in with Google (consents to non-sensitive
openid email profileonly). - Paste the audience string from Step 4 into WIF audience. (Mycorr shows the matching client ID inline for cross-checking.)
- Test connection and Save.
Revoking access
# Remove the principalSet binding (other resources unaffected):
gcloud storage buckets remove-iam-policy-binding gs://$BUCKET \
--member="$PRINCIPAL_SET" --role=roles/storage.objectViewer
# Tighten the condition (kicks off any user no longer matching):
gcloud iam workload-identity-pools providers update-oidc mycorr-issuer \
--workload-identity-pool=mycorr-pool --location=global \
--attribute-condition="attribute.email == 'specific-user@$USER_DOMAIN'"
# Nuclear — delete the provider (all Mycorr federation against it stops
# on next refresh):
gcloud iam workload-identity-pools providers delete mycorr-issuer \
--workload-identity-pool=mycorr-pool --location=global
In-flight 1-hour federated tokens stay valid until expiry; deleting the provider cuts off new exchanges immediately.
Troubleshooting
| Error in Mycorr | Likely cause | Fix |
|---|---|---|
linked Google connection not found | User hasn't signed in, or removed the Google connection | Click Sign in with Google again on the connection form |
Google STS exchange failed (400): invalid_target | WIF audience string mismatch | Re-copy the audience from Step 4 |
Google STS exchange failed (400): allowed audiences not configured | --allowed-audiences missing or wrong | Re-create the WIF provider with the flag |
Google STS exchange failed (400): audience does not match | --allowed-audiences includes a prefix — Google sets aud to the bare client_id | Use MYCORR_AUDIENCE exactly as /api/public/federation/config returns it |
Google STS exchange failed (403): attribute condition not satisfied | User identity (email / hd) doesn't match the condition | Check the condition expression; the user should sign out and back in if they signed in before the field was added |
403 storage.buckets.list permission denied (project scope) | principalSet has objectViewer but not bucketViewer | Add roles/storage.bucketViewer at project level |
403 storage.objects.list permission denied | Bucket IAM doesn't include the federated principalSet | Re-check the bucket binding step |
ALREADY_EXISTS creating WIF pool / provider | GCP soft-deletes for 30 days | Use undelete + update-oidc, or pick a new name |
Audit logging
The federated principal encodes the user's stable sub in
principalSubject. Cross-reference against your IdP / Workspace directory.
resource.type="gcs_bucket"
resource.labels.bucket_name="$BUCKET"
protoPayload.authenticationInfo.principalSubject=~"workloadIdentityPools/mycorr-pool"
Note on OAuth scopes
The Google consent screen requests only non-sensitive scopes:
openid, email, and profile. Mycorr needs the openid id-token to
federate — it never asks for a Cloud Storage or cloud-platform scope, so
there is no "View and manage your data across Google Cloud services"
prompt and no Google sensitive-scope verification.
What Mycorr can do with your bucket is bounded entirely by your IAM:
the federated principalSet is granted only storage.objectViewer
(+ bucketViewer for project scope) — read-only on the bucket. The OAuth
grant proves who the user is; your IAM bindings decide what they can
read.
Datasets
A dataset is a named set of tables you can share and publish as one thing.
It is not a model and not a table. A model is where you work; a dataset is what you hand over. The tables in a dataset can come from more than one model, and a table can belong to several datasets at once.
Find them under Datasets in the sidebar.
Creating one
- Open Datasets.
- Click New dataset.
- Give it a name.
Then add tables to it, either from the dataset or from a table's own menu with Add to dataset.
Members
The tables in a dataset are its members. Adding and removing them changes the dataset's current state — what it holds right now.
Some tables cannot be added, and the dialog says which and why:
| Refusal | Reason |
|---|---|
| Tables from an external connection | They are read through a live connector, so they cannot be released on their own |
| Restricted table | You cannot publish a table whose access is walled |
| You don't have access to this table | You cannot add what you cannot read |
When you add tables you own, you are offered "Also give access to the tables I own in this dataset" — sharing the dataset does not by itself share the tables inside it, so this is the shortcut that does both.
Deleted tables stay listed. A table that was removed shows as "This table was permanently deleted. It stays listed so the dataset's history reads true." A dataset's past releases referred to real tables, and quietly dropping them would make old releases describe something that never existed. If a table is merely in its model's trash, the row says so and you can restore it there.
Releases
A release freezes the dataset: it pins each member table at its current version, so anyone reading that release sees exactly what you released, however much the tables change afterwards.
- Open the dataset.
- Click Add a release.
- Optionally give it a label — a release name such as
2026-q3. - Confirm.
Labels must be unique within the dataset.
Once a release exists, every member is shown relative to it:
| State | Meaning |
|---|---|
| Unchanged since this release | The table is exactly as released |
| Ahead of this release | The table has changed since |
| Behind this release | The table is at an older version than the one released |
A new release is only available when something has actually changed — if nothing has, the app tells you "No member has changed since the last release."
Describing a dataset
A dataset carries the metadata that makes it usable by someone who did not build it:
| Field | What it is for |
|---|---|
| Description | What the dataset contains |
| Keywords | Terms people search by |
| Licence | What others may do with the data — see below |
| Attribution | Credit for the source the data came from |
| Creators | The people or organisations behind it |
| Related links | Documentation, a source page, anything relevant (http and https only) |
| Maintenance guide | How the dataset is kept up to date |
| Labels | Your own categories |
Licences
Pick a licence from the list and the link is filled in for you — you never type a licence URL for a known licence. That is what stops two datasets spelling the same licence differently.
If your licence is not on the list, choose the custom option and give a name and a URL. That is the only place a licence URL is entered by hand, and it must be https.
A licence's credit line is not part of the licence. It belongs in Attribution.
Access
Manage access controls who can see the dataset. Someone without access sees a Request access action instead, and once asked, the app tells them "The people who can grant it have been asked."
Datasets you can see but do not own appear under Shared with you.
Publishing
Making a dataset public is a catalog release. See that page for what publishing requires and what it means.
The Public Catalog
The catalog is Mycorr's public collection of datasets. A dataset published to it is readable by anyone, and its tables can be imported into anyone's model.
Catalog datasets
A catalog dataset is not an ordinary dataset with a flag set. It is created as one — New catalog dataset on the Datasets page — and it is owned by a role rather than by a person, so it does not disappear with the account that made it.
Publishing rights are held separately from ordinary dataset management: being able to manage a dataset does not make it publishable.
Releasing is publishing
For a catalog dataset, cutting a release and publishing it are the same act, not two steps. The button says Release & Publish, and it does what it says: each member table is pinned at its current version, and the result goes public.
There is no draft state between the two, and no review queue. Take the checks below as the gate, because once released it is out.
What must be resolved first
The app refuses to publish an incomplete dataset, and lists what is missing under Resolve these before publishing:
| Blocker | What it means |
|---|---|
| Missing dataset description | Nobody can tell what the dataset is |
| Missing table descriptions | Every published table needs its own description |
| Missing licence | Readers cannot tell what they may do with the data |
| Missing attribution | The source is uncredited |
| Invalid primary key | Remove duplicate or empty key values before publishing |
These are not style advice. A public dataset with no licence and no description is not usable by the people it is published for, so the checks are enforced rather than suggested.
What published data costs you
Nothing. Catalog data is unbilled: the bytes in a published catalog dataset are not charged to any organization's storage.
Two consequences worth knowing:
- Importing a catalog table into your own model does not charge you for its storage either — it stays billed to nobody. What it does charge is egress, because the data leaves Mycorr to reach you.
- A table with attachments cannot enter the catalog. Its files would stay billed to the source organization while being reachable by everyone, which is not a trade anyone agreed to.
Importing from the catalog
A catalog table is imported like any other shared table — it lands in your model as a read-only view onto the original. See Table Import.
Because a catalog dataset publishes releases, what you import is a pinned version. The catalog moves forward when a new release is cut, not every time someone edits a table.
Trash and Deletion
Nothing in Mycorr is deleted the moment you press delete. Models, spaces and organizations go into a window first, and during that window everything comes back.
Find deleted things under Trash in the sidebar:
Deleted models and spaces rest here for 30 days before they're permanently removed.
The windows
| What you delete | Window | Who can cancel |
|---|---|---|
| A model | 30 days | You, from Trash |
| A space, and everything under it | 30 days | Its manager, or an org owner or admin |
| An organization, and everything in it | 30 days | Its owner or any admin |
| Your account, and your personal organization | 48 hours | You, by signing in |
The account window is deliberately the short one. The others are undone by someone who is still there; a purged account has no owner left to change their mind, so the decision is made quickly and then honoured.
Models
A deleted model sits in Trash with its tables. Restore brings it back whole.
Delete forever removes it immediately, without waiting out the window. That cannot be undone.
Models close to the end of their window are flagged Permanently deleted very soon.
Spaces
Deleting a space takes every nested space and every model under it onto one clock. The Trash groups them under the space they came from, and Restore space brings the whole subtree back at once — you do not restore the models one by one.
Two rules that surprise people:
- You restore the root, not a branch. If a space was deleted as part of a larger deletion, restoring it alone is refused, and the message names the root to restore instead.
- A model already in the trash is re-clocked. If a model was trashed a week ago and then its space is deleted, its clock restarts with the space. Nothing outlives the teardown.
Trash is shown per organization, and only to the people who effectively manage the deleted spaces.
See Spaces for the deletion itself.
Organizations
Deleting an organization is the same act one level up: every space in it is put on the 30-day clock, doomed ones included, and every model is trashed.
Cancelling brings back everything under the organization — including anything that was already in the trash before the deletion was scheduled.
Your account
Deleting your account puts your personal organization, its spaces and every model you own into a 48-hour window. Sign in during that time and cancel, and it all comes back.
After that, one thing outlives the purge: tables other people imported stay copyable for a further 10 days.
That window is the whole offboarding mechanism, not a cleanup delay. There is no hand-over protocol — anyone still holding an import of one of your tables can copy or detach it during those ten days, and after that it is gone. It is the only chance for someone else's work to be rescued from an account that is no longer there.
See Account Management.
What deletion does not touch
Models in organization spaces you manage are not affected by deleting your account. They belong to the space, not to you — which is the practical reason to keep shared work in a space rather than in your personal organization.
A trashed table's attachments are held for the same window as the table. Files are only reclaimed once nothing references them, and only after a later sweep confirms it — so a restore never comes back missing its files.
Data Management
Mycorr is all about efficiently managing data. The platform is designed to help you organize, track, and collaborate on your data.
For more details on specific aspects of data management, see the sections below:
Data Versioning
One of the most important features in Mycorr is data versioning, which ensures that every significant change to your table is tracked and recoverable. This ensures a robust collaboration and provides the ability to restore previous states of your tables.
Table Versions
Each Table has a Snapshot at any given version. A Table Snapshot holds the Table Version, the Table Meta and the Table Schema at that version.
The Table Meta includes the metadata about rows, and on the other hand, the Table Schema includes the metadata about columns and the overall schema of the table.
Each data operation performed on a table, such as editing the schema, rows or modifying the data itself, results in the creation of a new Table Version. This ensures that you always have a complete history of meaningful changes.
Operations that do not affect the data or schema, such as resizing the table views, do not increment the Table Version.
Checkpoints
You can define a checkpoint for any table version. A checkpoint acts as a restorable point in your table's history.
Each table version can have one checkpoint.
Checkpoints can be deleted at any time.
Aliases
Aliases provide a way to give a table version a human-friendly name. When you rename a checkpoint, you are creating or updating an alias.
You can create many aliases for a Table Version, and you can set one of them as the default name for the Table Version.
Aliases can be deleted at any time.
Restoring and Checking Out
- Owned Tables: If the Table is Owned, meaning that you are working in it's parent Model, you can restore it to any checkpoint, effectively rolling back to that point in history.
- Imported Tables: For tables you have imported from other Models, you can only view a certain checkpoint, not restore or modify the original table.
Data Filtering
A filter narrows a table view to the rows you care about. It changes what the view shows, not what the table holds — nothing is deleted, and other people's views are unaffected.
Filters live on the table view, so a table can appear twice on the same canvas with a different filter on each.
Adding a filter
- Open the model canvas and select the table.
- In the details panel on the right, click Add Filter.
- Build one or more conditions.
- The view updates as the filter changes.
The button reads Edit Filter once a filter exists, and a Delete Filter control beside it removes the filter and restores the full view.
Conditions
A condition is a column, an operator, and usually a value.
| Operator | Applies to | Matches |
|---|---|---|
| Equal | Any column | Exactly the value given |
| Not Equal | Any column | Everything except that value |
| Greater Than | Ordered values — numbers, dates, timestamps | Strictly above |
| Greater Than or Equal | Ordered values | At or above |
| Less Than | Ordered values | Strictly below |
| Less Than or Equal | Ordered values | At or below |
| Contains | Text | The value appears anywhere in the cell |
| Not Contains | Text | The value appears nowhere in the cell |
| Is Null | Any column | The cell is empty |
| Is Not Null | Any column | The cell holds something |
| In | Any column | Matches any value in a list you give |
| Not In | Any column | Matches none of them |
In and Not In take several values rather than one, which is the quickest way to pick out a handful of known values without writing a condition for each.
Is Null and Is Not Null take no value at all.
Text comparisons carry a case-sensitivity toggle. Left off, ACME and acme match each other.
A categorical column offers its values in a picker rather than a free-text box, so you choose from what the column actually allows instead of typing a value it can never hold.
Combining conditions
Conditions sit in a group, and a group is joined by either AND or OR:
- AND — every condition in the group must match.
- OR — any one of them is enough.
Groups can be nested inside other groups, which is what lets you express something like "status is Active and (region is EU or priority is High)". Without nesting that question cannot be asked, because a single list of conditions can only be joined one way.
What a filter affects
Exports follow the filter. Downloading a filtered view as CSV or Parquet gives you the rows the view is showing, not the whole table. That is the simplest way to extract a subset without creating a new table for it.
The row count follows the filter, so the count under a filtered view is the number of matching rows.
Nothing is removed. Clearing the filter brings every row back, because the rows were never gone.
Data Commits
A commit is a set of data changes applied to a table as one act.
Most of the time you never think about it. A table edits automatically: you change a cell, and the change lands. Everyone else working in the model sees it immediately, and it becomes a new table version.
Sometimes that is not what you want. If you are reworking twenty cells and the result is only correct once all twenty are done, you do not want collaborators reading the half-finished state. For that, a table can be paused, and the changes gathered into a commit you apply yourself.
Automatic and manual
| Automatic | Manual | |
|---|---|---|
| When changes land | As you make them | When you apply the commit |
| What others see meanwhile | Every change, at once | Nothing until you apply |
| How to undo | Undo, or edit again | Discard the commit |
A control on the table switches between the two. While a table is paused, your edits accumulate instead of landing, and the table shows that a commit is open.
Two things you can then do:
- Apply the commit. Every change lands together and becomes one new table version.
- Cancel the commit. Every staged change is dropped and the table returns to where it was.
While a commit is open
Columns cannot be changed. Adding, removing or retyping a column during an open commit is refused — "Cannot modify columns during active commit" — because the staged changes are described against the columns as they stand.
Nobody else sees the staged work. That is the point of pausing.
Conflicts
If someone else changes the same data while your commit is open, the commit is marked as conflicted. It cannot be applied as it stands, because doing so would silently overwrite work you never saw.
Resolve it by dropping the commit and redoing the edits against the current state.
Conflicts are the cost of holding changes back. An automatic table cannot conflict, because each change lands against the state that existed a moment before it.
Where commits do not apply
Imported tables cannot be committed, and show no commit control at all. An imported table is a view onto a table owned by another model; it is read-only where it sits, and editing happens in the model that owns it.
See Sharing Tables for how an imported table relates to its original.
Commits and versions
Applying a commit produces exactly one new table version, however many cells it touched. That is worth knowing if you are working through a table's history: a manual commit of twenty edits is one entry, while the same twenty edits made automatically are twenty.
You can pin either with a checkpoint.
Organizations
An organization is the container everything else in Mycorr lives in. It owns the data, holds the roster, and carries the bill.
It sits above the structures you may already know:
- Models and tables belong to an organization.
- Spaces divide an organization's work and decide who can reach what.
- Teams are groups of people inside an organization.
- Billing is per organization — each one pays its own way.
Two kinds
| Personal | Company | |
|---|---|---|
| Created | With your account, automatically | By Mycorr, on request |
| Members | Exactly one — you | A roster you manage |
| Teams | Not available | Yes |
| Seats | Always one | 10 on Free, or as many as you buy |
| Can be deleted on its own | No | Yes |
Every account gets one Personal organization at sign-up. It holds exactly one person and always will, which is why it has no roster, no teams and no seat count to manage.
A Company organization holds a roster, teams and spaces.
Creating a company organization is not yet generally available. The app says so plainly if you reach the create page: "Organization creation is currently limited to MyCorr administrators." Ask us and we will create one for you. Everything else on this page applies normally once you have one.
The two kinds are not convertible. An organization's type is fixed when it is created.
Your Personal organization cannot be deleted by itself, because it is where your own work lives — deleting it means deleting your account.
Roles
An organization has three roles. Each one includes everything the one below it can do.
| Owner | Admin | Member | |
|---|---|---|---|
| Work with the organization's data | Yes | Yes | Yes |
| Create a top-level space | Yes | Yes | Yes |
| Add and remove members | Yes | Yes | — |
| Manage spaces | Yes | Yes | — |
| See the governance log | Yes | Yes | — |
| See Plan & usage and the meters | Yes | Yes | — |
| Promote or demote admins | Yes | — | — |
| Transfer ownership | Yes | — | — |
| All billing — buy, cancel, cards, invoices | Yes | — | — |
| Schedule the organization for deletion | Yes | — | — |
| Cancel a scheduled deletion | Yes | Yes | — |
Two rows there are deliberate and worth reading twice.
Billing is owner-only, and narrower than every other governance right. An admin runs the organization; the owner pays for it. See who can do what.
Cancelling a deletion is wider than scheduling one. Only an owner can start the clock, but any admin can stop it — otherwise a departing or compromised owner would have a unilateral path to destroying the organization.
An organization can have more than one owner. Every owner gets the full billing surface.
Organization settings
- Look at the top of the left sidebar. It shows the organization you are working in.
- Hover over it and click the gear that appears.
Which sections you see depends on your role and the kind of organization:
| Section | What it holds | Who sees it |
|---|---|---|
| General | Name, type, and the way out (leave, or delete) | Everyone |
| Members | The roster, roles, invitations | Owners and admins, company organizations only |
| Spaces | Every space, and who manages it | Owners and admins |
| Governance | A log of every governance act in the organization, spaces included | Owners and admins, company organizations only |
| Plan & usage | The plan, meters and invoices | Owners and admins |
A plain member sees General alone — the organization's identity, and the door out.
Your Personal organization keeps Spaces even though you are its only member, because it is the one place to reappoint a manager to a space that has been left without one.
Spaces
A space groups work inside an organization and decides who can reach it.
Any member can found a top-level space, and whoever founds it is its first manager. A top-level space is one of two kinds:
- Restricted — its name reaches people only through a link you send them.
- Sealed — it is never advertised to the organization at all.
A space manager can then create Open spaces nested inside, which inherit the parent's access. That is the whole rule: open spaces nest, restricted and sealed ones sit at the top. Sealing a space detaches it from its parent.
Deleting a space takes everything under it — every nested space and every model — into one 30-day window, after which it is gone.
See Spaces for the full picture: the three kinds, the roles, sealing and unsealing, and how deletion works.
Teams
A team is a named group of people inside a company organization, used to grant access to many people at once instead of one by one.
A team belongs to exactly one organization and never to a personal one. Team membership is managed by the team's own admin, while what the team can reach is decided at the space level — two separate authorities over one shared root.
See Teams for creating and managing them.
Deleting an organization
An owner can schedule a company organization for deletion. It is not immediate:
- The organization and everything under it enter a 30-day window.
- Every space is put on that same clock, and every model is moved to the trash.
- Any owner or admin can cancel during the window, and everything comes back — including anything that was already in the trash before the deletion was scheduled.
A Personal organization cannot be deleted from here. The organization settings page refuses and points you to account settings, because deleting it is deleting your account, which runs on its own shorter clock.
Spaces
A space divides an organization's work and decides who can reach it. Models live in spaces, and a space is where access is granted — not on each model one by one.
That is the point of them. Granting someone access to a space gives them everything in it, now and in future, instead of a share for every model you create.
The three kinds
Every space is one of three kinds, and the kind decides where it can sit.
| Kind | Sits | Visible to | Data can leave |
|---|---|---|---|
| Restricted | Top level | People you grant it to | Yes |
| Sealed | Top level | People you grant it to | No |
| Open | Nested inside another space | Whoever can see the parent | Follows the parent |
Restricted is the ordinary top-level space. It is not advertised to the organization — its name reaches people through a link you send them, or through a grant.
Sealed is a Restricted space with a wall around it. See sealed spaces below.
Open spaces nest. An Open space inherits everything from the space above it: who can reach it, at what level, and whether it sits inside a wall. It cannot exist at the top level, because an Open space with no parent has nothing to inherit — which is simply a Restricted space.
The rule in one line: Open nests, Restricted and Sealed are roots. Sealing a space detaches it from its parent, because a wall cannot inherit access from outside itself.
Creating one
Any member of an organization can create a top-level space, and whoever creates it becomes its first manager.
A manager can then create Open spaces inside it, and can grant that right to other people or to a team.
Roles in a space
| Manager | Collaborator | Viewer | |
|---|---|---|---|
| See the space and its models | Yes | Yes | Yes |
| Create models in it | Yes | Yes | — |
| Grant and revoke access | Yes | — | — |
| Create nested spaces | Yes | If granted | — |
| Delete the space | Yes | — | — |
Roles inherit down into Open sub-spaces. A collaborator on a parent is a collaborator on everything Open beneath it.
Two things about managers are worth knowing:
Managers are named individuals, never a team. The managers of a space are the owners of every model in it, and team membership is edited elsewhere by someone who cannot see what it would confer. If teams could be managers, adding someone to a team would silently make them an owner of models they have never seen. Collaborator and viewer can be granted to a team.
A viewer is implied. Anyone who is a collaborator or manager can also view, so you never grant both.
You can grant access to people outside the organization. They appear as Guest in the access list.
Organization owners and admins
An organization's owners and admins govern every space — they can manage access, delete a space, and appoint a manager to one that has lost its own.
What they do not get is standing read access. Governing a space does not let you read what is in it. To look inside, an admin has to grant themselves access, which is visible in the access list and recorded in the governance log.
That is deliberate: it makes reading someone's space an audited act rather than a silent privilege.
A space with no manager
If the last manager leaves or is removed, the space is left with nobody who can grant access to it, and the settings page says so: "This space has no manager".
An organization owner or admin fixes it with Assign manager. This is the reason the Spaces section stays visible even in a personal organization — it is the one place a stranded space can be given a manager again.
When removing the last manager, the app warns first: "Nobody owns the models inside it — until an org owner or admin appoints a manager."
Sealed spaces
Sealing puts a wall around a space. The confirmation states exactly what changes:
Nothing will inherit in. The space becomes invisible to non-members and its data cannot leave: no exports, no copies, no outbound imports, no per-model sharing. Access is granted on the space itself.
So inside a sealed space:
- Nothing inherits in. Access must be granted on the space itself.
- Nothing leaves. No exports, no copies, no importing its tables elsewhere, no sharing an individual model out of it.
- It is invisible to anyone without a grant.
Every Open space nested inside a sealed one sits inside the same wall. A space is inside at most one wall — walls do not nest, because a sealed space has no parent.
Unsealing
Unsealing is declassification, and it is not the manager's to do. Only an organization owner or admin can unseal a space.
The reason is that a manager operates inside the wall and can appoint more managers, so a manager-held unseal would be self-administered — the wall would only hold until someone inside decided otherwise.
What unsealing does:
Exports, copies and sharing are re-enabled. Sub-spaces that only inherited the wall are unsealed; sub-spaces sealed in their own right are unaffected. Inherited access is not restored and existing grants are unchanged.
Note the two things it does not undo: access that was lost when the space was sealed does not come back, and a sub-space that was sealed in its own right stays sealed. Unsealing is recorded in the governance log.
Deleting a space
Deleting a space takes everything under it — every nested space, and every model in any of them.
- Open space settings and choose Delete space.
- Read the analysis, which lists what will go, including the people whose only access is through this space.
- Type the space name to confirm.
- Confirm.
Then:
- The space and every live space beneath it enter a 30-day window.
- Every model under it goes to the Trash on the same clock.
- Models outside the space that imported from it lose their source.
Nothing is spliced out or re-homed. A space that is already in its own deletion window joins the act, and its clock restarts with the rest.
During the window the whole subtree can be brought back, models included. Cancel from the organization's Spaces section, where doomed spaces carry a badge and a Cancel action. Cancellation is done on the root of the deletion — cancelling a nested space alone is refused, and the message names the root to use instead.
Doomed spaces are hidden from ordinary working surfaces during the window, so nobody builds on something that is about to disappear.
Teams
You can kick-off collaboration the right way by creating a Team and inviting members on board. By doing so, you get to collectively manage resources with different users within a single shared workspace.
You, as a user, can create a team or be invited to one at any given time. We distinguish two roles within a Team :
Admin
This is the highest access-level. When creating a Team, you are automatically assigned as the Admin.
An Admin is a member who has full control over the Team and can perform most of the actions within the Team.
Member
When you are invited to a Team, you are assigned as a Member.
Unless you are assigned the Admin role alongside the invitation or later on, you will have limited administrative access to the Team but you can still contribute to the resources within the Team and collaborate effectively.
Depending on the Team role you have, you can perform different actions within the Team. Learn about Team Management
Creating a Team
When creating a Team, here are the steps you can follow:
- Access the Teams section from the left sidebar menu.
- Click on the "Create Team" button.
- Enter the Team's required metadata.
- Click on the "Create" button to create the Team.
For Team's Metadata, only the name is required. The description is optional and the color will be set to default if not specified.
You can invite members to your Team alongside the creation or you can add them later from the Team's page.
Team Management
Inside a team, Mycorr maintains the same fundamental structure, but adds a layer where models are grouped together in a shared workspace.
For team management, we distinguish two types of roles : Team-Level Roles and Model-Level Roles that are inherited through team membership.
Team-Level Roles
Team-level roles determine what administrative actions users can perform within the team structure itself.
| Actions | Admin | Member |
|---|---|---|
| Edit Team Metadata | Yes | — |
| Delete Team | Yes | — |
| Leave Team | Yes | Yes |
An admin can only leave a team if they are not the last admin in the team.
| Actions | Admin | Member |
|---|---|---|
| View Members | Yes | Yes |
| Add Members | Yes | — |
| Delete Members | Yes | — |
| Update Member Roles | Yes | — |
Model-Level Roles
Users inherit model-specific permissions based on their team membership and also their relationship to the models themselves.
Creating a Model within a Team
You can directly create a Model inside the Team and set the team's access-level to the Model. By doing so, all team members will inherit it.
The access-level of a team to a Model could either be a Collaborator or a Viewer. See what actions each role can perform on the Model.
If you are already a collaborator of the model outside of the team, meaning that the model was explicity shared with you, and the model is shared with the team with viewer access only, you will have the highest level of access. In this case, you will be a collaborator of the model inside the team.
Not only you can manually create models inside a team, but you can also link one of your models from your private workspace to a team, and similarily set the access-level of the team to this model.
Models Management within a Team
| Action | Admin | Member |
|---|---|---|
| Add Models | Yes | Yes |
| View Models | Yes | Yes |
| Edit Models | Only Owner/Collaborator | Only Owner/Collaborator |
| Dissociate Models | Yes | Only Owner |
Dissociating a model means that the model will no longer be shared with the team, but remains in the user's private workspace.
API Access
Mycorr provides multiple ways for users to access their data from external applications :
- Personal Access Tokens : Secure API keys for programmatic access
- SDKs : Official client libraries — fetch your tables straight into pandas or polars
- MCP Server : Connect AI assistants like Claude to query your data in natural language
Personal Access Tokens
Personal Access Tokens (PATs) are secure API credentials that allow you to authenticate and access your data in Mycorr from external applications. They are implemented using JWT (JSON Web Tokens), making them encrypted, secure and easy to use.
Creating a Personal Access Token
Step 1: Navigate to Access Page
- Log into your mycorr account.
- Navigate to the Access section in the left menu.
- Click on Generate button.
Step 2: Configure Your Token
- Name: Give your token a descriptive name.
- Scope: Choose the level of access needed :
- Read: Access to view data and resources
- Expiration: Set an expiration date of the token.
Step 3: Save your Token
Important: Once your token is generated, make sure to copy and save it immediately. For security reasons, you won't be able to view it again.
Mycorr SDKs
Access your Mycorr data programmatically using official SDKs.
Available SDKs
- Python SDK (pymycorr) — Fetch tables as pandas or polars DataFrames.
Python SDK (pymycorr)
The official Python client for accessing Mycorr table data programmatically. It uses Apache Arrow for efficient data transfer and returns data as pandas or polars DataFrames.
Installation
pip install pymycorr
⚠️ Requires Python 3.10 or higher.
Authentication
pymycorr authenticates using a personal access token. You can provide it in three ways:
- Environment variable — set
MYCORR_API_TOKENin your shell:
export MYCORR_API_TOKEN="your-api-token"
.envfile — create a.envfile in your project directory:
MYCORR_API_TOKEN=your-api-token
- Constructor parameter — pass the token directly:
from pymycorr import MyCorr
client = MyCorr(token="your-api-token")
To generate a token, see Personal Access Tokens.
⚠️ Never commit API tokens to version control. Use environment variables or a
.envfile that is listed in your.gitignore.
Quick Start
from pymycorr import MyCorr
# Initialize the client (reads MYCORR_API_TOKEN from env)
client = MyCorr()
# Fetch a table as a pandas DataFrame
df = client.get_table("your-table-id")
print(df.head())
# Fetch a specific version
df_v2 = client.get_table("your-table-id", version=2)
# Fetch as a polars DataFrame instead
df_polars = client.get_table("your-table-id", engine="polars")
# Get table metadata without downloading data
info = client.get_table_info("your-table-id")
print(info["schema"])
API Reference
MyCorr(url=None, token=None, env_file=None, progress="auto")
Creates a new client instance.
| Parameter | Description |
|---|---|
url | API endpoint. Defaults to the Mycorr production URL. |
token | API token. If not provided, reads from MYCORR_API_TOKEN env variable. |
env_file | Path to a .env file. Defaults to .env in the current directory. |
progress | Progress display: "auto", True, or False. |
get_table(table_id, version=None, engine="pandas", progress=None)
Fetches table data as a DataFrame.
| Parameter | Description |
|---|---|
table_id | The table identifier (found in the table URL). |
version | Version number (int) or alias ("latest", "stable"). Defaults to the latest version. |
engine | "pandas" (default) or "polars". |
progress | Override the client-level progress setting for this request. |
get_table_info(table_id, version=None)
Returns table metadata and schema as a dictionary, without downloading the full dataset.
| Parameter | Description |
|---|---|
table_id | The table identifier. |
version | Version number or alias. Defaults to the latest version. |
Error Handling
pymycorr raises specific exceptions for different error scenarios:
| Exception | Description |
|---|---|
TableNotFoundError | The requested table does not exist or you don't have access. |
QuotaExceededError | Your egress quota has been exceeded. |
TableConversionError | Failed to convert the data to a DataFrame. |
StreamingError | Error during data streaming. |
TableAPIError | Base exception for all API errors. |
from pymycorr import MyCorr
from pymycorr.exceptions import TableNotFoundError
client = MyCorr()
try:
df = client.get_table("your-table-id")
except TableNotFoundError:
print("Table not found — check the table ID and your permissions.")
MCP Server
The Mycorr MCP Server is a remote Model Context Protocol server that lets AI assistants — such as Claude — explore and query your Mycorr data in natural language. Once connected, an assistant can find the right Tables across your Models, inspect their schema, summarize columns, and run read-only SQL — all scoped to exactly the data you already have access to.
It turns Mycorr into an analytics backend for AI agents: instead of exporting data or writing glue code, you ask a question in plain language and the assistant discovers the relevant tables, understands their structure, and computes the answer against your live (or released) data.
The server is read-only. It can read and analyze your data, but it can never create, modify, or delete it.
What you can do with it
- Ask questions in plain language — "How many orders shipped last month?", "What's our total revenue by region?", "Which customer segment is growing fastest?" The assistant translates these into the right discovery and query calls.
- Explore data you forgot you had — search across every Model and Table you can access by topic, name, or description in a single step.
- Understand a table before querying it — schema, row counts, column statistics, and the joinable relationships (Links) between tables.
- Run analytical SQL — aggregations, window functions, CTEs, and joins across linked tables, with results returned as structured rows.
- Released tables stay consistent — when a Table has a release (a specific version your team has pinned and published), every read goes against that released version, not the live data that may still be changing. So when an assistant runs
describe_table,summarize_column, orrun_sqlagainst a released table, the schema, row counts, and totals it reports are the published numbers — the same ones your team sees — even if the table has been edited since the release. Tables that have no release simply serve their current data.
Connecting
Endpoint
| URL | https://space.mycorr.app/mcp |
| Transport | Streamable HTTP |
| Authentication | OAuth 2.0 (recommended) — or a Personal Access Token |
Authentication
The server supports two ways to authenticate:
- OAuth 2.0 (recommended). When you add Mycorr as a connector in a client that supports OAuth — such as Claude — you're redirected to sign in to Mycorr and authorize access. No token is copied by hand, and access follows your account's existing permissions. This is the standard flow for the Claude connectors directory.
- Personal Access Token (alternative). For desktop or CLI clients that connect with a static credential, send a Personal Access Token (PAT) as a bearer token in the
Authorizationheader.
Either way, the assistant can only ever see the Models and Tables your account already has access to — sharing and permissions are enforced on every request. See Sharing and Permissions.
Connecting from Claude (OAuth)
Add Mycorr as a custom connector:
- Open Settings → Connectors → Add custom connector.
- Set the URL to
https://space.mycorr.app/mcp. - Click Connect and sign in to Mycorr when prompted — Mycorr will ask you to authorize the connection, then return you to Claude.
That's it — there's no token to copy. You can revoke the connection at any time from Mycorr or from your Claude connector settings.
Connecting with a Personal Access Token
Clients that read an mcpServers configuration block (for example Claude Desktop or Claude Code) can connect with a Personal Access Token sent in the Authorization header:
{
"mcpServers": {
"mycorr": {
"url": "https://space.mycorr.app/mcp",
"headers": {
"Authorization": "Bearer ${MYCORR_API_TOKEN}"
}
}
}
}
Your token needs the Read scope.
⚠️ Treat your token like a password. Store it in an environment variable (
MYCORR_API_TOKEN) rather than hard-coding it, never commit it to version control, and revoke it from the Access page if it's exposed.
Tools
The server exposes six read-only tools. A typical session moves from discovery (find the right table) to introspection (understand its shape) to execution (compute the answer).
search
The entry point for any question that mentions data by name or topic. Searches names and descriptions across every Model and Table you can access in one round trip, using fuzzy matching that tolerates typos and separator differences. Each hit carries a relevance score and the field that matched.
| Parameter | Type | Description |
|---|---|---|
queries | string[] | 1–10 search phrases (3–256 characters each). |
model_id | string | Optional. Restrict the search to a single Model. |
include_descriptions | boolean | Optional, default true. Also match human-written descriptions. |
limit | integer | Optional, default 25 (max 100). Maximum hits to return. |
list_models
Enumerates every Model you own or can access, with each Model's id, name, description, and table count. Best for "show me everything I have." Takes no parameters.
list_tables
Lists every Table in a given Model — id, name, description, and current version.
| Parameter | Type | Description |
|---|---|---|
model_id | string | The Model to list tables for. |
describe_table
Returns a Table's full shape: name, description, current version, total row count, per-column schema (id, name, data type, nullability, and category labels for categorical columns), and the declared Links to other tables. The links array is the only valid source of join keys for run_sql.
| Parameter | Type | Description |
|---|---|---|
table_id | string | The Table to describe. |
include_sample_rows | boolean | Optional, default false. Include a few example rows. |
sample_rows_n | integer | Optional, default 3 (1–5). Number of sample rows. |
Sample rows let the assistant see a few real rows alongside the schema — handy for spotting how columns are actually populated before writing a query. They're off by default (schema only); set
include_sample_rowstotrueto include them.
summarize_column
Computes column-level statistics for a single column — always row count, null count, and null rate, plus type-specific extras:
- Numeric: min, max, sum, average, median, quartiles, and deciles.
- Categorical: each category's label, count, and percentage.
- Timestamp / date: earliest and latest values, plus monthly or yearly counts.
- String / boolean: most frequent values and how much of the column they cover.
| Parameter | Type | Description |
|---|---|---|
table_id | string | The Table containing the column. |
column_id | string | The column to summarize. |
limit | integer | Optional, default 50 (1–1000). Cap on returned value counts. |
run_sql
Runs a read-only SQL query against your Tables. See Querying with SQL below for the full contract.
| Parameter | Type | Description |
|---|---|---|
sql | string | A single read-only statement (SELECT / WITH / UNION / recursive CTE). |
max_rows | integer | Optional, default 10,000 (max 100,000). Result-row cap. |
Querying with SQL
run_sql uses the DataFusion SQL dialect and is strictly read-only — SELECT, WITH, UNION, INTERSECT, EXCEPT, recursive CTEs, and window functions are supported. Any statement that writes or changes state (INSERT, UPDATE, DELETE, DDL, COPY, SET, EXPLAIN) is rejected.
A few rules keep queries safe and correct:
- Reference tables and columns by id, not by name. Use the ids returned by
describe_table(e.g."tab-019e…","col_xxx"), wrapped in double quotes so the hyphens are read literally. - Joins are only allowed on declared Links. A join on any other column pair is rejected — use
describe_tableto discover valid join keys. Cross joins are not allowed. - Soft-deleted rows are excluded automatically. You never see deleted rows, and there is no column to query them.
- Released tables read their pinned cut. Query results reflect the released version, which may be older than today's live data.
Limits per query: up to 100,000 result rows, 1 GiB of memory, and a 30-second timeout.
Recommended workflow
search(orlist_tables) to find the relevant tables by name or topic.describe_tableto get column ids, types, and joinable links.run_sqlusing those table and column ids.
Example prompts
These show the kind of natural-language requests the server is built to answer. The assistant chooses and chains the tools for you.
Discovery → summary
"Find anything related to billing in my Mycorr data and tell me the total amount invoiced this year."
The assistant calls search(["billing", "invoice"]), picks the matching table, and either summarize_column (for a single total) or run_sql (for a grouped total).
Schema-aware aggregation
"In my orders table, what's the average order value by region?"
The assistant calls describe_table to learn the column ids and types, then issues a run_sql GROUP BY query.
Cross-table join
"Which product categories drive the most revenue from our enterprise customers?"
No single table holds this answer, and you don't have to name the tables. The assistant uses search and describe_table to find the relevant tables on its own, discovers how they relate through declared Links, and writes a single query that joins along those links and aggregates revenue by category for enterprise customers.
Distribution check
"How is the status column distributed in my support tickets table?"
The assistant calls summarize_column and reports the category breakdown with percentages.
Limits, permissions & data handling
- Read-only. The server exposes no write operations of any kind. It cannot modify your Models, Tables, or data.
- Per-user access control. Every request is authorized against your account. You only ever see Models and Tables you have access to, exactly as defined by Sharing and Permissions. Tables shared with you read-only stay read-only here.
- Trashed items are hidden. Models and Tables in the trash are excluded from discovery; querying one by id returns a clear error.
- Rate limiting. Requests are rate-limited per connection. If you exceed the limit you'll receive a
429response with aRetry-Afterhint; the assistant will back off and retry. - Data handling. Queries run against your data within Mycorr's infrastructure and return only the results to the connected assistant. No data is shared with third parties beyond the AI client you explicitly connect. See the Privacy Policy.
Support
Questions or issues with the MCP server? Reach us at support@mycorr.app.
Billing
In Mycorr, everything is billed to an organization, never to a person.
Every account has one Personal organization, created with the account and holding exactly one member — you. Company organizations hold a roster, teams and spaces, and are created by Mycorr on request. Each organization pays for itself: the data it stores, the data it serves, and the seats it holds. See Organizations for how they are structured and who may do what in one.
That is the single rule behind most of what follows:
- A table you import from someone else counts against their organization, not yours.
- A colleague who has run out of storage in their personal organization can still write into a company organization that has room.
- Moving a model between organizations moves the bill with it.
- Your personal organization and each company organization are on separate plans, with separate bills and separate invoices.
Who can do what
Governing an organization and paying for it are two different rights.
| Action | Owner | Admin | Member |
|---|---|---|---|
| See Plan & usage | Yes | Yes | — |
| See storage, egress and tool-call meters | Yes | Yes | — |
| Buy a plan, or cancel one | Yes | — | — |
| Change the seat count | Yes | — | — |
| Add or change the card | Yes | — | — |
| Edit the billing email, address and tax number | Yes | — | — |
| See and download invoices | Yes | — | — |
Billing is owner-only, and deliberately narrower than every other governance right. An admin runs the organization; the owner pays for it. An organization can have more than one owner, and every owner gets the full billing surface.
There is no "downgrade" button between tiers. You move up by buying a plan and down by cancelling it, which drops the organization to Free at the end of the cycle you have paid for. Within a tier you can move either way by changing the seat count.
Members are not shut out of everything. When an organization hits a limit, a banner tells every member which limit was reached and when it resets, so someone whose export just failed knows why — and is told that an owner can move to a larger plan.
Where to find it
- Look at the top of the left sidebar. It shows the organization you are working in, with its plan on a badge beside the name.
- Hover over it. A gear appears at the right of the row.
- Click the gear. Organization settings open.
- Choose Plan & usage from the menu on the left.
If you do not see Plan & usage, you are a member rather than an owner or admin of that organization.
To reach a different organization's billing, click the organization name first and switch to it, then use the gear.
What is on the page
- Plan — what the organization is on, what it costs, how many seats it holds, when it renews, and the buttons that change any of that.
- Usage — storage, egress and MCP tool calls, each against its ceiling, with the date the monthly allowances start over.
- Invoices — every payment, with a PDF to download.
Anything urgent — a failed card, a missing card, a payment being applied — appears above all three, at the top of the page.
Your personal organization also carries a small meter at the foot of the sidebar, which appears once you pass 80% of an allowance. It is a warning, not a dashboard; company organizations show their usage on the Plan & usage page instead, where the people who can act on it are.
Who takes the payment
Payments are handled by Paddle, who act as Merchant of Record. They charge the card, calculate and remit tax, and issue the invoice.
Two consequences worth knowing up front, because they explain a lot of what the app does:
- Card details never reach Mycorr. Every card form you see in Mycorr is Paddle's, rendered inside a Mycorr dialog. We never hold a card number.
- Money figures on an invoice are Paddle's to compute. Mycorr shows you the recurring rate, which is exact. Tax, proration and the final total are calculated by Paddle and appear on the invoice.
The company name and tax number you enter are held by Paddle, because they are what the invoice is issued against.
Read on
- Plans — what Free, Pro and Enterprise include, and how to buy one.
- Seats — how seats are counted, bought and freed.
- Usage and limits — what storage, egress and tool calls measure, and what happens at the ceiling.
- Managing your subscription — changing the card, cancelling, resuming.
- Billing details and invoices — the billing email, company details, tax number and receipts.
- When a payment fails — past-due, missing cards, and the other states that need attention.
Plans
Every organization sits on a plan, and a new one starts on Free. The plan belongs to the organization, so your personal organization and each company organization are each on their own plan and pay their own bill.
What each plan includes
| Free | Pro | Enterprise | |
|---|---|---|---|
| Price | $0 | $20 per seat / month $192 per seat / year | Talk to us |
| Storage | 1 GB | 20 GB per seat | Negotiated |
| Egress per month | 2 GB | 100 GB per seat | Negotiated |
| MCP tool calls per month | 500 | 25,000 per seat | Negotiated |
| Seats | 10 | As many as you buy, up to 500 | Negotiated |
| Models and tables | Unlimited | Unlimited | Unlimited |
Two things to read carefully in that table.
Pro's figures are per seat and they add up. Three seats is 60 GB of storage, 300 GB of egress a month and 75,000 tool calls a month — for the organization as a whole, not for each person. They replace the Free grant rather than stacking on top of it, so three seats is 60 GB, not 60 GB plus the free 1 GB.
Models and tables are uncapped on every plan, and that is a deliberate commitment rather than an unfinished limit. What costs anything is storage, egress and tool calls, and those three are the ones with ceilings. See usage and limits for what each measures.
Byte figures are decimal (1 GB = 1,000,000,000 bytes), which is how the app displays them everywhere.
A Personal organization holds exactly one person, so Pro there is always a one-seat plan. A Company organization on Free gets 10 seats without paying for them.
The 500-seat ceiling on Pro is a guard against a mistyped number becoming a five-figure invoice, not a real limit on how big a team can be. If you need more than that, talk to us about Enterprise.
Enterprise has no published price and cannot be bought from inside the app. It is the last card in the Plans dialog, and its button is Contact sales, which opens the support panel.
Monthly or yearly
Pro is sold on both terms, and the year is priced at a 20% discount — $192 a seat instead of $240. You pick the term on the plan card, before checking out.
The allowances are identical either way. The term changes the price and when you are charged, nothing else. It does change one thing later: when the cost of extra seats is collected.
Buying a plan
- Open Plan & usage (how).
- Click Upgrade, at the right of the plan's name. The Plans dialog opens, showing your current plan beside everything above it.
- If the tier offers both terms, choose monthly or yearly on its card.
- For a company organization, set the number of seats with the stepper on the card. It will not go below the people already in the organization, counting outstanding invitations. A personal organization has no stepper — it is always one seat.
- Click the button on the plan you want.
- You are asked where this organization should be billed. Your own email is offered when it is free; an email already used by another organization is refused, so pick or type one of this organization's own. Click Continue.
- The card form opens in a Mycorr dialog. Enter the card and confirm.
The dialog closes on payment, and the page shows Payment received — setting up your new plan. This usually takes a few seconds and the page updates itself.
If it has not landed after two minutes, the notice becomes Still setting up with a Check again button. Your payment is safe either way; do not buy a second time.
No Upgrade button? It appears only when the catalog holds a plan priced above your current one. On Pro there is nothing above it, so there is nothing to show. It is also hidden while a payment is being applied, while the plan is paused, and while the plan could not be read — in each case because offering it would risk selling you something you may already have.
Prices on the plan cards come from Paddle for your own country, so the figure you see already reflects local currency where we sell in one. Tax is added at checkout and appears on the invoice.
What happens before you are charged
Every purchase runs a check with Paddle first, on the email you are buying with, and it can stop the checkout before any money moves. If it does, you will see one of these, and nothing has been charged:
| Message | What it means | What to do |
|---|---|---|
| This organization already holds a paid subscription | You are already paying for this one | Nothing. The page refreshes to show it. |
| We found the subscription you already pay for and restored it | Common after an organization is re-created; your plan is simply back | Nothing. |
| You already pay for a subscription that isn't attached to any organization | A subscription exists but no organization claims it | Attach it |
| We couldn't confirm your payment details | We could not reach Paddle | Try again in a moment |
This check is why it is hard to end up paying twice for the same organization. It deliberately fails closed: if Paddle cannot be reached, the checkout stops rather than risking a second subscription.
Leaving a paid plan
There is no downgrade button between tiers. To leave Pro, cancel the subscription: the plan runs to the end of the cycle you have paid for, then the organization returns to Free.
To change capacity without changing tier, change the seat count — up, which takes effect at once, or down, which takes effect at the renewal.
Reading the plan on the page
The Plan section names the plan, states the rate and the seats, and carries one short line at the right — the strongest thing currently true of it:
| Line | Meaning |
|---|---|
Renews 14 Oct | Ordinary. The next charge is on that date. |
Ends 14 Oct | Cancelled. The plan runs to that date, then stops. |
Past due | A charge failed. See when a payment fails. |
Underneath the name you may also see a sentence about what came before — "Your Pro plan ended on 3 September 2026" — so an organization back on Free can say how it got there.
Seats
On a paid plan, an organization buys seats. A seat is capacity, not a person: you buy a number, and people occupy them.
Seats decide two things at once, which is why they matter more than a headcount:
- The bill. Pro is priced per seat.
- The allowances. Pro's storage, egress and tool-call ceilings are each multiplied by the seat count, so buying a seat raises what the organization can hold as well as who it can invite.
Your Personal organization always holds exactly one person, so it has no seat count to manage.
What occupies a seat
Every member and every outstanding invitation holds one.
Counting invitations is deliberate. An invitation you have sent is capacity you have already promised away, and it would be a poor surprise for the person accepting it to be turned back at the door. So the two doors count differently, on purpose:
| Action | Counted against |
|---|---|
| Sending an invitation | Members plus outstanding invitations |
| Accepting an invitation | Members alone |
The effect is that an invitation already sent can always be honoured, even if the organization filled up in the meantime.
Two more rules follow from "a seat is capacity":
- Removing a member frees their seat immediately, ready for the next invitation. It does not change the bill — you still own the seat, and it still renews.
- Withdrawing an invitation frees its seat the same way.
On Free, a company organization gets 10 seats. They are not bought and not billed, but they are counted by exactly the same rules.
Reading the seat count
The Plan section states the seats bought, with the headroom beside them:
| Shown | Meaning |
|---|---|
5 seats · 2 vacant | Two more people can be invited |
5 seats | Every seat is taken |
5 seats · 1 over | The organization holds more people than it has seats |
Being over happens after a plan ends, after a subscription is attached at a smaller count, or if an owner's quota was changed by hand. Nobody is removed and nothing stops working — you simply cannot invite anyone else until you add a seat. See when the seats are fewer than the people.
Changing the seat count
- Open Plan & usage (how).
- Click Change seats — or Add seats, if this subscription has no renewal date to reduce against yet.
- Set the number with the stepper, or use the +1 / +2 / +5 shortcuts. The shortcuts count from the seats you already hold, so pressing one twice does not compound.
- Read the ledger: what you already hold, what you are adding or removing, the new total, the rate, and the new recurring bill.
- Click the confirm button, which names the change — Add 2 seats · $100/mo, or Reduce to 3 seats.
The two directions behave differently, because one of them you have already paid for:
- More seats are usable straight away. Someone who has just bought a seat should not have to wait to fill it.
- Fewer seats take effect at the renewal, never on the click. See reducing the seat count.
When the money moves
Buying seats is the one place your term changes what happens. (A reduction is charged nothing either way — see reducing the seat count.)
| Term | What happens |
|---|---|
| Monthly | The seats are available now. The prorated cost for the rest of this cycle is added to your next invoice, and all the seats then renew together. |
| Yearly | Charged now, prorated to the end of this cycle. All the seats then renew together. If the card is declined, the whole change is refused and no seats are added. |
The difference is deliberate. A month of seats on credit is a rounding error and not worth a second invoice and a second processor fee; a year of them is not.
The recurring figure in the dialog (rate × seats) is exact and ours to compute. The prorated charge for the rest of this cycle is Paddle's, with tax, so the dialog tells you when it lands rather than quoting a number we cannot stand behind.
What adding a seat does not do
A mid-cycle seat raises the ceilings and leaves the counters where they are. You have bought capacity, not a fresh allowance, and your billing date does not move. See when the billing month starts.
Reducing the seat count
Seats you have bought are paid for to the end of the cycle, so a reduction does not take them away early. It is parked for the renewal instead: you keep every seat you hold until then, and the subscription renews at the smaller number.
Set a number below what you hold and confirm. The dialog says what will happen:
The seats you have stay until 14 October, when the subscription renews at 3. Nothing is charged for the change.
Nothing is charged, and nothing is refunded. The renewal is billed at the new count; there is no mid-cycle credit to issue because there is no mid-cycle change.
Once parked, Plan & usage carries a standing note:
Seats drop at the end of this cycle. This organization renews at 3 seats on 14 October. The 5 you have now stay until then.
Keep 5 beside it calls the reduction off and leaves the subscription where it is. So does setting the count back to what you hold.
The floor
The stepper will not go below the people already in place — members plus outstanding invitations — and says so:
This organization holds 4 members and outstanding invitations, so it can't hold fewer seats than that.
Remove members or withdraw invitations first, and the floor drops with them. The floor is checked again when the reduction actually lands, so a roster that grew while it waited is honoured rather than overridden.
A subscription that has no renewal date yet has no boundary to park against. There the stepper floors at the seats you hold and only Add seats is offered.
When the seats are fewer than the people
An organization can legitimately hold more people than it has seats — after a plan ends, after a subscription is attached at a smaller count, or after an owner's quota was changed by hand. Plan & usage says so:
Add a seat before inviting anyone new. The subscription carries 3 seats and this organization has 5 members. Everyone keeps working — invitations are what stop, including any already sent.
Nobody is removed and nothing they do is interrupted. Only invitations stop, and that includes ones already sent, which cannot be accepted until a seat is free.
Seats and cancellation
While a subscription is scheduled to end, the seat editor is not offered at all — there is no cycle after this one for a change to apply to. The same is true while the plan is paused.
Use Keep subscription first, then change the count.
Usage and Limits
Three things are metered, and all three are counted against the organization that owns the resource — never against the person who happened to click.
| Meter | What it counts | When it resets |
|---|---|---|
| Storage | Data held by this organization's tables | Never — it is a running total |
| Egress | Data leaving Mycorr | Every billing month |
| MCP tool calls | Tool calls an AI assistant made against this organization's data | Every billing month |
All three are on the Usage section of Plan & usage, each with a bar, a percentage and the ceiling it is measured against. The section header carries the reset date for the two monthly allowances, and a Refresh button — nothing on this page polls, so a number you are watching climb needs a nudge.
Storage
Everything your organization's tables hold. It goes up when data is added and down when it is deleted.
A table imported from another organization counts against its owner, not you. Importing is a view onto someone else's table; the bytes stay theirs. The same is true in reverse — publishing a table to the public catalog leaves the bytes billed to you.
Attachments count too. A file uploaded onto a row is stored against the organization that owns the table it landed on.
When storage is full, uploads and edits are refused until space is freed. Waiting does not help: this is the one meter that never resets. To free space, delete data, or buy more — on Pro, each seat carries 20 GB.
Enforcement always asks the organization that owns the resource, never the person writing. So an editor whose own personal organization is full can still write into a company organization that has room.
Egress
Data leaving Mycorr: exports, downloads, the API, and what AI tool calls return.
Reading inside the app is free. Scrolling a table, filtering it, opening a model — none of that is egress. What counts is data crossing out of Mycorr, to you or to something you have pointed at it.
Which organization pays is the organization you are acting in when you pull the data. If you export a table from inside a company organization, that organization pays. If someone outside it exports a table you shared with them, their organization pays, not yours — so sharing a table never puts your allowance at the mercy of the people you shared it with.
Enforcement is strict in two ways, and both exist so you never get a file you cannot trust:
- A download whose size is known in advance is refused whole if it would not fit. You do not get a partial file.
- A stream is cut the moment it crosses the ceiling, and the result is an error rather than a short file — so a truncated export can never be mistaken for a complete one.
When the allowance is spent, exports and API reads are refused until the reset date shown on the row.
MCP tool calls
Every tool call an AI assistant makes against this organization's data, through the MCP server.
The count is a rate governor rather than the cost — what those calls return is already charged as egress. It exists to stop a runaway agent loop eating your allowance.
A failed tool call still consumes a call but is charged no egress. The error is our answer, not your data. That is deliberate: refunding failed calls would make a malformed retry loop free.
When the billing month starts
Egress and tool calls reset on your organization's billing anniversary, not on the first of the calendar month. An organization whose cycle starts on the 14th resets on the 14th.
Short months are handled by clamping rather than drifting: an anchor on the 31st runs 31 Jan → 28 Feb → 31 Mar → 30 Apr, and returns to the 31st rather than ratcheting down for good.
The reset date does not move when you add seats, and it does not move when the plan changes.
On the panel, Since and Resets are two different clocks and will not always agree. Since is when the current plan period opened; Resets is the next billing anniversary. They coincide for a new organization and part company the first time a plan changes. That is the intended reading: the plan changed, the billing cycle did not.
Hitting a limit
A spent allowance stops the whole organization doing the thing, and every member is told — not just the owners. A banner appears across the top of the app naming which limit was reached, when it comes back, and who can act on it:
Limits reached: Egress. Egress resets on 14 October. An owner can move to a larger plan.
Owners see "See Plan & usage in organization settings" instead, because they can do something about it. Admins see the meters on Plan & usage too, but buying a plan is an owner's.
Below 100%, personal organizations show a small meter at the foot of the sidebar once you pass 80%. Company organizations do not — their usage lives on the Plan & usage page, where the people who can act on it are.
What a spent allowance does not stop
Storage and egress limits bound what an organization can take on and pull out. They never lock you out of what you already have:
- Reading inside the app keeps working on every meter.
- A full storage meter refuses new data, not access to old data.
The one thing that can make an organization read-only is an unpaid card, not a spent meter — and even then, reading and exporting keep working. See when a payment fails.
Managing Your Subscription
Everything on this page is owner-only and lives on Plan & usage.
Which buttons you will see
The row of actions changes with what the organization has, so you will rarely see all of them at once:
| Button | Appears when |
|---|---|
| Upgrade | The catalog holds a plan priced above the current one |
| Change seats / Add seats | There is a live paid subscription on a company organization, neither paused nor scheduled to end |
| Billing details | There is a live subscription and a readable billing address |
| Cancel subscription | There is a live subscription not already scheduled to end |
| Keep subscription | A cancellation is scheduled |
The seat button reads Change seats once the subscription has a renewal date to reduce against, and Add seats before then. See changing the seat count.
All receipts, beside the Invoices heading further down, is not one of these: it opens your receipts at Paddle and appears whenever the organization has invoices, live subscription or not — but only for the person whose card is on file, or for any owner once that person has left.
Cancel sits at the far right of the row, away from the others. The act you cannot take back is not the one nearest your cursor.
Changing the card
- Open Plan & usage.
- Click Billing details.
- Under Payment, click Update card (or Add a card if there is none).
- Enter the card in the dialog that opens and confirm.
You can also reach the same form in one click from whichever notice is asking for it — a failed payment, a missing card, or a departed payer each offer the button in place. That is on purpose: nothing that is failing right now should be two clicks away.
The form is Paddle's, shown inside a Mycorr dialog (why).
Changing the card is deliberately not done through Paddle's billing portal. A portal session covers the whole billing account wherever it lands, so a co-owner opening one could reach every other organization that account pays for. The inline form is scoped to this subscription alone, which is why every owner gets it — including owners who are not the person paying.
No card on file means exactly that, and the panel warns before anything fails. It is rare — every checkout takes a card — and usually means a subscription set up outside the app, or a card removed at Paddle. Add one before the renewal date shown.
Once you confirm a card, the status bar at the top follows it: Card saved — confirming with the payment processor…, then Card updated — or, if the card you added makes you the person paying, Card updated. Your card now pays for Acme Data. Paddle reports the change a little after the form closes, so this can take a minute; if it takes longer the notice says so and offers Check again. The card is safe at Paddle either way.
Cancelling
Cancel subscription schedules the plan to end at the close of the cycle you have already paid for. It is neither immediate nor destructive.
- Open Plan & usage.
- Click Cancel subscription.
- Read the confirmation, which names the exact end date.
- Click Cancel at end of cycle, or Keep subscription to back out.
What the confirmation tells you:
Your plan stays exactly as it is until 14 October, when it ends. Nothing is charged after that. Everything this organization has stored stays readable and exportable afterwards, and you can change your mind any time before then.
Three things to take from it:
- Nothing is deleted. After the plan ends the organization drops to Free. If it holds more than Free allows, you keep all of it — you simply cannot add more until you are back under the ceiling. Exports keep working throughout.
- The plan does not shrink early. Seats, storage and allowances stay at their paid level until the end date.
- It is reversible right up to that date.
If the organization is already holding more than Free allows, the confirmation says so before you commit, with the figures:
Storage is 14.2 GB and the free plan allows 1 GB, so afterwards this organization can read and export but not add data.
That is a courtesy, not a block — cancelling is still yours to do. It appears only when it applies.
Once scheduled, the plan line reads Ends 14 Oct and the button becomes Keep subscription. While a cancellation is scheduled the seat editor is not offered (why) and the billing details form is frozen — the paperwork on it is what a future invoice would carry, and none is coming.
The one exception is an unpaid cycle. Money already owed still has to settle, so the card stays reachable through a scheduled cancellation.
When the plan actually ends, the organization's billing email is freed shortly afterwards, so it can be used by another organization — or by this one again. Invoices are untouched by that; see one organization, one billing email.
Resuming
- Open Plan & usage.
- Click Keep subscription.
The plan renews as normal on its usual date and the button goes back to Cancel subscription. Nothing is charged for resuming, and seats and billing details unfreeze.
Once a subscription has ended
Most of the billing surface goes quiet: there is nothing left to cancel, no seats to buy, and no paperwork to edit.
What stays is the Invoices list, with All receipts beside it for the person whose card was on file. Invoices are yours to keep, including for a plan that has ended.
To come back, use Upgrade as normal. It is a first purchase again: you pick the email the organization will be billed at and enter a card, because the account it had was freed when the plan ended. The check that runs before any charge still guards against paying twice for the same organization.
If the plan is paused
Paddle can pause a subscription. When that happens the organization sits on Free with the subscription still in place, and the panel says so:
Your Pro subscription is paused. This organization is on Free until it resumes.
This is not the same as an ended plan, and the subscription is not lost. Upgrade is hidden while it lasts, so that you cannot be sold a second subscription alongside the paused one.
Billing Details and Invoices
Who gets invoiced, where, as which company, and where the receipts live afterwards. All of it is owner-only, and all of it sits behind the Billing details button on Plan & usage.
Editing the details
- Open Plan & usage.
- Click Billing details.
- Edit any of the fields below.
- Click Save.
Everything here applies to future invoices. Nothing already issued is rewritten.
What the dialog holds
Payment — the card on file, shown as Visa ending 4242 · expires 09/2028 where Paddle can tell us, with Update card beside it. See changing the card.
Invoices
| Field | What it does |
|---|---|
| Billing email | Where invoices and receipts are sent |
| Name on invoice | The name the invoice is made out to |
Company — fill this in when the invoice needs to carry a company rather than a person:
| Field | What it does |
|---|---|
| Company name | Appears on the invoice |
| Tax / VAT number | Decides reverse charge and how tax is applied |
| Company number | Registration number, where your jurisdiction wants one |
| Also send invoices to | Extra recipients, one per line, as Name <email> or a bare address |
Address — address, city, postal code, region or state, and country.
Checkout records a country (and in some places a postal code) and nothing more, so a fresh subscription's address section reads Add rather than Show: open it and the country is already chosen, fill in the rest. Once a street or city is on file the section is Show/Hide.
Changing the country shows "Tax may change". Tax is based on the country and applies from the next invoice.
This form is the only place these can be changed — Paddle's own portal does not edit them. If Paddle refuses something, such as a tax number in the wrong format or a postal code it does not recognise, the message appears on the field it names, so you can correct it in place rather than guessing.
The form is frozen while a cancellation is scheduled, and after a subscription ends. There is no future invoice for the details to appear on.
One organization, one billing email
Every organization is billed at an address of its own. Paddle keeps a single billing account per email, so two organizations on one email would share a receipts page, a name on the invoice and a saved card — and the app refuses to create that.
Changing the billing email moves where invoices and receipts go, and nothing else: the card, the address and the company details stay exactly as they were. There is no card to re-enter afterwards.
An email already used by another organization is refused. The dialog checks as you type and says so before you save:
Already used for billing elsewhere. Each organization needs its own billing email, so pick one that is not in use — or add this address as an invoice recipient to send copies there instead.
Add as recipient is offered right there, and is usually what was actually wanted — it adds the address to Also send invoices to and leaves the billing arrangement alone.
If the check itself could not run — Paddle unreachable for a moment — the dialog says "We couldn't check this email. If it is already used for billing elsewhere the save will be refused, and nothing changes." You can still save; the same rule is applied on the way in.
When a subscription ends, its billing email is freed. Shortly after the last subscription on an organization is cancelled — whether you cancelled it, or it was cancelled for you — the address it was billed at becomes available to any organization again, this one included. Nothing else changes: the invoices stay where they are (below).
Choosing at checkout
Every purchase with nothing live picks the email it will be billed at, before the card form opens:
Where should this organization be billed? Receipts go to the address you pick, and only it can manage payments later. Each organization needs an address of its own.
Your own account email is offered and selected when it is free. If it already bills another organization it is shown greyed out with Already used for billing elsewhere, and you type Another email. A typed address is checked the same way, and Continue stays off while it is taken — a charge that landed on another organization's account could not be undone afterwards, so this is the one moment it is refused.
This is true of a resubscribe too. An organization that cancelled and comes back is not offered its previous account: that account was freed when the subscription ended, so it picks an email and enters a card exactly as a first purchase does.
Invoices
Every payment appears in the Invoices section of Plan & usage: date, amount, invoice number, and a download button.
To download one:
- Open Plan & usage.
- Find the invoice in the Invoices list. Load more pages further back through the history.
- Click the download icon on its row. The PDF opens in a new tab.
The list is this organization's and nobody else's — which is what you want when reconciling a single team's spend.
Rows stay plain unless there is something to say. A status badge appears only when an invoice is not simply paid, and money that came back on a charge — a refund or a credit — appears on the invoice it came back from, as −€20.00 refunded, so a month's real cost is read off one row rather than two.
Cancelled subscriptions keep their invoices. An organization back on Free still shows everything it was charged.
All receipts
Receipts and payment methods at the foot of the Billing details dialog, and All receipts beside the Invoices heading on Plan & usage, both open Paddle's own page for the billing account. It shows the same invoices, plus the saved payment methods.
That page belongs to the billing account rather than to the organization, so it is offered only to the person whose card is on file. If you are an owner but not that person, the link simply is not there — and you are not missing anything you need: this organization's invoice list, its PDFs, refunds, the card form, the paperwork, seats and cancellation are all in the app and all available to you.
There is one exception. Once the person paying has left, every owner gets the link, so the receipts do not leave with them.
If Paddle cannot be reached at that moment you will see "Receipts could not be reached just now. Everything else here still saves." — that is an outage, not a permission problem. Try again shortly.
When a Payment Fails
One rule holds throughout, whatever state an organization is in: you can always read and export your own data. No amount owed changes that. Every export door, and both monthly meters in front of them, are untouched by whether a card went through.
What a failed payment stops is the organization growing.
The past-due ladder
| Days since the charge first failed | What still works | What is refused |
|---|---|---|
| 1 – 7 (grace) | Everything | Nothing |
| 8 – 39 (read-only) | Reading, exporting, renaming, sharing | New data, new members |
| 40 | Reading, exporting | The plan lapses |
Day 1 is the day the charge first failed, not the day of the latest retry. Paddle retries a failed card several times, and the window does not restart on each attempt.
Days 1 to 7
A warning at the top of Plan & usage:
Payment failed. We could not charge your card (day 3). Update it before 14 October to keep adding data and members. Nothing is locked yet.
Nothing is blocked during grace. To fix it:
- Click Update payment method on the notice.
- Enter a working card and confirm.
The window closes as soon as a charge succeeds, and any future failure starts a fresh window from day 1.
Days 8 onward
The warning becomes an error:
Read-only — payment overdue. Unpaid since day 12. This organization can't take on new data or members, and the plan lapses on 14 November. Everything it already holds stays readable and exportable.
Read-only means the organization may not grow. Writing data, and adding seats or members, are refused. Renaming things, editing descriptions and sharing are not — they cost nothing and grow nothing.
The fix is the same: Update payment method on the notice.
Owners see that button; other members see the state without it. The state is theirs to know; the fix is not theirs to make.
No card on file
If a subscription has no card behind it, the panel says so before anything fails:
No card on file. The next payment on 14 October will fail. Add a card for this organization.
Click Add a card and enter one. See changing the card for why this usually happens.
Upgrade is deliberately hidden while this notice is up. Buying again would risk a second subscription instead of fixing the first one.
The person paying has left
If the owner whose card is on the subscription leaves the organization, is removed, or deletes their account, every remaining owner gets a notification:
Priya is no longer in Acme Data, but its invoices still go to them. Update the billing email and card in Plan & usage.
and a standing callout on Plan & usage:
The person paying for this organization has left. Their card is still the one being charged, and invoices still go to
priya@acme.com. Update the card, then the billing email.
Do it in that order:
- Click Update card and enter a card that belongs to someone still here. The status bar confirms it once Paddle reports the change — Card updated. Your card now pays for Acme Data. — which can take a minute.
- Click Billing details and change the Billing email to an address you control.
The order matters, and the card is the half that counts. Taking the card over is what retires the callout — not changing the email, and not clicking anything to acknowledge it. Exactly four things clear it:
- An owner's card change, once Paddle confirms it.
- A new checkout on the organization.
- The departed person rejoining.
- Their account being deleted.
There is deliberately no way to dismiss it. A dismiss button used to sit here, and it silenced a state nobody had resolved — the departed person's card went on being charged and their address went on receiving the invoices, with nothing left on the page to say so. The notice stands until somebody takes the billing over.
It goes quiet on its own when there is nothing live to charge, so an organization whose plan has already ended is not nagged about it.
While this notice is up, every owner can open Paddle's receipts page for the billing account, not just the person whose card is on file. That is the exception to the usual rule, and it exists so a departed colleague cannot take the receipts with them.
A subscription that belongs to no organization
Occasionally an email is paying for a subscription that no organization claims — almost always one bought before the organization was re-created.
You already pay for a subscription that isn't attached to any organization. Your email is paying for a subscription no organization claims — usually one bought before this organization was re-created. Attach the one that belongs here; contact support to close any other.
Each one is listed with what it was bought for: the plan, the seat count, the organization name and kind, and since when.
- Find the row that matches this organization.
- Click Attach to this organization.
Mycorr will not guess. A company organization is never assumed to be a re-created namesake, so the attach is yours to confirm.
If more than one subscription is listed and only one belongs here, attach that one and contact support to close the rest.
A subscription bought for the other kind of organization
A subscription remembers which kind of organization it was bought for, and it cannot cross. What the row offers instead depends on which way round it is:
| The row is | Where you are | What it offers |
|---|---|---|
| Bought for a company organization | Your personal organization | Create an organization |
| Bought for a personal organization | A company organization | "Attach it from your personal organization" |
Create an organization carries the subscription to the new-organization form, where a tick asks whether to claim it:
Use the subscription you already pay for. Put this organization on Pro (5 seats) instead of Free. Nothing is charged — it moves the subscription you already pay for onto this organization, and the plan above stops applying.
The tick is the consent, because money is involved: leave it clear and the new organization starts on Free with the subscription still unattached. Every rule is checked again when the organization is created, so ticking it is intent rather than a promise.
Fewer seats than the organization holds
Attaching is allowed even when the subscription carries fewer seats than the organization has people — being over is a legal state, not an error. The row warns first:
3 seats for 5 members — add seats after attaching to invite anyone new.
and afterwards Plan & usage keeps a callout until a seat lands. Nobody is removed; see when the seats are fewer than the people.
Most of the time you will never see this screen. A recovery check runs quietly when you sign in and re-attaches whatever it can prove is yours.
Billed twice
If an organization ends up with two live subscriptions:
Billed twice. This organization has two live subscriptions, so it is being charged twice. Cancelling below ends
sub_01abc…only — contact support to have the other one refunded and closed.
- Cancel the subscription shown.
- Contact support about the other one. We will refund it.
A charge you disputed with your bank
Disputing a charge with your bank — a chargeback — is not the same as cancelling, and it does not go through the past-due ladder above. There is no grace window:
- The plan is given up at once and the organization drops to Free.
- The subscription is cancelled at Paddle, so the next cycle cannot charge a disputed card.
Your data is untouched and stays readable and exportable, as it does in every other state on this page. But nothing waits for the cycle to turn, because the money for the current one is being taken back.
If the dispute is later rejected or reversed, the plan does not come back on its own — use Upgrade to buy again, or contact support.
A refund or a credit changes none of this. Money coming back on an invoice is ordinary; it appears on the invoice it came back from and the plan carries on. Only a dispute ends it.
A payment that has not landed
After paying, the panel shows Payment received — setting up your new plan. This page updates the moment it lands. That normally takes seconds.
After two minutes it becomes Still setting up — your new plan is taking longer than usual to activate. Nothing about your payment is lost, with a Check again button.
Press Check again. Do not buy a second time — your payment is safe. If it persists, contact support.
The plan could not be read
If Plan & usage says The plan couldn't be loaded right now, that is a failure to read, not a statement that you have no plan. Upgrade is deliberately not offered in that state, so you cannot be sold something you may already have.
Refresh the page.
Legal
Terms of Service
1. Acceptance of Terms
By accessing or using Mycorr ("Service"), you agree to be bound by these Terms of Service ("Terms"). If you do not agree to these Terms, you must not access or use the Service.
These Terms constitute a legally binding agreement between you and Recons Ltd, a company incorporated in England and Wales under company number 14359202, with its registered office at Office 9, Dalton House, 60 Windsor Avenue, London SW19 2RR, United Kingdom ("Recons Ltd", "we", "us", or "our").
You must be at least 16 years of age to use the Service. By using the Service, you represent and warrant that you are at least 16 years old. If you are using the Service on behalf of an organisation, you represent and warrant that you have the authority to bind that organisation to these Terms.
2. Definitions
- "Content" means any data, text, files, schemas, table structures, database configurations, or other materials that you upload, create, store, or transmit through the Service.
- "Service" means the Mycorr web application, including all features, tools, and APIs provided at space.mycorr.app or any successor domain.
- "User" means any individual who accesses or uses the Service, whether as a registered account holder or otherwise.
3. Description of Service
Mycorr is a collaborative data modelling and database management platform that enables teams to model database schemas, manage data with real-time synchronisation, and handle data imports from various sources including CSV, Parquet, and Google Sheets.
4. Changes to the Service
- (a) We keep improving the Service, so features may be added, changed, or removed over time.
- (b) We may discontinue the Service, or any part of it. Where we can, we will give you reasonable notice first. If you are on a paid plan, our Refund Policy sets out the refund you are owed, including a refund of unused prepaid fees if we discontinue the Service or the plan you are on.
5. User Accounts
- (a) You can create an account by signing in with Google or by registering with an email address and password. You are responsible for maintaining the security of your Google account credentials or your password.
- (b) You are responsible for all activities that occur under your account.
- (c) You must notify us immediately at support@mycorr.app if you become aware of any unauthorised use of your account.
- (d) You may not create multiple accounts for the same individual.
- (e) We reserve the right to suspend or terminate accounts that we reasonably believe are compromised or being misused.
6. User Responsibilities
You agree to:
- Provide accurate and complete information when using the Service.
- Use the Service only for lawful purposes and in compliance with all applicable laws and regulations.
- Comply with all applicable data protection laws when storing personal data of third parties in the Service.
- Not use the Service in any manner that could damage, disable, overburden, or impair the Service.
7. Acceptable Use
You agree not to:
- Attempt to gain unauthorised access to the Service, other user accounts, or any systems or networks connected to the Service.
- Interfere with or disrupt the Service or servers or networks connected to the Service.
- Upload, transmit, or store any malicious code, viruses, or harmful content.
- Use the Service to store or process data that is subject to specific regulatory requirements (such as protected health information under HIPAA or payment card data under PCI DSS) unless you have independently ensured compliance with those requirements.
- Scrape, crawl, or use automated means to access the Service without our prior written consent.
- Reverse engineer, decompile, disassemble, or otherwise attempt to derive the source code of the Service.
- Circumvent, disable, or interfere with any security features of the Service.
- Use the Service to infringe upon the intellectual property rights of any third party.
- Impersonate any person or entity or misrepresent your affiliation with any person or entity.
- Use the Service for any illegal or unauthorised purpose.
8. User Content and Data Ownership
- (a) You retain all ownership rights in your Content. We do not claim ownership of any Content you upload, create, or store through the Service.
- (b) By using the Service, you grant us a limited, non-exclusive, worldwide, royalty-free licence to use, copy, store, transmit, and display your Content solely to the extent necessary to provide, maintain, and improve the Service.
- (c) You are solely responsible for the legality, reliability, appropriateness, and intellectual property ownership of your Content.
- (d) You represent and warrant that you have all necessary rights and permissions to upload and use your Content through the Service.
- (e) We may remove or disable access to Content that we reasonably believe violates these Terms or applicable law.
9. Intellectual Property
The Service, including its original content, features, functionality, design, source code, and underlying technology, is owned by Recons Ltd and is protected by international copyright, trademark, patent, trade secret, and other intellectual property laws. Our trademarks and trade dress may not be used in connection with any product or service without our prior written consent.
10. Feedback and Suggestions
If you provide us with any feedback, suggestions, ideas, or recommendations regarding the Service ("Feedback"), you hereby assign to us all rights, title, and interest in such Feedback. We shall be free to use, disclose, reproduce, licence, and otherwise distribute and exploit the Feedback without restriction or obligation to you of any kind.
11. Third-Party Services
The Service integrates with third-party services, including Google (for authentication, Google Sheets import, and cloud storage) and Paddle (for purchases of paid plans; see Section 12). Your use of these third-party services is subject to their respective terms of service and privacy policies. We are not responsible for the availability, accuracy, or content of any third-party services, and we do not warrant or endorse any third-party services.
12. Paid Plans and Billing
- (a) Some features of the Service are available only on a paid plan. The plans, their prices and what each includes are shown on our pricing page (https://mycorr.app/pricing/) and in the Service before you buy. Enterprise plans are governed by the agreement signed for them where it differs from these Terms.
- (b) Our order process is conducted by our online reseller Paddle.com. Paddle.com is the Merchant of Record for all our orders. Paddle provides all customer service inquiries and handles returns. The reseller is Paddle.com Market Limited ("Paddle"): you buy a paid plan from Paddle, and Paddle charges your payment method, issues your invoices and receipts, and calculates and collects any applicable taxes. Your purchase is also subject to Paddle's buyer terms, which Paddle presents at checkout.
- (c) A paid plan is bought for an organization in the Service and is billed per seat. Plans renew automatically at the end of each billing period (monthly or yearly) until cancelled.
- (d) Seats. Adding seats takes effect straight away: on a monthly plan the added seats are charged, pro-rated, on the next invoice; on a yearly plan they are charged immediately, pro-rated for the rest of the year. Removing seats takes effect from the start of the next billing period, and an organization cannot hold fewer seats than it has members.
- (e) Cancellation. An owner of the organization can cancel at any time in the Service. Cancellation takes effect at the end of the current billing period: the organization keeps its paid plan until then and then moves to the free plan. Deleting an organization cancels its subscription when the deletion takes effect.
- (f) Failed payments. If a renewal payment fails, Paddle will retry it. The organization keeps full access for the first 7 days; from day 8 it becomes read-only (you can still view and export your Content) until the payment succeeds. If the payment has still not succeeded by day 40, the organization moves to the free plan.
- (g) Moving to the free plan never deletes Content. If an organization then holds more Content or members than the free plan allows, you keep access to what is there, but you cannot add Content or members beyond the free plan's limits until you upgrade or reduce your usage.
- (h) We may change the prices of paid plans. We will tell the organization's owners by email at least 30 days before a price change applies. It applies from the next billing period after that notice, and you may cancel before it applies.
- (i) Refunds are covered by our Refund Policy (https://mycorr.app/refunds/), which forms part of these Terms.
13. Privacy
Your privacy is important to us. Our collection and use of personal data is governed by our Privacy Policy, which is incorporated into these Terms by reference. By using the Service, you consent to the collection and use of your data as described in the Privacy Policy.
14. WARRANTY DISCLAIMERS
THE SERVICE IS PROVIDED ON AN "AS IS" AND "AS AVAILABLE" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED. TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, RECONS LTD EXPRESSLY DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, INCLUDING BUT NOT LIMITED TO:
- IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
- WARRANTIES THAT THE SERVICE WILL BE UNINTERRUPTED, TIMELY, SECURE, OR ERROR-FREE.
- WARRANTIES THAT THE RESULTS OBTAINED FROM USE OF THE SERVICE WILL BE ACCURATE OR RELIABLE.
- WARRANTIES THAT DEFECTS IN THE SERVICE WILL BE CORRECTED.
- WARRANTIES THAT THE SERVICE WILL BE FREE FROM VIRUSES OR OTHER HARMFUL COMPONENTS.
- WARRANTIES REGARDING THE ACCURACY, COMPLETENESS, OR USEFULNESS OF ANY CONTENT OR INFORMATION PROVIDED THROUGH THE SERVICE.
NO ADVICE OR INFORMATION, WHETHER ORAL OR WRITTEN, OBTAINED FROM US OR THROUGH THE SERVICE SHALL CREATE ANY WARRANTY NOT EXPRESSLY STATED IN THESE TERMS.
NOTHING IN THESE TERMS SHALL EXCLUDE OR LIMIT ANY WARRANTY THAT CANNOT BE LAWFULLY EXCLUDED OR LIMITED UNDER APPLICABLE LAW, INCLUDING THE LAWS OF ENGLAND AND WALES.
15. LIMITATION OF LIABILITY
TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW:
- (a) IN NO EVENT SHALL RECONS LTD, ITS DIRECTORS, OFFICERS, EMPLOYEES, AGENTS, OR AFFILIATES BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES, INCLUDING BUT NOT LIMITED TO LOSS OF PROFITS, LOSS OF REVENUE, LOSS OF DATA, LOSS OF BUSINESS OPPORTUNITIES, LOSS OF GOODWILL, OR COST OF PROCUREMENT OF SUBSTITUTE SERVICES, ARISING OUT OF OR IN CONNECTION WITH YOUR USE OF OR INABILITY TO USE THE SERVICE, WHETHER BASED ON WARRANTY, CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY, OR ANY OTHER LEGAL THEORY, EVEN IF WE HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- (b) OUR TOTAL AGGREGATE LIABILITY FOR ALL CLAIMS ARISING OUT OF OR RELATING TO THESE TERMS OR YOUR USE OF THE SERVICE SHALL NOT EXCEED THE TOTAL AMOUNT OF FEES PAID BY YOU FOR THE SERVICE, INCLUDING FEES PAID TO OUR RESELLER PADDLE, DURING THE TWELVE (12) MONTHS IMMEDIATELY PRECEDING THE EVENT GIVING RISE TO THE CLAIM. IF YOU HAVE NOT PAID ANY FEES, OUR MAXIMUM LIABILITY SHALL BE ZERO POUNDS STERLING (GBP 0).
- (c) THE LIMITATIONS IN THIS SECTION APPLY REGARDLESS OF THE FORM OF ACTION, WHETHER IN CONTRACT, TORT, STRICT LIABILITY, OR OTHERWISE, AND SHALL SURVIVE ANY TERMINATION OR EXPIRATION OF THESE TERMS.
NOTHING IN THESE TERMS SHALL EXCLUDE OR LIMIT LIABILITY FOR DEATH OR PERSONAL INJURY CAUSED BY NEGLIGENCE, FRAUD OR FRAUDULENT MISREPRESENTATION, OR ANY OTHER LIABILITY THAT CANNOT BE LAWFULLY EXCLUDED OR LIMITED UNDER THE LAWS OF ENGLAND AND WALES.
16. Indemnification
You agree to indemnify, defend, and hold harmless Recons Ltd, its directors, officers, employees, agents, and affiliates from and against any and all claims, liabilities, damages, losses, costs, and expenses (including reasonable legal fees) arising out of or in connection with:
- Your use of the Service.
- Your Content or any data you store, process, or transmit through the Service.
- Your violation of these Terms.
- Your violation of any applicable law or regulation.
- Your violation of any third-party rights, including intellectual property rights or data protection rights.
- Any claim by a third party related to personal data you stored in the Service.
17. Termination
- (a) You may terminate your account at any time by using the account deletion feature in the Service or by contacting us at support@mycorr.app.
- (b) We may suspend or terminate your account at any time, with or without cause, and with or without notice, including but not limited to violations of these Terms. If we end a paid plan, our Refund Policy sets out any refund you are owed.
- (c) Upon termination, your right to use the Service will immediately cease. We may delete your Content and account data in accordance with our data retention policies as described in the Privacy Policy.
- (d) All provisions of these Terms that by their nature should survive termination shall survive, including but not limited to warranty disclaimers, limitation of liability, indemnification, and governing law.
18. Modifications to Terms
We reserve the right to modify these Terms at any time. When we make material changes, we will update the version number and effective date of these Terms and notify you through the Service. Material changes will require you to review and re-accept the updated Terms before continuing to use the Service. Your continued use of the Service after re-accepting the updated Terms constitutes your agreement to the changes.
19. Dispute Resolution
- (a) If any dispute arises out of or in connection with these Terms or your use of the Service, you agree to first attempt to resolve the dispute informally by contacting us at support@mycorr.app. We will attempt to resolve the dispute through good-faith negotiation for a period of thirty (30) days.
- (b) If the dispute cannot be resolved informally, either party may refer the dispute to mediation in accordance with the Centre for Effective Dispute Resolution (CEDR) Model Mediation Procedure.
- (c) If the dispute is not resolved through mediation within sixty (60) days, either party may bring proceedings in the courts of England and Wales.
20. Governing Law
These Terms shall be governed by and construed in accordance with the laws of England and Wales. Subject to the dispute resolution process in Section 19, the courts of England and Wales shall have exclusive jurisdiction over any disputes arising under these Terms.
If you are a consumer resident in the European Union, you shall also benefit from any mandatory provisions of the law of the country in which you are resident, and nothing in these Terms affects your rights as a consumer to rely on such mandatory provisions.
21. Severability
If any provision of these Terms is found to be invalid, illegal, or unenforceable by a court of competent jurisdiction, such provision shall be modified to the minimum extent necessary to make it valid and enforceable, or if modification is not possible, shall be severed from these Terms. The remaining provisions shall continue in full force and effect.
22. Entire Agreement
These Terms, together with the Privacy Policy and the Refund Policy, constitute the entire agreement between you and Recons Ltd regarding your use of the Service, and supersede all prior and contemporaneous agreements, proposals, representations, and understandings, whether written or oral.
23. Contact
If you have any questions about these Terms, please contact us at:
Recons Ltd, Office 9, Dalton House, 60 Windsor Avenue, London SW19 2RR, United Kingdom
Company number 14359202
support@mycorr.app
Privacy Policy
1. Introduction and Data Controller
This Privacy Policy explains how Recons Ltd ("Recons Ltd", "we", "us", or "our"), a company incorporated in England and Wales under company number 14359202, with its registered office at Office 9, Dalton House, 60 Windsor Avenue, London SW19 2RR, United Kingdom, collects, uses, shares, and protects your personal data when you use the Mycorr service ("Service") or visit our website, mycorr.app.
Recons Ltd is the data controller for the personal data we collect directly from you in connection with your use of the Service or our website. Where you store personal data of third parties in the Service, you are the data controller for that data and Recons Ltd acts as a data processor on your behalf (see Section 13).
This policy applies to all users of the Service and visitors to our website worldwide. We comply with the UK General Data Protection Regulation (UK GDPR), the EU General Data Protection Regulation (EU GDPR), and the California Consumer Privacy Act (CCPA) as applicable.
2. Information We Collect
We collect the following categories of personal data:
- (a) Account Information: your name, email address and profile photo. If you sign in with Google, we receive your name, email address and Google profile photo from your Google account. If you register with an email address and password, we store the password only as a salted one-way hash, never in readable form. You may also upload a profile photo of your own.
- (b) User-Generated Content: database schemas, table data, model configurations, and any other data you upload, create, or store through the Service. This content is controlled by you and may contain personal data of third parties.
- (c) Usage Data: session metadata, including when multiplayer collaboration sessions start and end. This data is used solely for system monitoring and service improvement.
- (d) Technical Data: IP address, browser type and version, device information, and operating system. This data is collected automatically by our web servers.
- (e) Cookie Data: session authentication cookies necessary for the operation of the Service, and analytics cookies set on our website with your consent (see Section 10).
- (f) Website Analytics Data: on our marketing website (mycorr.app), and only with your consent, we collect usage analytics through Google Analytics 4: the pages you visit, actions you take on the site (such as clicking a sign-up link or submitting the contact form), the campaign tags in the link that brought you (UTM parameters), approximate geographic location at country or city level, browser and device type, and a pseudonymous random identifier that distinguishes one visitor from another. This data does not include your Content, is not linked to your name or email address, and is not used to identify you personally.
- (g) Communications: when you write to us through the contact form on our website or the support form in the Service, the name and email address you give us (or, for the support form, your account email address), the subject you choose, and your message.
- (h) Billing Information, for organizations on a paid plan: the organization's billing email address and name, which member pays, the plan, the number of seats, the subscription's status and billing dates, and the identifiers Paddle gives the customer, subscription and payments. Paddle's payment notifications also tell us the card brand, the last four digits and expiry date of the card, and the cardholder's name. We never receive or store full card numbers or security codes: card details are entered directly into Paddle's secure payment form. Your billing address, company name and VAT or tax number are held by Paddle; we show and edit them through Paddle and keep only Paddle's reference to them. If you add invoice recipients, we pass their email addresses to Paddle, which sends them copies of your invoices.
3. How We Collect Information
We collect personal data in the following ways:
- Directly from you: when you register or sign in, create content, or contact us through our website or the Service.
- Automatically: through cookies, server logs, and session monitoring when you use the Service, and through Google Analytics 4 when you visit our website and have accepted analytics cookies.
- From third parties: your name, email address and profile photo from Google when you sign in with Google.
- From Paddle: the status of your subscription and payments, and the card details listed in Section 2(h), when you buy or change a paid plan.
4. Legal Basis for Processing
Under the UK GDPR and EU GDPR, we process your personal data on the following legal bases:
- (a) Performance of a Contract (Article 6(1)(b)): processing necessary to provide you with the Service, including account creation, authentication, data storage, collaboration features, and paid plans (checkout, seats, invoices, renewals and cancellation).
- (b) Legitimate Interests (Article 6(1)(f)): processing necessary for our legitimate interests, including service security, system monitoring, performance optimisation, service improvement, and keeping a record of billing actions (who changed a plan, its seats or its billing details) so that organizations can review changes and we can resolve disputes. Our legitimate interests do not override your fundamental rights and freedoms.
- (c) Consent (Article 6(1)(a)): where you have given specific consent for certain processing activities, such as analytics cookies on our website or optional communications. You may withdraw consent at any time, including through the "Cookie settings" link in the footer of our website.
- (d) Legal Obligation (Article 6(1)(c)): processing necessary to comply with applicable laws, regulations, or legal processes.
5. How We Use Your Information
We use your personal data for the following purposes:
- To provide, operate, and maintain the Service.
- To authenticate your identity and manage your account.
- To enable real-time collaboration features, including multiplayer sessions.
- To monitor and improve the performance, security, and reliability of the Service.
- To collect website usage analytics (with your consent) to understand how our marketing site is used and to improve it.
- To communicate with you about your account, including service updates and security notices.
- To respond to your requests and provide customer support.
- To sell and manage paid plans: to set up subscriptions, show invoices, apply seat changes and cancellations, and tell an organization's owners about failed payments.
- To comply with applicable laws and legal obligations.
- To enforce our Terms of Service and protect our rights.
We do not use your personal data for automated decision-making or profiling. We do not use your Content to train machine learning models.
6. Data Sharing and Subprocessors
We do not sell your personal data. We do not share your personal data with third parties for their own marketing purposes.
We share personal data with the following categories of service providers (subprocessors) who assist us in operating the Service:
- (a) Google Cloud Platform (Google LLC): cloud infrastructure hosting, authentication (OAuth), Google Sheets integration, and cloud storage. Data is hosted in Google Cloud Frankfurt (europe-west3), European Union.
- (b) Postmark (ActiveCampaign LLC): transactional email delivery for service-related communications, and delivery of the messages you send through our contact and support forms to our support inbox.
- (c) Google Analytics (Google LLC): usage analytics for our website (mycorr.app), collected only with your consent. Google acts as our processor under its data processing terms. See Section 7 for how transfers to the United States are safeguarded.
- (d) Discord (Discord Inc.): internal notifications to our team when you send us a message through the contact form on our website or the support form in the Service. Each notification contains the details listed in Section 2(g). See Section 7 for how transfers to the United States are safeguarded.
- (e) Infrastructure providers: database and caching services operated on our cloud infrastructure.
All subprocessors are bound by data processing agreements and are required to protect your personal data in accordance with applicable data protection laws.
Payments for paid plans are handled by Paddle.com Market Limited ("Paddle"), our reseller and the merchant of record for all purchases. When you buy a paid plan you buy it from Paddle, and Paddle processes your payment and billing details as an independent data controller under its own privacy notice (https://www.paddle.com/legal/privacy). We share with Paddle the organization's billing email address, its name, and our own identifiers for the organization and your account, so that Paddle can invoice you and we can link your purchase to the right organization. When you edit billing details or invoice recipients in the Service, we send them to Paddle.
We may also disclose your personal data if required to do so by law, regulation, legal process, or governmental request, or if we believe in good faith that disclosure is necessary to protect our rights, your safety, or the safety of others.
7. International Data Transfers
Your personal data is hosted on Google Cloud Platform in Frankfurt, Germany (europe-west3), within the European Union.
If you access the Service from outside the European Union or United Kingdom, your data will be transmitted to and stored on servers in the EU. The UK has an adequacy decision with the European Union, permitting data transfers between the UK and EU without additional safeguards.
For transfers to jurisdictions outside the EU/UK that do not have an adequacy decision, we rely on appropriate safeguards such as Standard Contractual Clauses approved by the European Commission or the UK Information Commissioner's Office.
Website analytics data collected through Google Analytics 4 is processed by Google LLC in the United States, and the support notifications described in Section 6 are processed by Discord Inc. in the United States. For those transfers we rely on each company's certification under the EU-U.S. Data Privacy Framework and the UK Extension to that framework, which have been recognised as providing adequate protection for personal data transferred from the EU and from the UK respectively.
Paddle may process your billing information outside the UK and EU; its privacy notice describes where and under which safeguards.
8. Data Retention
We retain your personal data as follows:
- (a) Account data (name, email): retained for as long as your account is active. Upon account deletion, your account data is deleted within 30 days.
- (b) User-generated content (schemas, table data): retained for as long as your account is active. When you delete your account, deletion takes effect after a 48-hour grace period during which you may cancel; your content is then queued for destruction and permanently deleted within 30 days of your request.
- (b1) Organization content: when an organization is deleted, its content enters a 30-day grace period during which any owner or administrator of that organization may cancel the deletion; the content is then permanently deleted within 30 days of the grace period ending. During the grace period, members retain access and may export their work using the built-in export features.
- (c) Session metadata: retained for 7 days for system monitoring purposes, then automatically deleted.
- (d) Server logs (including IP addresses): retained for 30 days for security and debugging purposes, then automatically deleted.
- (e) Backup data: retained for up to 30 days after the original data is deleted, then purged.
- (f) Website analytics data (Google Analytics 4): event-level data associated with a user identifier is retained by Google for 14 months, after which it is deleted or aggregated. The analytics cookies themselves expire 2 years after your last visit (see Section 10).
- (g) Billing records (the plan, seats, subscription status and dates, Paddle's identifiers, the billing email address and which member pays): retained for as long as the organization exists, and afterwards for up to six years where needed for accounting, tax and dispute purposes. Paddle keeps its own invoice and payment records under its own retention policy.
- (h) Payment notifications from Paddle, including the card details in Section 2(h): deleted 90 days after we process them.
- (i) The record of billing actions, including the previous and new billing email address when it changes: retained for as long as the organization exists, and afterwards for up to six years so that disputes about who changed what can be resolved.
We may retain certain data for longer periods where required by applicable law or to resolve disputes.
9. Your Rights
Depending on your location, you have the following rights regarding your personal data:
UK and EU Residents (UK GDPR / EU GDPR)
- Right of Access: you may request a copy of the personal data we hold about you.
- Right to Rectification: you may request that we correct inaccurate or incomplete personal data.
- Right to Erasure: you may request that we delete your personal data, subject to certain exceptions.
- Right to Restriction: you may request that we restrict the processing of your personal data in certain circumstances.
- Right to Data Portability: you may request a copy of your personal data in a structured, commonly used, machine-readable format.
- Right to Object: you may object to our processing of your personal data based on legitimate interests.
- Right to Withdraw Consent: where processing is based on consent, you may withdraw consent at any time without affecting the lawfulness of prior processing.
- Right to Lodge a Complaint: you have the right to lodge a complaint with the UK Information Commissioner's Office (ICO) at ico.org.uk, or with your local EU supervisory authority.
California Residents (CCPA)
- Right to Know: you may request information about the categories and specific pieces of personal data we have collected about you.
- Right to Delete: you may request that we delete the personal data we have collected from you, subject to certain exceptions.
- Right to Opt-Out: we do not sell your personal data. If this changes, we will provide a clear opt-out mechanism.
- Right to Non-Discrimination: we will not discriminate against you for exercising your CCPA rights.
Exercising Your Rights
To exercise any of these rights, please contact us at support@mycorr.app. We will respond to your request within 30 days (UK/EU GDPR) or 45 days (CCPA). We may request verification of your identity before processing your request.
You may also export your data directly from the Service using the built-in export features.
10. Cookies and Analytics
Essential Cookies
We use essential cookies necessary for the operation of the Service (space.mycorr.app):
- Session Cookie: an authentication cookie that identifies your logged-in session. This cookie is set when you sign in and expires when your session ends or after 7 days of inactivity.
Because essential cookies are strictly necessary, no consent is required for them under UK or EU law. We do not use advertising cookies, remarketing, or any other third-party tracking technologies on the Service.
Website Analytics (Consent-Based)
Our marketing website (mycorr.app) uses Google Analytics 4 to understand how the site is used. Analytics cookies are set only after you accept them in the banner shown when you first arrive. No analytics cookie is set before you make a choice, and if you decline, Google Analytics never loads and nothing is set.
Once you accept, the following cookies are set on mycorr.app:
- _ga: distinguishes one visitor from another. Expires 2 years after your last visit.
- _ga_84L0CXJQGE: maintains your session state for our Google Analytics property. Expires 2 years after your last visit.
The data collected is described in Section 2(f): the pages you visit, actions you take on the site, the campaign tags in the link that brought you, approximate geographic location, browser and device type, and a pseudonymous random identifier.
Legal basis: your consent, under Article 6(1)(a) of the UK GDPR and the EU GDPR, and the requirement for consent to non-essential storage under the UK Privacy and Electronic Communications Regulations and the EU ePrivacy Directive.
You may change your choice at any time using the "Cookie settings" link in the footer of mycorr.app, which reopens the banner. Declining there stops any further collection and deletes the analytics cookies already in your browser. Withdrawing consent does not affect data collected before you withdrew it.
Google Analytics is provided by Google LLC acting as our processor (see Section 6). Transfers to the United States are safeguarded as described in Section 7. Analytics data is retained for 14 months (see Section 8).
11. Data Security
We implement appropriate technical and organisational measures to protect your personal data, including:
- Encryption of data in transit using TLS/HTTPS.
- Encryption of data at rest.
- Fine-grained access controls using role-based authorisation.
- Regular security reviews and monitoring.
- Access to personal data limited to authorised personnel on a need-to-know basis.
- Secure authentication: sign-in with Google, or with an email address and a password that we store only as a salted one-way hash, never in readable form.
While we take reasonable measures to protect your data, no method of electronic transmission or storage is completely secure. We cannot guarantee absolute security.
12. Children's Privacy
The Service is not directed at individuals under the age of 16. We do not knowingly collect personal data from children under 16. If we become aware that we have collected personal data from a child under 16, we will take steps to delete such data promptly. If you believe we have collected data from a child under 16, please contact us at support@mycorr.app.
13. Data Processing Terms
This section sets out the terms under which Recons Ltd processes personal data on your behalf when you act as a data controller by storing personal data of third parties in the Service.
- (a) Roles: when you store personal data of third parties in the Service, you are the data controller and Recons Ltd is the data processor. You determine the purposes and means of processing; we process such data only on your documented instructions.
- (b) Scope of Processing: we process your third-party data solely to provide, maintain, and secure the Service. We do not access, use, or disclose such data for any other purpose unless required by applicable law.
- (c) Security Measures: we implement appropriate technical and organisational measures as described in Section 11 to protect all data processed through the Service.
- (d) Sub-Processing: we engage the subprocessors listed in Section 6 to assist in providing the Service. We will notify you of any changes to our subprocessors by updating Section 6 of this Privacy Policy. You may object to a new subprocessor by ceasing to use the Service.
- (e) Breach Notification: in the event of a personal data breach affecting data we process on your behalf, we will notify you without undue delay, and in any event within 72 hours of becoming aware of the breach, providing the nature of the breach, the categories of data affected, and the measures taken to address it.
- (f) Audit Rights: upon reasonable written request and subject to appropriate confidentiality obligations, we will make available to you information necessary to demonstrate our compliance with these data processing terms.
- (g) Data Return and Deletion: upon termination of your account, you may export your data using the built-in export features of the Service. Following your request for account deletion, we will delete all data processed on your behalf in accordance with the retention periods set out in Section 8.
- (h) Data Protection Impact Assessments: upon reasonable request, we will provide you with information necessary to carry out a data protection impact assessment.
14. Your Obligations When Storing Third-Party Data
If you use the Service to store, process, or manage personal data of third parties (for example, customer records, employee data, or contact information), you acknowledge and agree that:
- You are the data controller for such data and bear full responsibility for compliance with all applicable data protection laws.
- You must have a lawful basis for collecting and processing such data.
- You must inform the relevant data subjects about the processing of their data, including the fact that their data is stored using the Service.
- You must respond to and fulfil any data subject requests (access, deletion, rectification, etc.) relating to such data.
- You must not store special category data (racial or ethnic origin, political opinions, religious beliefs, health data, biometric data, etc.) or criminal offence data in the Service unless you have ensured compliance with the additional requirements of applicable data protection law.
- Recons Ltd acts as a data processor only and accepts no responsibility or liability for your compliance with data protection laws regarding third-party data you store in the Service.
15. Changes to This Policy
We may update this Privacy Policy from time to time. When we make material changes, we will update the version number and effective date at the top of this policy and notify you through the Service. Material changes will require you to review and re-accept the updated policy before continuing to use the Service.
We encourage you to review this Privacy Policy periodically.
16. Contact
If you have any questions about this Privacy Policy or our data practices, or if you wish to exercise any of your data protection rights, please contact us at:
Recons Ltd, Office 9, Dalton House, 60 Windsor Avenue, London SW19 2RR, United Kingdom
Company number 14359202
support@mycorr.app
For data protection matters, you may also contact the UK Information Commissioner's Office (ICO) at ico.org.uk.
Refund Policy
1. In Short
- You can have a full refund if you ask within 14 days of starting a paid plan, switching to yearly billing, or a yearly renewal, within the limits in Section 4.
- To ask, email support@mycorr.app.
- Other payments are not refundable, except for charges made in error, seats added by mistake, a faulty Service, or if we end your plan. When you cancel, you keep your plan until the end of the period you have paid for.
- Nothing in this policy takes away any right you have by law.
2. Who This Policy Covers
This Refund Policy explains when you can get your money back for a paid plan on Mycorr (the "Service", as defined in our Terms of Service). Mycorr is provided by Recons Ltd ("Recons Ltd", "we", "us", or "our"), a company registered in England and Wales under company number 14359202. This policy forms part of our Terms of Service.
- (a) "You" means the organisation that holds the paid subscription. Any owner or administrator of that organisation can ask for a refund.
- (b) It covers the Pro plan, whether billed monthly or yearly.
- (c) The Free plan costs nothing, so there is nothing to refund.
- (d) Enterprise plans are covered by the agreement signed for them, not by this policy.
3. Payments Through Paddle
Paid plans are sold through our online reseller, Paddle.com, which is the Merchant of Record for these orders. Paddle takes your payment, sends your receipt and pays out every refund, and its name appears on your card or bank statement. Paddle's Buyer Terms (https://www.paddle.com/legal/buyer-terms) and Refund Policy (https://www.paddle.com/legal/refund-policy) also apply to your purchase, and nothing in this policy reduces the rights they give you.
4. Refunds Within 14 Days
- (a) You can have a full refund of a payment if you ask within 14 days of it, where that payment starts a paid subscription (including the first full-price payment after a free trial or discount), moves a subscription from monthly to yearly billing, or renews a yearly subscription.
- (b) The 14 days are calendar days, counted from the payment date on your Paddle receipt. Your request is in time if you send it by the end of the 14th day.
- (c) You do not need to give a reason, though we would be glad to hear one.
- (d) Monthly renewals are not refundable under this section.
- (e) Each organisation can have one refund under this section in any 12 months. Refunds under Sections 7, 9, 10 and 12 do not count towards it, and this limit does not affect any legal right you have to cancel.
5. How to Ask for a Refund
- (a) Email support@mycorr.app, naming your organisation and the payment you would like refunded. Please write from the email address you use to sign in, so we can check that you can act for the organisation.
- (b) Cancelling in the app does not by itself ask for a refund. If your subscription has not been cancelled yet when you email us, we will cancel it for you.
- (c) Your request counts from when you send it, even if we reply after the 14 days are up. If we decline a request, we will tell you why.
- (d) Paddle refunds the payment, including any VAT or sales tax you paid, to the payment method you used and in the currency you paid in. Card refunds usually appear within 3 to 5 working days, depending on your bank.
- (e) A refunded plan ends when the refund is made, and your organisation moves to the Free plan (see Section 11).
6. Cancelling
- (a) An owner of your organisation can cancel the subscription at any time in the app. Cancelling stops the next renewal.
- (b) You keep your plan until the end of the period you have already paid for, whether a month or a year. Apart from the cases set out in this policy, we do not refund the rest of that period.
7. Changing Seats or Plans
- (a) On a monthly plan, seats you add are charged, pro-rated, on your next invoice. On a yearly plan, they are charged straight away, pro-rated for the rest of the year.
- (b) Removing seats takes effect from the start of your next billing period, and you cannot hold fewer seats than your organisation has members. Until then you keep the seats you have paid for, and we do not refund or credit the difference.
- (c) If seats were added by mistake, email us within 14 days of being charged for them. We will remove them straight away and refund what you paid for them.
8. Price Changes
We will email your organisation's owners at least 30 days before a price change applies to you. A new price takes effect from your next billing period, never part-way through a period you have already paid for. If you do not want to continue at the new price, cancel before your renewal date.
9. Charges Made in Error
If we charge you by mistake, for example a renewal after you cancelled or the same payment taken twice, tell us and we will arrange a full refund of that charge through Paddle.
10. If We End Your Plan
- (a) If we close your organisation's account or stop offering the paid plan you are on, for any reason other than a breach of our Terms of Service, we will refund the unused part of any period you have already paid for, in proportion to the time left.
- (b) If we close your organisation's account because of a serious or repeated breach of our Terms of Service, we do not refund fees for the rest of the period.
11. What Happens to Your Data
When a refund is made or a cancellation takes effect, your organisation moves to the Free plan. Moving to the Free plan never deletes your data, and members beyond the Free plan's limit of 10 stay on. If your organisation holds more than the Free plan allows, such as more than 1 GB of storage, you can still read, export and delete your data, but you cannot add data or members beyond the Free plan's limits until you are back under them or upgrade again.
12. Your Legal Rights
- (a) Nothing in this policy affects your statutory rights. If you are a consumer in the United Kingdom, the European Union or another country that gives you a legal right to cancel, you keep that right, and where the law gives you more than this policy does, the law applies.
- (b) If the Service is faulty or not as described, you may be entitled to a full or partial refund at any time. Please contact us first, so we can try to put it right.
13. Changes to This Policy
We may update this policy from time to time. When we do, we will update its version number and effective date, and if a change is material, we will tell you by email before it takes effect. A change never applies to a payment you made before it took effect.
14. Contact
If you have any questions about this policy, please contact us at:
Recons Ltd, Office 9, Dalton House, 60 Windsor Avenue, London SW19 2RR, United Kingdom
Company number 14359202
support@mycorr.app