# Tuumo > Tuumo has no dashboards to build. Your product sends events over the API, and you read the results from your AI tool through the Tuumo MCP server. Tuumo is product analytics you use by asking your AI tool. There are no dashboards to build: your product sends events with one API call, and anyone in the organization asks Claude, ChatGPT, Gemini, Cursor, Codex, Linear or any other MCP client about them, getting answers (and dashboards built on demand) from the workspace's own data. - MCP server for AI tools: https://mcp.tuumo.fi/mcp (sign in once; the tool gets the member's own permissions) - Events API: POST https://api.tuumo.fi/v1/events, one event per request, with an ingest key - Custom dashboards and reports: query the same MCP server from your own code with an analyst key - Every workspace includes 1,000,000 events a month; plans are per member: Free €0, Pro €10, Max €50 per month (excluding VAT) - Data is stored in UpCloud's Helsinki data center (Finland), off-site backups in Frankfurt (Germany); sub-processors: UpCloud (hosting) and Scaleway (email); every query is kept in the workspace's history - Scale: one ingest server took nearly 90,000 events a second in load tests on a developer machine with simulated storage, median response about 1 ms, no events dropped - Company: Tuumo Oy (business ID 3361053-4), Kuopio, Finland, support@tuumo.fi ## Website - [Home](https://www.tuumo.fi/): What Tuumo is, how it works, the AI tools it works with - [Pricing](https://www.tuumo.fi/pricing/): Plans, the monthly event quota and query credits - [Resources](https://www.tuumo.fi/resources/): The GOOSE framework, product metrics and product outcomes guides - [Security and privacy](https://www.tuumo.fi/security/): Where the data lives, the sub-processors, how it is protected, GDPR - [About](https://www.tuumo.fi/about/): Who builds Tuumo and why - [Terms of service](https://www.tuumo.fi/terms/): Plans, quotas, payment, liability and termination - [Data processing agreement](https://www.tuumo.fi/dpa/): Tuumo as processor, the sub-processors, breach notification, export and erasure - [Privacy policy](https://www.tuumo.fi/privacy/): How Tuumo handles its users' account data, for how long, and their rights ## Docs - [Setup guide](https://docs.tuumo.fi/docs/setup-guide/): Tuumo has no dashboards to build. Your product sends events over the API, and you read the results from your AI tool. - [Connect AI tools](https://docs.tuumo.fi/docs/connect-ai-tools/): Tuumo is used through an AI tool. Add the Tuumo MCP server to the tool you already use, sign in once, and ask your questions there. - [API reference](https://docs.tuumo.fi/docs/api-reference/): The Events API accepts events from your product, one per request. An ingest key sends events and never reads data back; reading from your own code uses a key with the role analyst. - [Event naming guide](https://docs.tuumo.fi/docs/event-naming-guide/): An AI tool reads your events and answers questions about them, so event names are the vocabulary it works with. Consistent names give precise answers. - [Query history](https://docs.tuumo.fi/docs/query-history/): Every query that runs is kept with what it returned and what it cost. Save a query by title to find it again, and run the same query again whenever you want. - [Plans and billing](https://docs.tuumo.fi/docs/plans-and-billing/): Tuumo meters what comes in and what you ask. Sending events is free up to a monthly quota, and a member's plan sets how much they can query. - [Roles and permissions](https://docs.tuumo.fi/docs/roles-and-permissions/): A workspace has three roles. Every member can query data through an AI tool, Admins also manage the workspace, and the Owner is the one Admin who cannot be removed. --- # Setup guide > Tuumo has no dashboards to build. Your product sends events over the API, and you read the results from your AI tool. Four steps take you from an empty workspace to your first answer: create an API key, send an event, connect an AI tool and ask a question. ## 1. Create an API key Your product sends events with an API key. Open **API keys** in the app and create one: - Choose the role `ingest`. An `ingest` key can send events and can never read data back. - Give the key a name, for example the app or the environment it belongs to, and a product. A product name that does not exist yet creates the product. - Copy the key when the app shows it: it is shown once. A key looks like `tm_` followed by 43 characters, and later the key list shows only its hint, `tm_…` and the last four characters. Keep the key in an environment variable such as `TUUMO_KEY`, never in the code or in the repository. If it leaks, revoke it under **API keys** and create another. ## 2. Send your first event Paste this to your coding agent (Claude Code, Cursor, Codex) in your product's repository. It adds the tracking and tells you which events it created. ```text Add Tuumo event tracking to this codebase. Send one event per request with POST https://api.tuumo.fi/v1/events and the TUUMO_KEY environment variable. Each event has a name and, when the request or app session has one, a session_id. Track signup, activation and the five most important user actions. Name events object_action in snake_case, for example report_exported. Full reference: https://docs.tuumo.fi/llms.txt ``` ### Or send a test event yourself ```sh curl https://api.tuumo.fi/v1/events \ -H "Authorization: Bearer $TUUMO_KEY" \ -H "Content-Type: application/json" \ -d '{"name": "signup_completed", "session_id": "s_8f2c41"}' ``` The answer is `202` with the id of the event: ```json { "event_id": "0192f3a0-7c1e-7b2a-8d4e-5f6a7b8c9d0e" } ``` The [API reference](https://docs.tuumo.fi/docs/api-reference/) lists every field and every error. ## 3. Connect an AI tool Add the Tuumo MCP server to the tool you already use and sign in with this account. On first use the tool opens a browser window for sign-in, where you choose the workspace to connect. The server's address is `https://mcp.tuumo.fi/mcp`. ### Claude Code ```sh claude mcp add --transport http tuumo https://mcp.tuumo.fi/mcp ``` ### Claude Open Settings, go to Connectors, choose Add custom connector, name it Tuumo and paste `https://mcp.tuumo.fi/mcp`. ### Cursor Create `.cursor/mcp.json` in your project, or `~/.cursor/mcp.json` for every project: ```json { "mcpServers": { "tuumo": { "url": "https://mcp.tuumo.fi/mcp" } } } ``` ### Codex ```sh codex mcp add tuumo --url https://mcp.tuumo.fi/mcp codex mcp login tuumo ``` ### Linear A Linear admin adds `https://mcp.tuumo.fi/mcp` as a custom MCP server for Linear Agent; each member then signs in with their Tuumo account. [Connect AI tools](https://docs.tuumo.fi/docs/connect-ai-tools/) has the full steps for each tool. When the tool is connected, it appears under **AI tools** in the app. ## 4. Ask your first question Once a tool is connected, just ask. A few to start with: ```text How many signups did we get this week compared to last week? ``` ```text Show the funnel from signup_started to signup_completed. ``` ```text Which events dropped most since last month, and for which users? ``` ## More in the docs - [API reference](https://docs.tuumo.fi/docs/api-reference/) - [Event naming guide](https://docs.tuumo.fi/docs/event-naming-guide/) - [What your AI tool can do](https://docs.tuumo.fi/docs/connect-ai-tools/#what-your-ai-tool-can-do) - [docs.tuumo.fi/llms.txt](https://docs.tuumo.fi/llms.txt), the whole documentation as one file for an AI tool --- # Connect AI tools > Tuumo is used through an AI tool. Add the Tuumo MCP server to the tool you already use, sign in once, and ask your questions there. The MCP server's address is the same for every tool: ```text https://mcp.tuumo.fi/mcp ``` When you sign in, you choose one workspace. Each connection is for that workspace only; to use another workspace, connect again and choose it. The tool acts with your role in the workspace (see [Roles and permissions](https://docs.tuumo.fi/docs/roles-and-permissions/)), never with more. ## Claude Code For the terminal and IDE extensions. 1. Add the server from your terminal: ```sh claude mcp add --transport http tuumo https://mcp.tuumo.fi/mcp ``` 2. Start Claude Code and run `/mcp`. Choose tuumo and select Authenticate. ```text /mcp ``` 3. Sign in with your Tuumo account in the browser window that opens, choose the workspace and approve access. 4. Ask a question to check it works: ```text How many events did we receive yesterday? ``` ## Claude (web and desktop) For claude.ai and the Claude desktop app. 1. Open Settings and go to Connectors. 2. Choose Add custom connector. Name it Tuumo and paste the MCP server URL. 3. Select Connect, sign in with your Tuumo account, choose the workspace and approve access. 4. In a chat, open the tools menu and make sure Tuumo is switched on. ## Cursor The server can be added for one project or for all of them. 1. Create `.cursor/mcp.json` in your project, or `~/.cursor/mcp.json` for every project: ```json { "mcpServers": { "tuumo": { "url": "https://mcp.tuumo.fi/mcp" } } } ``` 2. Open Cursor Settings, go to MCP and switch tuumo on. 3. Select the sign-in prompt next to the server and approve access in the browser. 4. Ask in Agent mode: ```text Which events dropped most since last month? ``` ## Codex For the Codex CLI and IDE extension. 1. Add the server: ```sh codex mcp add tuumo --url https://mcp.tuumo.fi/mcp ``` 2. Sign in: ```sh codex mcp login tuumo ``` 3. Or add it by hand to `~/.codex/config.toml`: ```toml [mcp_servers.tuumo] url = "https://mcp.tuumo.fi/mcp" ``` 4. Start Codex and ask a question about your events. ## Linear For Linear Agent in chat, comments and automations. 1. A Linear admin allows the server: open Workspace settings, go to AI & Agents, then Linear Agent, switch on Enable MCP servers and add a custom URL: ```text https://mcp.tuumo.fi/mcp ``` 2. Each member opens Settings, then Agent personalization, and adds Tuumo under MCP servers. 3. Sign in with your Tuumo account and approve access to your workspace. 4. Mention Tuumo when you ask Linear Agent a question, in chat or in an issue comment. ## What your AI tool can do A connected tool has the permissions of your role, and a role change reaches it within a minute. - **Every member's tool** reads and analyses the events: it lists the event names, describes the events table and one event, and runs read-only queries. Long queries run in the background: the tool can start one, check it, list the workspace's queries, cancel one or delete one with its result. It can save a query with a title and parameters for reuse, list and archive saved queries, export a result as a Parquet, CSV or JSON lines file, and list the workspace's products. - **An Admin's or the Owner's tool** can also create, rename, archive and restore products, list, create, rename and revoke API keys, and file and list requests to delete data. The keys it creates can never exceed the permissions of the member who connected the tool. - **No tool** sends events (events come from your product with an API key), changes members, roles, plans or settings, or deletes the workspace. Every query uses your query credits, see [Plans and billing](https://docs.tuumo.fi/docs/plans-and-billing/). Every query is kept in the workspace's [Query history](https://docs.tuumo.fi/docs/query-history/). ## If it does not connect - The tool does not show up under **AI tools** in the app: the sign-in was not finished. Start it again from the tool. - You see another workspace's data: you approved the wrong workspace. Disconnect the tool under **AI tools** and sign in again. - The tool says it has no Tuumo tools: restart it after adding the server. - The tool worked and now answers that you are not allowed: your role changed, or you were removed from the workspace, which disconnects your tools. Ask an admin of the workspace. - The tool says your query credits for the month are used: queries start again on the first of the month (UTC), or when your plan changes. --- # API reference > The Events API accepts events from your product, one per request. An ingest key sends events and never reads data back; reading from your own code uses a key with the role analyst. ## Overview | Setting | Value | | ---------- | ------------------------------------ | | Base URL | `https://api.tuumo.fi` | | Endpoint | `POST /v1/events`, one event per request | | Format | JSON over HTTPS, UTF-8 | | Version | In the path: `/v1` | | Body limit | 256 KiB | ## Authentication Send your API key as a bearer token on every request. Create keys under **API keys**, one per app or environment. A key looks like `tm_` followed by 43 characters, and the app shows it once. ```text Authorization: Bearer $TUUMO_KEY ``` A key sends events when its role is `ingest` (or `admin`), and a key belongs to one product: its events are filed under that product. A key with any other role, an unknown key, a missing or malformed header, a revoked or expired key and a key of an archived product all get the same answer, `401`. A revoked key stops working within a minute; events already received are kept. A client application that sends events embeds an `ingest` key only: it cannot read data back. ## Send an event `POST /v1/events` accepts one event per request and answers `202 Accepted` with the id of the event. The body is a JSON object: | Field | Type | Required | Description | | ------------ | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------- | | `name` | string | Yes | Event name, 1 to 128 characters, no control characters. Use object_action in snake_case, for example `signup_completed`. | | `timestamp` | string | No | When the event happened: RFC 3339 with an offset, for example `2026-10-21T09:15:02Z`. Without it, the time Tuumo received the request. | | `user_id` | string | No | The person the event belongs to, the same id on every platform. | | `session_id` | string | No | Id of the session the event belongs to. Events with the same id are grouped together. Optional, and recommended. | | `properties` | object | No | Any JSON object with the detail of the event. Arrays, strings, numbers and booleans are refused. Without it, `{}`. | A field sent as `null` counts as absent, except `name`. A field that is not in the table, a repeated field, invalid JSON and an empty body are `400`. ```sh curl https://api.tuumo.fi/v1/events \ -H "Authorization: Bearer $TUUMO_KEY" \ -H "Content-Type: application/json" \ -d '{"name": "report_exported", "timestamp": "2026-10-21T09:15:02Z", "user_id": "u_1842", "session_id": "s_8f2c41", "properties": {"format": "csv", "duration_ms": 412}}' ``` ### Response ```json { "event_id": "0192f3a0-7c1e-7b2a-8d4e-5f6a7b8c9d0e" } ``` `202` means Tuumo has the event; it appears in queries a short while later. Tuumo does not remove duplicates: if you send a request again because you never saw its answer, the event is stored twice, each with its own `event_id`. ## Errors Every error answer is JSON, `{"error": "", "detail": "…"}`; `detail` is there for a `400` and says what is wrong. | Status | Code | Meaning | What to do | | ------ | ------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | | 400 | `invalid_event` | The body is not valid JSON, a field has the wrong type or a required field is missing | Fix the event; do not retry as is | | 401 | `unauthorized` | The key is missing, malformed, revoked, expired or not allowed to send events | Check the key and its role under API keys | | 402 | `quota_exceeded` | The workspace has used its monthly event quota; the event was not stored | Stop sending until the month turns (UTC) or the quota grows; do not retry in a loop. There is no `Retry-After` | | 408 | `request_timeout` | The request did not arrive in time | Retry | | 413 | `payload_too_large` | The body is over 256 KiB | Send a smaller event; do not retry as is | | 429 | `overloaded` | Too many events are being received; slow down | Wait for `Retry-After` seconds, with some jitter, then retry | | 503 | `no_writers` | Tuumo cannot store events right now | Wait for `Retry-After` seconds, with backoff, then retry | Any other path is `404` and any other method on `/v1/events` is `405`. See [Plans and billing](https://docs.tuumo.fi/docs/plans-and-billing/) for the monthly event quota. ## Reading data Most reading happens in an AI tool through the Tuumo MCP server, see [Connect AI tools](https://docs.tuumo.fi/docs/connect-ai-tools/). To query from your own code, for example for a dashboard, create a key with the role `analyst` under **API keys** and send it as a bearer token to the MCP server: ```text https://mcp.tuumo.fi/mcp ``` An `analyst` key can read and query data but cannot send events. Keep it, and any `admin` key, on your server; never ship it in a client application. Its queries use the query credits and the plan of the member who created the key. --- # Event naming guide > An AI tool reads your events and answers questions about them, so event names are the vocabulary it works with. Consistent names give precise answers. ## The rules 1. Object first, then action: `report_exported`, not `exported_report`. 2. Lowercase snake_case only: no spaces, capitals, dots or dashes. 3. Past tense, because it has happened: `invite_sent`, not `send_invite`. 4. One name per thing on web, mobile and backend. 5. Describe what the user did, not the UI: `plan_upgraded`, not `blue_button_clicked`. 6. Put the variation in properties, not in the name. ## Good and bad names | Instead of | Use | Why | | ---------------------------- | ------------------------------------ | -------------------------------------------- | | `SignupCompleted` | `signup_completed` | One casing everywhere | | `clicked export button` | `report_exported` | The outcome, not the click | | `export_pdf`, `export_csv` | `report_exported` with a `format` property | One event, variation as a property | | `signup` | `signup_started`, `signup_completed` | Say which step | | `ios_app_opened` | `app_opened` with a `platform` property | Platform is a property | An event name is 1 to 128 characters. ## Properties Properties carry the detail that lets one event answer many questions. They are the `properties` object of the event. Use the same name across events, keep each one the same type every time, keep them flat, and put units in the name when they are not obvious (`duration_ms`, `amount_eur`). Do not send personal data you do not need: no names, email addresses, phone numbers, free text, passwords or tokens. ## Users and identity Send the same `user_id` for the same person from every platform, and make it an id that never changes: your database id, not an email. Send a `session_id` with the events of one visit or app session: it is optional, and it is what groups a visit's events together, so it is recommended. For visitors who are not signed in, send an `anonymous_id` property, and send both ids on the signup event. For B2B products, add an `account_id` property to every event. ## Starter tracking plan | Event | When it fires | Key properties | | ------------------------ | ---------------------------------- | ------------------ | | `signup_started` | The signup form is opened | `source` | | `signup_completed` | The account is created | `source`, `method` | | `onboarding_completed` | The last onboarding step is done | `duration_ms` | | `project_created` | The user creates a project | `template` | | `invite_sent` | The user invites teammates | `count` | | `report_exported` | A core output is produced | `format` | | `plan_upgraded` | The plan changes upward | `from`, `to` | | `subscription_cancelled` | The subscription is cancelled | `reason` | ## Changing events Never rename an event in place: history under the old name stops matching questions asked with the new one. To rename, send both names for one release, then stop sending the old one. To change what an event means, give it a new name. ## Prompt for your coding agent Paste this into Claude Code, Cursor or Codex in your product's repository. ```text Add Tuumo event tracking to this codebase. - Send one event per request with POST https://api.tuumo.fi/v1/events, authenticated with the TUUMO_KEY environment variable. Never hard-code the key. - Each event has a name. Send a session_id too when the request or app session has one. - Create one small tracking module and call it everywhere. - Name events object_action in snake_case and past tense. - Start with signup_started, signup_completed and the five most important user actions you can find in this product. - Retry 408, 429 and 503 responses, after the Retry-After seconds when there is one. Stop sending on 402, and do not retry 400, 401 or 413. - Write the final list to docs/tracking-plan.md. Full reference: https://docs.tuumo.fi/llms.txt ``` --- # Query history > Every query that runs is kept with what it returned and what it cost. Save a query by title to find it again, and run the same query again whenever you want. ## What is saved A query is what to calculate. A query result is the data that came back. Every query of the workspace is kept in its history, whether an AI tool, an API key or the app ran it. A query becomes a saved query when you give it a title, in the app or by asking your AI tool. | Field | What it holds | | -------------- | ------------------------------------------------------------------------------------------------------ | | **Statement** | The exact query that ran, with the values of its parameters | | **Who** | The member it ran for, and the AI tool or the API key that submitted it | | **When** | When it was submitted, when it started and finished, and how long it ran | | **Cost** | The query credits it used, the peak memory it needed and the memory limit of the plan | | **Outcome** | Finished, stopped (it needed more memory or time than the plan allows, or it was cancelled) or failed | | **Result** | The first rows of the result, the number of rows, and the full result as a Parquet file while it is kept | A query that was refused before it started, for example because the member's query credits were used, leaves no record. ## Saved queries A saved query is a read-only query with a title, an optional description and optional parameters, stored for the whole workspace. A parameter is a named, typed value in the query, written `$name`, so the same query can run for another week or another product without editing its text. Any member can save, rename and run a saved query, and archive it; archiving is final. A member can save a query while the workspace has fewer unarchived saved queries than the member's plan allows: 20 on Free, 200 on Pro, 2,000 on Max. Archived queries do not count. ## Run a query again Each query has an id. Choose **Run again** on it in the app, or give the id to your AI tool, to run exactly the same statement. A saved query runs with its parameter values, or with the defaults. - Running again uses query credits like any other query, and the same memory limit applies. - Looking at a stored result is free: nothing is recalculated. - A run is a new query of its own, with its own result. The earlier result stays as it was. - Late-arriving events can change an old period, so a stored result shows what was known when the query ran. ```text Show my queries from last week. ``` ```text Run the saved query "signup funnel" again for this week. ``` ## Who sees the history - Every member sees every query of the workspace, including the ones run with an API key. - A member's name stays on the queries they ran for 90 days after they leave the workspace, then the history shows "former member". - Any member can delete a query: its result file is removed within about a minute, and the record stays in the history marked as deleted. Nobody can edit a query. ## Exports An export writes a whole result to a file, as Parquet, CSV or JSON lines, for use outside Tuumo. It is a query like the others, and it is kept in the history in the same way. A plan limits the rows of an export: 1,000,000 on Free, 50,000,000 on Pro and none on Max. When the limit cuts an export, the answer says so. CSV cells are written as stored, so a spreadsheet may read a cell that starts with `=`, `+`, `-` or `@` as a formula. Use Parquet or JSON lines for a file a spreadsheet opens. ## Retention - A result file is kept for the plan of the member who ran the query: 7 days on Free, 30 days on Pro and 90 days on Max. After that the query reads as expired, and running it again gives a fresh result. - A link to download a result works for 15 minutes; ask for a new one when it has expired. The link is a secret: anyone who has it can download the file, so do not share it; hand on the file instead. - The record of the query, with its statement, cost and outcome, stays in the history, also after the query is deleted, until the workspace is destroyed, 30 days after the workspace is deleted. --- # Plans and billing > Tuumo meters what comes in and what you ask. Sending events is free up to a monthly quota, and a member's plan sets how much they can query. ## How it works - A workspace includes 1,000,000 events a month for free. - A plan belongs to a member, not to the workspace. One workspace can mix plans, for example one member on Max, two on Pro and three on Free. The same person can be on different plans in different workspaces. - A member's plan sets their query credits for the month, the memory and time a query may use, and their place in the queue when the system is busy. - Every paid member also raises the workspace's monthly event quota. Every member starts on Free. ## Plans Prices are per member per month. They are shown for information. The prices and the allowances on this page, the query credits included, may change before launch. | Plan | Price | Adds to the monthly event quota | Query credits | | -------- | ----- | ------------------------------- | ------------- | | **Free** | €0 | – | 500 | | **Pro** | €10 | + 100,000 events | 20,000 | | **Max** | €50 | + 1,000,000 events | 100,000 | Query credits are counted per month, in GiB-seconds, which the section on query credits explains. ## Monthly event quota The monthly event quota is the workspace's free million plus what each paid member adds. It is shared by the whole workspace and resets on the first of the month, UTC. Example: one member on Max, two on Pro and three on Free. | Source | Events per month | | ----------------------------------- | ---------------- | | Included with the workspace | 1,000,000 | | 1 member on Max | + 1,000,000 | | 2 members on Pro | + 200,000 | | 3 members on Free | 0 | | **Total** | **2,200,000** | To get more quota, put more members on paid plans or upgrade existing ones. A change reaches the system within a minute. When the quota is used up, new events are refused with `402 quota_exceeded` until the month turns or the quota grows; refused events are not stored. Your product should stop sending at that point, see the [API reference](https://docs.tuumo.fi/docs/api-reference/#errors). The quota is checked against counts up to about half a minute old, so a busy workspace can go somewhat over it before events are refused. The **Billing** page shows the month's quota and how much of it is used. ## Query credits A query credit is one gigabyte of query memory for one second: a GiB-second. A query that runs for 10 seconds with 1 GiB of memory costs 10 credits, and one that runs for 10 seconds with 4 GiB costs 40. A quick query over little data costs a few credits; a slow one over a lot of data costs more. - Credits are personal and counted per workspace. One member running out does not affect the others. - Only the run that gives the answer is charged. If a query runs out of memory and Tuumo runs it again with more, the first run costs nothing. - Looking at a stored result is free. Running a query again, a saved query or an export costs credits like any other query. - When the system is busy, queries from higher plans run first: Max, then Pro, then Free. - When the credits are used up, new queries are refused with "this account has used its query credits for the month; try again next month or upgrade the plan". They count again from the first of the month (UTC). Your AI tool reports how many credits a query used. The sidebar and the **Account** page show this month's credits, for example "38% used", and when they reset. ## Query memory and time limits A query starts with 1 GiB of memory, or with the size the same query needed last time. If it needs more, Tuumo runs it again with more, up to the limit of the plan. A query that needs more than the limit is stopped: narrow the time range, ask for fewer breakdowns, or run it for a member on a higher plan. A query that runs longer than the time limit is stopped too. | Plan | Starts at | Up to | Time limit per query | | -------- | --------- | ----- | -------------------- | | **Free** | 1 GiB | 2 GiB | 60 seconds | | **Pro** | 1 GiB | 4 GiB | 5 minutes | | **Max** | 1 GiB | 4 GiB | 15 minutes | A plan also sets how many queries a member can run at once and have waiting, how long results are kept, how many rows an export holds and how many saved queries the workspace may hold when the member saves one: | Plan | At once | Waiting or running | Results kept | Export rows | Saved queries | | -------- | ------- | ------------------ | ------------ | ----------- | ------------- | | **Free** | 1 | 5 | 7 days | 1,000,000 | 20 | | **Pro** | 2 | 20 | 30 days | 50,000,000 | 200 | | **Max** | 4 | 50 | 90 days | No limit | 2,000 | ## Billing Billing comes later. Nothing can be bought or paid in the app yet: the **Billing** page shows the monthly event quota and these plans for information. Until billing arrives, plans are not self-service: Tuumo sets a member's plan by hand. A workspace admin can ask for a change by writing to support@tuumo.fi from the email address of their account; billing in the app comes later. --- # Roles and permissions > A workspace has three roles. Every member can query data through an AI tool, Admins also manage the workspace, and the Owner is the one Admin who cannot be removed. ## What each role can do The roles are Member, Admin and Owner. In the product's own terms, a Member is an `analyst`: the same role names are used for API keys and AI tools, so the permissions of a person and of a machine are the same sets. | Action | Member | Admin | Owner | | --------------------------------------------------- | ------ | --------------------- | ----------------------------- | | Connect an AI tool and query data | Yes | Yes | Yes | | See products and the event list | Yes | Yes | Yes | | Save queries, run them again and export results | Yes | Yes | Yes | | See the AI tools connected to the workspace | Yes | Yes | Yes | | Disconnect their own AI tools | Yes | Yes | Yes | | Change their own profile, password and email | Yes | Yes | Yes | | Leave the workspace | Yes | Yes | After transferring ownership | | See API keys | – | Yes | Yes | | Create and revoke API keys | – | Yes | Yes | | Rename and delete products, delete events | – | Yes | Yes | | Invite and remove members | – | Yes | Yes | | Change a member's role | – | Yes, except the Owner | Yes | | Disconnect another member's AI tools | – | Yes | Yes | | Change the workspace name and the event retention | – | Yes | Yes | | Transfer ownership | – | – | Yes | | Delete the workspace | – | – | Yes | ## The Owner A workspace always has exactly one Owner, and at least one Admin, counting the Owner. - The person who creates the workspace is its Owner. - The Owner cannot leave, be removed or be demoted. To step down they transfer ownership to another member, and the previous Owner becomes an Admin. - An Admin can leave or be demoted freely, because the Owner remains. - Before the Owner deletes their account, each workspace they own that has other members must be transferred. A workspace where they are the only member is deleted with the account. - An invitation carries a role: Member or Admin. Nobody can be invited as Owner. - Deleting a workspace ends access within a minute: its keys and AI-tool connections stop working, and its data is destroyed after 30 days. ## API keys and AI tools Role and plan are separate. The role decides what a member may manage; the plan decides how much they can query. A Member can be on Max and an Owner can be on Free. A member sees their own plan and query credits on the **Account** page, see [Plans and billing](https://docs.tuumo.fi/docs/plans-and-billing/). **API keys** hold a role of their own. A key is never an Owner. Keep an `analyst` or `admin` key on your server; never ship it in a client application. | Key role | What the key can do | | --------- | --------------------------------------------------------------------------------------------------------- | | `ingest` | Sends events and nothing else. It cannot read data, so it is the key for a client application | | `analyst` | Reads and queries data, for example for a dashboard. It cannot send events | | `admin` | Everything an `analyst` can do and sends events, and manages products and keys and files and lists deletion requests through an AI tool's tools | A key can never be given more than the member who creates it holds. Keys belong to the workspace, and each key records the member who made it: its queries run under that member's plan and use that member's query credits. **AI tools** act with the role of the member who connected them, and a change of role reaches the tool within a minute. A Member's tool can read and query data, save queries and export results. An Admin's or the Owner's tool can also manage products and API keys and file requests to delete data. No AI tool can send events, invite people, change roles or settings or delete the workspace, whatever the role of the member behind it. Removing a member disconnects their AI tools within a minute. The API keys they created keep working, because keys belong to the workspace, except that a key can run queries only while the member who made it is still in the workspace. ## Optional - [GOOSE framework](https://www.tuumo.fi/resources/goose/): Goals, Outcomes, Opportunities, Solutions, Experiments: a structured way to navigate uncertainty, make better decisions and keep learning. - [Goal clarity workshop](https://www.figma.com/community/file/1550764516812758250/goose-goal-clarity-workshop): Turn a company's vision and goals into concrete, testable strategic hypotheses, with the leadership team and product leaders in one room. - [Product metrics](https://www.tuumo.fi/resources/product-metrics/): Define clear, actionable metrics aligned with business outcomes, using the retention-first RARRA flywheel. - [Defining product outcomes](https://www.tuumo.fi/resources/define-product-outcomes/): Identify critical bottlenecks, map dependencies, prioritize high-impact problems and define SMART outcomes. - [Continuous learning loop](https://www.tuumo.fi/resources/goose/continuous-learning/): How to conduct systematic research at every GOOSE level to maximize organizational learning. - [Conquer the messy middle](https://www.tuumo.fi/resources/conquer-the-messy-middle/): Bridge the gap between customer problems and business impact with Impact, Outcome and Opportunity. - [Team Topologies for SMEs](https://www.tuumo.fi/resources/team-topologies-for-smes/): The four team types and three interaction modes as hats the same people wear in a small company.